You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Verilog数据锁存与均值计算FSM卡在filter_data_64状态问题

Verilog有限状态机卡在filter_data_64状态问题

我正在开发一款用于锁存输入数据并计算其均值的Verilog有限状态机(FSM),但该FSM始终卡在filter_data_64状态。仿真结果显示它在之前的状态中切换完全正常,却卡在了这个状态。相关代码及Modelsim仿真波形如下:

`timescale 1ps/1ps

module amf_ctrl #(
parameter data_bits    = 64,
parameter average_cont = 16
)
(
    input            clk,
    input            rst,
    input            vld,
    input           last,
    output           rdy,
    input [7:0] data_flit,
    input [5:0] valid_bytes,
    output [7:0] filter_data_o,
    output           done
    );
        
    reg [7:0] data_buff [data_bits-1:0]; 
    reg [data_bits-1:0] byte_cont;
    reg [7:0] avg_cont, byte_cont_64, filter_data; 
    reg [3:0] state;
    reg [3:0] nextstate;
    reg [7:0] r0, r1, r2, r3, sum_reg;
    reg [5:0] valid_no;
    reg done_sig, rdy_sig, vld_dly, vld_pe, byte_64_en;
    assign done = done_sig; 
    assign filter_data_o = filter_data;
    assign rdy = rdy_sig;
    ////////////////////////////////////////
    parameter idle = 4'b0000, buffer_data = 4'b0001, buffer_data_1 = 4'b0010, filter_data_state = 4'b0011;
    parameter Avg_cal = 4'b0100, Sum_data = 4'b0101, Shift_data = 4'b0110, Result_data = 4'b0111;
    parameter filter_data_64 = 4'b1000, Sum_data_64 = 4'b1001, Shift_data_64 = 4'b1010, Result_data_64 = 4'b1011;
    ////////////////////////////
    always @ (posedge clk) begin
        vld_dly <= vld;
    end
    ////////////////////////////
    // Detect no of valid Bytes //
    always @ (posedge clk or negedge rst) begin
         if (~rst) begin
             valid_no <= 5'b00000;
             byte_64_en <= 1'b0;end
             
        else if (last) begin 
                 valid_no <= valid_bytes;
             
          if(valid_bytes == 0)
             byte_64_en <= 1'b1;end
             
         
         else begin     
            byte_64_en <= 1'b0;
         end            
    end
    ////////////////////////////
    always @(posedge clk or negedge rst) 
    
      if ((~rst)||(byte_cont==data_bits-1)) 
          byte_cont <= 0;
     else     
        if (!vld & vld_dly) begin
            byte_cont <= byte_cont + 1;
            data_buff[byte_cont] <= data_flit;
      end   
   ////////////////////////////////////
   always @(posedge clk) begin
       if (~rst) begin
           done_sig  <= 1'b0;
           rdy_sig   <= 1'b0 ;
           sum_reg   <= 8'h00;
           filter_data <= 8'h00;
           avg_cont    <= 8'h00;
           state <= idle;
         end  
        else begin     
              case(state)
                    idle:begin    
                        if(vld)begin
                           rdy_sig <= 1'b1;
                           nextstate <= buffer_data;
                        end 
                        else if (last)begin
                            rdy_sig  <= 1'b0;
                            nextstate <= filter_data_state;end 
           
                        else begin   
                          rdy_sig <= 1'b0;
                          nextstate <= idle;end
                        end 
                    ////////////////////////////////////     
                    buffer_data:begin
                               rdy_sig <= 1'b0;
                               nextstate <= idle; 
                     end        
                    //////////////////////////////////
                    filter_data_state:begin
                      //if(byte_64_en)begin 
                         //rdy_sig <= 1'b0;
                         //avg_cont     <= average_cont;
                         //byte_cont_64 <= data_bits - 1;
                         //nextstate <= filter_data_64;end
                         
                         
                      //else if (byte_64_en)begin
                      //else begin
                         //rdy_sig <= 1'b0;
                         nextstate <= Avg_cal;//end
                         
                      end                     
                      //////////////////////////////////
                      Avg_cal:begin
                      if(valid_no == 0)begin
                         done_sig <= 1'b0;                    
                         nextstate = idle;
                        end 
                      else begin
                         done_sig <= 1'b0;
                         r0 <= data_buff[valid_no];
                         r1 <= data_buff[valid_no - 1]; 
                         r2 <= data_buff[valid_no - 2];
                         r3 <= data_buff[valid_no - 3]; 
                         valid_no <= valid_no - 4;
                         nextstate = Sum_data;end
                      end    
                      /////////////////////////////////
                      Sum_data: begin
                            sum_reg <= r0 + r1 + r2 +r3;
                            nextstate <= Shift_data;
                            end
                     /////////////////////////////////
                     Shift_data: begin
                            sum_reg <= sum_reg >> 2; 
                            nextstate <= Result_data;
                            end
                     /////////////////////////////////      
                     Result_data: begin
                            filter_data <= sum_reg;
                            done_sig <= 1'b1;                           
                            nextstate <= Avg_cal;
                            end                         
                     ////////////////////////////// 
                     filter_data_64:begin
                          if(avg_cont == 0)begin 
                             done_sig <= 1'b0;                    
                             nextstate <= idle;
                            end 
                          else begin
                             done_sig <= 1'b0;
                             r0 <= data_buff[byte_cont_64];
                             r1 <= data_buff[byte_cont_64 - 1]; 
                             r2 <= data_buff[byte_cont_64 - 2];
                             r3 <= data_buff[byte_cont_64 - 3];
                             byte_cont_64 <= byte_cont_64 - 4;                           
                             avg_cont <= avg_cont - 1;
                             nextstate <= Sum_data_64;end
                      end        
                     ////////////////////////////////////
                     Sum_data_64: begin
                                      sum_reg <= r0 + r1 + r2 +r3;
                                      nextstate <= Shift_data_64;
                                   end
                     ///////////////////////////////////
                     Shift_data_64: begin
                                        sum_reg <= sum_reg >> 2; 
                                        nextstate <= Result_data_64;
                                    end
                     /////////////////////////////////      
                     Result_data_64: begin
                            filter_data <= sum_reg;
                            done_sig <= 1'b1;                           
                            nextstate <= filter_data_64;    
                            end                             
                                 
                     
                     
  endcase
 end 
end 
endmodule
////////////////////

/* Verilog test bench : it simulates AXI slave as per document \"AMBA® 4 AXI4-Stream Protocol Version: 1.0 Specification\" */

// Testbench //
`timescale 1ps/1ps
module tb_amf_ctrl();

reg     tb_clk;             // To drive input \"d\" of the DUT
reg     tb_rst;         // To drive input \"en\" of the DUT
reg     tb_vld;         // To drive input \"rstn\" of the DUT
reg     tb_last;    // To ensure q has not changed when en=0
wire    tb_rdy;             // To tap output \"q\" from DUT
wire    tb_done; 
reg     [7:0] tb_data_flit;
reg     [5:0] tb_vld_bytes;
wire    [7:0] tb_filter_data_o;

amf_ctrl DUT (
                      .clk(tb_clk),
                      .rst(tb_rst),
                      .vld(tb_vld),
                      .last(tb_last),
                      .rdy(tb_rdy),
                      .data_flit(tb_data_flit),
                      .valid_bytes(tb_vld_bytes),
                      .filter_data_o(tb_filter_data_o),
                      .done(tb_done)
                      );
// Clock //
initial tb_clk = 0;                   
  always #5 tb_clk = ~tb_clk;           
/////////////////////////
//////////      
initial begin
    tb_rst  <= 1'b0;
    tb_vld  <= 1'b0;
    tb_last <= 1'b0;
    tb_data_flit <= 8'h00;
    tb_vld_bytes <= 6'b000000;
    #30;
    tb_rst <= 1'b1;
    #10;
    //1st byte
    tb_vld  <= 1'b1;
    tb_data_flit <= 8'h11;
    #20;
    tb_vld  <= 1'b0;
    #20;
    //2nd byte
    tb_vld  <= 1'b1;
    tb_data_flit <= 8'h02;
    #20;
    tb_vld  <= 1'b0;
    #20;
    //3rd byte
    tb_vld  <= 1'b1;
    tb_data_flit <= 8'h03;
    #20;
    tb_vld  <= 1'b0;
    #20;
    //4th byte
    tb_vld  <= 1'b1;
    tb_data_flit <= 8'h04;
    #20;
    tb_vld  <= 1'b0;
    #20;
    //// Last ////
    #10;
    tb_last <= 1'b1;
    tb_vld_bytes <= 6'b000100;
    //tb_vld_bytes <= 6'b000000;
    #50;
    $finish(2);
end         

endmodule
//////////////////////////////////////

Modelsim仿真波形

内容的提问来源于stack exchange,提问作者FPGAguru2015

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:34:51