您的位置:首页 > 其它

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

2017-05-20 09:41 706 查看
好的设计思路,扎实的设计基础是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
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)实现数码管秒表















代码实现:
`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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: