其他分享
首页 > 其他分享> > 数码管动态显示Verilog实现(参考小梅哥教程)(视觉暂留)

数码管动态显示Verilog实现(参考小梅哥教程)(视觉暂留)

作者:互联网

 

一个数码管有九个引脚,控制八段二极管的亮灭,用以显示需要的数字。

当有N个数码管时,一个一个控制的话需要N x 9 个引脚,消耗资源较多。

因此可以利用动态显示的方案通过人眼的视觉暂留特性达到静态显示的效果(动态显示周期<20ms),只需N+8个引脚。节省了大量资源。(动态静显)

 

数码管动态显示的逻辑电路如下:

Verilog设计代码如下:

module digital_tube(//八个数码管显示
    clk,
    reset,
    disp_num_all,
    dg_tube,
    tube_part
    );
    
    input clk ;
    input reset ;
    input [31:0]disp_num_all ;
    output [7:0]dg_tube ;
    output [7:0]tube_part ;
    
    parameter one_dis_t = 25'd1_000_000 ;//每个晶体管显示时间(计数)
    
    reg [16:0]counter1 ;
    reg [2:0] counter2 ;
    
    always @ ( posedge clk or negedge reset )//分频
    begin
        if (! reset )
        counter1 <= 17'd0 ;
        else if ( (one_dis_t-1) <= counter1 )
        counter1 <= 17'd0 ;
        else
        counter1 <= counter1 +1'b1 ;
    end
    
    always @ ( posedge clk or negedge reset )//循环
    begin
        if (! reset )
        counter2 <= 3'd0 ;
        else if ( (one_dis_t-1) <= counter1 ) 
        counter2 <= counter2 +1'b1 ;
    end
    
    wire [3:0]disp_num_one ;
    
    //3-8译码器 控制哪个数码管显示
    decoder_3_8 tube_select(//控制
               .a(counter2[2] ),
               .b(counter2[1]),
               .c(counter2[0]),
               .out(dg_tube)
        );
    
    //需要一个八选一选通器,对应哪个数码管显示什么内容
    mux8  tube_display(//选通
    .sel(counter2),
    .data(disp_num_all),
    .out(disp_num_one)
    );
    
    //真值表对应显示数字
    LUT_truth translator(//控制
    .num(disp_num_one),
    .out(tube_part)
    );
endmodule
module decoder_3_8(
               a,
               b,
               c,
               out
        );
      input a;
      input b;
      input c;
      output reg [7:0]out;
      
      always@(*)begin//等价于always({a,b,c})a是高位,c是低位
         case({a,b,c})
              3'b000:out=8'b0000_0001;             
              3'b001:out=8'b0000_0010; 
              3'b010:out=8'b0000_0100; 
              3'b011:out=8'b0000_1000; 
              3'b100:out=8'b0001_0000; 
              3'b101:out=8'b0010_0000; 
              3'b110:out=8'b0100_0000; 
              3'b111:out=8'b1000_0000; 
         endcase
      end
      
endmodule
module mux8(
    sel,
    data,
    out
    );
    
    input [2:0]sel ;
    input [31:0]data ;
    output reg [3:0]out ;
    
    always@(*)
    begin
    case(sel)

        3'b000 : out = data[3:0] ;
        3'b001 : out = data[7:4] ;
        3'b010 : out = data[11:8] ;
        3'b011 : out = data[15:12] ;
        3'b100 : out = data[19:16] ;
        3'b101 : out = data[23:20] ;
        3'b110 : out = data[27:24] ;
        3'b111 : out = data[31:28] ;

    endcase
    end
endmodule
module LUT_truth(
    num,
    out
    );
    
    input [3:0]num ;
    output reg [7:0]out ;
    
    always@(num)
    begin
        case(num)
        4'h0 : out = 8'hc0 ;
        4'h1 : out = 8'hf9 ;
        4'h2 : out = 8'ha4 ;
        4'h3 : out = 8'hb0 ;
        4'h4 : out = 8'h99 ;
        4'h5 : out = 8'h92 ;
        4'h6 : out = 8'h82 ;
        4'h7 : out = 8'hf8 ;
        4'h8 : out = 8'h80 ;
        4'h9 : out = 8'h90 ;
        4'ha : out = 8'h88 ;
        4'hb : out = 8'h83 ;
        4'hc : out = 8'hc6 ;
        4'hd : out = 8'ha1 ;
        4'he : out = 8'h86 ;
        4'hf : out = 8'h8e ;
        endcase
    end
endmodule
`timescale 1ns / 1ns
module digital_tube_tb();
    
    reg clk ;
    reg reset ;
    reg [31:0]disp_num_all;
    wire [7:0]dg_tube ;
    wire [7:0]tube_part ;
    
    digital_tube   
    #( 
    .one_dis_t( 100 )
    )
    digital_tube_im(//八个数码管显示
    clk,
    reset,
    disp_num_all,
    dg_tube,
    tube_part
    );
    
    initial clk = 1 ;
    always #10 clk = ! clk ;
    initial
    begin
        reset = 0 ;
        disp_num_all = 32'd0 ;
        #201 ;
        reset = 1 ;
        #200 ;
        disp_num_all = 32'habb02525 ;
        #20000;
        disp_num_all = 32'h52520bba ;
        #30000;        
        $stop;
    end
    


    
endmodule

 

标签:动态显示,视觉暂留,clk,tube,数码管,num,input,data,out
来源: https://www.cnblogs.com/fbur/p/16370587.html