基于Xilinx7系FPGA的电子表设计,Verilog

这篇博客介绍了作者作为初学者如何基于Xilinx7系列FPGA,使用Verilog语言设计一个24小时格式的电子表。设计包括时钟生成、数码管显示和74HC595驱动模块。通过74HC595移位寄存器节省FPGA资源,数码管采用共阳极连接方式,时钟生成模块中涉及了十六进制到十进制的转换,确保数码管正确显示时间。

写在前面

本人也是初学者,刚开始学FPGA开发半个月左右,代码和设计有诸多不好的地方,各位大神口下留情。

分享给初学者,希望能一起进步。

项目简介

基于Xilinx7系FPGA,使用Verilog语言设计一个电子表,并使用8段数码管显示,要求时间为24h格式。

设计思路
首先,分析电子表的显示要素有哪些,我们也不是做多高大上的一个东西,就是一个基础的能计时24h的电子表,我们需要显示的内容主要就是时、分、秒。
具体怎么在8段数码管进行显示,可以参考下图(略丑)
8段数码管
这里的数码管一共有8个,我这里选择用sel[7:6]显示小时(H),sel[5]和sel[2]显示途中符号(没有冒号将就用了),sel[4:3]显示分钟(min),sel[1:0]显示秒(s)。

至于数码管的显示原理我就不讲了,网上一大堆都是的,我这里的数码管采用的是共阳极的连接方式。
另外需要说明的是,因为我买的是现成的开发板,所以个模块的集成度比较高,这里的数码管显示用到了74HC595芯片,其工作原理可以参考这篇文章。

链接: link.

该芯片的作用就是移位寄存器,通过移位的方式,节省FPGA的管脚。

接下来就直接上程序了。采用模块化设计。这里用到了三个模块,分别是数码管显示模块,74HC595驱动模块,时间(时分秒)生成模块。

时钟生成模块

这里需要注意的一个地方,通常我们见到的时间都是十进制的,但是我们用计数器计数之后输出的数据通常为16进制数。
十进制数显示的范围为0~9;
十六进制数显示的范围为0~f;我们需要的数只有0到9,所以当数超过9时对于我们的电子表来说是多余的。因此我们需要对十六进制数进行转换,让输出的数(也就是数码管上显示的数)为十进制。

其转换原理为:
对应十进制数大于9时,进行加6操作;
对应十进制数大于19时,进行加12操作;
对应十进制数大约29时,进行加18操作;
以此类推···

其转换的核心思想是将二进制数转化为BCD码,我这里以图片说明。
在这里插入图片描述
可以看到,转换后的BCD码输出就跟我们需要的十进制输出一致。至于这里为什么要转换为BCD码,就是为了方便在数码管上显示时间对应的十进制输出。具体请看联调代码。

// 时钟生成模块
// An highlighted block
`timescale 1ns / 1ps
//////////////////////////////////////////////
//code by 清月
//time:2021.09.14
// 时钟信息的产生,时,分,秒
//////////////////////////////////////////////

module dzb_cnt(
    clk,
    ret,
    h_out,
    m_out,
    s_out
);
    input clk;
    input ret;
    output reg[7:0]h_out;//小时输出
    output reg[7:0]m_out;//分钟输出
    output reg[7:0]s_out;//秒输出
    
    parameter MCNT = 50000000;
    
    //基本时间单位计数(单位S)
    reg [31:0]div_cnt;
    always@(posedge clk or negedge ret)
    if(!ret)
        div_cnt<= 0;
    else if(div_cnt>=MCNT-1) 
        div_cnt<= 0;
    else
        div_cnt<= div_cnt+1'd1;
        
    // 时间单位计数,1min = 60s
    reg [7:0]s_cnt;
    reg [7:0]r_s_out;//寄存s
    
    always@(posedge clk or negedge ret)
    if(!ret)begin
        s_cnt <= 0;
        r_s_out <= 0;
    end
    else if(s_cnt > 8'd59)
        s_cnt <= 0;
    else if(div_cnt == MCNT-1)begin   
        s_cnt <= s_cnt +1'd1;
        r_s_out <= s_cnt+1'd1;
    end else
        r_s_out <= r_s_out;
        
    always@(posedge clk)
    if(r_s_out > 8'd09 && r_s_out<8'd20)begin
        s_out <= r_s_out + 8'd6;end
    else if(r_s_out>8'd19 && r_s_out<8'd30)begin
        s_out <= r_s_out + 8'd12;end
    else if(r_s_out>8'd29 && r_s_out<8'd40)begin
        s_out <= r_s_out + 8'd18;end
    else if(r_s_out>8'd39 &&r_s_out<8'd50)begin
        s_out <= r_s_out + 8'd24;end  
    else if(r_s_out>8'd49 && r_s_out<8'd60)begin
        s_out <= r_s_out + 8'd30;end 
    else
         s_out <= r_s_out;                   
            
    //时间单位计数,1h = 60min
    reg [7:0]m_cnt;
    reg [7:0]r_m_out;
    always@(posedge clk or negedge ret)
    if(!ret)begin
        m_cnt <= 0;
        r_m_out <= 0;
        end
    else if(m_cnt > 8'd59)
        m_cnt <= 0;
    else if(s_cnt > 8'd59)begin
        m_cnt <= m_cnt +1'd1;
        r_m_out <= m_cnt+1'd1;
    end else
        r_m_out <= r_m_out;
        
    always@(posedge clk)
    if(r_m_out > 8'h09 && r_m_out<8'd20)begin
        m_out <= r_m_out +  8'd6;end 
    else if(r_m_out>8'h13 && r_m_out<8'd30) begin     
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值