基于vivado+Verilog FPGA开发 — 数码管动态扫描显示v2.0 — 使用 74HC595串转并芯片 节省FPGA引脚资源

代码规范:Verilog 代码规范_verilog代码编写规范-CSDN博客

开发流程:FPGA基础知识----第二章 FPGA 开发流程_fpga 一个项目的整个流程-CSDN博客 

源码下载:https://github.com/Redamancy785/FPGA-Learning-Record.git

零、74HC595芯片驱动

1、74HC595串转并芯片 内部原理图

2、74HC595串转并芯片 时序图

3、使用两片74HC595芯片 实现三根数据线传输十六位数据

4、驱动模块设计输入以及目标输出时序图

module hc595_driver(
    clk_i,
    reset_n_i,
    sel_i,
    seg_i,
    dio_o,
    srclk_o,
    rclk_o
    );

    input clk_i,reset_n_i;
    input [7:0] sel_i;
    input [7:0] seg_i;
    output dio_o,srclk_o,rclk_o;
    
    parameter FREQUENCY = 50_000_000; // Hz
    parameter SRCLK_FREQUENCY = 12_500_000;  // Hz
    parameter SRCLK_TURN_INTERVAL = FREQUENCY/SRCLK_FREQUENCY/2;  

    reg [31:0] srclk_turn_interval_cnt;
    always@(posedge clk_i or negedge reset_n_i)
        if(!reset_n_i) 
            srclk_turn_interval_cnt <= 0;
        else if(srclk_turn_interval_cnt == (SRCLK_TURN_INTERVAL - 1))
            srclk_turn_interval_cnt <= 0; 
        else 
            srclk_turn_interval_cnt <= srclk_turn_interval_cnt + 1;
            
    reg [4:0] srclk_turn_cnt;
    always@(posedge clk_i or negedge reset_n_i)
        if(!reset_n_i) 
            srclk_turn_cnt <= 0;
        else if(srclk_turn_interval_cnt == (SRCLK_TURN_INTERVAL - 1)) 
            srclk_turn_cnt <= srclk_turn_cnt + 1; 

    reg dio_o;
    reg rclk_o;
    always@(posedge clk_i) 
        if(!reset_n_i) 
            rclk_o <= 0;
        else begin
            case(srclk_turn_cnt)
                0:  begin dio_o <= seg_i[7]; rclk_o <= 1; end
                1:  rclk_o <= 0; 
                2:  dio_o <= seg_i[6];
                4:  dio_o <= seg_i[5];
                6:  dio_o <= seg_i[4];
                8:  dio_o <= seg_i[3];
                10: dio_o <= seg_i[2];
                12: dio_o <= seg_i[1];
                14: dio_o <= seg_i[0];
                16: dio_o <= sel_i[7];
                18: dio_o <= sel_i[6];
                20: dio_o <= sel_i[5];
                22: dio_o <= sel_i[4];
                24: dio_o <= sel_i[3];
                26: dio_o <= sel_i[2];
                28: dio_o <= sel_i[1];
                30: dio_o <= sel_i[0];
            endcase
        end 
        
    reg srclk_o; 
    always@(posedge clk_i) 
        if(!reset_n_i) 
            srclk_o <= 0;
        else begin
            case(srclk_turn_cnt%2)
                0:  srclk_o <= 0;
                1:  srclk_o <= 1; 
            endcase
        end
        
endmodule

   

    
    
    

一、功能定义

二、设计输入 

module digital_tube_hc595(
    clk_i,
    reset_n_i,
    switch_i,
    dio_o,
    srclk_o,
    rclk_o
    );

    input clk_i,reset_n_i;
    input [1:0] switch_i;
    output dio_o,srclk_o,rclk_o;
    reg [31:0] disp_data_i;

    wire [7:0] u_sel_o;
    wire [7:0] u_seg_o ;  
    digital_tube U_digital_tube_0(
        .clk_i(clk_i),
        .reset_n_i(reset_n_i),
        .disp_data_i(disp_data_i),
        .sel_o(u_sel_o),
        .seg_o(u_seg_o)
    );
    
    hc595_driver U_hc595_driver_0(
        .clk_i(clk_i),
        .reset_n_i(reset_n_i),
        .sel_i(u_sel_o),
        .seg_i(u_seg_o),
        .dio_o(dio_o),
        .srclk_o(srclk_o),
        .rclk_o(rclk_o)
    );
    
    
    always@(*)
        case (switch_i)
         0 : disp_data_i = 32'h01234567;
         1 : disp_data_i = 32'h89abcdef;
         2 : disp_data_i = 32'h08192a3b;
         3 : disp_data_i = 32'h4c5d6e7f;
        endcase
        
endmodule

三、功能仿真 

`timescale 1ns / 1ps

module digital_tube_hc595_tb();
    reg u_clk_i,u_reset_n_i;
    reg [1:0] u_switch_i;
    wire u_dio_o,u_srclk_o,u_rclk_o;
    
    digital_tube_hc595 U_digital_tube_hc595_0(
        .clk_i(u_clk_i),
        .reset_n_i(u_reset_n_i),
        .switch_i(u_switch_i),
        .dio_o(u_dio_o),
        .srclk_o(u_srclk_o),
        .rclk_o(u_rclk_o)
    );
    
    initial u_clk_i = 1;
    always #10 u_clk_i = ~u_clk_i; 

    initial begin
        u_reset_n_i = 0;
        #201;
        u_reset_n_i = 1;
        u_switch_i = 0;
        #10_000_000;
        u_switch_i = 1;
        #10_000_000;
        u_switch_i = 2;
        #10_000_000;
        u_switch_i = 3;
        #10_000_000;
        $stop;
    end

endmodule

 

四、综合优化

五、布局布线

六、时序仿真

七、板级调试 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用Vivado 2018.3软件和Verilog HDL语言实现Basys3四位数码管动态显示的一个简单例子。 首先,在Vivado中创建一个新项目,添加Basys3开发板作为目标板卡,并设置好约束文件。 然后,我们需要创建一个Verilog模块,用于控制四位数码管动态显示。以下是一个示例代码: ```verilog module digit_display( input clk, // 时钟信号 input [3:0] data_in, // 输入数据,4位二进制数值 output reg [6:0] anodes, // 数码管阳极输出 output reg [6:0] segments // 数码管阴极输出 ); reg [25:0] counter; // 计数器,用于控制数码管动态显示 reg [3:0] digit; // 当前显示数码管编号 // 数码管显示控制 always @(posedge clk) begin counter <= counter + 1; if(counter == 250000) begin // 50Hz 的刷新频率 counter <= 0; digit <= digit + 1; if(digit == 4) begin digit <= 0; end end end // 数码管数据输出 always @(posedge clk) begin case(digit) 0: begin anodes <= 7'b1111110; segments <= { data_in[0] ? 7'b0000001 : 7'b1111110, data_in[1] ? 7'b0000001 : 7'b1111110, data_in[2] ? 7'b0000001 : 7'b1111110, data_in[3] ? 7'b0000001 : 7'b1111110 }; end 1: begin anodes <= 7'b1100111; segments <= { data_in[0] ? 7'b0000001 : 7'b1111110, data_in[1] ? 7'b0000001 : 7'b1111110, data_in[2] ? 7'b0000001 : 7'b1111110, data_in[3] ? 7'b0000001 : 7'b1111110 }; end 2: begin anodes <= 7'b1001111; segments <= { data_in[0] ? 7'b0000001 : 7'b1111110, data_in[1] ? 7'b0000001 : 7'b1111110, data_in[2] ? 7'b0000001 : 7'b1111110, data_in[3] ? 7'b0000001 : 7'b1111110 }; end 3: begin anodes <= 7'b1110011; segments <= { data_in[0] ? 7'b0000001 : 7'b1111110, data_in[1] ? 7'b0000001 : 7'b1111110, data_in[2] ? 7'b0000001 : 7'b1111110, data_in[3] ? 7'b0000001 : 7'b1111110 }; end endcase end endmodule ``` 在这个模块中,我们使用计数器和一个 `digit` 变量来控制四位数码管动态显示。每个数码管的数据由输入的 4 位二进制数值决定,通过 `case` 语句来选择要显示数码管。在每个时钟上升沿时,根据 `digit` 的值输出相应的阳极和阴极信号。 最后,将这个Verilog模块添加到Vivado项目中,并生成比特流文件,烧录到Basys3开发板上即可实现四位数码管动态显示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值