• 欢迎光临~

HDLBits-Verilog Practice-3-Verification: Reading Simulations -> Verification: Writing Testbenches

1. 本文范围 Verification: Reading Simulations -> Verification: Writing Testbenches

2. 网页本身给出的语法点，和一些语法的使用思路

3. 做题过程中的反思

4. 参考HDLBits 中文导学 - 知乎

5. 参考答案xiaop1/Verilog-Practice: HDLBits website practices & solutions

Finding bugs in code

Bugs mux2

1. A mux coded as `(~sel & a) | (sel & b)` does not work for vectors.
This is because these are bitwise operators, and sel is only a 1 bit wide quantity, which leaves the upper bits of a and b zeroed. It is possible to code it using the replication operator, but this is somewhat difficult to read: `( {8{~sel}} & a ) | ( {8{sel}} & b )`

2. The simulation waveform shows that when sel = 1, a should be selected. This is flipped in the suggested code.

因此，我们有， `assign out = sel ? a : b;`

Bugs nand3

You must use the provided 5-input AND gate:`module andgate ( output out, input a, input b, input c, input d, input e );`

``````module top_module (input a, input b, input c, output out);
wire temp;
andgate inst1 ( temp, a, b, c, 1'b1, 1'b1 );
assign out=~temp;

endmodule
``````

Bugs mux4

1. 声明临时向量时记得要写向量域
2. 这里使用 分治算法 解决 选择 问题，需要分析 选择的依据（喂给子模块的sel）的选取 。
``````module top_module (
input [1:0] sel,
input [7:0] a,
input [7:0] b,
input [7:0] c,
input [7:0] d,
output [7:0] out  ); //

wire [7:0]mux0, mux1;
mux2 mux00 ( sel[0],    a,    b, mux0 );
mux2 mux01 ( sel[0],    c,    d, mux1 );
mux2 mux02 ( sel[1], mux0, mux1,  out );

endmodule
``````

1. 对于向量是否为全0 应先使用 归约运算符 得到 1-bit 的结果；再写判断
2. 组合逻辑 if-else 要写全避免锁存器；
``````always @(*) begin
case (do_sub)
0: out = a+b;
1: out = a-b;
endcase

if (~(|out))
result_is_zero = 1;
else
result_is_zero = 0;
end
``````

Bugs case

``````module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid=1 );

always @(*)begin
case (code)
8'h45: out = 0;
8'h16: out = 1;
8'h1e: out = 2;
8'h26: out = 3;
8'h25: out = 4;
8'h2e: out = 5;
8'h36: out = 6;
8'h3d: out = 7;
8'h3e: out = 8;
8'h46: out = 9;
default: begin
valid=0;
out=0;
end
endcase
end
endmodule
``````

always块 里的 case语句中的 default 对valid 的赋值（L19） 将会永久覆盖 上面module参数声明列表中的默认赋值（L4）。即，上述代码将 valid 恒置为0。

（由此看来，在参数列表的默认赋值没什么用，太容易被覆盖了。）

``````module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid
);

// A combinational always block.
always @(*) begin
out = 0;		// To avoid latches, give the outputs a default assignment
valid = 1;		//   then override them in the case statement. This is less
//   code than assigning a value to every variable for every case.
case (code)
8'h45: out = 0;
8'h16: out = 1;
8'h1e: out = 2;
8'h26: out = 3;		// 8'd26 is 8'h1a
8'h25: out = 4;
8'h2e: out = 5;
8'h36: out = 6;
8'h3d: out = 7;
8'h3e: out = 8;
8'h46: out = 9;		// 6'h46 is 8'h46
default: valid = 0;
endcase
end

endmodule
``````

Build a circuit from a simulation waveform.

笔记

Sim/circuit9

``````module top_module ();
reg clk=0;
always #5 clk = ~clk;  // Create clock with period=10
initial `probe_start;   // Start the timing diagram

`probe(clk);        // Probe signal "clk"
`probe(a);
`probe(q);

// A testbench
reg in=0;
reg a=1;
initial begin
#40 a<=0;
#50 \$finish;            // Quit the simulation
end
reg [3:0]q;
test inst1 ( clk,a,q );   // Sub-modules work too.

endmodule

module test (
input clk,
input a,
output reg [3:0] q=4'h3 );	//initialization

always@(posedge clk)
if(a)
q<=4'h4;
else
q<= (q+1'b1==4'h7)? 4'h0:q+1'b1;

endmodule
``````

Sim/circuit8

``````assign p=clock?a&clock:p;

always@(negedge clock)
q<=p|clock;
``````

Verification: Writing Testbenches

Tb/and

``````initial begin
in = 2'b00;
#10
in = 2'b01;
#10
in = 2'b10;
#10
in = 2'b11;
end

andgate inst(.in(in), .out(out));
``````