【FPGA】译码器、计数器及数码管显示

这篇具有很好参考价值的文章主要介绍了【FPGA】译码器、计数器及数码管显示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在前面
万万没想到秋招春招找工作以C++为主、FPGA为辅,最后去了FPGA岗位
也算是不忘初心,回归了从研一就开始学的FPGA老本行
但之前学FPGA的时候并没有养成写笔记的习惯,导致后面有些东西都比较模糊,因此打算从今天开始从头来过,把之前基础知识和新学到的FPGA相关内容记录下来,记录我的FPGA之路!

这是某本书上的第一章节,感觉写的还是挺不错的,大概看了一下让我回想起很多知识,个人感觉比较适合学习了Verilog语法和数电之后上板的同学

1. 原理介绍

1.1 数码管

数码管按段分可分为七段数码管八段数码管,区别就是八段数码管多了个小数点
【FPGA】译码器、计数器及数码管显示
常见的数码管有两种:共阴数码管共阳数码管
共阴数码管就是高电平亮,低电平灭;共阳数码管就是低电平亮,高电平灭。

1.2 译码器

七段数码管译码器的结构图如下,4个输入变量能够组合成十六进制数字0-F,那么相应的输出就可以通过七个输出变量,表示成数字,从而达到译码的效果。
【FPGA】译码器、计数器及数码管显示
这里译码器有两种写法,一种比较复杂,就是通过对应的真值表或者卡诺图写出h的逻辑表达式,写起来比较繁琐,就直接放代码,通过逻辑门(assign赋值语句)实现译码器

assign h[6] = (~b[3] & ~b[2] & ~b[1]) | (~b[3] & b[2] & b[1] & b[0]) | (b[3] & b[2] & ~b[1] & ~b[0]);
assign h[5] = (~b[3] & ~b[2] & ~b[0]) | (~b[3] & ~b[2] & b[1]) | (~b[3] & b[1] & ~b[0]) |(b[3] & b[2] & ~b[1] & b[0]);
assign h[4] = (~b[3] & b[0]) | (~b[3] & b[2] & ~b[1]) | (b[3] & ~b[2] & ~b[1] & b[0]);
assign h[3] = (~b[2] & ~b[1] & b[0]) | (~b[3] & b[2] & ~b[1] & ~b[0]) | (b[2] & b[1] & b[0] ) | (b[3] & ~b[2] &b[1] & ~b[0]);
assign h[2] = (~b[3] & ~b[2] & b[1] & ~b[0]) | (b[3] & b[2] & ~b[1] & ~b[0]) | (b[3] & b[2] & b[1]);
assign h[1] = (~b[3] & b[2] & ~b[1] & b[0]) | (& b[2] & b[1] & ~b[0]) | (b[3] & b[2] & ~b[0]) | (b[3] & b[1] & b[0]);
assign h[0] = (~b[3] & ~b[2] & ~b[1] & b[0]) | (~b[3] & b[2] & ~b[1] & ~b[0]) | (b[3] & b[2] & ~b[1] & b[0] | b[3] & ~b[2] & b[1] & b[0]);

当然,这样不仅要推导,写起来就很麻烦
所以还可以用case条件语句实现

case (b)
    4`b0000: h = 7`b1000000;
    4`b0001: h = 7`b1111001;
    4`b0010: h = 7`b0100100;
    4`b0011: h = 7`b0110000;
    4`b0100: h = 7`b0011001;
    4`b0101: h = 7`b0010010;
    4`b0110: h = 7`b0000010;
    4`b0111: h = 7`b1111000;
    4`b1000: h = 7`b0000000;
    4`b1001: h = 7`b0011000;
    4`b1010: h = 7`b0001000;
    4`b1011: h = 7`b0000011;
    4`b1100: h = 7`b1000110;
    4`b1101: h = 7`b0100001;
    4`b1110: h = 7`b1000110;
    4`b1111: h = 7`b1001110;
endcase

1.3 D触发器

D触发器的特性方程Qn+1 = D,Qn+1为次态,D为输入信号,都是数电上的东西,Verliog HDL代码为:

module dff(
    input clk,
    intpu d,
    output reg q
);

always @(posedge clk)
    q <= d;
endmudle;

而通常会用到复位信号来设定电路的起始值或者做清楚动作,因此D触发器根据复位的不同分为两种:异步复位D触发器和同步复位D触发器

异步复位D触发器:
“异步”指的是和工作时钟不同步的意思,即寄存器的复位不关心时钟的有效沿来不来,只要检测到复位信号有效,就立即执行复位操作。

module DFF_async_rst(
    input clk,
    input rst_n,
    intpu d,
    output reg q
);

always @(posedge clk,negedge rst_n)
    if(~rst_n)            //复位信号rst_n的优先级比时钟信号clk高
        q <= 1'b0;
    else
        q <= d;
endmudle;

同步复位D触发器
“同步”是和工作时钟同步的意思,即复位信号只有在时钟的有效沿到来时,才能有效,否则无法完成复位任务。

module DFF_async_rst(
    input clk,
    input rst_n,
    intpu d,
    output reg q
);

always @(posedge clk)     //always语句只有一个触发条件
    if(~rst_n)            //复位信号rst_n需要在clk的上升沿触发下才能起作用
                          //当rst_n=0,并且clk上升沿到来时,Q才会被清零
        q <= 1'b0;
    else
        q <= d;
endmudle;

1.4 寄存器

寄存器是数字系统中用来存储二进制数据的逻辑部件。1个触发器可以存储一位二进制数据,存储n位二进制数据的寄存器需要用n个触发器组成。

当然,上述说法是表现在硬件上,在代码方便只是定义了输入输出的位宽:

module reg4bits(
    input clk,
    input rst_n,
    input en;
    intpu [3:0] d,
    output reg [3:0] q
);

always @(posedge clk,negedge rst_n)
    if(~rst_n)         
        q <= 4'b0000;
    else if(en)             //增加了使能端
        q <= d;
    else                    
        q <= q;
endmudle;

1.5 计数器

计数器不仅可以用于对脉冲进行计数,还可用于分频、定时、产生节拍脉冲以及其他时序信号。

同步二进制加(减)计数器

module counter_up(
    input        clk,
    input        rst_n,
    input        en,
    output  reg [3:0] q
);

always @(posedge clk or negedge rst_n)
begin
    if(~rst_n)
        q <= 4'b0000;             //复位,计数清零
    else if(en)                   //计数器使能,开始计数
        q <= q + 1'b1;            //加计数
      //q <= q - 1'b1;            //减计数,原理都是一样的
    else                          //计数器未使能,计数器保持不变
        q <= q;
end
endmodule

模m计数器
计数器运行时总是从某个起始状态开始,以此经过所有不重复的状态后完成一次循环。把一次循环所包含的状态数称为计数器的模,用M表示。

module counter_m #(
    parameter n = 4
    parameter m = 16
)(
    input             clk,
    input             rst_n;
    input             en;
    output reg [3:0]  cnt;           //计数器计数值
    output            carry_out;     //计数器进位输出
);

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)              //复位,计数值清零
        cnt <= 4'b0000;
    else if(en)             //计数器使能端,开始计数
    begin             
        if (cnt == m-1)     //计数值达到m-1,计数值清零
            cnt <= 4'b0000;
        else
            cnt <= cnt + 1'b1;
    end
    else 
        cnt <= cnt;
end
assign carry_out = (cnt == m-1);   //计数值达到m-1,计数器进位输出1
endmodule

1.6 数码管显示

前面说了那么多,都是为了将其结合起来,原理也比较简单,就直接放上代码了

译码器decod7seg

module decod7seg (
    input       [3:0]   hex,
    output  reg [6:0]   display
);

always @ (hex)
    case (hex)
        4'h0: display = 7'b1000000;
        4'h1: display = 7'b1111001;
        4'h2: display = 7'b0100100;
        4'h3: display = 7'b0110000;
        4'h4: display = 7'b0011001;
        4'h5: display = 7'b0010010;
        4'h6: display = 7'b0000010;
        4'h7: display = 7'b1111000;
        4'h8: display = 7'b0000000;
        4'h9: display = 7'b0011000;
        4'hA: display = 7'b0001000;
        4'hB: display = 7'b0000011;
        4'hC: display = 7'b1000110;
        4'hD: display = 7'b0100001;
        4'hE: display = 7'b0000110;
        4'hF: display = 7'b0001110;
    endcase

endmodule

计数器

module counter_up_down (
    input               clk,
    input               rst_n,
    input               up_down,
    output  reg [3:0]   q
);
    
always @(posedge clk or negedge rst_n)
begin
    if (~rst_n)
        q <= 4'b0000;
    else if (up_down)
        q <= q + 1'b1;
    else
        q <= q - 1'b1;
end
    
endmodule

控制模块

module display_controller (
    input           clk,
    input           rst_n,
    input           up_down,
    output  [6:0]   hex0_out
);

wire [3:0] q;

counter_up_down counter_up_down_inst (
    .clk        (clk),
    .rst_n      (rst_n),
    .up_down    (up_down),
    .q          (q)
);
    
decod7seg decod7seg_inst (
    .hex        (q),
    .display    (hex0_out)
);
    
endmodule

测试文件文章来源地址https://www.toymoban.com/news/detail-501380.html

module display_controller_tb (
    input           clk,
    input           rst_n,
    input           up_down,
    output  [6:0]   hex0_out
);

wire [3:0] q;

counter_up_down counter_up_down_inst (
    .clk        (clk),
    .rst_n      (rst_n),
    .up_down    (up_down),
    .q          (q)
);
    
decod7seg decod7seg_inst (
    .hex        (q),
    .display    (hex0_out)
);
    
endmodule

到了这里,关于【FPGA】译码器、计数器及数码管显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA_38译码器

    本文来自《小梅哥FPGA视频》的笔记整理 不要眼高手低,一定一定要实践,自己动手去敲一遍!!! 在数字电路中可以根据电路功能的不同分为,组合逻辑电路与时序逻辑电路。 组合逻辑 电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状

    2023年04月11日
    浏览(37)
  • (2)FPGA仿真——3-8译码器设计

    译码是编码的逆过程,在编码时,每一种二进制代码,都赋予了特定的含义,即都表示了一个确定的信号或者对象。把代码状态的特定含义翻译出来的过程叫做译码,实现译码操作的电路称为译码器。或者说,译码器是可以将输入二进制代码的状态翻译成输出信号,以表示其

    2024年02月08日
    浏览(45)
  • FPGA二四译码器设计及实现

    FPGA二四译码器设计及实现 在数字电路中,二进制的计数方式广泛应用于各种场合。然而,当我们需要控制多个开关或LED时,手动进行二进制转换并不是一种好的选择。因此,在这种情况下,二进制译码器就显得尤为重要。 二四译码器是一种将两个输入字线转换为四个输出字

    2024年02月04日
    浏览(44)
  • 基于STM32的四位数码管计数器设计与实现

    ✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进, 代码获取、问题探讨及文章转载可私信。  ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇 点击领取更多详细资料 本文介绍了一种基于STM

    2024年02月02日
    浏览(47)
  • Verilog 编程实现 3-8 译码器 FPGA

    Verilog 编程实现 3-8 译码器 FPGA FPGA 是一种可重构的数字电路芯片,可用于实现各种逻辑电路。在 FPGA 中,我们可以使用 Verilog HDL(硬件描述语言)来编写数字电路设计。本篇文章将为您介绍如何使用 Verilog 实现基本的数字电路,即 3-8 译码器。 3-8 译码器是一种常用的数字电路

    2024年02月07日
    浏览(41)
  • FPGA学习小例子:38译码器设计与仿真

    译码器74x138是数字电路课程重点内容之一。译码器的设计比 较简单,使用Verilog语言实现译码器就更为简单。本教程设计了一个3-8译码器并做了仿真。 打开vivado,点击File 填写项目名,以及选择项目路径 并勾选“Do not specify sources at this time”,意思是先创建工程,后期再添加

    2024年02月09日
    浏览(47)
  • FPGA学习笔记(八)——3-8译码器的设计与验证

        3-8译码器是三输入,八输出。当输入信号按二进制方式的表示值为N时,输出端标号为N的输出端输出高电平表示有信号产生,而其它则为低电平表示无信号产生。因为三个输入端能产生的组合状态有八种,所以输出端在每种组合中仅有一位为高电平的情况下,能表示所有

    2024年02月05日
    浏览(43)
  • FPGA数字电路设计:三八译码器的原理与实现

    FPGA数字电路设计:三八译码器的原理与实现 三八译码器是常用于数字电路设计中的一种重要元件。它的作用是将三位二进制信号转换成八个输出信号,通常用于地址解码、选通控制、状态指示等应用场景。 在FPGA数字电路设计中,三八译码器的实现需要借助Verilog HDL语言进行

    2024年02月08日
    浏览(45)
  • 【FPGA】Verilog:计数器 | 异步计数器 | 同步计数器 | 2位二进制计数器的实现 | 4位十进制计数器的实现

    目录 Ⅰ. 实践说明 0x00 计数器(Counter) 0x01 异步计数器(Asynchronous Counter)

    2024年02月05日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包