FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)

好的设计思路,扎实的设计基础是Verilog设计电路的重点。

这一下来看计数器设计。

Verilog状态机设计请看:http://blog.csdn.net/fengyuwuzu0519/article/details/72571740

一、计数器使用要点

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第1张图片

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第2张图片

初始值建议0

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第3张图片

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第4张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第5张图片

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第6张图片

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第7张图片

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第8张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第9张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第10张图片



二、计数器练习

(1)实现流水灯

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第11张图片
FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第12张图片
FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第13张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第14张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第15张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第16张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第17张图片FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第18张图片
参考一下几种代码实现:
module counter_1(
    clk    ,
    rst_n  ,
    //其他信号,举例dout
    led 
);

    //参数定义
    parameter      TIME_1S =         12;

    
    //输入信号定义
    input               clk    ;
    input               rst_n  ;
    
    //输出信号定义
    output[TIME_1S-1:0]  led    ;
    
    //输出信号reg定义
    reg   [TIME_1S-1:0]  led    ;
    
    //中间信号定义
    reg   [25:0]         cnt    ;


    //时序逻辑写法


    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            cnt <= 0;
		end
        else if(cnt==49_999_999)begin
            cnt <= 0;
		end
        else begin
            cnt <= cnt + 1;
        end
    end





    always@(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            led <= 12'h1;
				end
            else if(led==12'h1000_0000_0000)begin
                led <= 12'h1;
				end
        
        else begin
            if(cnt==49_999_999)begin
                led <= led<<12'h1;
            end
        end
    end


endmodule

`else

//至简设计法实现的。
//注意我们所有计数器都是同一模式,设计都是有步骤实现的
module counter_1(
    clk    ,
    rst_n  ,
    //其他信号,举例dout
    led
);

    //参数定义
    parameter      TIME_1S =         12;

    
    //输入信号定义
    input               clk    ;
    input               rst_n  ;
    
    //输出信号定义
    output[TIME_1S-1:0]  led    ;
    
    //输出信号reg定义
    reg   [TIME_1S-1:0]  led    ;
    
    //中间信号定义
    reg   [25:0]         cnt    ;
    wire                 add_cnt;
    wire                 end_cnt;


    //时序逻辑写法

    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            cnt <= 0;
        end
        else if(add_cnt) begin
            if(end_cnt)
                cnt <= 0;
            else
                cnt <= cnt + 1;
        end
    end
    assign add_cnt = 1;
    assign end_cnt = add_cnt && cnt==50_000_000-1;




    always@(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            led <= 12'h1;
		end
        else if(end_cnt)begin
            if(led==12'b1000_0000_0000)begin
                led <= 12'h1;
			end
            else begin
                led <= led<<1;
            end
        end
    end


endmodule


`endif


/*********www.mdy-edu.com 明德扬科教 注释开始****************
修改后的设计
**********www.mdy-edu.com 明德扬科教 注释结束****************/
/**********www.mdy-edu.com 明德扬科教 注释结束****************
module counter_1(
    clk    ,
    rst_n  ,
    //其他信号,举例dout
    led
    );

    //参数定义
    parameter      TIME_1S = 50_000_000;

    //输入信号定义
    input               clk    ;
    input               rst_n  ;

    //输出信号定义
    output[11:0]  led   ;

    //输出信号reg定义
    reg   [11:0]  led   ;

    //中间信号定义
    reg                 time_1s;
    reg   [25:0]        cnt    ;



    //时序逻辑写法
    always@(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            led <= 12'h1;
        end
        else if(time_1s==1'b1)begin
            led <= {led[10:0],led[11]};
				end
        else begin
            led <= led;
        end
    end

    //组合逻辑
    always  @(*)begin
        if(cnt==TIME_1S-1)begin
            time_1s = 1'b1;
				end
            else begin
                time_1s =1'b0;
        end
     end

     //时序逻辑
     always  @(posedge clk or negedge rst_n)begin
         if(rst_n==1'b0)begin
             cnt <= 0;
         end
         else if(cnt==TIME_1S-1)
             cnt <= 0;
         else begin
             cnt <= cnt + 1;
         end
     end



endmodule

(2)实现数码管秒表

FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第19张图片
FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第20张图片
FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第21张图片 FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第22张图片 FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第23张图片 FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第24张图片 FPGA学习(第6节)-Verilog计数器(实现流水灯+实现数码管秒表)_第25张图片
代码实现:
`define SIMPLE

`ifndef SIMPLE

module counter_4(
    clk    ,
    rst_n  ,
    segment,
    seg_sel
    );

    //参数定义
	 parameter      TIME_1S = 50_000_000   ;
    parameter      DATA0   = 8'b00000011  ;
    parameter      DATA1   = 8'b11110011  ;
    parameter      DATA2   = 8'b00100101  ;
    parameter      DATA3   = 8'b00001101  ;
    parameter      DATA4   = 8'b10011001  ;
    parameter      DATA5   = 8'b01001001  ;
    parameter      DATA6   = 8'b01000001  ;
    parameter      DATA7   = 8'b00011111  ;
    parameter      DATA8   = 8'b00000001  ;
    parameter      DATA9   = 8'b00001001  ;


    //输入信号定义
    input               clk    ;
    input               rst_n  ;

    //输出信号定义
    output[7:0]  segment ;
    output[7:0]  seg_sel ;

    //输出信号reg定义
    reg      [7:0]  segment ;
    wire     [7:0]  seg_sel ;


    //中间信号定义
   reg    [25:0] cnt     ;
   reg    [3 :0] cnt_t   ;

    
    //时序逻辑写法
    always@(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            segment <= 0;
        end
        else begin
            case(cnt_t)
              0:  segment <= DATA0      ;
              1:  segment <= DATA1      ;
              2:  segment <= DATA2      ;
              3:  segment <= DATA3      ;
              4:  segment <= DATA4      ;
              5:  segment <= DATA5      ;
              6:  segment <= DATA6      ;
              7:  segment <= DATA7      ;
              8:  segment <= DATA8      ;
              9:  segment <= DATA9      ;
              default:segment <= 8'hff  ;
            endcase
        end
    end

     //数码管段选

    assign   seg_sel = 8'hfe;
    



    //计数器设计
    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            cnt <= 0;
        end
        else if(cnt==TIME_1S-1)begin
            cnt <= 0;
        end
        else begin
            cnt <= cnt + 1;            
        end
    end

    always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            cnt_t <= 0;
        end
        else if(cnt==TIME_1S-1)begin
            if(cnt_t==9)
                cnt_t <= 0;
            else
                cnt_t <= cnt_t + 1;
        end
    end
endmodule

`else

module counter_4(
    clk    ,
    rst_n  ,
    segment,
    seg_sel
    );

    //参数定义
	parameter      TIME_1S = 50_000_000   ;
    parameter      DATA0   = 8'b00000011  ;
    parameter      DATA1   = 8'b11110011  ;
    parameter      DATA2   = 8'b00100101  ;
    parameter      DATA3   = 8'b00001101  ;
    parameter      DATA4   = 8'b10011001  ;
    parameter      DATA5   = 8'b01001001  ;
    parameter      DATA6   = 8'b01000001  ;
    parameter      DATA7   = 8'b00011111  ;
    parameter      DATA8   = 8'b00000001  ;
    parameter      DATA9   = 8'b00001001  ;


    //输入信号定义
    input               clk    ;
    input               rst_n  ;

    //输出信号定义
    output[7:0]  segment ;
    output[7:0]  seg_sel ;

    //输出信号reg定义
    reg      [7:0]  segment ;
    wire     [7:0]  seg_sel ;


    //中间信号定义
   reg    [25:0] cnt     ;
   reg    [3 :0] cnt_t   ;
   wire          add_cnt ;
   wire          add_cnt_t;
   wire          end_cnt ;
   wire          end_cnt_t;

   always @(posedge clk or negedge rst_n)begin
       if(!rst_n)begin
           cnt <= 0;
       end
       else if(add_cnt)begin
           if(end_cnt)
               cnt <= 0;
           else
               cnt <= cnt + 1;
       end
   end

   assign add_cnt = 1;       
   assign end_cnt = add_cnt && cnt==TIME_1S-1;

   always  @(posedge clk or negedge rst_n)begin
       if(rst_n==1'b0)begin
           cnt_t <= 0;
       end
       else if(add_cnt_t) begin
           if(end_cnt_t)
               cnt_t <= 0;
           else
               cnt_t <= cnt_t + 1;
       end
   end

   assign add_cnt_t = end_cnt;
   assign end_cnt_t = add_cnt_t && cnt_t==10-1;



    
    //时序逻辑写法
    always@(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            segment <= 0;
        end
        else begin
            case(cnt_t)
              0:  segment <= DATA0      ;
              1:  segment <= DATA1      ;
              2:  segment <= DATA2      ;
              3:  segment <= DATA3      ;
              4:  segment <= DATA4      ;
              5:  segment <= DATA5      ;
              6:  segment <= DATA6      ;
              7:  segment <= DATA7      ;
              8:  segment <= DATA8      ;
              9:  segment <= DATA9      ;
              default:segment <= 8'hff  ;
            endcase
        end
    end

     //数码管段选

    assign   seg_sel = 8'hfe;
    
endmodule

`endif


你可能感兴趣的:(FPGA)