FPGA的秒表设计案例(verilog实现)

秒表设计案例

  • 案例1:秒表0
  • 案例2:秒表1
  • 案例3:秒表2

案例1:秒表0

实现功能:1位数码管实现0~9计数。

实验现象:

第1秒: 1位数码管显示0,

第2秒: 1位数码管显示1,

第3秒: 1位数码管显示2,

第4秒: 1位数码管显示3,

第5秒: 1位数码管显示4,

第6秒: 1位数码管显示5,

第7秒: 1位数码管显示6,

第8秒: 1位数码管显示7,

第9秒: 1位数码管显示8,

第10秒: 1位数码管显示9,

……

10s一个周期,重复进入下一次循环。

代码实现:

//秒表模块,0~9计数
module stopwatch(
    input clk,
    input rst_n,
    
    output reg [5:0] seg_sel,//位选
    output reg [7:0] seg_ment//段选
);

 // 计数器cnt_1s循环计数,计到cnt_1s_max-1得到1s 
 parameter cnt_1s_max = 26'd5000_0000;
 reg [25:0] cnt_1s;
 
 
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_1s <= 25'd0;
   else if(cnt_1s == cnt_1s_max)
     cnt_1s <= 25'd0;
   else
     cnt_1s <= cnt_1s + 1'b1;
 end
 
 // 计数器cnt_10,计到9为10次 
 parameter cnt_10_max = 4'd10 - 1'b1;
 reg [3:0] cnt_10;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_10 <= 4'd0;
   else if(cnt_10 == cnt_10_max && cnt_1s == cnt_1s_max)
     cnt_10 <= 4'd0;
   else if(cnt_1s == cnt_1s_max)
     cnt_10 <= cnt_10 + 1'b1;
   else  
     cnt_10 <= cnt_10;
 end
 
 //位选信号
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     seg_sel <= 6'b111111;
   else
     seg_sel <= 6'b111110;//位选信号,低电平有效
 end
 
 //段选信号
  always@(posedge clk or negedge rst_n) begin
     if (!rst_n) 
        seg_ment <= 8'b1100_0000;
     else begin
        case(cnt_10)
          4'd0: seg_ment <= 8'b1100_0000;
          4'd1: seg_ment <= 8'b1111_1001;
          4'd2: seg_ment <= 8'b1010_0100;
          4'd3: seg_ment <= 8'b1011_0000;
          4'd4: seg_ment <= 8'b1001_1001;
          4'd5: seg_ment <= 8'b1001_0010;
          4'd6: seg_ment <= 8'b1000_0010;
          4'd7: seg_ment <= 8'b1111_1000;           
          4'd8: seg_ment <= 8'b1000_0000;            
          4'd9: seg_ment <= 8'b1001_0000;           
          default: seg_ment <= 8'b1100_0000;
        endcase
    end
 end
 
endmodule

案例2:秒表1

实现功能:1位数码管实现0~9计数。

实验现象:

第1秒: 1位数码管显示0,

第2~3秒: 1位数码管显示1,

第4~6秒: 1位数码管显示2,

第7~10秒: 1位数码管显示3,

第11~15秒: 1位数码管显示4,

第16~21秒: 1位数码管显示5,

第22~28秒: 1位数码管显示6,

第29~36秒: 1位数码管显示7,

第37~45秒: 1位数码管显示8,

第46~55秒: 1位数码管显示9,

……

55s一个周期,重复进入下一次循环。

代码实现:

//秒表模块,0~9计数
//1s--0,2s--1,……,10s--9
module stopwatch_10s(
    input clk,
    input rst_n,
    
    output reg [5:0] seg_sel,//位选
    output reg [7:0] seg_ment//段选
);

 // 计数器cnt_1s循环计数,计到cnt_1s_max-1得到1s 
 parameter cnt_1s_max = 26'd5000_0000;
 reg [25:0] cnt_1s;
 
 
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_1s <= 25'd0;
   else if(cnt_1s == cnt_1s_max)
     cnt_1s <= 25'd0;
   else
     cnt_1s <= cnt_1s + 1'b1;
 end
 
  // 计数器cnt_s循环计数,计到cnt_s_max-1
 reg [3:0] cnt_s_max;
 reg [3:0] cnt_s;
 
 
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_s <= 4'd0;
   else if(cnt_s == cnt_s_max && cnt_1s == cnt_1s_max)
     cnt_s <= 4'd0;
   else if(cnt_1s == cnt_1s_max)
     cnt_s <= cnt_s + 1'b1;
   else
     cnt_s <= cnt_s;
 end
 
 
 // 计数器cnt_10,计到9为10次 
 parameter cnt_10_max = 4'd10 - 1'b1;
 reg [3:0] cnt_10;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_10 <= 4'd0;
   else if(cnt_10 == cnt_10_max && cnt_s == cnt_s_max && cnt_1s == cnt_1s_max)
     cnt_10 <= 4'd0;
   else if(cnt_s == cnt_s_max && cnt_1s == cnt_1s_max)
     cnt_10 <= cnt_10 + 1'b1;
   else  
     cnt_10 <= cnt_10;
 end
 
 //每次数码管显示数字的时长
 always@(*) begin
    case(cnt_10)
      4'd0: cnt_s_max <= 4'd1;
      4'd1: cnt_s_max <= 4'd2;
      4'd2: cnt_s_max <= 4'd3;
      4'd3: cnt_s_max <= 4'd4;
      4'd4: cnt_s_max <= 4'd5;
      4'd5: cnt_s_max <= 4'd6;
      4'd6: cnt_s_max <= 4'd7;
      4'd7: cnt_s_max <= 4'd8;           
      4'd8: cnt_s_max <= 4'd9;            
      4'd9: cnt_s_max <= 4'd10;           
      default: cnt_s_max <= 4'd1;
    endcase
 end
 
 
 //位选信号
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     seg_sel <= 6'b111111;
   else
     seg_sel <= 6'b111110;//位选信号,低电平有效
 end
 
 //段选信号
  always@(posedge clk or negedge rst_n) begin
     if (!rst_n) 
        seg_ment <= 8'b1100_0000;
     else begin
        case(cnt_10)
          4'd0: seg_ment <= 8'b1100_0000;
          4'd1: seg_ment <= 8'b1111_1001;
          4'd2: seg_ment <= 8'b1010_0100;
          4'd3: seg_ment <= 8'b1011_0000;
          4'd4: seg_ment <= 8'b1001_1001;
          4'd5: seg_ment <= 8'b1001_0010;
          4'd6: seg_ment <= 8'b1000_0010;
          4'd7: seg_ment <= 8'b1111_1000;           
          4'd8: seg_ment <= 8'b1000_0000;            
          4'd9: seg_ment <= 8'b1001_0000;           
          default: seg_ment <= 8'b1100_0000;
        endcase
    end
 end
 
endmodule

案例3:秒表2

实现功能:6位数码管同时显示相同的数字,1s改变一次,数字按照"02468ACE13579bdF"的顺序显示。

实验现象:

第1秒: 6位数码管显示0,

第2秒: 6位数码管显示2,

第3秒: 6位数码管显示4,

第4秒: 6位数码管显示6,

第5秒: 6位数码管显示8,

第6秒: 6位数码管显示A,

第7秒: 6位数码管显示C,

第8秒: 6位数码管显示E,

第9秒: 6位数码管显示1,

第10秒: 6位数码管显示3,

第11秒: 6位数码管显示5,

第12秒: 6位数码管显示7,

第13秒: 6位数码管显示9,

第14秒: 6位数码管显示b,

第15秒: 6位数码管显示d,

第16秒: 6位数码管显示F,
……

16s一个周期,重复进入下一次循环。

代码实现:

//数字显示模块:1s改变一次,按照02468ACE13579bdF顺序显示
module data_display(
    input clk,
    input rst_n,
    
    output reg [5:0] seg_sel,//位选
    output reg [7:0] seg_ment//段选
);

 // 计数器cnt_1s循环计数,计到cnt_1s_max-1得到1s 
 parameter cnt_1s_max = 26'd5000_0000;
 reg [25:0] cnt_1s;
 
 
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_1s <= 25'd0;
   else if(cnt_1s == cnt_1s_max)
     cnt_1s <= 25'd0;
   else
     cnt_1s <= cnt_1s + 1'b1;
 end
 
 // 计数器cnt_16,计到15为16次 
 parameter cnt_16_max = 4'd15;
 reg [3:0] cnt_16;

 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     cnt_16 <= 4'd0;
   else if(cnt_16 == cnt_16_max && cnt_1s == cnt_1s_max)
     cnt_16 <= 4'd0;
   else if(cnt_1s == cnt_1s_max)
     cnt_16 <= cnt_16 + 1'b1;
   else  
     cnt_16 <= cnt_16;
 end
 
 //位选信号
 always @(posedge clk or negedge rst_n) begin
   if (!rst_n)
     seg_sel <= 6'b111111;
   else
     seg_sel <= 6'b000000;//位选信号,低电平有效
 end
 
 //段选信号
  always@(posedge clk or negedge rst_n) begin
     if (!rst_n) 
        seg_ment <= 8'b1100_0000;
     else begin
        case(cnt_16)
          4'd0:  seg_ment <= 8'b1100_0000;//0
          4'd1:  seg_ment <= 8'b1010_0100;//2
          4'd2:  seg_ment <= 8'b1001_1001;//4
          4'd3:  seg_ment <= 8'b1000_0010;//6
          4'd4:  seg_ment <= 8'b1000_0000;//8
          4'd5:  seg_ment <= 8'b1000_1000;//A(10)
          4'd6:  seg_ment <= 8'b1100_0110;//C(12)
          4'd7:  seg_ment <= 8'b1000_0110;//E(14)        
          4'd8:  seg_ment <= 8'b1111_1001;//1             
          4'd9:  seg_ment <= 8'b1011_0000;//3
          4'd10: seg_ment <= 8'b1001_0010;//5 
          4'd11: seg_ment <= 8'b1111_1000;//7 
          4'd12: seg_ment <= 8'b1001_0000;//9 
          4'd13: seg_ment <= 8'b1000_0011;//B(11)
          4'd14: seg_ment <= 8'b1010_0001;//D(13)
          4'd15: seg_ment <= 8'b1000_1110;//F(15)
          default: seg_ment <= 8'b1100_0000;//0
        endcase
    end
 end
 
endmodule

:本案例为静态数码管显示实验,由计时器和数码管显示构成,实现设定的3个功能,在正点原子FPGA开拓者开发板上亲测有效。

你可能感兴趣的:(Verilog,HDL,verilog)