data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v
1: b'%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:2: Cannot find include file: syn_tb_defines.vh\n`include "syn_tb_defines.vh" \n         ^~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb,data/full_repos/permissive/509468557/syn_tb_defines.vh\n             data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb,data/full_repos/permissive/509468557/syn_tb_defines.vh.v\n             data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb,data/full_repos/permissive/509468557/syn_tb_defines.vh.sv\n             syn_tb_defines.vh\n             syn_tb_defines.vh.v\n             syn_tb_defines.vh.sv\n             obj_dir/syn_tb_defines.vh\n             obj_dir/syn_tb_defines.vh.v\n             obj_dir/syn_tb_defines.vh.sv\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:26: Define or directive not defined: \'`DLA_ADDR_START\'\nparameter MEM_ADDR_START=`DLA_ADDR_START;  \n                         ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:26: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\nparameter MEM_ADDR_START=`DLA_ADDR_START;  \n                                        ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:29: Define or directive not defined: \'`AXI_ADDR_WIDTH\'\ninput [`AXI_ADDR_WIDTH-1:0]  slave2mem_addr;\n       ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:30: Define or directive not defined: \'`WORD_SIZE\'\ninput [`WORD_SIZE-1:0] slave2mem_data;\n       ^~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:31: Define or directive not defined: \'`WORD_BYTES\'\ninput [`WORD_BYTES-1:0] slave2mem_wr_mask;\n       ^~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:32: Define or directive not defined: \'`AXI_LEN_WIDTH\'\ninput [`AXI_LEN_WIDTH-1:0] slave2mem_len_wr;\n       ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:36: Define or directive not defined: \'`AXI_ADDR_WIDTH\'\noutput [`AXI_ADDR_WIDTH-1-`LOG2_MEM:0] q2mem_curr_wr_addr;\n        ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:36: Define or directive not defined: \'`LOG2_MEM\'\noutput [`AXI_ADDR_WIDTH-1-`LOG2_MEM:0] q2mem_curr_wr_addr;\n                          ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:36: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\noutput [`AXI_ADDR_WIDTH-1-`LOG2_MEM:0] q2mem_curr_wr_addr;\n                                   ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:37: Define or directive not defined: \'`WORD_SIZE\'\noutput [`WORD_SIZE-1:0] q2mem_curr_wr_data;\n        ^~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:38: Define or directive not defined: \'`WORD_BYTES\'\noutput [`WORD_BYTES-1:0] q2mem_curr_wr_mask;\n        ^~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:39: Define or directive not defined: \'`AXI_LEN_WIDTH\'\noutput [`AXI_LEN_WIDTH-1:0] q2mem_curr_wr_len;\n        ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:41: Define or directive not defined: \'`AXI_LEN_WIDTH\'\nreg [`AXI_LEN_WIDTH-1:0] mem2q_wrresp_burst_count;\n     ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:43: Define or directive not defined: \'`MSEQ_CONFIG_SIZE\'\nreg [`MSEQ_CONFIG_SIZE-1:0]            config_mem[`NUM_CONFIGS-1:0];\n     ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:43: Define or directive not defined: \'`NUM_CONFIGS\'\nreg [`MSEQ_CONFIG_SIZE-1:0]            config_mem[`NUM_CONFIGS-1:0];\n                                                  ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:44: Define or directive not defined: \'`WR_Q_MAX\'\nreg [`WR_Q_MAX:0]     s_write_q[`QUEUE_SIZE-1:0];\n     ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:44: syntax error, unexpected \':\', expecting TYPE-IDENTIFIER\nreg [`WR_Q_MAX:0]     s_write_q[`QUEUE_SIZE-1:0];\n              ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:44: Define or directive not defined: \'`QUEUE_SIZE\'\nreg [`WR_Q_MAX:0]     s_write_q[`QUEUE_SIZE-1:0];\n                                ^~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:46: Define or directive not defined: \'`LOG2_Q\'\nreg [`LOG2_Q-1:0] s_write_head;\n     ^~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:47: Define or directive not defined: \'`LOG2_Q\'\nreg [`LOG2_Q-1:0] s_write_tail;\n     ^~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:48: Define or directive not defined: \'`LOG2_Q\'\nreg [`LOG2_Q-1:0] s_write_count;\n     ^~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:50: Define or directive not defined: \'`LOG2_Q\'\nwire [`LOG2_Q-1:0] s_write_latency;  \n      ^~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:53: Define or directive not defined: \'`WR_ADDR_RANGE\'\nassign q2mem_curr_wr_addr = s_write_q[s_write_tail][`WR_ADDR_RANGE] - (MEM_ADDR_START >> `LOG2_MEM);\n                                                    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:53: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign q2mem_curr_wr_addr = s_write_q[s_write_tail][`WR_ADDR_RANGE] - (MEM_ADDR_START >> `LOG2_MEM);\n                                                                  ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:53: Define or directive not defined: \'`LOG2_MEM\'\nassign q2mem_curr_wr_addr = s_write_q[s_write_tail][`WR_ADDR_RANGE] - (MEM_ADDR_START >> `LOG2_MEM);\n                                                                                         ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:54: Define or directive not defined: \'`WR_MASK_RANGE\'\nassign q2mem_curr_wr_mask = s_write_q[s_write_tail][`WR_MASK_RANGE];\n                                                    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:54: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign q2mem_curr_wr_mask = s_write_q[s_write_tail][`WR_MASK_RANGE];\n                                                                  ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:55: Define or directive not defined: \'`WR_DATA_RANGE\'\nassign q2mem_curr_wr_data = s_write_q[s_write_tail][`WR_DATA_RANGE];\n                                                    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:55: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign q2mem_curr_wr_data = s_write_q[s_write_tail][`WR_DATA_RANGE];\n                                                                  ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:56: Define or directive not defined: \'`WR_LEN_RANGE\'\nassign q2mem_curr_wr_len  = s_write_q[s_write_tail][`WR_LEN_RANGE];\n                                                    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:56: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign q2mem_curr_wr_len  = s_write_q[s_write_tail][`WR_LEN_RANGE];\n                                                                 ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:57: Define or directive not defined: \'`S0_WRITE_LATENCY\'\nassign s_write_latency = config_mem[`S0_WRITE_LATENCY] - `WRITE_LATENCY_CORRECTION;\n                                    ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:57: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign s_write_latency = config_mem[`S0_WRITE_LATENCY] - `WRITE_LATENCY_CORRECTION;\n                                                     ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:57: Define or directive not defined: \'`WRITE_LATENCY_CORRECTION\'\nassign s_write_latency = config_mem[`S0_WRITE_LATENCY] - `WRITE_LATENCY_CORRECTION;\n                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:58: Define or directive not defined: \'`WR_VALID\'\nassign q2mem_write_q_tail_valid = s_write_q[s_write_tail][`WR_VALID];\n                                                          ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:58: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\nassign q2mem_write_q_tail_valid = s_write_q[s_write_tail][`WR_VALID];\n                                                                   ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:74: Define or directive not defined: \'`QUEUE_SIZE\'\n      for (i=0; i<`QUEUE_SIZE; i=i+1) begin\n                  ^~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:74: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n      for (i=0; i<`QUEUE_SIZE; i=i+1) begin\n                             ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:74: syntax error, unexpected \')\', expecting \';\'\n      for (i=0; i<`QUEUE_SIZE; i=i+1) begin\n                                    ^\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:75: Define or directive not defined: \'`WR_VALID\'\n          s_write_q[i][`WR_VALID] <= 1\'b0;\n                       ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:77: syntax error, unexpected else\n   end else begin\n       ^~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:78: Define or directive not defined: \'`QUEUE_SIZE\'\n  if (modSub (s_write_head, s_write_tail, `QUEUE_SIZE) > s_write_latency) begin\n                                          ^~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:86: Define or directive not defined: \'`WR_VALID\'\n   if (s_write_q[s_write_head][`WR_VALID]) begin\n                               ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:92: Define or directive not defined: \'`WR_VALID\'\n    s_write_q[s_write_head][`WR_VALID]      <= 1\'b1;\n                            ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:93: Define or directive not defined: \'`WR_MASK_RANGE\'\n    s_write_q[s_write_head][`WR_MASK_RANGE] <= slave2mem_wr_mask;\n                            ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:94: Define or directive not defined: \'`WR_ADDR_RANGE\'\n    s_write_q[s_write_head][`WR_ADDR_RANGE] <= slave2mem_addr[`AXI_ADDR_WIDTH-1:`LOG2_MEM];\n                            ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:94: Define or directive not defined: \'`AXI_ADDR_WIDTH\'\n    s_write_q[s_write_head][`WR_ADDR_RANGE] <= slave2mem_addr[`AXI_ADDR_WIDTH-1:`LOG2_MEM];\n                                                              ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:94: Define or directive not defined: \'`LOG2_MEM\'\n    s_write_q[s_write_head][`WR_ADDR_RANGE] <= slave2mem_addr[`AXI_ADDR_WIDTH-1:`LOG2_MEM];\n                                                                                ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/nvdla/src/main/resources/hw/verif/synth_tb/slave2mem_wr.v:95: Define or directive not defined: \'`WR_DATA_RANGE\'\n    s_write_q[s_write_head][`WR_DATA_RANGE] <= slave2mem_data;\n                            ^~~~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module slave2mem_wr (
   clk,
   reset,
   
   slave2mem_cmd_wr,
   slave2mem_addr,
   slave2mem_data,
   slave2mem_wr_mask,
   slave2mem_len_wr,
   mem2slave_wr_ready,
   mem2slave_wrresp_vld,
   q2mem_write_q_tail_valid,
   q2mem_curr_wr_addr,
   q2mem_curr_wr_data,
   q2mem_curr_wr_mask,
   q2mem_curr_wr_len,
   mem2q_wr_ready
);

input clk;
input reset;
parameter AXI_SLAVE_ID = 0;
parameter MEM_ADDR_START=`DLA_ADDR_START;

input         slave2mem_cmd_wr;
input [`AXI_ADDR_WIDTH-1:0]  slave2mem_addr;
input [`WORD_SIZE-1:0] slave2mem_data;
input [`WORD_BYTES-1:0] slave2mem_wr_mask;
input [`AXI_LEN_WIDTH-1:0] slave2mem_len_wr;
output reg    mem2slave_wr_ready;
output reg    mem2slave_wrresp_vld;
output q2mem_write_q_tail_valid;
output [`AXI_ADDR_WIDTH-1-`LOG2_MEM:0] q2mem_curr_wr_addr;
output [`WORD_SIZE-1:0] q2mem_curr_wr_data;
output [`WORD_BYTES-1:0] q2mem_curr_wr_mask;
output [`AXI_LEN_WIDTH-1:0] q2mem_curr_wr_len;
input mem2q_wr_ready;
reg [`AXI_LEN_WIDTH-1:0] mem2q_wrresp_burst_count;

reg [`MSEQ_CONFIG_SIZE-1:0]            config_mem[`NUM_CONFIGS-1:0];
reg [`WR_Q_MAX:0]     s_write_q[`QUEUE_SIZE-1:0];

reg [`LOG2_Q-1:0] s_write_head;
reg [`LOG2_Q-1:0] s_write_tail;
reg [`LOG2_Q-1:0] s_write_count;
reg s_write_count_inc, s_write_count_dec;
wire [`LOG2_Q-1:0] s_write_latency;
integer i;

assign q2mem_curr_wr_addr = s_write_q[s_write_tail][`WR_ADDR_RANGE] - (MEM_ADDR_START >> `LOG2_MEM);
assign q2mem_curr_wr_mask = s_write_q[s_write_tail][`WR_MASK_RANGE];
assign q2mem_curr_wr_data = s_write_q[s_write_tail][`WR_DATA_RANGE];
assign q2mem_curr_wr_len  = s_write_q[s_write_tail][`WR_LEN_RANGE];
assign s_write_latency = config_mem[`S0_WRITE_LATENCY] - `WRITE_LATENCY_CORRECTION;
assign q2mem_write_q_tail_valid = s_write_q[s_write_tail][`WR_VALID];

initial begin
   $readmemh("slave_mem.cfg", config_mem);
end

always @(posedge clk or negedge reset) begin
   if(!reset) begin
      mem2q_wrresp_burst_count <= 0;
      mem2slave_wr_ready  <= 1;
      mem2slave_wrresp_vld<= 0;
      s_write_head        <= s_write_latency;
      s_write_tail        <= 0;
      s_write_count       <= 0;
      s_write_count_inc   <= 0;
      s_write_count_dec   <= 0;
      for (i=0; i<`QUEUE_SIZE; i=i+1) begin
          s_write_q[i][`WR_VALID] <= 1'b0;
      end
   end else begin
		if (modSub (s_write_head, s_write_tail, `QUEUE_SIZE) > s_write_latency) begin
			mem2slave_wr_ready  <= 0;
		end else begin
			mem2slave_wr_ready  <= 1;
		end

		if( slave2mem_cmd_wr ) begin

			if (s_write_q[s_write_head][`WR_VALID]) begin
				$display("%0t SMEM: ERROR: Slave %0d write head detected unread entry! Commands are probably getting dropped.", $time, AXI_SLAVE_ID);
				$finish;
			end else begin


				s_write_q[s_write_head][`WR_VALID]      <= 1'b1;
				s_write_q[s_write_head][`WR_MASK_RANGE] <= slave2mem_wr_mask;
				s_write_q[s_write_head][`WR_ADDR_RANGE] <= slave2mem_addr[`AXI_ADDR_WIDTH-1:`LOG2_MEM];
				s_write_q[s_write_head][`WR_DATA_RANGE] <= slave2mem_data;
				s_write_q[s_write_head][`WR_LEN_RANGE] <= slave2mem_len_wr;
				$display("%0t SMEM: Received slave %0d write addr 0x%010x mask 0x%016x data 0x%0128x", $time, AXI_SLAVE_ID, slave2mem_addr, slave2mem_wr_mask, slave2mem_data);

				s_write_head <= modAdd (s_write_head, 'd1, `QUEUE_SIZE);
				s_write_head <= s_write_head + 1;

				s_write_count_inc <= 1;
			end
		end else begin
			s_write_count_inc <= 0;

			if (modSub (s_write_head, s_write_tail, `QUEUE_SIZE) <= s_write_latency) begin
				s_write_head <= modAdd (s_write_tail, s_write_latency, `QUEUE_SIZE);
			end
		end
			

      

      if( s_write_q[s_write_tail][`WR_VALID] == 1'b1 ) begin

          if (mem2q_wr_ready) begin

             if(mem2q_wrresp_burst_count < s_write_q[s_write_tail][`WR_LEN_RANGE]) begin
               mem2slave_wrresp_vld <= 0;
               mem2q_wrresp_burst_count <= mem2q_wrresp_burst_count + 1;
             end else begin
               mem2slave_wrresp_vld <= 1;
               mem2q_wrresp_burst_count <= 0;
             end
             s_write_q[s_write_tail][`WR_VALID] <= 1'b0;
             s_write_count_dec <= 1;

             s_write_tail <= modAdd (s_write_tail, 'd1, `QUEUE_SIZE);
          end else begin
             mem2slave_wrresp_vld <= 0;
             s_write_count_dec <= 0;
          end
      end else begin
          mem2slave_wrresp_vld <= 0;
          s_write_count_dec <= 0;
          s_write_tail <= modAdd (s_write_tail, 'd1, `QUEUE_SIZE);
      end


      s_write_count <= s_write_count + s_write_count_inc - s_write_count_dec;
   end
end

always @* begin
   if( (s_write_head == s_write_tail) && reset )
      $display("%0t SMEM: ERROR: Slave %0d write head caught up to write tail! Commands are probably getting dropped.", $time, AXI_SLAVE_ID);
`ifdef EMU_TB

`else
   if( q2mem_curr_wr_addr > (`MEM_SIZE-1) && reset ) begin
      $display("%0t SMEM: ERROR: Slave %0d wrote the last address in memory, which doesn't exist due to VCS limitations.", $time, AXI_SLAVE_ID);
      $finish;
   end
`endif
end



function [`LOG2_Q-1:0] modAdd;
	input [`LOG2_Q:0] x;
	input [`LOG2_Q:0] delta;
	input [`LOG2_Q:0] wrapSize;

begin
	modAdd = (x + delta) % wrapSize;
end

endfunction


function [`LOG2_Q-1:0] modSub;
	input [`LOG2_Q:0] x;
	input [`LOG2_Q:0] delta;
	input [`LOG2_Q:0] wrapSize;

begin
	modSub = (x - delta) % wrapSize;
end

endfunction

endmodule
module slave2mem_wr (
   clk,
   reset,
   
   slave2mem_cmd_wr,
   slave2mem_addr,
   slave2mem_data,
   slave2mem_wr_mask,
   slave2mem_len_wr,
   mem2slave_wr_ready,
   mem2slave_wrresp_vld,
   q2mem_write_q_tail_valid,
   q2mem_curr_wr_addr,
   q2mem_curr_wr_data,
   q2mem_curr_wr_mask,
   q2mem_curr_wr_len,
   mem2q_wr_ready
);


input clk;
input reset;
parameter AXI_SLAVE_ID = 0;
parameter MEM_ADDR_START=`DLA_ADDR_START;

input         slave2mem_cmd_wr;
input [`AXI_ADDR_WIDTH-1:0]  slave2mem_addr;
input [`WORD_SIZE-1:0] slave2mem_data;
input [`WORD_BYTES-1:0] slave2mem_wr_mask;
input [`AXI_LEN_WIDTH-1:0] slave2mem_len_wr;
output reg    mem2slave_wr_ready;
output reg    mem2slave_wrresp_vld;
output q2mem_write_q_tail_valid;
output [`AXI_ADDR_WIDTH-1-`LOG2_MEM:0] q2mem_curr_wr_addr;
output [`WORD_SIZE-1:0] q2mem_curr_wr_data;
output [`WORD_BYTES-1:0] q2mem_curr_wr_mask;
output [`AXI_LEN_WIDTH-1:0] q2mem_curr_wr_len;
input mem2q_wr_ready;
reg [`AXI_LEN_WIDTH-1:0] mem2q_wrresp_burst_count;

reg [`MSEQ_CONFIG_SIZE-1:0]            config_mem[`NUM_CONFIGS-1:0];
reg [`WR_Q_MAX:0]     s_write_q[`QUEUE_SIZE-1:0];

reg [`LOG2_Q-1:0] s_write_head;
reg [`LOG2_Q-1:0] s_write_tail;
reg [`LOG2_Q-1:0] s_write_count;
reg s_write_count_inc, s_write_count_dec;
wire [`LOG2_Q-1:0] s_write_latency;
integer i;

assign q2mem_curr_wr_addr = s_write_q[s_write_tail][`WR_ADDR_RANGE] - (MEM_ADDR_START >> `LOG2_MEM);
assign q2mem_curr_wr_mask = s_write_q[s_write_tail][`WR_MASK_RANGE];
assign q2mem_curr_wr_data = s_write_q[s_write_tail][`WR_DATA_RANGE];
assign q2mem_curr_wr_len  = s_write_q[s_write_tail][`WR_LEN_RANGE];
assign s_write_latency = config_mem[`S0_WRITE_LATENCY] - `WRITE_LATENCY_CORRECTION;
assign q2mem_write_q_tail_valid = s_write_q[s_write_tail][`WR_VALID];

initial begin
   $readmemh("slave_mem.cfg", config_mem);
end

always @(posedge clk or negedge reset) begin
   if(!reset) begin
      mem2q_wrresp_burst_count <= 0;
      mem2slave_wr_ready  <= 1;
      mem2slave_wrresp_vld<= 0;
      s_write_head        <= s_write_latency;
      s_write_tail        <= 0;
      s_write_count       <= 0;
      s_write_count_inc   <= 0;
      s_write_count_dec   <= 0;
      for (i=0; i<`QUEUE_SIZE; i=i+1) begin
          s_write_q[i][`WR_VALID] <= 1'b0;
      end
   end else begin
		if (modSub (s_write_head, s_write_tail, `QUEUE_SIZE) > s_write_latency) begin
			mem2slave_wr_ready  <= 0;
		end else begin
			mem2slave_wr_ready  <= 1;
		end

		if( slave2mem_cmd_wr ) begin

			if (s_write_q[s_write_head][`WR_VALID]) begin
				$display("%0t SMEM: ERROR: Slave %0d write head detected unread entry! Commands are probably getting dropped.", $time, AXI_SLAVE_ID);
				$finish;
			end else begin


				s_write_q[s_write_head][`WR_VALID]      <= 1'b1;
				s_write_q[s_write_head][`WR_MASK_RANGE] <= slave2mem_wr_mask;
				s_write_q[s_write_head][`WR_ADDR_RANGE] <= slave2mem_addr[`AXI_ADDR_WIDTH-1:`LOG2_MEM];
				s_write_q[s_write_head][`WR_DATA_RANGE] <= slave2mem_data;
				s_write_q[s_write_head][`WR_LEN_RANGE] <= slave2mem_len_wr;
				$display("%0t SMEM: Received slave %0d write addr 0x%010x mask 0x%016x data 0x%0128x", $time, AXI_SLAVE_ID, slave2mem_addr, slave2mem_wr_mask, slave2mem_data);

				s_write_head <= modAdd (s_write_head, 'd1, `QUEUE_SIZE);
				s_write_head <= s_write_head + 1;

				s_write_count_inc <= 1;
			end
		end else begin
			s_write_count_inc <= 0;

			if (modSub (s_write_head, s_write_tail, `QUEUE_SIZE) <= s_write_latency) begin
				s_write_head <= modAdd (s_write_tail, s_write_latency, `QUEUE_SIZE);
			end
		end
			

      

      if( s_write_q[s_write_tail][`WR_VALID] == 1'b1 ) begin

          if (mem2q_wr_ready) begin

             if(mem2q_wrresp_burst_count < s_write_q[s_write_tail][`WR_LEN_RANGE]) begin
               mem2slave_wrresp_vld <= 0;
               mem2q_wrresp_burst_count <= mem2q_wrresp_burst_count + 1;
             end else begin
               mem2slave_wrresp_vld <= 1;
               mem2q_wrresp_burst_count <= 0;
             end
             s_write_q[s_write_tail][`WR_VALID] <= 1'b0;
             s_write_count_dec <= 1;

             s_write_tail <= modAdd (s_write_tail, 'd1, `QUEUE_SIZE);
          end else begin
             mem2slave_wrresp_vld <= 0;
             s_write_count_dec <= 0;
          end
      end else begin
          mem2slave_wrresp_vld <= 0;
          s_write_count_dec <= 0;
          s_write_tail <= modAdd (s_write_tail, 'd1, `QUEUE_SIZE);
      end


      s_write_count <= s_write_count + s_write_count_inc - s_write_count_dec;
   end
end

always @* begin
   if( (s_write_head == s_write_tail) && reset )
      $display("%0t SMEM: ERROR: Slave %0d write head caught up to write tail! Commands are probably getting dropped.", $time, AXI_SLAVE_ID);
`ifdef EMU_TB

`else
   if( q2mem_curr_wr_addr > (`MEM_SIZE-1) && reset ) begin
      $display("%0t SMEM: ERROR: Slave %0d wrote the last address in memory, which doesn't exist due to VCS limitations.", $time, AXI_SLAVE_ID);
      $finish;
   end
`endif
end



function [`LOG2_Q-1:0] modAdd;
	input [`LOG2_Q:0] x;
	input [`LOG2_Q:0] delta;
	input [`LOG2_Q:0] wrapSize;

begin
	modAdd = (x + delta) % wrapSize;
end

endfunction


function [`LOG2_Q-1:0] modSub;
	input [`LOG2_Q:0] x;
	input [`LOG2_Q:0] delta;
	input [`LOG2_Q:0] wrapSize;

begin
	modSub = (x - delta) % wrapSize;
end

endfunction

endmodule