考研上微电子入了材料坑,开始自学verilog
此文很多也是在其他优秀的博文中复制过来
(在此也非常感谢大家在网上分享的笔记)
仅为方便记录自己学习的笔记
习题链接:HDLBits
四、验证
4.1,找bug
MUX2
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0]out );
assign out = sel?a:b;
endmodule
MUX4
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]m0, m1;
mux2 mux0 ( sel[0], a, b, m0 );
mux2 mux1 ( sel[0], c, d, m1 );
mux2 mux2 ( sel[1], m0, m1, out );
endmodule
NAND
module top_module (input a, input b, input c, output out);//
wire q;
andgate inst1 ( q,a, b, c, 1,1 );
assign out = ~q;
endmodule
ADD/SUB
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==0)
result_is_zero = 1;
else
result_is_zero = 0;
end
endmodule
CASE
module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid=1 );//
always @(*)begin
valid = 1;
out = 0;
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: valid = 0;
endcase
end
endmodule
4.2,根据仿真波形构建电路
中间还有几题没啥写的必要
sequential circuit 7
输出q的状态时输入a的反
module top_module (
input clk,
input a,
output q );
always@(posedge clk)
q <= ~a;
endmodule
sequential circuit 8
根据波形图,判断输出p是在高电平时由输入a赋值,低电平保持;输出q是下降沿取反
module top_module (
input clock,
input a,
output p,
output q );
initial begin// 定义输出q的初始量 设置为 1'b1 第一次设置的为0 但是仿真后发现q的值是反的
q = 1'b1;
end
always@(negedge clock)
q <= ~q;
always@(*)begin//高电平时赋值
if(clock) p=a;
else p=p;
end
endmodule
但是仿真后还是不对,根据答案可以看出,在一次下降沿中q并没有翻转,
看了一会想明白了,原来就是下降沿是把p的值赋给q,行吧0.0
module top_module (
input clock,
input a,
output p,
output q );
always@(negedge clock)
q <= p;
always@(*)begin//高电平时赋值
if(clock) p=a;
else p=p;
end
endmodule
sequential circuit 9
clk上边沿,a高电平时q为4,a低电平时q变为模七计数
module top_module (
input clk,
input a,
output [3:0] q );
always@(posedge clk)begin
if(a) q<=4;
else if(q==6) q<=0;
else q<=q+1;
end
endmodule
sequential circuit 10
根据时序图,看出,输出state的状态是由输入a与b有关的组合逻辑,当a b同时为1时,state输出1,当a b同时为零时,state输出为0,当a b其中一个为1一个为0时,state输出不变;而输出q的状态不仅与输入a与b有关,还和state的状态有关,当state为1时,q时a与b的同或,当state为0时,q是a与b的异或
module top_module (
input clk,
input a,
input b,
output q,
output state );
always@(posedge clk)begin
if(a==1&b==1) state<=1;
else if(a==0&b==0) state<=0;
else state<=state;
end
assign q =state?(a~^b):a^b;
endmodule
(2024.03.13)
五、验证:编写测试平台
clock
You are provided a module with the following declaration:
module dut ( input clk ) ;
Write a testbench that creates one instance of module dut (with any instance name), and create a clock signal to drive the module's clk input. The clock has a period of 10 ps. The clock should be initialized to zero with its first transition being 0 to 1.
`timescale 1ps/1ps
module top_module();
reg clk;
integer count = 0;
integer period = 10;
dut dut (
.clk(clk)
);
always begin
if (count == period/2) begin
clk = ~clk; // 五个周期翻转一次
count <= 1; // 重置计数
end else begin
count <= count + 1; // 计数1~5,五个周期
end
#1; // Increment simulation time
end
initial begin
clk = 0;
end
endmodule
刚看到时,比较懵,不知道怎么写,找AI学习了一波,最后搞懂了。
关于这个 `timescale 1ps/1ps :在 Verilog 代码中,timescale
语句通常用于指定时间单位和时间精度。一般来说,timescale
语句应该在代码的开头部分声明,以确保正确指定时间单位和时间精度。虽然并不是强制要求在代码的开头部分声明 timescale
语句,但最佳实践是将其放在代码的开头,以提高代码的可读性。
其实`timescale 1ps/1ps不加也不影响仿真结果
testbench1
Create a Verilog testbench that will produce the following waveform for outputs A and B:
直接赋值
module top_module ( output reg A, output reg B );
// generate input patterns here
initial begin
A=0;B=0;
#10 A=1;
#5 B=1;
#5 A=0;
#20 B=0;
end
endmodule
AND gate
You are given the following AND gate you wish to test:
module andgate (
input [1:0] in,
output out
);
You are given the following AND gate you wish to test:
module top_module();
reg [1:0]in,out;
initial begin
in = 2'b00;
#10 in = in+1;
#10 in = in+1;
#10 in = in+1;
end
andgate sum(in, out);
endmodule
testbench2
module q7 (
input clk,
input in,
input [2:0] s,
output out
);
Write a testbench that instantiates module q7 and generates these input signals exactly as shown in the waveform above.
module top_module();
reg in,out;
reg clk=0;
reg [2:0]s;
always #5 clk=~clk;
initial begin
in=0;s=2;
#10 s=6;
#10 begin in=1;s=2;end
#10 begin in=0;s=7;end
#10 begin in=1;s=0;end
#30 in=0;
end
q7 q7(clk,in,s,out);
endmodule
T触发器
You are given a T flip-flop module with the following declaration:
module tff (
input clk,
input reset, // active-high synchronous reset
input t, // toggle
output q
);
Write a testbench that instantiates one tff and will reset the T flip-flop then toggle it to the "1" state.
module top_module ();
reg clk=0;
reg reset=0;
reg t,q;
always #5 clk=~clk;
always@(posedge clk)begin//reset为高电平时,t置为零,为低电平时,t和输入数值一致
if(reset==1)
t <= 0;
else
t <= t;
end
initial begin
#5 t=1;
#30 reset=1;
#5 t=1;
#30 reset=0;
#5 t=1;
end
tff tff(clk,reset,t,q);
endmodule
T触发器是输入为1且reset为低的时候,输出翻转。
(2024.03.13)