在数字电路设计的学习与实践中,Verilog 语言作为硬件描述的有力工具,被广泛应用于各类电路设计场景。今天,我们将深入探讨如何运用 Verilog 实现多路复用显示驱动的设计与测试,这不仅能加深对 Verilog 语言的理解,还能提升数字电路设计的实践能力。
一、实验目的
本次实验旨在回顾多路复用显示驱动电路的功能,通过 Verilog 语言实现各个模块的逻辑功能,学会在顶层模块中调用子模块,并掌握利用波形图分析实验结果的方法。这一系列目标的达成,有助于我们系统地掌握数字电路设计中从理论到实践的关键环节,为后续更复杂的电路设计打下坚实基础。
二、实验环境与工具
本次实验主要借助以下工具:
- Modelsim:作为强大的电路仿真软件,它能够对设计的电路进行功能验证和波形分析,帮助我们在实际硬件搭建前发现并解决潜在问题。
- Notepad++:一款便捷的文本编辑器,为编写 Verilog 代码提供了良好的环境,支持语法高亮和代码编辑辅助功能,提高编程效率。
- 笔记本电脑:作为运行 Modelsim 和 Notepad++ 的硬件平台,为整个实验提供计算和存储资源。
三、实验步骤详解
(一)理解实验所需模块功能
本次实验主要涉及以下几个关键模块功能:
- 两位计数器:利用时钟脉冲信号实现两位计数器的功能,为后续模块提供计数结果。
- 数码管动态驱动:根据计数器的结果动态控制数码管的显示,实现数字的动态展示。
- 74LS153 选择器:将计数器的结果作为 74LS153 的选择信号,从四组数据中选择一组进行输出。
- 74LS47 译码器:74LS47 芯片将输入信号加上预设值,把 BCD 码转换为驱动数码管显示的二进制代码。
(二)两位计数器模块设计
module binary_counter(clk, rst_n, counter);
input clk,rst_n;
output reg[1:0] counter;
wire [1:0] D;
assign D[0]=!counter[0];
assign D[1]= counter[0] ^counter[1];
always @ (posedge clk)
begin
if (rst_n==1'b0)
counter <=2'b00 ;
else
counter <=D;
end
endmodule
该模块通过时钟信号clk
和复位信号rst_n
控制计数器的运行。always
块在时钟上升沿触发,当复位信号有效时,计数器清零;否则,根据逻辑表达式更新计数器的值。
(三)7 段数码管动态驱动模块设计
module driving(
input [1:0] count,
output reg [3:0] display
);
always @(*)begin
case ( count)
2'b00: display ='b0001;
2'b01: display ='b0010;
2'b10: display = 'b0100;
2'b11: display ='b1000;
endcase
end
endmodule
此模块根据输入的计数器值count
,通过case
语句选择对应的显示代码,实现对数码管显示位的动态控制。
(四)74LS153 模块
74LS153 模块的功能是根据选择信号从四组输入数据中选择一组输出。
module ls153 (
input [1:0] S, //选择信号
input [1:0] C0,
input [1:0] C1,
input [1:0] C2,
input [1:0] C3,
output reg [1:0] ans
);
always @ (*)
begin
case (S)
2'b00: ans = C0;
2'b01: ans = C1;
2'b10: ans = C2;
2'b11: ans = C3;
endcase
end
endmodule
(五)74LS47 模块设计
module 1s47 (
input [1:0] ANS,
output reg [6:0] result
);
always @(*)
begin
case (ANS)
2'b00: result = 7'b001 1001;
2'b01: result = 7'b001 0010;
2'b10: result = 7'b000 0010;
2'b11: result =7'b111_1000;
endcase
end
endmodule
该模块接收输入信号ANS
,通过case
语句将其转换为驱动数码管显示的二进制代码,完成 BCD 码到显示代码的转换。
(六)顶层模块调用
module top (
Clk,
Rst_n,
Display,
Result,
data0,
data1,
data2,
data3
);
input wire Clk;
input wire Rst_n;
input wire [1:0] data0;
input wire [1:0] data1;
input wire [1:0] data2;
input wire [1:0] data3;
output wire [3:0] Display;
output wire [6:0] Result;
wire [1:0] cont;
wire [1:0] Ans;
binary_counter b_c(
.clk(Clk),
.rst_n (Rst_n),
.counter(cont)
);
driving dri(
.count (cont),
.display (Display)
);
1s153 mux8_2(
.S (cont),
.C0 (data0),
.C1 (data1),
.C2 (data2),
.C3 (data3),
.ans (Ans)
);
1s47 coding(
.ANS (Ans),
.result (Result)
);
endmodule
顶层模块top
将各个子模块连接起来,实现整个多路复用显示驱动系统的功能。通过实例化各个子模块,并正确连接它们的输入输出端口,使各个模块协同工作。
(七)编写顶层程序测试代码
`timescale 1 ps/ 1 ps
module mux4_tb;
reg clk_sig;
reg rst_n_sig;
reg [1:0] Data0;
reg [1:0] Data1;
reg [1:0] Data2;
reg [1:0] Data3;
wire [3:0] Display;
wire [6:0] Result;
top mux4_inst(
.Clk(clk_sig),
.Rst_n(rst_n_sig),
.data0 (Data0),
.data1(Data1),
.data2 (Data2),
.data3 (Data3),
.Display (Display),
.Result (Result)
);
always
#10 clk_sig = ~clk_sig;
initial
begin
clk_sig = 1'b0;
rst_n_sig = 0;
Data0 = 2'b00;
Data1 = 2'b01;
Data2 = 2'b10;
Data3 = 2'b11;
#30 rst_n_sig = 1;
#100;
$stop;
end
endmodule
四 Modelsim 仿真结果波形分析

通过 Modelsim 进行仿真,得到的波形图展示了各个信号的变化情况。从波形图中可以观察到,时钟信号clk_sig
、复位信号rst_n_sig
以及输入数据Data0
- Data3
按照设定的规则变化,输出的Display
和Result
信号也符合预期,这表明整个多路复用显示驱动系统的设计和实现是正确的。