一个问题:六位八段数码管(Verilog)
【基本信息】
需求: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)的更多相关文章
- arduino八段数码管使用
一:八段数码管的使用 控制要求:0-9的计时数据 实物连接图: 控制代码: //智慧自动化2018.6.11 ;//定义数字接口7 连接a 段数码管 ;// 定义数字接口6 连接b 段数码管 ;// ...
- Verilog HDL那些事_建模篇笔记(实验七:数码管电路驱动)
1.同步动态扫描 多个数码管的显示采用的是同步动态扫描方法,同步动态扫描指的是:行信号和列信号同步扫描,是一种并行操作. 2.数码管驱动电路实现思路 如果要求数码管显示我们想要的数字,首先需 ...
- [51单片机] 以PWM控制直流电机为例建一个简单的51工程框架
目录 1)功能概述 2)引脚连接 3)框架介绍 4)模块说明 5)复用规则 6)工程链接 1)功能概述 名称:独立按键控制直流电机调速 内容:对应的电机接口需用杜邦线连接到uln2003电机控制端; ...
- AC620教程 第十五节 8位7段数码管驱动设计与验证
本章导读 电子系统中常用的显示设备有数码管.LCD液晶以及VGA显示器等.其中数码管又可分为段式显示(7段.米字型等)以及点阵显示(8*8.16*16等),LCD液晶的应用可以分为字符式液晶(1602 ...
- 【.NET 与树莓派】LED 数码管驱动模块——TM1638
LED 数码管,你可以将它看做是 N 个发光二级管的组合,一个灯负责显示一个段,七个段组合一位数字,再加一个小数点,这么一来,一位数码管就有八段.一般,按照顺时针的方向给每个段编号. 上图中的 h 就 ...
- 音响音箱/恒温壶/电量显示/电子数字时钟等LED数码管显示驱动IC-VK1640B 8段12位/12段8位显示
市面上最常用的数码管为七段/八段显示,八段数码管比七段数码管多一个发光二极管单元(比七段数码管多一个点),又按能显示多少个"8"可分为1位.2位.4位等等.数码管又分为共阳极驱动/ ...
- system verilog的一些总结(从其他博客复制来的)
转载自 http://blog.sina.com.cn/s/blog_e7fec2630101f5t9.html SystemVerilog是一种硬件描述和验证语言(HDVL),它基于IEEE 136 ...
- 单片机C语言开发学习笔记---动态的数码管
在郭天祥的那本书中,有一个通过按键控制数码管的例子,在运行这个例子的时候,我发现当按键按下的时候,第一位数码管会熄掉,这是为什么呢? 后来在网上找到了原因,当我按下按键不松开的时候,接下来要运行的代码 ...
- 对Verilog 初学者比较有用的整理(转自它处)
*作者: Ian11122840 时间: 2010-9-27 09:04 ...
- 我的 FPGA 学习历程(08)—— 实验:点亮单个数码管
数码管是一种常见的用于显示的电子器件,根据数码管大致可以分为共阴极和共阳极两种,下图所示的是一个共阳极的数码管的电路图(摘自金沙滩工作室的 51 开发板电路图),我的 AX301 开发板与这张图的情况 ...
随机推荐
- asyncio和aiohttp携程并发
import asyncio from aiohttp import web import time async def process(): for i in range(10): print(&q ...
- 使用JSZip实现在浏览器中操作文件与文件夹
1. 引言 浏览器中如何创建文件夹.写入文件呢? 答曰:可以借助JSZip这个库来实现在浏览器内存中创建文件与文件夹,最后只需下载这个.zip文件,就是最终得结果 类似的使用场景如下: 在线下载很多图 ...
- 力扣579(MySQL)-查询员工的累积薪水(困难)
题目: Employee 表保存了一年内的薪水信息. 请你编写 SQL 语句,对于每个员工,查询他除最近一个月(即最大月)之外,剩下每个月的近三个月的累计薪水(不足三个月也要计算). 结果请按 Id ...
- 力扣682(java)-棒球比赛(简单)
题目: 你现在是一场采用特殊赛制棒球比赛的记录员.这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分. 比赛开始时,记录是空白的.你会得到一个记录操作的字符串列表 ops,其中 ops ...
- 我,PolarDB云原生数据库,5年来实现这些重磅技术创新
简介: 过去5年,阿里云针对PolarDB进行了诸多创新,通过采用存储计算分离.软硬一体化设计,PolarDB实现成本仅为传统商业数据库的十分之一.所实现的计算.内存与存储资源的"三层解耦& ...
- Flagger on ASM·基于Mixerless Telemetry实现渐进式灰度发布系列 1 遥测数据
简介: 服务网格ASM的Mixerless Telemetry技术,为业务容器提供了无侵入式的遥测数据.遥测数据一方面作为监控指标被ARMPS/prometheus采集,用于服务网格可观测性:另一方面 ...
- RDS PostgreSQL一键大版本升级技术解密
简介: 内容简要: 一.PostgreSQL行业位置 二.PostgreSQL版本升级背景 三.PostgreSQL版本升级解密 四.PostgreSQL版本升级成果 一.PostgreSQL行业位 ...
- Solution Set - 点分治
A[POJ1741].给定一棵树,边有权,求长度不超过\(k\)的路径数目. B[HDU4871].给定一张图,边有权,求它的最短路径树上恰含\(k\)个点的路径中最长路径的长度及数目. C[HDU4 ...
- 羽夏壳世界—— PE 解析的实现
写在前面 此系列是本人一个字一个字码出来的,包括代码实现和效果截图. 如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后 ...
- 【GUI软件】小红书指定博主批量采集笔记,支持多博主同时采集!
目录 一.背景介绍 1.1 爬取目标 1.2 演示视频 1.3 软件说明 二.代码讲解 2.1 爬虫采集模块 2.2 软件界面模块 2.3 日志模块 三.获取源码及软件 一.背景介绍 1.1 爬取目标 ...