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 //////////////////////////////////////

内容的提问来源于stack exchange,提问作者FPGAguru2015
相关产品推荐
相关产品推荐

