基于FPGA的简易数字时钟

Posted brucemengbm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于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  


[email protected]( 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



















































































































































































































































































































以上是关于基于FPGA的简易数字时钟的主要内容,如果未能解决你的问题,请参考以下文章

基于FPGA的数字时钟verilog开发

FPGA的学习:简易电压表的设计与验证

FPGA的学习:简易电压表的设计与验证

[SystemVerilog] 基于 FPGA 的数字钟设计

[SystemVerilog] 基于 FPGA 的数字钟设计

CIC滤波器基于MATLAB/FPGA的数字CIC滤波器的设计