
1、实验名称:
Verilog HDL程序设计与仿真实验
2、实验设计要求以及内容:
利用Verilog HDL语言和描述下列芯片的功能,编写激励测试程序并在Modelsim软件中仿真运行、记录相关波形。芯片包括:CD4532、74X138、74HC4511、74HC151、74HC85、74HC283、74HC194、74LVC161。
3、实验软件:
Modelsim软件。
4、芯片功能与真值表:
CD4532:8位优先编码器:
| 输入 | 输出 |
| CS E0 | |
| 0 x x x x x x x x 1 0 0 0 0 0 0 0 0 1 1 x x x x x x x 1 0 1 x x x x x x 1 0 0 1 x x x x x 1 0 0 0 1 x x x x 1 0 0 0 0 1 x x x 1 0 0 0 0 0 1 x x 1 0 0 0 0 0 0 1 x 1 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 0 1 0 1 0 1 1 0 1 0 0 1 0 0 1 1 1 0 0 1 0 1 0 0 0 1 1 0 0 0 0 1 0 |
| 输入 | 输出 | |
| x 1 x x x 1 1 x x 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 | x x x x x x x x x 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 |
| 十进制或功能 | 输入 | 输出 | 字 形 | |||
| LE | a b c d e f g | |||||
| 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 10 0 0 0 0 0 1 10 1 0 10 1 1 11 0 0 11 0 1 11 1 0 11 1 1 20 0 0 1 0 0 1 1 0 1 0 1 0 1 1 21 0 0 1 1 0 1 1 1 1 0 1 1 1 1 | 1 1 1 1 1 1 0 11 1 0 0 0 0 1 1 0 1 1 0 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 1 1 0 0 1 1 1 1 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 0 1 2 3 4 5 6 7 8 9 熄灭 熄灭 熄灭 熄灭 熄灭 熄灭 |
| 灯测试 | x | x | 0 | x x x x | 1 1 1 1 1 1 1 | 8 |
| 灭灯 | x | 0 | 1 | x x x x | 0 0 0 0 0 0 0 | 熄灭 |
| 锁存 | 1 | 1 | 1 | x x x x | * | * |
| 输入 | 输出 | |
| 使能 | 选择 | Y |
| 1 0 0 0 0 0 0 0 0 | x x x 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 | 0 1
|
74HC283:4位二进制全加器:
74HC194:4位双向移位寄存器:
| 输入 | 输出 | 功能 | ||||
| 清零 | 控制信号 | 时钟 | 串行输入 | 并行输入 | ||
| CR | CP | 右移 左移 | ||||
| L H H H H H H | x x L L L H L H H L H L H H | x x ↑ ↑ ↑ ↑ ↑ | x x x x L x H x x L x H x x | x x x x x x x x x x x x x x x x x x x x x x x x | L L L L L H | |
| 输入 | 输出 | |||||
| 清零 CR | 预支 PE | 使能 CEP CET | 时钟 CP | 预支数据输入 | 进位 TC | |
| L H H H H | x L H H H | x x x x L x x L H H | x ↑ x x ↑ | x x x x x x x x x x x x x x x x | L L L L 保持 保持 保持 | L # # L # |
CD4532-8位优先编码器:
模块设计代码:
module CD4532(EI,I,Y,GS,EO);//8位优先编码器
input EI;
input [7:0] I;
output reg [2:0] Y;
output reg GS,EO;
always @ (EI,I)
begin
if(EI==0) begin Y=3'd0; GS=0; EO=0; end
else//当EI=1时,实现优先编码器的功能
begin
GS=1; EO=0;//当编码器输入信号有效时,设定GS、EO的输出值
if(I[7]) Y=3'd7; else//根据I的高位情况对Y的输出进行控制
if(I[6]) Y=3'd6; else
if(I[5]) Y=3'd5; else
if(I[4]) Y=3'd4; else
if(I[3]) Y=3'd3; else
if(I[2]) Y=3'd2; else
if(I[1]) Y=3'd1; else
if(I[0]) Y=3'd0;
else
begin Y=3'd0; GS=0; EO=1; end//当编码器输入信号无效时,设定GS、EO的输出值
end
end
endmodule
对应testbench设计代码:
`timescale 1ns/1ns //设定仿真时间间隔单位,之后的testbench中这句代码功能类似
module CD4532_tb;
reg [7:0] D_in;// 设定testbench输入数据类型为reg型 reg EI_in;
wire [2:0] Q_result;// / 设定testbench输出数据类型为wire型
wire GS_result,EO_result;
initial
begin
EI_in=0;//初始化相关数据的值
D_in=8'b0000_0001;
#80 EI_in=1;
#80 $stop();//上一个语句执行完毕后的80个时间单位后仿真终止
end
always #10 //每隔10个时间单位执行一次
begin
if(D_in==8'b1000_0000)
D_in=8'b0000_0001;
else
D_in=(D_in<<1);
end
CD4532 U1(.EI(EI_in),.I(D_in),.Y(Q_result),.GS(GS_result),.EO(EO_result));
endmodule
74X138-3 线-8线译码器:
模块设计代码:
module _74X138(A,EN,Y);//3 线-8线译码器,输出为低电平有效
input [2:0] A;
input EN;//使能端
output reg [7:0] Y;
integer k;
always @ (A,EN)
begin
Y=8'b1111_1111;
for(k=0;k<=7;k=k+1)
begin
if((EN==1)&&(A==k))
Y[k]=0;//EN=1时根据输入的A进行译码
else
Y[k]=1;//使能无效时或输入无效
end
end
endmodule
对应testbench设计代码:
`timescale 1ns/1ns
module _74X138_tb;
reg [2:0] A_in;
reg EI_in;
wire [7:0] Y_result;
initial
begin
EI_in=0;
A_in=3'b000;
#80 EI_in=1;
#160 $stop();
end
always #10
begin
if(A_in==3'b111)
A_in=3'b000;
else
A_in=A_in+1;
end
_74X138 U1(.A(A_in),.EN(EI_in),.Y(Y_result));
endmodule
74HC4511-七段显示译码器:
模块设计代码:
module _74HC4511(D,LE,BL,LT,a,b,c,d,e,f,g);//七段显示译码器
input [3:0] D;//输入信号端口
input LE,BL,LT;//控制信号
output reg a,b,c,d,e,f,g;
always@(LE,BL,LT,D)
begin
if(LT==0) {a,b,c,d,e,f,g}=7'b111_1111;//显示器全亮
else if(BL==0) {a,b,c,d,e,f,g}=7'b000_0000;//显示器全灭
else if(LE==0) {a,b,c,d,e,f,g}={a,b,c,d,e,f,g};//显示器保持当前显示
else
case(D)//根据输入的8421BCD码进行译码
4'd0: {a,b,c,d,e,f,g}=7'b111_1110;//0
4'd1: {a,b,c,d,e,f,g}=7'b011_0000;//1
4'd2: {a,b,c,d,e,f,g}=7'b110_1101;//2
4'd3: {a,b,c,d,e,f,g}=7'b111_1001;//3
4'd4: {a,b,c,d,e,f,g}=7'b011_0011;//4
4'd5: {a,b,c,d,e,f,g}=7'b101_1011;//5
4'd6: {a,b,c,d,e,f,g}=7'b001_1111;//6
4'd7: {a,b,c,d,e,f,g}=7'b111_0000;//7
4'd8: {a,b,c,d,e,f,g}=7'b111_1111;//8
4'd9: {a,b,c,d,e,f,g}=7'b111_1011;//9
default:{a,b,c,d,e,f,g}=7'b000_0000;//非8421BCD码输入时,不译码
endcase
end
endmodule
对应testbench设计代码:
`timescale 1ns/1ns
module _74HC4511_tb;
reg [3:0] D_in;
reg LE_in,BL_in,LT_in;
wire A,B,C,D,E,F,G;
initial
begin
//开始为全亮
LE_in=1;//保持,低电平有效
BL_in=1;//全灭,低电平有效
LT_in=0;//全亮,低电平有效
D_in=4'b0000;
#100 begin LE_in=1; BL_in=0; LT_in=1; end//全灭
#100 begin LE_in=1; BL_in=1; LT_in=1; end//正常显示
#100 begin LE_in=0; BL_in=1; LT_in=1; end//保持
#100 $stop();
end
always #10
begin
if(D_in==4'd9)
D_in=4'b0000;
else
D_in=D_in+1;
end
_74HC4511 U1(D_in,LE_in,BL_in,LT_in,A,B,C,D,E,F,G);
endmodule
74HC151-八选一数据选择器:
模块设计代码:
module _74HC151(S,D,E,Y0,Y1);//八选一数据选择器
input [2:0] S;//控制信号
input [7:0] D;//输入信号
input E;//使能端
output reg Y0,Y1;//Y0,Y1分别为同相和反相输出信号
always@(E,S,D)
begin
if(~E)
begin Y0=0; Y1=1; end//不工作,输出默认信号
else
begin
case(S)//根据控制信号选择不同通道的输入信号作为输出
3'b000: begin Y0=D[0]; Y1=~Y0; end//0
3'b001: begin Y0=D[1]; Y1=~Y0; end//1
3'b010: begin Y0=D[2]; Y1=~Y0; end//2
3'b011: begin Y0=D[3]; Y1=~Y0; end//3
3'b100: begin Y0=D[4]; Y1=~Y0; end//4
3'b101: begin Y0=D[5]; Y1=~Y0; end//5
3'b110: begin Y0=D[6]; Y1=~Y0; end//6
3'b111: begin Y0=D[7]; Y1=~Y0; end//7
default: begin Y0=0; Y1=~Y0; end//若控制信号不符合要求则输出默认信号
endcase
end
end
endmodule
对应testbench设计代码:
`timescale 1ns/1ns
module _74HC151_tb;
reg [2:0] S_in;
reg [7:0] D_in;
reg E_in;
wire Y0_result,Y1_result;
initial
begin
E_in=0;
S_in=3'b000;
D_in=8'b0010_0110;
#80 E_in=1;
#80 D_in=8'b1001_1110;
#80 E_in=0;
#80 $stop();
end
always #10
begin
if(S_in==3'b111)
S_in=3'b000;
else
S_in=S_in+1;
end
_74HC151 U1(S_in,D_in,E_in,Y0_result,Y1_result);
Endmodule
74HC85-4位数值比较器:
模块设计代码:
module _74HC85(A,B,I0,I1,I2,Fab0,Fab1,Fab2);//4位数值比较器,以下均为高电平有效
input [3:0] A,B;//输入信号
input I0,I1,I2;//低位比较结果,依次为低位A=B,AB
output reg Fab0,Fab1,Fab2;//输出信号Fab0,Fab1,Fab2依次为A=B,AB.
reg F000,F001,F002,F110,F111,F112,F220,F221,F222,F330,F331,F332;//中间节点,依次对应Ai=Bi,Ai always@(A,B,I0,I1,I2) begin if(A[3]>B[3])//比较第4位 begin F330=0; F331=0; F332=1; end else if(A[3] begin F330=0; F331=1; F332=0; end else begin F330=1; F331=0; F332=0; end if(A[2]>B[2])//比较第3位 begin F220=0; F221=0; F222=1; end else if(A[2] begin F220=0; F221=1; F222=0; end else begin F220=1; F221=0; F222=0; end if(A[1]>B[1])//比较第2位 begin F110=0; F111=0; F112=1; end else if(A[1] begin F110=0; F111=1; F112=0; end else begin F110=1; F111=0; F112=0; end if(A[0]>B[0])//比较第1位 begin F000=0; F001=0; F002=1; end else if(A[0] begin F000=0; F001=1; F002=0; end else begin F000=1; F001=0; F002=0; end //输出结果如下 if((F000&&F110&&F220&&F330)&&I0)//低位进位信号出错 begin Fab2=0; Fab1=0; Fab0=1; end else if((F000&&F110&&F220&&F330)&&(~I0&&I1&&I2))//低位进位信号出错 begin Fab2=0; Fab1=0; Fab0=0; end else if((F000&&F110&&F220&&F330)&&(~I0&&~I1&&~I2))//低位进位信号出错 begin Fab2=1; Fab1=1; Fab0=0; end else//低位进位信号正常 begin Fab2=F332||F330&&F222||F330&&F220&&F112||F330&&F220&&F110&&F002||F330&&F220&&F110&&F000&&I2; Fab1=F331||F330&&F221||F330&&F220&&F111||F330&&F220&&F110&&F001||F330&&F220&&F110&&F000&&I1; Fab0=F330&&F220&&F110&&F000&&I0; end end endmodule 对应testbench设计代码: `timescale 1ns/1ns module _74HC85_tb; reg [3:0] A_in,B_in; reg I0_in,I1_in,I2_in; wire Fab0_result,Fab1_result,Fab2_result; initial begin I0_in=0; I1_in=0; I2_in=0; A_in=4'b1010; B_in=4'b0111; #10 begin I0_in=1; I1_in=0; I2_in=0; end//低位A=B #10 begin I0_in=0; I1_in=1; I2_in=0; end//低位A #10 begin I0_in=0; I1_in=0; I2_in=1; end//低位A>B #10 begin I0_in=0; I1_in=0; I2_in=0; //低位归位 A_in=4'b0100; B_in=4'b1001; end #10 begin I0_in=1; I1_in=0; I2_in=0; end//低位A=B #10 begin I0_in=0; I1_in=1; I2_in=0; end//低位A #10 begin I0_in=0; I1_in=0; I2_in=1; end//低位A>B #10 begin I0_in=0; I1_in=0; I2_in=0; //低位归位 A_in=4'b0010; B_in=4'b0010; end #10 begin I0_in=1; I1_in=0; I2_in=0; end//低位A=B #10 begin I0_in=0; I1_in=1; I2_in=0; end//低位A #10 begin I0_in=0; I1_in=0; I2_in=1; end//低位A>B #10 $stop(); end _74HC85 U1(A_in,B_in,I0_in,I1_in,I2_in,Fab0_result,Fab1_result,Fab2_result); endmodule 74HC283-4位二进制全加器: 模块设计代码: module _74HC283(A,B,Ci,Co,S);//4位二进制全加器 input Ci;//低位进位信号 input [3:0] A,B;//输入信号 output reg [3:0] S;//输出结果 output reg Co;//高位进位信号Co=C[3] reg [3:0] C,G,P; integer k; always@(A,B,Ci) begin for(k=0;k<4;k=k+1) begin G[k]=A[k]&&B[k]; P[k]=A[k]&&~B[k]||~A[k]&&B[k]; end C[0]=G[0]||P[0]&&Ci; C[1]=G[1]||P[1]&&C[0]; C[2]=G[2]||P[2]&&C[1]; C[3]=G[3]||P[3]&&C[2]; S[0]=P[0]&&~Ci||~P[0]&&Ci; S[1]=P[1]&&~C[0]||~P[1]&&C[0]; S[2]=P[2]&&~C[1]||~P[2]&&C[1]; S[3]=P[3]&&~C[2]||~P[3]&&C[2]; Co=C[3]; end endmodule 对应testbench设计代码: `timescale 1ns/1ns module _74HC283_tb; reg [3:0] A_in,B_in; reg Ci_in;//低位进位信号 wire [3:0] S_out;//本位相加结果 wire Co_out;//高位进位信号 initial begin Ci_in=0; A_in=4'b1010; B_in=4'b0111; #10 begin A_in=4'b0011; B_in=4'b1111; end #10 begin A_in=4'b0101; B_in=4'b1001; end #10 begin A_in=4'b1111; B_in=4'b0010; end #10 $stop(); end always #5 begin Ci_in=~Ci_in;//循环改变低位进位信号 end _74HC283 U1(A_in,B_in,Ci_in,Co_out,S_out); endmodule 74HC194-4位双向移位寄存器: 模块设计代码: module _74HC194(S0,S1,Dsl,Dsr,CP,CR,D,Q);//4位双向移位寄存器_P339 input S0,S1;//输入端口 input Dsr,Dsl;//串行数据输入 input CP,CR;//时钟和清零 input [3:0] D;//并行数据输入 output reg [3:0] Q;//输出结果 always@(posedge CP, negedge CR) begin if(~CR) Q<=4'b0000;//异步清零 else case({S1,S0}) 2'b00:Q<=Q;//输出保持不变 2'b01:Q<={Q[2:0],Dsr};//右移,低位移向高位 2'b10:Q<={Dsl,Q[3:1]};//左移,高位移向低位 2'b11:Q<=D;//并行置数 endcase end endmodule 对应testbench设计代码: `timescale 1ns/1ns module _74HC194_tb; reg [3:0] D_in;//并行数据输入 reg S0_in,S1_in;//控制信号输入端口 reg Dsr_in,Dsl_in;//串行数据输入 reg CP_in,CR_in;//时钟和清零,清零为低电平有效 wire [3:0] Q_out;//输出结果 initial begin CP_in=1; CR_in=1; S0_in=1; S1_in=1;//开始先输入串行数据 Dsr_in=0; Dsl_in=0; D_in=4'b0110; #243 CR_in=~CR_in; #20 $stop(); end always #5 begin CP_in=~CP_in;//周期为10ns的时钟信号 end always #15//循环调整控制输入信号,周期60ns begin case({S1_in,S0_in}) 2'b00:begin S1_in=0; S0_in=1; end 2'b01:begin S1_in=1; S0_in=0; end 2'b10:begin S1_in=1; S0_in=1; end 2'b11:begin S1_in=0; S0_in=0; end endcase end always #10//循环调整串行数据输入信号,周期40ns begin case({Dsr_in,Dsl_in}) 2'b00:begin Dsr_in=0; Dsl_in=1; end 2'b01:begin Dsr_in=1; Dsl_in=0; end 2'b10:begin Dsr_in=1; Dsl_in=1; end 2'b11:begin Dsr_in=0; Dsl_in=0; end endcase end _74HC194 U1(S0_in,S1_in,Dsl_in,Dsr_in,CP_in,CR_in,D_in,Q_out); endmodule 74LVC161-4位二进制同步计数器: 模块设计代码: module _74LVC161(CEP,CET,PE,CP,CR,D,TC,Q);//4位二进制同步计数器_P340 input CEP,CET,PE,CP,CR;//输入端口 input [3:0] D;//并行数据输入 output TC;//进位输出 output reg [3:0] Q;//输出结果 wire CE; assign CE=CEP&CET;//CE=1时计数器计数 assign TC=CET&PE&(Q==4'b1111);//产生进位输出信号 always@(posedge CP, negedge CR) begin if(~CR) Q<=4'b0000;//异步清零 else if(~PE) Q<=D;//PE=0,同步输入数据 else if(CE) begin if((TC==1)&&(Q==4'b1111)) Q<=4'b0000;//计数器计满后自动归零 else Q<=Q+1'b1;//加1计数 end else Q<=Q;//保持输出不变 end endmodule 对应testbench设计代码: `timescale 1ns/1ns module _74LVC161_tb; reg CEP_in,CET_in,PE_in,CP_in,CR_in;//输入端口 reg [3:0] D_in;//并行数据输入 wire TC_out;//进位输出 wire [3:0] Q_out;//输出结果 initial begin CEP_in=0; CET_in=1; PE_in=0; CP_in=1; CR_in=1; D_in=4'b1101; #10 begin PE_in=1;D_in=4'b1001; end #20 begin CEP_in=1; CET_in=1; end #220 begin PE_in=0; end #23 CR_in=~CR_in; #20 $stop(); end always #5 begin CP_in=~CP_in;//周期为10ns的时钟信号 end _74LVC161 U1(CEP_in,CET_in,PE_in,CP_in,CR_in,D_in,TC_out,Q_out); endmodule 6、输出仿真波形以及相关数据: CD4532-8位优先编码器: 以下波形由上至下依次是:D_in, EI_in, Q_result, GS_result, EO_result; 74X138-3 线-8线译码器: 以下波形由上至下依次是:A_in, EI_in, Y_result; 74HC4511-七段显示译码器: 以下波形由上至下依次是:D_in, LE_in, LT_in, A, B, C, D, E, F, G; 74HC151-八选一数据选择器: 以下波形由上至下依次是:S_in, D_in, E_in, Y0_result, Y1_result; 74HC85-4位数值比较器: 以下波形由上至下依次是:A_in, B_in, I0_in, I1_in, I2_in, Fab0_result, Fab1_result, Fab2_result; 74HC283-4位二进制全加器: 以下波形由上至下依次是:A_in, B_in, S_out, Co_out; 74HC194-4位双向移位寄存器: 以下波形由上至下依次是:D_in, S0_in, S1_in,Dsr_in, Dsl_in, CP_in, CR_in, Q_out; 74LVC161-4位二进制同步计数器: 以下波形由上至下依次是:CEP_in, CET_in, PE_in, CP_in, CR_in, D_in, T_out, Q_out; 7、仿真结果分析: 仿真输出波形符合预期,与芯片的功能表描述的功能相符。 8、实验总结与感想 本次实验总体效果还行,在实验过程中虽然出现了一些错误和困惑,但是我在参考了先前的代码案例后,在同学的帮助下基本解决了这些问题。这次仿真实验让我对利用Verilog HDL设计相关电路的方法有了更深的认识,也掌握利用Modelsim软件对电路模拟分析的相关方法与技巧。总的来说,收获颇丰。
