思路:此题目不难,但是Testbench很有意思
对于case语句的使用,保持良好的代码风格,需要添加default情况,防止select出现以上列举的取值之外的数值,导致电路中出现不必要的锁存器。另一方面,当每个取值情况下执行的代码超过一句,需要使用begin…end包含,如果只有一句,则可以省略begin…end。
`timescale 1ns/1ns
module data_select(
input clk,
input rst_n,
input signed[7:0]a,
input signed[7:0]b,
input [1:0]select,
output reg signed [8:0]c
);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
c <= 9'd0;
end
else begin
case(select)
2'd0:begin
c <= a;
end
2'd1:begin
c <= b;
end
2'd2:begin
c <= a + b;
end
2'd3:begin
c <= a - b;
end
default:
c <= 9'd0;
endcase
end
end
endmodule
Testbench
`timescale 1ns/1ns
module testbench();
reg signed [7:0] a,b;
reg [1:0] select;
reg clk=0;
reg rst_n;
wire signed [8:0]c;
initial begin
$dumpfile("out.vcd");
$dumpvars(0, testbench);
end
initial begin
repeat(100)
#5 clk = ~clk;
end
data_select dut(
.clk(clk),
.rst_n(rst_n),
.a(a),
.b(b),
.select(select),
.c(c)
);
initial begin
rst_n = 0;
a = 8'b00000011;
b = 8'b00000001;
select = 2'd0;
#10
rst_n = 1;
#20;
select = 2'd2;
#30;
select = 2'd3;
#30;
#70;
end
endmodule
注意:要想clk出现锯齿波形,需要使用repeat()语句。否则clk的波形就是阴影。
initial begin
repeat(100)
#5 clk = ~clk;
end
这段代码非常重要
由于a,b,select,clk,rst_n需要出现在initial块中,所以需要在testbench中重定义为reg 类型,但是不明白为什么c定义为reg型就报错,提示只能定义为线网型。