Xilinx FPGA:vivado实现数码管计数

译码器模块:

`timescale 1ns / 1ps
module decoder(
   input      [3:0]    num    ,
   output   reg[7:0]   seg   

    );
    always@(*)
    case(num)
        4'd0: seg = 8'h3f;
        4'd1: seg = 8'h06;
        4'd2: seg = 8'h5b;
        4'd3: seg = 8'h4f;
        4'd4: seg = 8'h66;
        4'd5: seg = 8'h6d;
        4'd6: seg = 8'h7d;
        4'd7: seg = 8'h07;
        4'd8: seg = 8'h7f;
        4'd9: seg = 8'h6f;
        default:;
    endcase
endmodule

数码管模块:

`timescale 1ns / 1ps
module number_timer_tude(

input                  sys_clk     ,
input                  rst_n       ,
input    wire[15:0]   number       ,   //0~9999
output    wire[3:0]     DIG         ,
output    wire[7:0]     SEG                  

    );
    parameter       MODE     = 0     ;
    
    //数据处理

    reg            [3:0]        num             ;
    wire            [7:0]        seg             ;
    reg            [3:0]        dig             ;
    wire           [3:0]        num_ge          ;
    wire           [3:0]        num_shi         ;
    wire           [3:0]        num_bai         ;
    wire           [3:0]        num_qian        ;
    
    assign          num_ge   = number%10        ; 
    assign          num_shi  = number/10%10     ; 
    assign          num_bai  = number/100%10    ; 
    assign          num_qian = number/1000%10   ; 
    
    decoder    u1(
              . num  (num)  ,      //利用状态机完成将各十百千分别赋给num
              . seg  (seg) 
              
    );
    
    
    //状态机
    parameter             TIME_1ms= 16'd50_000 ;
    
    reg       [3:0]        cur_state      ;
    reg       [3:0]        next_state     ;
    reg       [20:0]       cnt_1ms         ;
    
    localparam             IDLE = 4'b0000 ;
    localparam             GE   = 4'b0001 ;
    localparam             SHI  = 4'b0010 ;
    localparam             BAI  = 4'b0100 ;
    localparam             QIAN = 4'b1000 ;
    
    always@(posedge sys_clk )
           if(!rst_n)                  
             cur_state <= IDLE;      
           else                        
             cur_state <= next_state;
          
   always@(*)
          case(cur_state)
           IDLE :
                begin
                next_state = GE  ;
                end
           GE   :
                begin
                if( cnt_1ms == TIME_1ms -1 )
                next_state = SHI   ;
                else
                next_state = cur_state ;
                end
           SHI  :
                begin                    
                if( cnt_1ms == TIME_1ms -1 )
                next_state = BAI   ;     
                else                     
                next_state = cur_state ; 
                end
           BAI  :
                begin                        
                if( cnt_1ms == TIME_1ms -1 ) 
                next_state = QIAN   ;         
                else                         
                next_state = cur_state ;     
                end                          
           QIAN :  
                begin                       
                if( cnt_1ms == TIME_1ms -1 )
                next_state = GE   ;       
                else                        
                next_state = cur_state ;    
                end         
           endcase  
           
                 
     always@(posedge sys_clk)  
           if (!rst_n)begin
               dig <= 0 ;
               num <= 0 ;
               cnt_1ms <= 0 ;
               end
               else
               case(cur_state)
               IDLE  :
                      begin
                      dig <= 0 ;
                      num <= 0 ;
                      cnt_1ms <= 0 ;
                      end
               GE    :
                      begin
                      dig <= 4'b1110 ;
                      num <= num_ge  ;
                         if( cnt_1ms == TIME_1ms -1 )
                          cnt_1ms <= 0 ;
                         else
                          cnt_1ms <= cnt_1ms +1 ;
                      end
               SHI   :
                     begin 
                     dig <= 4'b1101  ;                          
                     num <= num_shi  ;               
                        if( cnt_1ms == TIME_1ms -1 )
                         cnt_1ms <= 0 ;             
                        else                        
                         cnt_1ms <= cnt_1ms +1 ;    
                     end                            
               BAI   :
                     begin  
                     dig <= 4'b1011  ;                           
                     num <= num_bai  ;                         
                        if( cnt_1ms == TIME_1ms -1 )
                         cnt_1ms <= 0 ;             
                        else                        
                         cnt_1ms <= cnt_1ms +1 ;    
                     end                            
               QIAN  :
                     begin  
                     dig <= 4'b0111  ;                          
                     num <= num_qian  ;              
                        if( cnt_1ms == TIME_1ms -1 )
                         cnt_1ms <= 0 ;             
                        else                        
                         cnt_1ms <= cnt_1ms +1 ;     
                     end   
               default:;    
               endcase   
               
      assign      DIG = (MODE == 0) ? dig : ~dig   ;
      assign      SEG = (MODE == 0) ? seg : ~seg   ;                  
endmodule

顶层设计:

`timescale 1ns / 1ps
module top(
  input                  sys_clk     ,
  input                  rst_n       ,
  
  output   wire[3:0]     DIG         ,   
  output   wire[7:0]     SEG             
  
    );
    
    parameter       TIME_1s = 50_000_000;
    reg       [26:0]    cnt     ;
    reg       [15:0]  number   ;
number_timer_tude u2(
    . sys_clk     (sys_clk  )    ,
    . rst_n       (rst_n   )    ,
    . number      (number  )    , /数码管显示的数字
    .  DIG        ( DIG    )     ,
    .  SEG        ( SEG    )
    );
/数码管计时器
always@(posedge sys_clk)
    if(!rst_n)begin
        cnt <= 0;
        number <= 0;
    end
    else if(cnt == TIME_1s - 1)begin
        cnt <= 0;
        if(number == 16'd9999) 
            number <= 0;
        else
            number <= number + 1;   
    end
    else begin
        number <= number;
        cnt <= cnt + 1;
    end

endmodule

仿真代码:

`timescale 1ns / 1ps
module testbench();
reg          sys_clk;
reg          rst_n  ;
reg[15:0]   number  ;
wire[3:0]     DIG   ;
wire[7:0]     SEG   ;
number_timer_tude u(

.   sys_clk   (   sys_clk )  ,
.   rst_n     (   rst_n   )  ,
.  number     (  number   )  ,   //0~9999
.    DIG      (    DIG    )   ,
.    SEG      (    SEG    )            

    );
initial
    begin
        sys_clk = 0;
        rst_n = 0;
        #10 rst_n = 1; 
        number = 16'd1234;  
    end
always #1 sys_clk = ~sys_clk;
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值