FPGA项目五:数码管动态扫描(中)

简介: FPGA项目五:数码管动态扫描

确定完两个计数器后来思考输出信号 seg_sel 的变化。根据信号波形图得知,第 1 秒时 FPGA输出值为 8’hfe;第 2 秒时输出值为 8’hfd;以此类推,在第 8 秒时输出值为 8’h7f。设计中使用 cnt1来表示第几个 1 秒,即 cnt1==0 的时候,输出值为 8’hfe;在 cnt1==1 的时候输出值为 8’hfd;以此类推,在 cnt1==7 时输出值为 8’h7f。将其翻译成代码,调用至简设计法模板,在编辑模式下输入“Shixu2”,然后补充完整,得到信号 seg_sel 代码如下:

1670927854260.jpg

1670927862794.jpg

观察补充完整的代码可以发现:代码表示与文字描述基本上是一模一样的,这其实是体现了 verilog“硬件描述语言”的特点。上文所列代码可以正确实现 seg_sel 功能,且从实现角度和资源角度来说都足以完成设计,但依然可以将其进行进一步的概括从而得到简化版的代码。根据设计目标可知,第 1 个数码管显示“0”时,seg_sel 输出为 b8’b1111_1110;第 2 个数码管显示“1”时,seg_sel 输出为 b8’b1111_1101;第 3 个数码管显示“2”时,seg_sel 输出为 b8’b1111_1011;第 4 个数码显示“3”时,seg_sel 输出为 b8’b1111_0111;第 5 个数码管显示“4”时,seg_sel 输出为 b8’b1110_1111;第 6 个数码管显示“5”时,seg_sel 输出为 b8’b1101_1111;第 7个数码管显示“6”时,seg_sel 输出为 b8’b1011_1111;第 8 个数码管显示“7”时,seg_sel 输出为 b8’b0111_1111;根据规律可以发现每个控制数码管的闪亮信号,其对应数字“0”都依次向左移动 1 位。在设计中可以统一设为将 8’b1 向左移位,将其取反后的值再赋给 seg_sel,可以观察出每次左移的位数和 cnt1 的值相等。因此可得以下代码,其中的第 6 行即表示先将 8’b1 向左移位,再取反,将该值赋给 seg_sel。


也可以带入数值计算一下,假如此刻 cnt1 等于 0,则 8’b1<<0 的结果是 8’b0000_0001,取反的值为 8’hfe 即b8’b1111_1110;假如此刻 cnt1 等于 3,则 8’b1<<3 的结果为 8’b000_1000,取反后的结果为 8’hf7 即 8’b1111_0111。两段代码的对比结果相同,但是这种方法下代码经过简化,更加清晰。


这里同样可以在编辑模式下输入“Shixu2”,调出至简设计法模板,补充完整后得到代码如下:

1670927870572.jpg

最后来思考输出信号 seg_ment 的变化。分析波形图可知,在第 1 次显示时,其输出值为 7’h01;在第 2 次显示时,其输出值为 7’h4f;以此类推,在第 8 次显示时,其输出值为 7’h0f。用计数器 cnt1 表示第几次显示,也就是说:当 cnt1==0 时 seg_ment 输出值为 7’h01;在 cnt1==1 时输出值为 7’ h4f;以此类推,在 cnt1==7 时输出值为 7’h0f。将其翻译成代码,在编辑模式下“Shixu2”,调出至简设计法模板,补充完整后的代码如下:

1670927879231.jpg

1670927890233.jpg

上面的代码可以正确实现 seg_ment 的功能,对于本设计来说已经足够。但进一步思考可以发现:该代码实现了类似译码的功能,将数字设成数码管显示的值,代码中只对 0~7 进行译码。为了方便日后设计,在这里设计一个通用的译码模块,将 0~9 都进行译码。这样的话今后遇到类似的工程,就可以随时调用这一代码,译码模块代码如下所示:

1670927901418.jpg

1670927909594.jpg

在本设计中只要控制 data 信号,即可实现在数码管显示相应数字。前文可知:当 cnt1=0,则数码管会显示 0。当 cnt1=1,则数码管会显示 1。因此 data 信号代码如下:

1670927928405.jpg

在代码的最后一行写下 endmodule

1670927936477.jpg

至此,主体程序已经完成。


3.3 信号定义


接下来要将 module 补充完整,首先来定义信号类型。再次强调,在进行 reg 和 wire 的判断时,总会有多余的联想,比如认为 reg 是寄存器,wire 是线;或者认为 reg 的会综合成寄存器,wire 不会综合成寄存器。但是这些其实和 reg 型还是 wire 型都并无关系,在信号类型的判断时不需要做任何的联想,只要记住一个规则“用 always 实现的是 reg 型,其他都是 wire 型”就可以了。进行类型定义时,需要设定信号的位宽。至简设计法在这里们分享一个非常实用的位宽获取技巧:打开计算器,点击“查看”,选择“程序员”模式,在“十进制”下将信号值输入进去,就会获得对应的信号位宽,如下图所示。

1670927951294.jpg

cnt0 是用 always 产生的信号,因此类型为 reg。其计数的最大值为 50_000_000,通过计算器可以得知需要用 26 根线表示,即位宽是 26 位。add_cnt0 和 end_cnt0 都是用 assign 方式设计的,因此类型为 wire。其值是 0 或 1,用 1 个线表示即可。打开 GVIM,在编辑模式下输入“Wire1”调用至简设计法模板,补充完整后得到代码表示如下:

1670927960767.jpg

同理,cnt1 是用 always 产生的信号,因此类型为 reg。其计数的最大值为 7,需要用 3 根线表示,即位宽是 3 位。编辑模式下输入“Reg3”调用至简设计法模板并补充完整;add_cnt1 和 end_cnt1 都是用 assign 方式设计的,因此类型为 wire。其值是 0 或者 1,用 1 根线表示即可。编辑模式下输入“Wire1”调用至简设计法模板,补充完整后得到代码表示如下:

1670927970943.jpg

seg_sel 是用 always 方式设计的,因此类型为 reg,其需要用 8 根线表示,即位宽为 8。编辑模式下输入“Reg8”调用至简设计法模板,补充完整后得到代码表示如下:

1670927980316.jpg

seg_ ment 是用 always 方式设计的,因此类型为 reg,其需要用 7 根线表示,即位宽为 7,代

码表示如下:

1670927987609.jpg

如果使用译码电路则会用到 data 信号。该信号是用 assign 设计的,所以类型为 wire,其最大值为 9,位宽为 4。编辑模式下输入“Wire4”调用至简设计法模板,补充完整后得到代码表示如下:

1670927994669.jpg

至此,整个代码的设计工作已经完成。完整版的工程代码如下:

1670928002987.jpg

1670928012079.jpg

1670928018965.jpg

1670928025852.jpg

相关文章
|
29天前
|
芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(三)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
|
6月前
|
测试技术 异构计算
【FPGA基础入门实践】Verilog 基本项目操作逐步演示
【FPGA基础入门实践】Verilog 基本项目操作逐步演示
78 0
|
异构计算
FPGA项目五:数码管动态扫描(下)
FPGA项目五:数码管动态扫描
150 0
FPGA项目五:数码管动态扫描(下)
|
异构计算
FPGA项目五:数码管动态扫描(上)
FPGA项目五:数码管动态扫描
215 0
FPGA项目五:数码管动态扫描(上)
|
9天前
|
机器学习/深度学习 算法 异构计算
m基于FPGA的多通道FIR滤波器verilog实现,包含testbench测试文件
本文介绍了使用VIVADO 2019.2仿真的多通道FIR滤波器设计。展示了系统RTL结构图,并简述了FIR滤波器的基本理论,包括单通道和多通道的概念、常见结构及设计方法,如窗函数法、频率采样法、优化算法和机器学习方法。此外,还提供了Verilog核心程序代码,用于实现4通道滤波器模块,包含时钟、复位信号及输入输出接口的定义。
28 7
|
3月前
|
算法 异构计算
基于FPGA的ECG信号滤波与心率计算verilog实现,包含testbench
基于FPGA的ECG信号滤波与心率计算verilog实现,包含testbench
|
2月前
|
算法 异构计算
m基于FPGA的电子钟verilog实现,可设置闹钟,包含testbench测试文件
该文介绍了基于FPGA的电子钟设计,利用Vivado2019.2平台进行开发并展示测试结果。电子钟设计采用Verilog硬件描述语言,核心包括振荡器、分频器和计数器。时间显示为2个十进制格式,闹钟功能通过存储器和比较器实现,当当前时间等于设定时间时触发。文中给出了Verilog核心程序示例,展示了时钟信号、设置信号及输出的交互。
29 2
|
4月前
|
算法 5G 数据处理
m基于FPGA的PPM光学脉位调制解调系统verilog实现,包含testbench
m基于FPGA的PPM光学脉位调制解调系统verilog实现,包含testbench
48 0

热门文章

最新文章