前言
-
之前的文章《如何学习verilog,如何快速入门?》中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站。
-
这篇文章,是接着《verilog练习:hdlbits网站上的做题笔记(7)》写的!
4. Verification: Reading Simulations
4.1 Finding bugs in code
4.1.1 Mux(Bugs mux2)
This 8-bit wide 2-to-1 multiplexer doesn’t work. Fix the bug(s).
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output out );
assign out = (~sel & a) | (sel & b);
endmodule
- 那就熟悉一下二选一选择器,通过波形,
sel为1时,输出a,sel为0时,输出b
//我的答案
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0] out );
//assign out = sel?a:b;
always@(*)
if(sel) out=a;
else out=b;
endmodule
4.1.2 NAND(Bugs nand3)
This three-input NAND gate doesn’t work. Fix the bug(s).
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);//
andgate inst1 ( a, b, c, out );//上面说的是五输入与门!
endmodule
//我的答案!
module top_module (input a, input b, input c, output out);//
wire out_reg;
andgate inst1 ( out_reg,a, b, c,1'b1,1'b1);
assign out=~out_reg;
//nand ( out ,a, b, c);
//assign out=~(a&b&c);
endmodule
4.1.3 Mux(Bugs mux4)
This 4-to-1 multiplexer doesn’t work. Fix the bug(s).
//给出有bug的
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 mux0, mux1;
mux2 mux0 ( sel[0], a, b, mux0 );
mux2 mux1 ( sel[1], c, d, mux1 );
mux2 mux2 ( sel[1], mux0, mux1, out );
endmodule
先编译,将mux0/mux1/mux2修改为mux_0/mux_1/mux_2,发现下面的时序图!
sel=0,out=a;
sel=1,out=b;
sel=2,out=c;
sel=3,out=d;
//四选一多路选择器,需要选择4个bit的
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 mux_0 ( sel[0], a, b, mux0 );
mux2 mux_1 ( sel[0], c, d, mux1 );
mux2 mux_2 ( sel[1], mux0, mux1, out );
endmodule
4.1.4 Add/sub(Bugs addsubz)
The following adder-subtractor with zero flag doesn’t work. Fix the bug(s).
//原题bug
// synthesis verilog_input_version verilog_2001
module top_module (
input do_sub,
input [7:0] a,
input [7:0] b,
output reg [7:0] out,
output reg result_is_zero
);//
always @(*) begin
case (do_sub)
0: out = a+b;
1: out = a-b;
endcase
if (~out)
result_is_zero = 1;
end
endmodule
- 参考答案
// synthesis verilog_input_version verilog_2001
module top_module (
input do_sub,
input [7:0] a,
input [7:0] b,
output reg [7:0] out,
output reg result_is_zero
);//
always @(*) begin
case (do_sub)
0: out = a+b;
1: out = a-b;
endcase
if (8'd0==out)
result_is_zero = 1;
else
result_is_zero = 0;
end
endmodule
4.1.5 Case statement(Bugs case)
This combinational circuit is supposed to recognize 8-bit keyboard scancodes for keys 0 through 9. It should indicate whether one of the 10 cases were recognized (valid), and if so, which key was detected. Fix the bug(s).
//原题bug
module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid=1 );//
always @(*)
case (code)
8'h45: out = 0;
8'h16: out = 1;
8'h1e: out = 2;
8'd26: out = 3;
8'h25: out = 4;
8'h2e: out = 5;
8'h36: out = 6;
8'h3d: out = 7;
8'h3e: out = 8;
6'h46: out = 9;
default: valid = 0;
endcase
endmodule
- 参考答案
module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid=1 );//
always @(*)
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: out = 0;
endcase
//直接使用了assign,是对的,但是output是reg型,为什么没报错?
//assign valid = code==8'h45|code==8'h16|code==8'h1e|code==8'h26|code==8'h25|code==8'h2e|code==8'h36|code==8'h3d|code==8'h3e|code==8'h46;
always@(*)
valid=(out=='d0 && code!='h45)?0:1;
endmodule
4.2 Build a circuit from a simulation waveform
- 根据波形写电路!
4.2.1 Combinational circuit 1(Sim/circuit1)
module top_module (
input a,
input b,
output q );//
assign q = a&b; // Fix me
endmodule
4.2.2 Combinational circuit 2(Sim/circuit2)
- 偶数个1,输出为1;奇数个1,输出为0;
module top_module (
input a,
input b,
input c,
input d,
output q );//
assign q = a~^b~^c~^d; // Fix me
endmodule
4.2.3 Combinational circuit 3(Sim/circuit3)
module top_module (
input a,
input b,
input c,
input d,
output q );//
assign q = b?(c|d):(a?(c|d):0); // Fix me
endmodule
4.2.4 Combinational circuit 4(Sim/circuit4)
module top_module (
input a,
input b,
input c,
input d,
output q );//
assign q = b|c; // Fix me
endmodule
4.2.5 Combinational circuit 5(Sim/circuit5)
module top_module (
input [3:0] a,
input [3:0] b,
input [3:0] c,
input [3:0] d,
input [3:0] e,
output [3:0] q );
always@(*)begin
case(c)
0:q=b;
1:q=e;
2:q=a;
3:q=d;
default:q='hf;
endcase
end
endmodule
4.2.6 Combinational circuit 6(Sim/circuit6)
module top_module (
input [2:0] a,
output [15:0] q );
always@(*)
case(a)
'd0:q='h1232;
'd1:q='haee0;
'd2:q='h27d4;
'd3:q='h5a0e;
'd4:q='h2066;
'd5:q='h64ce;
'd6:q='hc526;
'd7:q='h2f19;
endcase
endmodule
4.2.7 Sequential circuit 7(Sim/circuit7)
module top_module (
input clk,
input a,
output q );
always@(posedge clk)
q <= ~a;
endmodule
4.2.8 Sequential circuit 8(Sim/circuit8)
module top_module (
input clock,
input a,
output p,
output q );
always@(*)
if(clock)
p = a;
always@(negedge clock)
q <= p;
endmodule
4.2.9 Sequential circuit 9(Sim/circuit9)
module top_module (
input clk,
input a,
output [3:0] q );
always@(posedge clk)
if(a) q<='d4;
else if(q=='d6)q<='d0;
else q <= q+1'b1;
endmodule
4.2.10 Sequential circuit 10(Sim/circuit10)
module top_module (
input clk,
input a,
input b,
output q,
output state );
always@(posedge clk)
if(a == b)
state <= a;
assign q = a^b^state;
endmodule
5. Verification: Writing Testbenches
5.1 Clock(Tb/clock)
module top_module ( );
reg clk;
initial clk='b0;
always #5 clk=~clk;
dut dut_inst(.clk(clk));
endmodule
5.2 Testbench1
module top_module ( output reg A, output reg B );//
// generate input patterns here
initial begin
A=0;
B=0;
#10;//10
A=1;
#5;//15
B=1;
#5;//20
A=0;
#20;
B=0;
end
endmodule
5.3 AND gate
module top_module();
reg [1:0] in;
wire out;
initial begin
in=2'b00;
#10;
in=2'b01;
#10;
in=2'b10;
#10;
in=2'b11;
end
andgate andgate_inst(.in(in),.out(out));
endmodule
5.4 Testbench2
module top_module();
reg clk;
reg in;
reg [2:0]s;
wire out;
initial clk='b0;
always #5 clk=~clk;
initial begin
in='b0;
s='d2;
#10;//10
s='d6;
#10;//20
in='b1;
s='d2;
#10;//30
in='b0;
s='d7;
#10;//40
in='b1;
s='d0;
#30;//70
in='b0;
end
q7 q7_inst(
.clk (clk),
.in (in ),
.s (s ),
.out (out)
);
endmodule
5.5 T flip-flop
module top_module ();
reg clk;
reg reset;
reg t;
wire q;
initial clk=1'b0;
always #5 clk=~clk;
initial begin
reset = 1'b0;
#3;
reset = 1'b1;
#10;
reset = 1'b0;
end
always@(posedge clk)
if(reset) t <= 1'b0;
else t <= 1'b1;
tff tff_inst(
.clk(clk),
.reset(reset), // active-high synchronous reset
.t(t), // toggle
.q(q)
);
endmodule
后记
- 本系列到此完毕!