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

来源:互联网 发布:淘宝翰哥只卖正品 编辑:程序博客网 时间:2024/05/20 20:04

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

这一下来看计数器设计。

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

一、计数器使用要点



初始值建议0








二、计数器练习

(1)实现流水灯




参考一下几种代码实现:
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    endendmodule`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    endendmodule`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     endendmodule

(2)实现数码管秒表




代码实现:
`define SIMPLE`ifndef SIMPLEmodule 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    endendmodule`elsemodule 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


阅读全文
1 0
原创粉丝点击