测试文件写法参考:使用VIVADO编写简单的Verilog程序和Testbench
加法器
半加器
-
其真值表如下:
-
其电路图为
-
其表达式为
-
实现代码
`timescale 1ns / 1ps
module half_adder(
input a,b,
output sum,cout
);
assign sum=a ^ b;
assign cout=a & b;
endmodule
- 测试文件
module tb_half_adder();
//一般将待测试模块的输入设置为reg,输出设置为wire即可
reg a,b;
reg clk;//clk是时钟
wire sum,cout;
initial
begin//#表示时延,开始的时候电流可能有点不稳定,后面a和b代表信号的初始化
#1
a = 0;
b = 0;
clk = 0;
end
always #5 clk = ~clk;//这个#5也表示时延5个周期,并且always可以用于组合逻辑和时序逻辑,clk = ~clk必须有时延,否则会形成"死锁",代表时序逻辑,信号在这儿停留5个周期
always @(posedge clk)//这个表示触发条件是:边沿触发
begin//这个表示产生随机数
a = {$random} % 2;
b = {$random} % 2;
end
half_adder u1(a,b,sum,cout);//这个是调用原来的仿真文件,我们这个是顺序对应,所以不需要.a(a)这么写了
endmodule
- vivado仿真出来的电路图
- modelsim仿真出来的测试波形
全加器
-
其真值表如下
-
其电路图如下
-
其表达式如下
-
实现代码
`timescale 1ns / 1ps
module adder(
input a,b,c,
output sum,cout
);
wire m1,m2,m3;
assign sum = a ^ b ^ c;
//assign cout = ((a^b)&c)|(a&b);
xor(m1,a,b);
and(m2,m1,c);
and(m3,a,b);
or(cout,m2,m3);
endmodule
- 测试文件
`timescale 1ns / 1ps
module tb_adder();
reg a,b,c;
reg clk;
wire sum,cout;
initial
begin
#1
a = 0;
b = 0;
c = 0;
clk = 0;
end
always #5 clk = ~clk;
always @(posedge clk)
begin
a = {$random} % 2;
b = {$random} % 2;
c = {$random} % 2;
end
adder u1(a,b,c,sum,cout);
endmodule
- 仿真电路图
- 仿真波形
全减器
- 其真值表如下
- 其电路图如下
- 其表达式如下
- 实现代码
`timescale 1ns / 1ps
module Full_subtracter(
input a,b,c,
output d,cin//本位想高位的借位
);
assign d = a ^ b ^ c;
assign cin = (~a & (b^c)) | (b&c);
endmodule
- 测试文件
`timescale 1ns / 1ps
module tb_subtracter();
reg a,b,c;
reg clk;
wire d, cin;
initial
begin
#1
clk = 0;
a = 0;
b = 0;
c = 0;
end
always #5 clk = ~clk;
always @(posedge clk)
begin
a = {$random} % 2;
b = {$random} % 2;
c = {$random} % 2;
end
Full_subtracter u1(a, b, c, d, cin);
endmodule
- 仿真电路图
- 仿真波形
偶校验发生器
- 其真值表如下
- 其电路图如下
- 其表达式如下
- 实现代码
`timescale 1ns / 1ps
module check(
input a,b,c,d,
output p
);
assign p = (c^d)^(a^b);
endmodule
- 测试文件
`timescale 1ns / 1ps
module tb_check();
reg a,b,c,d;
reg clk;
wire p;
initial
begin
#1
clk = 0;
a = 0;
b = 0;
c = 0;
d = 0;
end
always #5 clk = ~clk;
always @(posedge clk)
begin
a = {$random} % 2;
b = {$random} % 2;
c = {$random} % 2;
end
check u1(a,b,c,d,p);
endmodule
- 仿真电路图
- 仿真波形
数据比较器
-
其真值表如下
-
其电路图如下
-
其表达式如下
-
实现代码
`timescale 1ns / 1ps
module comparator(
input a, b,
output Fb, Fe, Fs
);
assign Fb = ~b & a;
assign Fe = ~a & b;
assign Fs = (a & b) | (~a & ~b);
endmodule
- 测试文件
`timescale 1ns / 1ps
module tb_comparator();
reg a, b;
reg clk;
wire Fb, Fe, Fs;
initial
begin
#1
clk = 0;
a = 0;
b = 0;
end
always #5 clk = ~clk;
always @(posedge clk)
begin
a = {$random} % 2;
b = {$random} % 2;
end
comparator u1(a, b, Fb, Fe, Fs);
endmodule
- 仿真电路图
- 仿真波形
编码器
- 其真值表如下
- 实现代码
`timescale 1ns / 1ps
module encoder(
In,
Out
);
input [7:0] In;
output [2:0] Out;
reg [2:0] Out;
always @(In)
begin
case(In)
8'b0000_0001:Out = 3'b111;
8'b0000_0010:Out = 3'b110;
8'b0000_0100:Out = 3'b101;
8'b0000_1000:Out = 3'b100;
8'b0001_0000:Out = 3'b011;
8'b0010_0000:Out = 3'b010;
8'b0100_0000:Out = 3'b001;
8'b1000_0000:Out = 3'b000;
default: Out=3'bxxx;
endcase
end
endmodule
- 测试文件
//`timescale 1ns / 1ps
//module tb_encoder();
//endmodule
`timescale 1ns/1ns
`define clk_period 20
module tb_encoder();
reg [7:0] In;
wire [2:0] Out;
reg clk;
encoder tb_encoder(
.In(In),
.Out(Out)
);
initial clk = 1'b1;
always #`clk_period clk = ~clk;
initial begin
In = 8'b0000_0001;
#`clk_period;
In = 8'b0000_0010;
#`clk_period;
In = 8'b0000_0100;
#`clk_period;
In = 8'b0000_1000;
#`clk_period;
In = 8'b0001_0000;
#`clk_period;
In = 8'b0010_0000;
#`clk_period ;
In = 8'b0100_0000;
#`clk_period;
In = 8'b1000_0000;
#`clk_period;
In = 8'b0000_0000;
#`clk_period;
$stop;
end
endmodule
- 仿真电路图
- 仿真波形
- 小感悟
测试文件的写法还是不太会啊QWQ,后面还是会去好好研究一下测试文件怎么写
译码器
- 其真值表如下
- 实现代码
module decoder(
Y,
S,
A
);
output wire [7:0] Y;
input wire [2:0] S;
input wire [2:0] A;
assign Y = (S==3'b100) ? ~(8'b000_001 << A) : 8'b0000_0000;
endmodule
- 测试文件
`timescale 1ns/1ns
module tb_decoder;
wire [7:0] Y;
reg [2:0] S;
reg [2:0] A;
decoder tb_decoder(
.Y(Y),
.S(S),
.A(A)
);
initial begin
A = 3'b000;
S = 3'b000;
#200;
A = 3'b001;
S = 3'b010;
#200;
A = 3'b000;
S = 3'b001;
#200;
A = 3'b001;
#200;
A = 3'b010;
#200;
A = 3'b011;
#200;
A = 3'b100;
#200 ;
A = 3'b101;
#200;
A = 3'b110;
#200;
A = 3'b111;
#200;
A = 3'b000;
#200;
$stop;
end
endmodule
- 仿真波形
- 莫名其妙显示的是十进制,很难受,后续调整吧QWQ
数据选择器(4选1)
- 其真值表如下
- 其逻辑图如下
- 其表达式如下
- 实现代码
`timescale 1ns / 1ps
module mux(
input D0, D1, D2, D3,
input A0, A1,
output Y
);
assign Y = ((D0 & ~A0 & ~A1)|(D1 & ~A0 & A1)|(D2 & A0 & ~A1)|(D3 & A0 & A1));
endmodule
- 测试文件
`timescale 1ns / 1ps
module tb_mux();
reg D0, D1, D2, D3;
reg A0, A1;
reg clk;
wire Y;
initial
begin
#1
clk = 0;
A0 = 0;
A1 = 0;
D0 = 1;
D1 = 1;
D2 = 1;
D3 = 1;
end
always #5 clk = ~clk;
always @(posedge clk)
begin
A0 = {$random} % 2;
A1 = {$random} % 2;
D0 = {$random} % 2;
D1 = {$random} % 2;
D2 = {$random} % 2;
D3 = {$random} % 2;
end
mux u1(D0, D1, D2, D3, A0, A1, Y);
endmodule
- 仿真电路图
- 仿真波形
多路分配器
- 其真值表如下
- 实现代码
`timescale 1ns / 1ps
module selector(
input D,
input A0, A1,
output Y0, Y1, Y2, Y3
);
// reg Y0, Y1, Y2, Y3;
// initial
// {Y0,Y1,Y2,Y3}=4'b1111;
// always@(*)
// case({A1,A0})
// 2'b00:begin
// Y0 = D; Y1=1'b1; Y2=1'b1; Y3=1'b1;
// end
// 2'b01:begin
// Y0 = 1'b1; Y1=D; Y2=1'b1; Y3=1'b1;
// end
// 2'b10:begin
// Y0 = 1'b1; Y1=1'b1; Y2=D; Y3=1'b1;
// end
// 2'b11:begin
// Y0 = 1'b1; Y1=1'b1; Y2=1'b1; Y3=D;
// end
// endcase
assign Y0=~A1 & ~A0 & D;
assign Y1=~A1 & A0 & D;
assign Y2= A1 & ~A0 & D;
assign Y3= A1 & A0 & D;
endmodule
- 测试文件
`timescale 1ns / 1ps
module tb_selector();
reg D;
reg A0, A1;
reg clk;
wire Y0, Y1, Y2, Y3;
initial
begin
#1
clk = 0;
D = 0;
A0 = 0;
A1 = 0;
end
always #5 clk = ~clk;
always @(posedge clk)
begin
D = {$random} % 2;
A0 = {$random} % 2;
A1 = {$random} % 2;
end
selector u1(D, A0, A1, Y0, Y1, Y2, Y3);
endmodule
-
仿真电路图
-
仿真波形