hdlbits网站:HDLBits (01xz.net)
其他hdlbits博客:
【hdlbits】个人学习交流分享(带答案)——verilog language部分-CSDN博客
【hdlbits】个人学习交流分享(带答案)——combinational logic部分-CSDN博客
【hdlbits】个人学习交流分享(带答案)——sequential logic部分-CSDN博客
【hdlbits】个人学习交流分享(带答案)——finite state machines(FSM)-CSDN博客
正文:
Verification: Reading Simulations
Finding bugs in code
Mux
要8 位宽的 2 对 1 多路复用器
原代码:
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output out );
assign out = (~sel & a) | (sel & b);
endmodule
问题:1.out位宽为1位,应该改成8位。
2.sel是1位,和8位的a/b进行&运算只会得到1位结果
正确答案:
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0]out );
assign out = ({8{sel}} & a) | (~{8{sel}} & b);
endmodule
NAND
题目给的5输入AND门
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
问题:1.用5 输入 AND 门实现3输入NAND门,没有给d和e分配信号
2.另外接口排列out位置也不对
3.也没有体现出NAND门的效果
正确答案:
module top_module (input a, input b, input c, output out);//
wire out1;
andgate inst1 (out1,a,b,c,1'b1,1'b1);
assign out=~out1;
endmodule
Mux
要求实现4 对 1 多路复用器,提供了如下8位宽 2 对 1 多路复用器:
module mux2 (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0] out
);
原代码:
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
问题:1.wire位宽不对,应该是8位
2.例化名与模块名(mux2)重复了,语法错误
3.例化名与变量名(mux0和mux1)重复了,语法错误
4.sel信号配置错误,无法选出c信号。
mux2中要选mux1赋给out要求sel[1]为0,这时mux1中只能选d赋给mux1,可以实现“d→mux1→out”,无法实现“c→mux1→out”,也就是无法片选出c信号
正确答案:
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 mux0_inst ( sel[0], a, b, mux0 );
mux2 mux1_inst ( sel[0], c, d, mux1 );
mux2 mux2_inst ( sel[1], mux0, mux1, out );
endmodule
add/sub
原代码:
// 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
问题:1.if-else语句不完整缺少else,出现了未设定的状态,进行综合会出现latch
2.if内的(~out)是对out结果按位取反,这混淆逻辑非和按位非,出现错误。
举一个例子理解:
out是8'b10001000,~out就是8'b01110111,if的()内进行的是布尔值的判断,这里~out的布尔值为true(逻辑1),所以会执行“result_is_zero = 1;”这一句,即认定out为0是真。这显然是错误的。
布尔值的判断应该用逻辑非!out,只有out是8'b00000000时候,也就是只有out为0时候,!out才为ture(逻辑1),才会执行“result_is_zero = 1;”这一句,即认定out为0是真。
虽然在很多情况下“逻辑与或非”和‘‘按位与或非’’都仿真综合得到正确的结果,但是这并不适用于所有情况,两者并不完全等价,所以要能够区分“逻辑与或非”和‘‘按位与或非’’
按位运算符、逻辑运算符_两个数的逻辑运算和按位运算-CSDN博客
正确答案:
// 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;
else
result_is_zero = 0;
end
endmodule
case statement
原代码
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
问题:1.vaild赋初值的位置错误,在变量声明的括号内不会起作用,想要赋初值在always块内起作用,应该把赋值语句放always块内。
2.把8'd26改为8'h26,6'h46改为8'h46
3.没有给out分配默认值,default下应该给out赋值(按理说这里随便赋都可以,我赋值为4'hf,结果仿真不对,核对了时序图作者这里要求default下必须把out赋值为0,再次吐槽作者项目要求都提不清楚)
module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid );//
always @(*)begin
valid=1;
case (code)
8'h45: out = 4'h0;
8'h16: out = 4'h1;
8'h1e: out = 4'h2;
8'h26: out = 4'h3;
8'h25: out = 4'h4;
8'h2e: out = 4'h5;
8'h36: out = 4'h6;
8'h3d: out = 4'h7;
8'h3e: out = 4'h8;
8'h46: out = 4'h9;
default:begin
valid=0;
out=4'h0;
end
endcase
end
endmodule
buliding a circuit from a simulation waveform
combinational circuit 1

组合电路可以根据波形图写真值表或者写逻辑表达式,没难度,直接放答案,下面题目同
module top_module (
input a,
input b,
output q );//
assign q = a&b; // Fix me
endmodule
combinational circuit 2

module top_module (
input a,
input b,
input c,
input d,
output q );//
assign q =~a & ~b & ~c & ~d | ~a & ~b & c & d | ~a & b & ~c & d | ~a & b & c & ~d | a & ~b & ~c & d | a & ~b & c & ~d | a & b & ~c & ~d | a & b & c & d; // Fix me
endmodule
combinational circuit 3

module top_module (
input a,
input b,
input c,
input d,
output q );//
assign q = b & d | b & c | a & d | a & c; // Fix me
endmodule
combinational circuit 4

module top_module (
input a,
input b,
input c,
input d,
output q );//
assign q =b | c;// Fix me
endmodule
combinational circuit 5

根据仿真波形图很容易看出这是多路选择器,c是选择端,a、b、d、e是数据端,q是输出端
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)
4'd0: q = b;
4'd1: q = e;
4'd2: q = a;
4'd3: q = d;
default:q = 4'hf;
endcase
end
endmodule
combinational circuit 6

本题也是多路选择器,a是选择端,q是输出端,没有给出数据端
module top_module (
input [2:0] a,
output [15:0] q );
always @(*) begin
case(a)
3'd0: q = 16'h1232;
3'd1: q = 16'haee0;
3'd2: q = 16'h27d4;
3'd3: q = 16'h5a0e;
3'd4: q = 16'h2066;
3'd5: q = 16'h64ce;
3'd6: q = 16'hc526;
default:q = 16'h2f19;
endcase
end
endmodule
sequential circuit 7

module top_module (
input clk,
input a,
output reg q );
always @(posedge clk) begin
q <= ~a;
end
endmodule
sequential circuit 8

当clock为1,p波形和a相同;clock为0,p和上一个clk的p一样,保持不变。
当clock下降沿时候,q的数值同q,注意的是,下降沿出现的clk内,q数值就和变到p相同了,这里没有一个clk的时延,所以赋值要用阻塞赋值。
module top_module (
input clock,
input a,
output p,
output q );
assign p = clock ? a : p;
always @(negedge clock) begin
q = p;//看波形,下降沿出现的clk,q数值就和变到p相同了,没有时延,所以是阻塞赋值“=”。
end
endmodule
sequential circuit 9

本题是一个6禁止计数器,a是置数信号,置数置为4。
module top_module (
input clk,
input a,
output reg [3:0] q );
always @(posedge clk) begin
if(a) begin
q <= 4'd4;
end
else if(q == 4'd6) begin
q <= 4'd0;
end
else begin
q <= q + 4'd1;
end
end
endmodule
sequential circuit 10

module top_module (
input clk,
input a,
input b,
output q,
output reg state );
assign q = a^b^state;
always @(posedge clk) begin
if (a&b) begin
state <= 'd1;
end
else if (~a&~b) begin
state <= 'd0;
end
else begin
state <= state;
end
end
endmodule
verification:writing testbenches
clock
提供模块:module dut ( input clk ) ;

module top_module ( );
reg clk;
dut ut(clk);
initial begin
clk = 1'b0;
end
always begin
#5 clk = ~clk;
end
endmodule
testbench 1

module top_module ( output reg A, output reg B );//
// generate input patterns here
initial begin
A = 1'b0;
B = 1'b0;
#10 A = 1'b1;
#5 B = 1'b1;
#5 A = 1'b0;
#20 B = 1'b0;
end
endmodule
把A和B分开写更清楚:
module top_module ( output reg A, output reg B );//
// generate input patterns here
initial begin
A = 1'b0;
#10 A = 1'b1;
#10 A = 1'b0;
end
initial begin
B = 1'b0;
#15 B = 1'b1;
#25 B = 1'b0;
end
endmodule
AND gate
提供的AND模块:
module andgate (
input [1:0] in,
output out
);

module top_module();
reg [1:0]in;
reg out;
andgate u0(in,out);
initial begin
in[0] = 1'b0;
in[1] = 1'b0;
#10 in[0] = 1'b1;
#10
in[0] = 1'b0;
in[1] = 1'b1;
#10 in[0] = 1'b1;
end
endmodule
testbench 2
提供的模块:
module q7 (
input clk,
input in,
input [2:0] s,
output out
);

module top_module();
reg clk,in,out;
reg [2:0]s;
q7 ut(clk,in,s,out);
initial begin
in=1'b0;
#20 in=1'b1;
#10 in=1'b0;
#10 in=1'b1;
#30 in=1'b0;
end
initial begin
s=3'd2;
#10 s=3'd6;
#10 s=3'd2;
#10 s=3'd7;
#10 s=3'd0;
end
initial begin
clk=0;
end
always begin
#5 clk=~clk;
end
endmodule
T filp-flop
提供的T触发器模块:
module tff (
input clk,
input reset, // active-high synchronous reset
input t, // toggle
output q
);
module top_module ();
reg clk,reset,t,q;
tff ut(clk,reset,t,q);
initial begin
reset=1'd0;
#10 reset=1'd1;
#10 reset=1'd0;
end
always@(posedge clk)begin
if(reset)//题干表述,复位reset将toggle(t)置0,复位信号无效后将t置1;
t<=1'd0;
else
t<=1'd1;
end
initial begin
clk=0;
end
always begin
#5 clk=~clk;
end
endmodule
到这里hdlbits总共178道题目练习就彻底结束了,如果能吃透这178道题,也算是对verilog HDL基础有了不错的了解,算是为FPGA开发和数字IC设计打了HDL 的基础
1066

被折叠的 条评论
为什么被折叠?



