最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

verilog - FSM stuck at one state - Stack Overflow

programmeradmin3浏览0评论

I am developing a fsm to latch on to incoming data and compute its average in verilog, but my fsm seems to be just stuck at one state.

Although the simulation shows it did shifted perfectly in previous states, but it is stuck at "filter_data_64" state f.

    `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 
end module
////////////////////

/* 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 simulation :

Modelsim Simulation wave image : 1

发布评论

评论列表(0)

  1. 暂无评论