SystemVerilog模块,为什么复位不复位

问题描述 投票:0回答:1

我正在编写一个 SystemVerilog 模块,该模块将数据存储在 2 个存储器中以进行矩阵向量乘法。我正在运行我的教授提供的测试平台,但我一直在努力调试一个内存地址逻辑,它根本不会重置为零!非常感谢任何想法或建议。

波形: waveforms

模块代码:

module input_mems #(
 parameter INW=4,
 parameter M=4,
 parameter N=4,
 localparam LOGN = $clog2(N),
 localparam LOGMN = $clog2(M*N)
 )(
 input clk, reset,

 input [INW-1:0] AXIS_TDATA,
 input AXIS_TVALID,
 input AXIS_TLAST,
 input [LOGN:0] AXIS_TUSER,
 output logic AXIS_TREADY,
 output logic input_loaded,
 input done,
 output logic [LOGN-1:0] D,
 input [LOGN-1:0] vector_read_addr,
 output logic [INW-1:0] vector_val,
 output logic [LOGN-1:0] vector_row,
 input [LOGMN-1:0] matrix_read_addr,
 output logic [INW-1:0] matrix_data
 );
   enum {RESET, INM, INV, INL} state, next_state;
   logic [LOGMN-1:0] matrix_addr;
   logic matrix_wr_en;
   logic [LOGN-1:0] vector_addr;
   logic vector_wr_en;
   logic matrix_loaded;
   logic vector_loaded;
   logic new_matrix;
   assign new_matrix = AXIS_TUSER[0];
   logic INM_skip;
   logic [$clog2(N)-1:0] row;
   assign row = AXIS_TUSER[$clog2(N):1];
   logic [INW+$clog2(N)-1:0] vector_cat_in;
   logic [INW+$clog2(N)-1:0] vector_cat_out;
   logic data_ready_INM;
   logic data_ready_INV;

   //fsm 
   //output logic
   always_comb begin
      if(state == RESET) begin
         AXIS_TREADY = 0;
         input_loaded = 0;
      end
      else if(state == INM) begin
         AXIS_TREADY = 1;
         input_loaded = 0;
      end
      else if(state == INV) begin
         AXIS_TREADY = 1;
         input_loaded = 0;
      end
      else if(state == INL) begin
         input_loaded = 1;
         AXIS_TREADY = 0;
      end
      else begin
         AXIS_TREADY = 0;
         input_loaded = 0;
      end
   end

   //next state logic
   always_comb begin
      if((state == RESET) && (reset == 1)) //stay in reset state
         next_state = RESET;
      else if((state == RESET) && (reset == 0)) //exit reset state
         next_state = INM;
      else if((state == INM) && (matrix_loaded == 1)) //matrix is loaded
         next_state = INV;
      else if((state == INM) && (INM_skip == 1)) //new_matrix says reuse matrix
         next_state = INV;
      else if((state == INM) && (matrix_loaded == 0)) //matrix not loaded yet
         next_state = INM;
      else if((state == INV) && (vector_loaded == 1)) //TLAST asserted
         next_state = INL;
      else if((state == INV) && (vector_loaded == 0)) //vector not loaded yet
         next_state = INV;
      else if((state == INL) && (done == 1)) //go back to beginning
         next_state = INM;
      else if((state == INL) && (done == 0)) //data not loaded yet
         next_state = INL;
   end

   //state register
   always_ff @(posedge clk) begin
      if(reset == 1)
         state <= RESET;
      else
         state <= next_state;
   end


   //memory reset
   always_ff @(posedge clk) begin
      if (reset == 1) begin
         matrix_addr <= 0;
         vector_addr <= 0;
         D <= 0;  //reset D counter
      end 
      else if (state == INL && next_state == INM) begin
         matrix_addr <= 0;
         vector_addr <= 0;
         D <= 0;
     end
   end

   //Matrix memory
memory #(
   .WIDTH(INW),
   .SIZE(M*N)
   )memory_matrix(
   .data_in(AXIS_TDATA),
   .data_out(matrix_data),
   .clk(clk),
   .addr(matrix_addr),
   .wr_en(matrix_wr_en));

   //Vector memory
memory#(
   .WIDTH(INW+$clog2(N)),
   .SIZE(N)
   )memory_vector(
   .data_in(vector_cat_in),
   .data_out(vector_cat_out),
   .clk(clk),
   .addr(vector_addr),
   .wr_en(vector_wr_en));

   //Matrix
   //wr_en signal
   always_comb begin
      if((AXIS_TREADY == 1) && (AXIS_TVALID == 1) && (state == INM))
         matrix_wr_en = 1;
      else
         matrix_wr_en = 0;
   end

   //Matrix address
   always_ff @(posedge clk) begin
      if(matrix_wr_en == 1)
         matrix_addr <= matrix_addr + 1;
      else
         matrix_addr <= matrix_addr;
   end

   //Matrix loaded check
   always_comb begin
      if(reset == 1)
         matrix_loaded = 0;
      else if(matrix_addr == $clog2(M*N)) //we have written to all addresses
         matrix_loaded = 1;
      else
         matrix_loaded = 0;
   end

   //new_matrix check
   always_comb begin
      if((AXIS_TREADY == 1) && (AXIS_TVALID == 1) && (state == INM) && (matrix_addr == 0) && (new_matrix == 0))
         INM_skip = 1;
      else
         INM_skip = 0;
   end

   //Vector
   //wr_en signal
   always_comb begin
      if((AXIS_TREADY == 1) && (AXIS_TVALID == 1) && (state == INV))
         vector_wr_en = 1;
      else
         vector_wr_en = 0;
   end

   //Vector address
   always_ff @(posedge clk) begin
      if(reset == 1)
         vector_addr <= 0;
      else if(vector_wr_en == 1)
         vector_addr <= vector_addr + 1;
      else
         vector_addr <= vector_addr;
   end
 
   //Vector loaded check
   always_comb begin
      if(reset == 1)
         vector_loaded = 0;
      else if(AXIS_TLAST == 1) //TLAST signal
         vector_loaded = 1;
      else
         vector_loaded = 0;
   end

   //Vector Data Concat.
   always_comb begin
      vector_cat_in = {AXIS_TDATA, row};
   end

   //D Counter
   always_ff @(posedge clk) begin
      if(reset == 1)
         D <= 0;
      else if((AXIS_TREADY == 1) && (AXIS_TVALID == 1) && (state == INV) && (AXIS_TDATA != 0))
         D <= D + 1;
      else
         D <= D;
   end

   //Loaded
   //Matrix Read
   always_ff @(posedge clk) begin
      if(input_loaded == 1)
         matrix_addr <= matrix_read_addr;
      else
         matrix_addr <= matrix_addr;
   end

   //Vector Read
   always_ff @(posedge clk) begin
      if(input_loaded == 1) begin
         vector_addr <= vector_read_addr;
         vector_val <= vector_cat_out[INW+$clog2(N)-1:$clog2(N)]; // Select INW upper bits
         vector_row <= vector_cat_out[$clog2(N)-1:0]; // Select $clog2(N) lower bits
      end
      else
         vector_addr <= vector_addr;
   end

endmodule

不要过多关注数据发生的情况,我只是不明白为什么我的重置不会将我的matrix_addr设置为零。

system-verilog
1个回答
0
投票

该帖子在变量matrix_addr上有多个驱动程序

这个过程

   //memory reset
   always_ff @(posedge clk) begin
      if (reset == 1) begin
         matrix_addr <= 0;
         vector_addr <= 0;
         D <= 0;  //reset D counter
      end 
      else if (state == INL && next_state == INM) begin
         matrix_addr <= 0;
         vector_addr <= 0;
         D <= 0;
     end
   end

还有这个过程

   //Matrix address
   always_ff @(posedge clk) begin
      if(matrix_wr_en == 1)
         matrix_addr <= matrix_addr + 1;
      else
         matrix_addr <= matrix_addr;
   end

还有这个过程

   //Loaded
   //Matrix Read
   always_ff @(posedge clk) begin
      if(input_loaded == 1)
         matrix_addr <= matrix_read_addr;
      else
         matrix_addr <= matrix_addr;
   end

全部驱动相同的变量matrix_addr。

只有一个进程可以驱动同一范围内的变量。

我在 EDA Playground 上使用 Cadence 时遇到了几个与此类似的编译错误。

xmelab: *E,MULAXX (./design.sv,124|11): Multiple drivers to always_ff output variable matrix_addr detected.
© www.soinside.com 2019 - 2024. All rights reserved.