fpga项目:用状态机管理计数器,实现可控计数 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki
目的
- 用状态机管理计数器。底层计数器相当于是div_cnt,顶层状态机相当于是lms_cnt。
- 一个always实现
- 更加灵活可扩展
- 可以实现one-time-counter
- 注意代码的特点,case语句没有default。否则就变成循环执行了。
代码1
module tb5;
reg clk, rst_n;
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#1000;
rst_n=1;
end
//1)
reg [15:0] dly_cnt;
reg [2:0] state;
always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
dly_cnt<=0;
state=0;
end
else case(state)
0: if(cnt_end) begin
dly_cnt<=0;
state<=1;
end
else
dly_cnt<=dly_cnt+1;
// 1: if(cnt_end) begin
// dly_cnt<=0;
// state<=2;
// end
// else
// dly_cnt<=dly_cnt+1;
endcase
assign cnt_end=(state==0 && dly_cnt==15-1) || (state==1 && dly_cnt==31-1);
endmodule

代码2
module tb5;
reg clk, rst_n;
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#1000;
rst_n=1;
end
//1)
reg [15:0] dly_cnt;
reg [2:0] state;
always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
dly_cnt<=0;
state=0;
end
else case(state)
0: if(cnt_end) begin
dly_cnt<=0;
state<=1;
end
else
dly_cnt<=dly_cnt+1;
1: if(cnt_end) begin
dly_cnt<=0;
state<=2;
end
else
dly_cnt<=dly_cnt+1;
endcase
assign cnt_end=(state==0 && dly_cnt==15-1) || (state==1 && dly_cnt==31-1);
endmodule

代码3:有start_pulse的情况
module tb6;
reg clk, rst_n;
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#1000;
rst_n=1;
end
reg start_pulse;
initial begin
start_pulse=0;
wait(rst_n==1);
@(posedge clk) #1 start_pulse=1;
@(posedge clk) #1 start_pulse=0;
end
//1)
reg [15:0] dly_cnt;
reg [2:0] state;
always @(posedge clk or negedge rst_n)
if(rst_n==0) begin
dly_cnt<=0;
state=0;
end
else case(state)
0: if(start_pulse) state<=1;
1: if(cnt_end) begin
dly_cnt<=0;
state<=2;
end
else
dly_cnt<=dly_cnt+1;
2: if(cnt_end) begin
dly_cnt<=0;
state<=0;
end
else
dly_cnt<=dly_cnt+1;
endcase
assign cnt_end=(state==1 && dly_cnt==15-1) || (state==2 && dly_cnt==31-1);
endmodule

可见用状态机管理计数器,是一个很方便的做法,并在只用1个always就实现了。