Skip to content

fpga项目:用状态机管理计数器,实现可控计数

minichao9901 edited this page Mar 12, 2024 · 5 revisions

目的

  • 用状态机管理计数器。底层计数器相当于是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

image

代码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

image

代码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

image

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

Clone this wiki locally