【基本信息】

需求:verilog程序,显示任意六位字符或数值,包含点号,且能够按需点亮位数。(学习篇)

芯片型号:cyclone Ⅳ EP4CE10F17C8

数码管属性:六位、八段

【最终成果图】

经过多轮测试,最后代码程序满足设计要求,但结合仿真发现了一个问题,仿真和上机不匹配,当然还是要以上机为准。

【模块例化图】

这里就是简单地赋个初始值,来测试digital模块,最终是要seg_led和seg_sel的显示变化。

【verilog程序】

1、digital模块

模块化设计,六个位上的值直接拆开做处理,分析起来清晰。sel_cnt表示目前要显示的位数(从右往左),即sel_cnt = 6代表全亮。dp_cnt表示点号所在位数,若dp_cnt=0则代表没有点号。clk_2khz为数码管的刷新信号。

module digital
(
input sys_clk ,
input sys_rst ,
input clk_2khz , input [3:0] num6,
input [3:0] num5,
input [3:0] num4,
input [3:0] num3,
input [3:0] num2,
input [3:0] num1,
input [2:0] sel_cnt ,
input [2:0] dp_cnt , output reg[5:0] seg_sel ,
output reg[7:0] seg_led
);
reg[2:0] sel_cnt_tran;
reg[3:0] num;
reg[2:0] tran1;
//endmodule

定义了几个变量,sel_cnt_tran用来根据数码管刷新信号更替数码管的位选,而num用来接引各位上的值,数码管根据num编号段选信号。tran1在过程讨论部分做解释。

always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst)
sel_cnt_tran = 3'd0;
else
if(clk_2khz)begin
if(sel_cnt_tran < sel_cnt)begin
tran1 = sel_cnt_tran;
sel_cnt_tran = sel_cnt_tran + 1'b1;
end
else begin
tran1 = sel_cnt_tran;
sel_cnt_tran = 3'd0;
end
end
end

上述代码就是位选更替,可以直观得到,tran1比sel_cnt_tran要晚上一个数码管刷新周期。

always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst)
seg_sel <= 6'b111_111;
else if(clk_2khz)begin
case(sel_cnt_tran)
3'd1:begin
seg_sel <= 6'b111_110;
num <= num1;
end
3'd2:begin
seg_sel <= 6'b111_101;
num <= num2;
end
3'd3:begin
seg_sel <= 6'b111_011;
num <= num3;
end
3'd4:begin
seg_sel <= 6'b110_111;
num <= num4;
end
3'd5:begin
seg_sel <= 6'b101_111;
num <= num5;
end
3'd6:begin
seg_sel <= 6'b011_111;
num <= num6;
end
default:begin
seg_sel <= 6'b111_111;
end
endcase
end
end

根据原理图,数码管是共阳极,并且位选拉低有效,这里测试是没有问题的。

always @(posedge sys_clk or negedge sys_rst)begin
if (!sys_rst)
seg_led = 8'b0;
else begin
case (num)
4'h0 : seg_led = 8'b1100_0000;
4'h1 : seg_led = 8'b1111_1001;
4'h2 : seg_led = 8'b1010_0100;
4'h3 : seg_led = 8'b1011_0000;
4'h4 : seg_led = 8'b1001_1001;
4'h5 : seg_led = 8'b1001_0010;
4'h6 : seg_led = 8'b1000_0010;
4'h7 : seg_led = 8'b1111_1000;
4'h8 : seg_led = 8'b1000_0000;
4'h9 : seg_led = 8'b1001_0000;
4'ha : seg_led = 8'b1000_1000;
4'hb : seg_led = 8'b1000_0011;
4'hc : seg_led = 8'b1100_0110;
4'hd : seg_led = 8'b1010_0001;
4'he : seg_led = 8'b1000_0110;
4'hf : seg_led = 8'b1000_1110;
default : seg_led = 8'b1100_0000;//多余
endcase
if(dp_cnt == (tran1))begin //确定点号,这里不是sel_cnt_tran
seg_led = seg_led & 8'b0111_1111;
end
end
end

2、clk_2khz模块

module clk_2khz
(
input sys_clk ,
input sys_rst , output reg clk_out
);
parameter cnt_2khz_max = 25_000;
reg[14:0] cnt;

clk_2khz时钟产生很简单,cnt_2khz_max = 1/2_000x50_000_000,在这就放下代码。注意两个问题:一个是不要直接posedge clk_2khz方式来读上升沿,另外尽量不要采用取反方式产生分频时钟信号,如果是取反,可以采用wire en;assign en = d1 & d0来读边沿信号。

always @(posedge sys_clk or negedge sys_rst)begin
if(!sys_rst)begin
cnt <= 15'd0;
clk_out <= 1'b0;
end
else if(cnt <(cnt_2khz_max-1'b1))begin
cnt <= cnt + 1'b1;
clk_out <= 1'b0;
end
else begin
cnt <= 15'd0;verilog
clk_out <= 1'b1;
end
end
endmodule

3、顶部例化测试

module digital_top  (
input sys_clk ,
input sys_rst ,
output [5:0] seg_sel ,
output [7:0] seg_led
);
wire clk_2khz_tran;
reg[3:0] num1 = 4'd2;
reg[3:0] num2 = 4'h1;
reg[3:0] num3 = 4'd5;
reg[2:0] sel_cnt = 3'd6;
reg[2:0] dp_cnt = 3'd6;
digital digital_inst(); //例化省略
clk_2khz clk_generator1();
endmodule

4、Modelsim仿真

`timescale 1ns/1ns
module digital_tb(); parameter T1 =20 ;
parameter T2 =200;
parameter max = 14;
reg sys_clk;
reg clk_2khz;
reg sys_rst;
reg[3:0] num1 = 4'h1;
reg[3:0] num2 = 4'h1;
reg[3:0] num3 = 4'h1;
reg[2:0] sel_cnt = 3'd6;
reg[2:0] dp_cnt = 3'd6;
reg[3:0] cnt;
wire[7:0] seg_led;
wire[5:0] seg_sel; always # (T1/2) sys_clk <= ~sys_clk; always @(posedge sys_clk or negedge sys_rst)begin
if(!sys_rst)
cnt <= 4'd0;
else begin
if(cnt < max)begin
cnt <= cnt + 1'b1;
clk_2khz <= 1'b0;
end
else begin
cnt <= 4'd0;
clk_2khz <= 1'b1;
end
end
end initial begin
sys_clk <=1'b0;
sys_rst <=1'b0;
#50 sys_rst <=1'b1;
end
digital digital_inst();//例化省略
endmodule

【过程讨论】

首先由于自己疏忽,数码管位选刷新位置采用的是非阻塞赋值的方法,通过用sel_cnt_tran判断为真的话,通过仿真(下图)观察到,位选和段选不匹配,就是说,点号的位置不正确,现象是位选落后了。

然后想着将赋值方法改为阻塞赋值,还是有问题。强制更改,设定判断条件为if(dp_cnt == (sel_cnt_tran-1’b1))看看,显然,这样虽然有效(图在下面),但只能保证最终的点号位置有限,比如dp_cnt = 6就有问题,因为sel_cnt_tran在6后赋值是0,达不到条件。后面借助变量tran1在sel_cnt_tran刷新处赋值使其落后一个周期,仿真显示不正确,但上机测试有效。

一个问题:六位八段数码管(Verilog)的更多相关文章

  1. arduino八段数码管使用

    一:八段数码管的使用 控制要求:0-9的计时数据 实物连接图: 控制代码: //智慧自动化2018.6.11 ;//定义数字接口7 连接a 段数码管 ;// 定义数字接口6 连接b 段数码管 ;// ...

  2. Verilog HDL那些事_建模篇笔记(实验七:数码管电路驱动)

    1.同步动态扫描 多个数码管的显示采用的是同步动态扫描方法,同步动态扫描指的是:行信号和列信号同步扫描,是一种并行操作. 2.数码管驱动电路实现思路      如果要求数码管显示我们想要的数字,首先需 ...

  3. [51单片机] 以PWM控制直流电机为例建一个简单的51工程框架

    目录 1)功能概述 2)引脚连接 3)框架介绍 4)模块说明 5)复用规则 6)工程链接 1)功能概述 名称:独立按键控制直流电机调速 内容:对应的电机接口需用杜邦线连接到uln2003电机控制端; ...

  4. AC620教程 第十五节 8位7段数码管驱动设计与验证

    本章导读 电子系统中常用的显示设备有数码管.LCD液晶以及VGA显示器等.其中数码管又可分为段式显示(7段.米字型等)以及点阵显示(8*8.16*16等),LCD液晶的应用可以分为字符式液晶(1602 ...

  5. 【.NET 与树莓派】LED 数码管驱动模块——TM1638

    LED 数码管,你可以将它看做是 N 个发光二级管的组合,一个灯负责显示一个段,七个段组合一位数字,再加一个小数点,这么一来,一位数码管就有八段.一般,按照顺时针的方向给每个段编号. 上图中的 h 就 ...

  6. 音响音箱/恒温壶/电量显示/电子数字时钟等LED数码管显示驱动IC-VK1640B 8段12位/12段8位显示

    市面上最常用的数码管为七段/八段显示,八段数码管比七段数码管多一个发光二极管单元(比七段数码管多一个点),又按能显示多少个"8"可分为1位.2位.4位等等.数码管又分为共阳极驱动/ ...

  7. system verilog的一些总结(从其他博客复制来的)

    转载自 http://blog.sina.com.cn/s/blog_e7fec2630101f5t9.html SystemVerilog是一种硬件描述和验证语言(HDVL),它基于IEEE 136 ...

  8. 单片机C语言开发学习笔记---动态的数码管

    在郭天祥的那本书中,有一个通过按键控制数码管的例子,在运行这个例子的时候,我发现当按键按下的时候,第一位数码管会熄掉,这是为什么呢? 后来在网上找到了原因,当我按下按键不松开的时候,接下来要运行的代码 ...

  9. 对Verilog 初学者比较有用的整理(转自它处)

    *作者: Ian11122840    时间: 2010-9-27 09:04                                                              ...

  10. 我的 FPGA 学习历程(08)—— 实验:点亮单个数码管

    数码管是一种常见的用于显示的电子器件,根据数码管大致可以分为共阴极和共阳极两种,下图所示的是一个共阳极的数码管的电路图(摘自金沙滩工作室的 51 开发板电路图),我的 AX301 开发板与这张图的情况 ...

随机推荐

  1. 自己diy一个smi(可以监控gpu,cpu,memory)

    diy-smi 1.0(DIY System management interface) 在我们训练自己深度学习模型时,我们想看GPU信息,也想看CPU和内存信息.我常用的是nvidia-smi和ht ...

  2. 如何实现数据库数据到Abp vnext实体对象的同步?以及代码生成工具

    在采用了EF Core的Code First方式下,如果你在数据库中直接添加了新表或存储过程,你需要在项目代码中手动反向工程这些数据库的更改,以保持Code First的代码与数据库同步.这种情况可以 ...

  3. 《c#高级编程》第4章C#4.0中的更改(八)——协变和逆变

    一.协变 C#协变是指在一些特定的情况下,可以将一个派生类型的实例赋值给其基类或接口类型的引用.这里的"派生类型"指的是从某个基类或接口继承并增加了新的成员的类型. C# 4.0 ...

  4. HarmonyOS NEXT应用开发—自定义视图实现Tab效果

    介绍 本示例介绍使用Text.List等组件,添加点击事件onclick,动画,animationTo实现自定义Tab效果. 效果预览图 使用说明 点击页签进行切换,选中态页签字体放大加粗,颜色由灰变 ...

  5. 基于开源PolarDB-X打造中正智能身份认证业务数据基座

    简介: 在10月25日由阿里云开发者社区.PolarDB开源社区.infoQ联合举办的「开源人说」第三期--<数据库PolarDB专场>沙龙上,中正智能科技有限公司平台软件部研发总监韩毅带 ...

  6. 阿里巴巴云数据仓库 MaxCompute 数据安全最佳实践

    ​简介:MaxCompute作为企业级SaaS模式云数据仓库,正在为客户业务及其数据提供持续的安全保护. MaxCompute 近期对产品的安全能力进行了全面升级 ,结合数据生命周期,针对数据误用.数 ...

  7. 阿里千万实例可观测采集器-iLogtail正式开源

    ​简介:11月23日,阿里正式开源可观测数据采集器iLogtail.作为阿里内部可观测数据采集的基础设施,iLogtail承载了阿里巴巴集团.蚂蚁的日志.监控.Trace.事件等多种可观测数据的采集工 ...

  8. ACMMM2021|在多模态训练中融入“知识+图谱”:方法及电商应用实践

    ​简介: 随着人工智能技术的不断发展,知识图谱作为人工智能领域的知识支柱,以其强大的知识表示和推理能力受到学术界和产业界的广泛关注.近年来,知识图谱在语义搜索.问答.知识管理等领域得到了广泛的应用. ...

  9. WPF 已知问题 传入错误数据给到 WriteableBitmap 可能导致渲染线程锁住

    本文记录一个 WPF 已知问题,此问题已经被我修复.传入错误的数据给到 WriteableBitmap 对象,比如调用 WritePixels 时传入错误的 stride 数值,将可能导致渲染线程进入 ...

  10. python入门_模块2

    0.collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdic ...