data/full_repos/permissive/17099167/system/hardware/cores/ram_wb/ram_wb_b3.v
data/verilator_xmls/ab36a50a-e3c9-4fbc-b54e-7aed87c55a27.xml
module ram_wb_b3(
		 wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i,
		 wb_stb_i, wb_we_i,

		 wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o,

		 wb_clk_i, wb_rst_i);

   parameter dw = 32;
   parameter aw = 32;

   input [aw-1:0]	wb_adr_i;
   input [1:0] 		wb_bte_i;
   input [2:0] 		wb_cti_i;
   input 		wb_cyc_i;
   input [dw-1:0] 	wb_dat_i;
   input [3:0] 		wb_sel_i;
   input 		wb_stb_i;
   input 		wb_we_i;
   
   output 		wb_ack_o;
   output 		wb_err_o;
   output 		wb_rty_o;
   output [dw-1:0] 	wb_dat_o;
   
   input 		wb_clk_i;
   input 		wb_rst_i;


   parameter mem_size_bytes = 32'h0000_5000;
   parameter mem_adr_width = 15;
   
   parameter bytes_per_dw = (dw/8);
   parameter adr_width_for_num_word_bytes = 2;
   parameter mem_words = (mem_size_bytes/bytes_per_dw);   


   reg [dw-1:0] 	mem [ 0 : mem_words-1 ];


   reg [(mem_adr_width-adr_width_for_num_word_bytes)-1:0] adr;
   
   wire [31:0] 			   wr_data;



   reg 				   wb_b3_trans;
   wire 			   wb_b3_trans_start, wb_b3_trans_stop;
   

   reg [mem_adr_width-adr_width_for_num_word_bytes-1:0]  burst_adr_counter;
   reg [2:0] 			   wb_cti_i_r;
   reg [1:0] 			   wb_bte_i_r;
   wire 			   using_burst_adr;
   wire 			   burst_access_wrong_wb_adr;


   wire 			   addr_err;   
   
   

   assign wb_b3_trans_start = ((wb_cti_i == 3'b001)|(wb_cti_i == 3'b010)) & 
			      wb_stb_i & !wb_b3_trans;
   
   assign  wb_b3_trans_stop = ((wb_cti_i == 3'b111) & 
			      wb_stb_i & wb_b3_trans & wb_ack_o) | wb_err_o;
   
   always @(posedge wb_clk_i)
     if (wb_rst_i)
       wb_b3_trans <= 0;
     else if (wb_b3_trans_start)
       wb_b3_trans <= 1;
     else if (wb_b3_trans_stop)
       wb_b3_trans <= 0;


   always @(wb_ack_o or wb_b3_trans or wb_b3_trans_start
	    or wb_bte_i_r or wb_cti_i_r or wb_adr_i or adr)
     if (wb_b3_trans_start)



       burst_adr_counter = wb_adr_i[mem_adr_width-1:2];
     else if ((wb_cti_i_r == 3'b010) & wb_ack_o & wb_b3_trans)

       begin
	  if (wb_bte_i_r == 2'b00)
	    burst_adr_counter = adr + 1;
	  if (wb_bte_i_r == 2'b01)
	    burst_adr_counter[1:0] = adr[1:0] + 1;
	  if (wb_bte_i_r == 2'b10)
	    burst_adr_counter[2:0] = adr[2:0] + 1;
	  if (wb_bte_i_r == 2'b11)
	    burst_adr_counter[3:0] = adr[3:0] + 1;
       end

   always @(posedge wb_clk_i)
     wb_bte_i_r <= wb_bte_i;


   always @(posedge wb_clk_i)
     wb_cti_i_r <= wb_cti_i;

   assign using_burst_adr = wb_b3_trans;
   
   assign burst_access_wrong_wb_adr = (using_burst_adr & 
				       (adr != wb_adr_i[mem_adr_width-1:2]));


   always@(posedge wb_clk_i)
     if(wb_rst_i)
       adr <= 0;
     else if (using_burst_adr)
       adr <= burst_adr_counter;
     else if (wb_cyc_i & wb_stb_i)
       adr <= wb_adr_i[mem_adr_width-1:2];



   parameter memory_file = "sram.vmem";

`ifdef verilator
   
   task do_readmemh;

      $readmemh(memory_file, mem);
   endtask
   
`else
   
   initial
     begin
	$readmemh(memory_file, mem);
     end
   
`endif

   assign wb_rty_o = 0;


   assign wr_data[31:24] = wb_sel_i[3] ? wb_dat_i[31:24] : wb_dat_o[31:24];
   assign wr_data[23:16] = wb_sel_i[2] ? wb_dat_i[23:16] : wb_dat_o[23:16];
   assign wr_data[15: 8] = wb_sel_i[1] ? wb_dat_i[15: 8] : wb_dat_o[15: 8];
   assign wr_data[ 7: 0] = wb_sel_i[0] ? wb_dat_i[ 7: 0] : wb_dat_o[ 7: 0];
   
   wire ram_we;
   assign ram_we = wb_we_i & wb_ack_o;

   assign wb_dat_o = mem[adr];
    

   always @ (posedge wb_clk_i)
     begin
	if (ram_we)
	  mem[adr] <= wr_data;
     end
   

   reg wb_ack_o_r;

   assign wb_ack_o = wb_ack_o_r & wb_stb_i & 
		     !(burst_access_wrong_wb_adr | addr_err);
   
   always @ (posedge wb_clk_i)
     if (wb_rst_i)
       wb_ack_o_r <= 1'b0;
     else if (wb_cyc_i)
       begin
	  if (addr_err & wb_stb_i)
	    begin
	       wb_ack_o_r <= 1;
	    end
	  else if (wb_cti_i == 3'b000)
	    begin

	       if (wb_stb_i)
		 begin
		    if (!wb_ack_o_r)
		      wb_ack_o_r <= 1;
		    else
		      wb_ack_o_r <= 0;
		 end
	    end
	  else if ((wb_cti_i == 3'b001) | (wb_cti_i == 3'b010))
	    begin

	       if (wb_stb_i)
		 wb_ack_o_r <= 1;
	       else
		 wb_ack_o_r <= 0;
	    end
	  else if (wb_cti_i == 3'b111)
	    begin

	       if (!wb_ack_o_r)
		 wb_ack_o_r <= wb_stb_i;
	       else
		 wb_ack_o_r <= 0;
	    end
       end
     else
       wb_ack_o_r <= 0;





   


   assign addr_err  = wb_cyc_i & wb_stb_i & (|wb_adr_i[aw-1:mem_adr_width]);
 
   

   assign wb_err_o =  wb_ack_o_r & wb_stb_i & 
		      (burst_access_wrong_wb_adr | addr_err);




   

   function [31:0] get_mem32;

      input [aw-1:0] 		addr;
      get_mem32 = mem[addr];
   endfunction


   function [7:0] get_mem8;

      input [aw-1:0] 		addr;
            reg [31:0] 		temp_word;
      begin
	 temp_word = mem[{addr[aw-1:2],2'd0}];

	 get_mem8 = (addr[1:0]==2'b00) ? temp_word[31:24] :
		    (addr[1:0]==2'b01) ? temp_word[23:16] :
		    (addr[1:0]==2'b10) ? temp_word[15:8] : temp_word[7:0];
	 end
   endfunction


   function set_mem32;

      input [aw-1:0] 		addr;
      input [dw-1:0] 		data;
      mem[addr] = data;
   endfunction
   
endmodule
module ram_wb_b3(
		 wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i,
		 wb_stb_i, wb_we_i,

		 wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o,

		 wb_clk_i, wb_rst_i);


   parameter dw = 32;
   parameter aw = 32;

   input [aw-1:0]	wb_adr_i;
   input [1:0] 		wb_bte_i;
   input [2:0] 		wb_cti_i;
   input 		wb_cyc_i;
   input [dw-1:0] 	wb_dat_i;
   input [3:0] 		wb_sel_i;
   input 		wb_stb_i;
   input 		wb_we_i;
   
   output 		wb_ack_o;
   output 		wb_err_o;
   output 		wb_rty_o;
   output [dw-1:0] 	wb_dat_o;
   
   input 		wb_clk_i;
   input 		wb_rst_i;


   parameter mem_size_bytes = 32'h0000_5000;
   parameter mem_adr_width = 15;
   
   parameter bytes_per_dw = (dw/8);
   parameter adr_width_for_num_word_bytes = 2;
   parameter mem_words = (mem_size_bytes/bytes_per_dw);   


   reg [dw-1:0] 	mem [ 0 : mem_words-1 ];


   reg [(mem_adr_width-adr_width_for_num_word_bytes)-1:0] adr;
   
   wire [31:0] 			   wr_data;



   reg 				   wb_b3_trans;
   wire 			   wb_b3_trans_start, wb_b3_trans_stop;
   

   reg [mem_adr_width-adr_width_for_num_word_bytes-1:0]  burst_adr_counter;
   reg [2:0] 			   wb_cti_i_r;
   reg [1:0] 			   wb_bte_i_r;
   wire 			   using_burst_adr;
   wire 			   burst_access_wrong_wb_adr;


   wire 			   addr_err;   
   
   

   assign wb_b3_trans_start = ((wb_cti_i == 3'b001)|(wb_cti_i == 3'b010)) & 
			      wb_stb_i & !wb_b3_trans;
   
   assign  wb_b3_trans_stop = ((wb_cti_i == 3'b111) & 
			      wb_stb_i & wb_b3_trans & wb_ack_o) | wb_err_o;
   
   always @(posedge wb_clk_i)
     if (wb_rst_i)
       wb_b3_trans <= 0;
     else if (wb_b3_trans_start)
       wb_b3_trans <= 1;
     else if (wb_b3_trans_stop)
       wb_b3_trans <= 0;


   always @(wb_ack_o or wb_b3_trans or wb_b3_trans_start
	    or wb_bte_i_r or wb_cti_i_r or wb_adr_i or adr)
     if (wb_b3_trans_start)



       burst_adr_counter = wb_adr_i[mem_adr_width-1:2];
     else if ((wb_cti_i_r == 3'b010) & wb_ack_o & wb_b3_trans)

       begin
	  if (wb_bte_i_r == 2'b00)
	    burst_adr_counter = adr + 1;
	  if (wb_bte_i_r == 2'b01)
	    burst_adr_counter[1:0] = adr[1:0] + 1;
	  if (wb_bte_i_r == 2'b10)
	    burst_adr_counter[2:0] = adr[2:0] + 1;
	  if (wb_bte_i_r == 2'b11)
	    burst_adr_counter[3:0] = adr[3:0] + 1;
       end

   always @(posedge wb_clk_i)
     wb_bte_i_r <= wb_bte_i;


   always @(posedge wb_clk_i)
     wb_cti_i_r <= wb_cti_i;

   assign using_burst_adr = wb_b3_trans;
   
   assign burst_access_wrong_wb_adr = (using_burst_adr & 
				       (adr != wb_adr_i[mem_adr_width-1:2]));


   always@(posedge wb_clk_i)
     if(wb_rst_i)
       adr <= 0;
     else if (using_burst_adr)
       adr <= burst_adr_counter;
     else if (wb_cyc_i & wb_stb_i)
       adr <= wb_adr_i[mem_adr_width-1:2];



   parameter memory_file = "sram.vmem";

`ifdef verilator
   
   task do_readmemh;

      $readmemh(memory_file, mem);
   endtask
   
`else
   
   initial
     begin
	$readmemh(memory_file, mem);
     end
   
`endif

   assign wb_rty_o = 0;


   assign wr_data[31:24] = wb_sel_i[3] ? wb_dat_i[31:24] : wb_dat_o[31:24];
   assign wr_data[23:16] = wb_sel_i[2] ? wb_dat_i[23:16] : wb_dat_o[23:16];
   assign wr_data[15: 8] = wb_sel_i[1] ? wb_dat_i[15: 8] : wb_dat_o[15: 8];
   assign wr_data[ 7: 0] = wb_sel_i[0] ? wb_dat_i[ 7: 0] : wb_dat_o[ 7: 0];
   
   wire ram_we;
   assign ram_we = wb_we_i & wb_ack_o;

   assign wb_dat_o = mem[adr];
    

   always @ (posedge wb_clk_i)
     begin
	if (ram_we)
	  mem[adr] <= wr_data;
     end
   

   reg wb_ack_o_r;

   assign wb_ack_o = wb_ack_o_r & wb_stb_i & 
		     !(burst_access_wrong_wb_adr | addr_err);
   
   always @ (posedge wb_clk_i)
     if (wb_rst_i)
       wb_ack_o_r <= 1'b0;
     else if (wb_cyc_i)
       begin
	  if (addr_err & wb_stb_i)
	    begin
	       wb_ack_o_r <= 1;
	    end
	  else if (wb_cti_i == 3'b000)
	    begin

	       if (wb_stb_i)
		 begin
		    if (!wb_ack_o_r)
		      wb_ack_o_r <= 1;
		    else
		      wb_ack_o_r <= 0;
		 end
	    end
	  else if ((wb_cti_i == 3'b001) | (wb_cti_i == 3'b010))
	    begin

	       if (wb_stb_i)
		 wb_ack_o_r <= 1;
	       else
		 wb_ack_o_r <= 0;
	    end
	  else if (wb_cti_i == 3'b111)
	    begin

	       if (!wb_ack_o_r)
		 wb_ack_o_r <= wb_stb_i;
	       else
		 wb_ack_o_r <= 0;
	    end
       end
     else
       wb_ack_o_r <= 0;





   


   assign addr_err  = wb_cyc_i & wb_stb_i & (|wb_adr_i[aw-1:mem_adr_width]);
 
   

   assign wb_err_o =  wb_ack_o_r & wb_stb_i & 
		      (burst_access_wrong_wb_adr | addr_err);




   

   function [31:0] get_mem32;

      input [aw-1:0] 		addr;
      get_mem32 = mem[addr];
   endfunction


   function [7:0] get_mem8;

      input [aw-1:0] 		addr;
            reg [31:0] 		temp_word;
      begin
	 temp_word = mem[{addr[aw-1:2],2'd0}];

	 get_mem8 = (addr[1:0]==2'b00) ? temp_word[31:24] :
		    (addr[1:0]==2'b01) ? temp_word[23:16] :
		    (addr[1:0]==2'b10) ? temp_word[15:8] : temp_word[7:0];
	 end
   endfunction


   function set_mem32;

      input [aw-1:0] 		addr;
      input [dw-1:0] 		data;
      mem[addr] = data;
   endfunction
   
endmodule