zoukankan      html  css  js  c++  java
  • 基于FPGA的简易数字时钟


             基于FPGA的可显示数字时钟,设计思路为自底向上,包含三个子模块:时钟模块,进制转换模块。led显示模块。所用到的FPGA晶振频率为50Mhz,首先利用它得到1hz的时钟然后然后得到时钟模块。把时钟模块输出的时、分、秒输入到进制转换模块后得到十进制的值再输入到led显示模块,该project已经在FPGA开发板上亲測可用。

           下图为模块示意图(实际project中并没有採用原理图的输入方法。这里仅作示意)。

















    以下分模块说明:

            clk1:  时钟模块,设计思路为首先依据50M晶振得到1hz的时钟,然后通过时分秒的关系得到时钟模块(详细见代码)。

                                            输入   clk:系统时钟信号 50Mhz            rst_n:低电平异步复位      

                                            输出  sec:  8bit位宽的秒位                    min:  8bit位宽的分位       hour  8bit位宽的时位

         bin_dec1: 进制转换模块,设计思路全然依照之前的博文《利用verilog将二进制码转换为十进制BCD码  》,代码稍作改动,去掉两个用不到的输出。

                                            输入   clk:系统时钟信号 50Mhz            rst_n:低电平异步复位         bin:  8bit位宽的输入待转换二进制数 

                                            输出  one: 十进制数的个位                  ten: 十进制数的十位           hun: 十进制数的百位,这里用不到所以空置了。

            led:            数码管显示模块,八段数码管在一定频率下切换赋值,每个时钟对一个数码管单独赋值并显示,切换频率大于一定值后。看起来像8位数码管同一时候显示(详细设计见代码)。

                                          输入   clk: 系统时钟信号50Mhz            

                                                      sec0,sec1,min0,min1。hour0。hour1:  4bit位宽的值。分代表时钟秒、分、时的个位和十位。

                                      

                                           输出    sel: 8bit 数码管位选信号               

                                                       data:8bit数码管译码显示的值


    以下给出code:

     clk1:

    module clock1(sec,min,hour,clk,rst_n
        );
    input            clk,rst_n;
    output [7:0]  sec,min;
    output [7:0]  hour;
    reg    [7:0]  sec=0;
    reg    [7:0]  min=0;
    reg    [7:0]  hour=0;
    reg           clk_div;
    reg    [32:0] cnt;

    ////////////////////////////////////////  分频部分  50MHz - 1Hz
    always @ ( posedge clk or negedge rst_n)
    begin
        if(!rst_n)
        begin
        cnt <= 0;
     clk_div <= 0;
        end
       else begin
    if ( cnt < 25000000 - 1 )
       begin
       clk_div <= 0;
       cnt <= cnt + 1;
       end
    else if ( cnt < 50000000 - 1 )
       begin
       clk_div <= 1;
       cnt <= cnt + 1 ;
           end
        else
           cnt <=0 ;
    end
    end
    ///////////////////////////////////////// 时钟部分
    always @ ( posedge clk_div or negedge rst_n )
    begin
       if(!rst_n)
        sec <= 0;
      else begin
    if ( sec == 59 )
     sec <= 0 ;
    else 
     sec <= sec + 1 ;
      end
    end
    always @ ( posedge clk_div or negedge rst_n)
    begin
       if(!rst_n)
        min <= 0;
       else begin
     if ( sec == 59 )
     begin
     if (min ==59 )
     min <= 0;
     else
     min <= min + 1 ;
     end
         end
    end

    always @ ( posedge clk_div or negedge rst_n)
    begin
       if(!rst_n)
        hour <= 0;
      else begin
    if ( sec == 59 && min ==59 )
    begin
    if (hour == 23)
    hour <= 0 ;
    else
    hour <= hour + 1;
    end
    end
    end

    endmodule


     

    bin_dec1
     module bin_dec1(clk,bin,rst_n,one,ten,hun
        );
    input  [7:0] bin;
    input        clk,rst_n;
    output [3:0] one,ten;
    output [1:0] hun;
    reg    [3:0] one,ten;
    reg    [1:0] hun;
    reg    [3:0] count;
    reg    [17:0]shift_reg=18'b000000000000000000;
    ////////////////////// 计数部分 ////////////////////////
    always @ ( posedge clk or negedge rst_n )
    begin
     if( !rst_n ) 
       count<=0;
     else if (count==9)
       count<=0;
     else
       count<=count+1;
    end
    ////////////////////// 二进制转换为十进制 /////////////////
    always @ (posedge clk or negedge rst_n )
    begin
      if (!rst_n)
           shift_reg=0;
      else if (count==0)
           shift_reg={10'b0000000000,bin};
      else if ( count<=8)                //实现8次移位操作
       begin
          if(shift_reg[11:8]>=5)         //推断个位是否>5。假设是则+3  
              begin
                 if(shift_reg[15:12]>=5) //推断十位是否>5。假设是则+3  
                     begin
       shift_reg[15:12]=shift_reg[15:12]+2'b11;   
       shift_reg[11:8]=shift_reg[11:8]+2'b11;
    shift_reg=shift_reg<<1;  //对个位和十位操作结束后,总体左移
     end
                 else
           begin
                       shift_reg[15:12]=shift_reg[15:12];
    shift_reg[11:8]=shift_reg[11:8]+2'b11;
    shift_reg=shift_reg<<1;
     end
              end  
                 
          else
              begin
                 if(shift_reg[15:12]>=5)
                     begin
       shift_reg[15:12]=shift_reg[15:12]+2'b11;
       shift_reg[11:8]=shift_reg[11:8];
    shift_reg=shift_reg<<1;
     end
                 else
           begin
                       shift_reg[15:12]=shift_reg[15:12];
    shift_reg[11:8]=shift_reg[11:8];
    shift_reg=shift_reg<<1;
     end
              end  
          
      end
      end
    /////////////////输出赋值//////////////////////////
    always @ ( posedge clk or negedge rst_n )
    begin
     if ( !rst_n )
      begin
        one<=0;
        ten<=0;
        hun<=0; 
      end
     endmodule


    led:

    module led(clk,sec0,sec1,min0,min1,hour0,hour1,sel,data
        );
    input             clk;
    input      [3:0]  sec0,sec1,min0,min1,hour0,hour1;
    output reg [7:0]  data;
    output reg [7:0]  sel;
           reg [3:0]  data_dis=0;
    reg [20:0] m=0;
     
    always @ ( posedge clk )
    begin
        m<=m+1;
    end  


    always@( posedge clk) 
     begin
     case(m[16:14])
       0: begin
      data_dis<=4'b0000;
    sel<=8'b1111_1110;
      end
    1: begin
      data_dis<=4'b0000;
    sel<=8'b1111_1101;
    end
    2: begin
      data_dis<=hour1;
    sel<=8'b1111_1011;
      end
    3: begin
      data_dis<=hour0;
    sel<=8'b1111_0111;
      end
    4: begin
      data_dis<=min1;
    sel<=8'b1110_1111;
        end
    5: begin
      data_dis<=min0;
    sel<=8'b1101_1111;
    end
    6: begin
      data_dis<=sec1;
    sel<=8'b1011_1111;
      end
    7: begin
      data_dis<=sec0;
    sel<=8'b0111_1111;
    end
    default:begin
      data<=8'bz;
    sel<=8'bz;
    end
    endcase

    end


    always @(data_dis)
    begin
    case(data_dis)//七段译码
    4'h0:data = 8'hc0;//显示0
    4'h1:data = 8'hf9;//显示1
    4'h2:data = 8'ha4;//显示2
    4'h3:data = 8'hb0;//显示3
    4'h4:data = 8'h99;//显示4
    4'h5:data = 8'h92;//显示5
    4'h6:data = 8'h82;//显示6
    4'h7:data = 8'hf8;//显示7
    4'h8:data = 8'h80;//显示8
    4'h9:data = 8'h90;//显示9
    default data = 8'hxx;
    endcase
    end

    endmodule

    顶层例化模块:

    top

    module top(clk,rst_n,sel,data
        );
    input         clk,rst_n;
    output  [7:0] sel,data;
    wire    [7:0] sec,min,hour;
    wire    [3:0] one1,ten1,one2,ten2,one3,ten3;

    clock1     clock(
                     .clk(clk),
     .rst_n(rst_n),
     .sec(sec),
     .min(min),
     .hour(hour)
     );  

    bin_dec1    bin_dec1(
                     .clk(clk),
     .rst_n(rst_n),
     .bin(sec),
     .one(one1),
     .ten(ten1)
     );
     
    bin_dec1    bin_dec2(
                     .clk(clk),
     .rst_n(rst_n),
     .bin(min),
     .one(one2),
     .ten(ten2)
     );
     
    bin_dec1    bin_dec3(
                     .clk(clk),
     .rst_n(rst_n),
     .bin(hour),
     .one(one3),
     .ten(ten3)
     );
     
    led    led(
                     .clk(clk),
     .sec0(one1),
     .sec1(ten1),
     .min0(one2),
     .min1(ten2),
     .hour0(one3),
     .hour1(ten3),
     .sel(sel),
     .data(data)
     );

    endmodule





  • 相关阅读:
    分配一维动态数组or 二维动态数组的方法以及学习 new 方法or vector
    关于i++与++i的学习讨论!
    vector 中需要注意的东西!
    c++中 函数的默认参数 学习
    为什么 c++中函数模板和类模板的 声明与定义需要放到一起?
    c++中赋值运算符重载为什么要用引用做返回值?
    为什么const对象只能调用const成员函数,而不能调用非const成员函数?
    java 文件读写
    java Vector
    getRequestDispatcher
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6869587.html
Copyright © 2011-2022 走看看