Added multiplication instruction, fixed sram_wrapper, added chip_controller logic, first steps to do dv tests
diff --git a/verilog/rtl/elpis/IO_arbiter.v b/verilog/rtl/elpis/IO_arbiter.v
index c6a176f..bdad2f0 100644
--- a/verilog/rtl/elpis/IO_arbiter.v
+++ b/verilog/rtl/elpis/IO_arbiter.v
@@ -132,5 +132,3 @@
 	end
 
 endmodule
-
-
diff --git a/verilog/rtl/elpis/alu.v b/verilog/rtl/elpis/alu.v
index 835b77a..183c19f 100644
--- a/verilog/rtl/elpis/alu.v
+++ b/verilog/rtl/elpis/alu.v
@@ -73,6 +73,11 @@
 				 exception_code = 32'b0;
 				 carry = 0;
 			 end
+			 `ALU_OP_MUL: begin
+				 w ={$signed(x)*$signed(y)};
+				 exception_code = 32'b0;
+				 carry = 0;
+			 end
 			 default: begin
 				 w = 32'b0;
 				 exception_code = 32'b0;
diff --git a/verilog/rtl/elpis/arbiter.v b/verilog/rtl/elpis/arbiter.v
index e2cb850..3a6a748 100644
--- a/verilog/rtl/elpis/arbiter.v
+++ b/verilog/rtl/elpis/arbiter.v
@@ -149,3 +149,4 @@
     end
 
 endmodule
+
diff --git a/verilog/rtl/elpis/betweenStages.v b/verilog/rtl/elpis/betweenStages.v
index 59077d9..c6a0bb5 100644
--- a/verilog/rtl/elpis/betweenStages.v
+++ b/verilog/rtl/elpis/betweenStages.v
@@ -326,18 +326,15 @@
 			sb_is_byte_out <= 0;
 			sb_data_out_out <= 0;
 			is_mov_out <= 0;
-			// if (rm2_in) begin
-			//  	rm2_out <= rm2_in;
-			// 	rm0_out <= rm0_in;
-			// 	rm1_out <= rm1_in;
-			// end else begin
-			//  	rm2_out <= exc_code_in;
-			// 	rm0_out <= rm0_in;
-			// 	rm1_out <= 0;
-			// end
-			rm2_out <= (rm2_in) ? rm2_in : exc_code_in;
-			rm0_out <= (rm2_in) ? rm0_in : rm0_in;
-			rm1_out <= (rm2_in) ? rm1_in : 0;
+			if (rm2_in) begin
+			 	rm2_out <= rm2_in;
+				rm0_out <= rm0_in;
+				rm1_out <= rm1_in;
+			end else begin
+			 	rm2_out <= exc_code_in;
+				rm0_out <= rm0_in;
+				rm1_out <= 0;
+			end
 			psw_out <= psw_in;
 			was_stall_dcache_out <= 0;
 			sb_data_to_cache_out <= 0;
@@ -592,4 +589,6 @@
 		end
 	end
 
-endmodule
\ No newline at end of file
+endmodule
+
+
diff --git a/verilog/rtl/elpis/cache.v b/verilog/rtl/elpis/cache.v
index c144132..c49ffc3 100644
--- a/verilog/rtl/elpis/cache.v
+++ b/verilog/rtl/elpis/cache.v
@@ -23,22 +23,19 @@
 	output reg[31:0] read_data_out, output reg hit_out, output reg[19:0] mem_addr_out, output reg[127:0] mem_data_out, output reg req_mem, output reg mem_we_out,
 	output reg hit_tlb, output reg exc_protected_page_tlb);
 
-	wire is_hit_tlb, is_tlb_we, is_tlb_re, is_exc_protected_page_tlb;
+	wire is_hit_tlb, is_exc_protected_page_tlb;
 	wire[19:0] phys_addr_out;
 
 	always@(*) begin
 		hit_tlb <= is_hit_tlb;
 		exc_protected_page_tlb <= (tlb_we && !privilege_mode) ? 1'b1 : 1'b0;
 	end
-	
-	assign is_tlb_we = tlb_we;
-	assign is_tlb_re = tlb_re;
 
 	assign is_hit_tlb = 1'b1;
 	wire[19:0] i_address_candidate = `ITLB_BASE_ADDRESS_SHIFT_CORE0 + address_in[19:0];
 	wire[19:0] d_address_candidate = `DTLB_BASE_ADDRESS_SHIFT_CORE0 + address_in[19:0];
 	assign phys_addr_out = privilege_mode ? address_in[19:0] : ( (CACHE_TYPE == `CACHE_TYPE_DCACHE) ? d_address_candidate : i_address_candidate);
-	
+
 	reg[0:0] cacheValidBits[0:`NUM_CACHE_LINES-1];
 	reg[0:0] cacheDirtyBits[0:`NUM_CACHE_LINES-1];
 	reg[`CACHE_TAG_SIZE-1:0] cacheTag[0:`NUM_CACHE_LINES-1];
diff --git a/verilog/rtl/elpis/chip_controller.v b/verilog/rtl/elpis/chip_controller.v
new file mode 100644
index 0000000..3ac611c
--- /dev/null
+++ b/verilog/rtl/elpis/chip_controller.v
@@ -0,0 +1,36 @@
+module chip_controller(
+    input[31:0] output_data_from_elpis_to_controller,
+    input output_enabled_from_elpis_to_controller, // not used, do something with it
+    input wb_clk_i,
+    input wb_rst_i,
+    input[127:0] la_data_in,
+    input[127:0] la_oenb,
+    output[127:0] la_data_out,
+    output clk,
+    output rst,
+    output reset_core,
+    output is_loading_memory_into_core,
+    output read_enable_to_Elpis,
+    output output_enabled_from_controller_to_pico,
+    output[31:0] data_to_core_mem,
+    output[31:0] read_value_to_Elpis,
+    output[19:0] addr_to_core_mem,
+    output[31:0] wbs_dat_o
+);
+
+    assign clk = (~la_oenb[96]) ? la_data_in[96]: wb_clk_i;
+    assign rst = (~la_oenb[97]) ? la_data_in[97]: wb_rst_i;
+
+    // Input data wires from PicoRiscV to Elpis
+    assign addr_to_core_mem = la_data_in[19:0];
+    assign data_to_core_mem = la_data_in[63:32];
+    assign read_value_to_Elpis = la_data_in[95:64];
+
+    // Permissions from PicoRiscV to Elpis
+    assign reset_core = la_data_in[97];
+    assign is_loading_memory_into_core = la_data_in[98];
+    assign read_enable_to_Elpis = la_data_in[99];
+    assign output_enabled_from_controller_to_pico = la_data_out[100];
+    assign wbs_dat_o = output_data_from_elpis_to_controller;
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/elpis/controlunit.v b/verilog/rtl/elpis/controlunit.v
index 1b4bad5..6e7c867 100644
--- a/verilog/rtl/elpis/controlunit.v
+++ b/verilog/rtl/elpis/controlunit.v
@@ -93,4 +93,4 @@
 		io_code = io_code_wire;
 	end
 
-endmodule
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/elpis/core.v b/verilog/rtl/elpis/core.v
index e3ca1b1..c3b9cee 100644
--- a/verilog/rtl/elpis/core.v
+++ b/verilog/rtl/elpis/core.v
@@ -20,10 +20,6 @@
 module core
 #(parameter CORE_ID = 0)
 (
-`ifdef USE_POWER_PINS
-	inout vccd1,	// User area 1 1.8V supply
-	inout vssd1,	// User area 1 digital ground
-`endif
 	input clk,
 	input rst,
 	input[31:0] read_interactive_value,
diff --git a/verilog/rtl/elpis/custom_sram.v b/verilog/rtl/elpis/custom_sram.v
index 5ef3ae1..16cc28f 100644
--- a/verilog/rtl/elpis/custom_sram.v
+++ b/verilog/rtl/elpis/custom_sram.v
@@ -34,8 +34,9 @@
     reg[31:0] mem[0:`MEMORY_SIZE-1];
 
     always @(posedge clk) begin
-        if (!we)
+        if (!we) begin
             mem[a] <= d;
+        end
         q <= mem[a];
     end 
 
diff --git a/verilog/rtl/elpis/datapath.v b/verilog/rtl/elpis/datapath.v
index d63e7fd..f6b05df 100644
--- a/verilog/rtl/elpis/datapath.v
+++ b/verilog/rtl/elpis/datapath.v
@@ -273,9 +273,7 @@
 		.addr_b(id_reg_src2_addr),
 		.addr_d(wb_or_hf_addr_to_reg),
 		.a(id_reg_a_content),
-		.b(id_reg_b_content),
-		.dest_read(id_reg_dest_addr),
-		.dest_value(id_reg_dest_value)
+		.b(id_reg_b_content)
 	);
 	
 	specialreg specialreg(
diff --git a/verilog/rtl/elpis/decoder.v b/verilog/rtl/elpis/decoder.v
index 8a1a6ba..be8eb81 100644
--- a/verilog/rtl/elpis/decoder.v
+++ b/verilog/rtl/elpis/decoder.v
@@ -80,6 +80,9 @@
 							`FUNCT7_OP_SUB: begin
 								op_alu = `ALU_OP_SUB;
 							end
+							`FUNCT7_OP_MUL: begin
+               					op_alu = `ALU_OP_MUL;
+							end
 							default: begin
 								is_illegal = 1;
 								wrd_reg = 0;
@@ -282,3 +285,4 @@
 	end
 	
 endmodule
+
diff --git a/verilog/rtl/elpis/definitions.v b/verilog/rtl/elpis/definitions.v
index be14f81..601ff56 100644
--- a/verilog/rtl/elpis/definitions.v
+++ b/verilog/rtl/elpis/definitions.v
@@ -19,7 +19,7 @@
 `define PC_INITIAL 32'h00000000
 
 // PC Exceptions
-`define PC_EXCEPTIONS 32'h00002000
+`define PC_EXCEPTIONS 32'h00000040
 
 // ALU Opcodes
 `define ALU_OP_ADD 			4'b0000
@@ -31,6 +31,8 @@
 `define ALU_OP_SRA 			4'b0110
 `define ALU_OP_SRL 			4'b0111
 `define ALU_OP_SLL 			4'b1000
+`define ALU_OP_MUL 			4'b1001
+
 
 // Decode constants for move instructions
 `define MOV_RM_TO_REGULAR	2'b01
@@ -88,7 +90,7 @@
 
 // Constants for memory
 `define MEMORY_DELAY_CYCLES	5
-`define MEMORY_SIZE		512  		// 2^20 - 2^5 = 2^15.
+`define MEMORY_SIZE		8192  		// 2^20 - 2^5 = 2^15.
 
 // Constants for cache
 `define CACHE_LINE_SIZE		128
@@ -131,8 +133,8 @@
 `define OFFSET_OS_DATA_CORE0 8'h00
 
 // Constants for TLB
-`define ITLB_BASE_ADDRESS_SHIFT_CORE0  	16'h1000	// 1024
-`define DTLB_BASE_ADDRESS_SHIFT_CORE0  	16'h4000	// 4096
+`define ITLB_BASE_ADDRESS_SHIFT_CORE0  	16'h100	// 256 -> 64
+`define DTLB_BASE_ADDRESS_SHIFT_CORE0  	16'h400	// 1024 -> 256
 `define NUM_TLB_LINES           		5'd16
 
 // Constants for History File
@@ -160,4 +162,3 @@
 	(x <= 2048)		? 11 : \
 	(x <= 4096)		? 12 : \
 	(x <= 8192)		? 13 : )
-
diff --git a/verilog/rtl/elpis/forwardingunit.v b/verilog/rtl/elpis/forwardingunit.v
index a3c21b3..6ea2406 100644
--- a/verilog/rtl/elpis/forwardingunit.v
+++ b/verilog/rtl/elpis/forwardingunit.v
@@ -69,5 +69,3 @@
 	end
 
 endmodule
-  
-  
\ No newline at end of file
diff --git a/verilog/rtl/elpis/hazardDetectionUnit.v b/verilog/rtl/elpis/hazardDetectionUnit.v
index 7e24335..5ff199f 100644
--- a/verilog/rtl/elpis/hazardDetectionUnit.v
+++ b/verilog/rtl/elpis/hazardDetectionUnit.v
@@ -17,7 +17,9 @@
     `include "/project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v"
 `endif
 
-module hazardDetectionUnit(input[4:0] ex_reg_dest_addr_in, input ex_mem_read_in, input[4:0] id_reg_a_addr_in, input[4:0] id_reg_b_addr_in, output reg stall_out);
+module hazardDetectionUnit(input[4:0] ex_reg_dest_addr_in, input ex_mem_read_in, input[4:0] id_reg_a_addr_in, input[4:0] id_reg_b_addr_in, 
+	input[4:0] m1_reg_dest_addr_in, input m1_is_mul, input[4:0] m2_reg_dest_addr_in, input m2_is_mul, input[4:0] m3_reg_dest_addr_in, input m3_is_mul,
+	input[4:0] m4_reg_dest_addr_in, input m4_is_mul, input[4:0] m5_reg_dest_addr_in, input m5_is_mul, output reg stall_out);
 
 	always@(*) begin
 		if (ex_mem_read_in & ((ex_reg_dest_addr_in == id_reg_a_addr_in) | (ex_reg_dest_addr_in == id_reg_b_addr_in))) // Load stalls
diff --git a/verilog/rtl/elpis/memory.v b/verilog/rtl/elpis/memory.v
deleted file mode 100644
index db1f125..0000000
--- a/verilog/rtl/elpis/memory.v
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-*
-* This file is part of the Elpis processor project.
-*
-* Copyright © 2020-present. All rights reserved.
-* Authors: Aurora Tomas and Rodrigo Huerta.
-*
-* This file is licensed under both the BSD-3 license for individual/non-commercial
-* use. Full text of both licenses can be found in LICENSE file.
-*/
-
-`default_nettype none
-
-`ifdef TESTS
-	`include "elpis/definitions.v"
-`else
-    `include "/project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v"
-`endif
-
-module memory
-	(
-`ifdef USE_POWER_PINS
-	inout vdda1,        // User area 1 3.3V supply
-	inout vdda2,        // User area 2 3.3V supply
-	inout vssa1,        // User area 1 analog ground
-	inout vssa2,        // User area 2 analog ground
-	inout vccd1,        // User area 1 1.8V supply
-	inout vccd2,        // User area 2 1.8v supply
-	inout vssd1,        // User area 1 digital ground
-	inout vssd2,        // User area 2 digital ground
-`endif
-	input clk,
-	input reset,
-	input we,
-	input[19:0] addr_in,
-	input[127:0] wr_data,
-	input requested,
-	input reset_mem_req,
-	output reg[127:0] rd_data_out,
-	// output[127:0] rd_data_out,
-	output ready,
-	input is_loading_memory_into_core,
-	input[19:0] addr_to_core_mem,
-	input[31:0] data_to_core_mem
-);
-	// wire[19:0] addr_output_mem;
-	// wire[7:0] first_bit_out_current;
-	// reg[7:0] first_bit_out_previous;
-	// wire[31:0] auxiliar_mem_out;
-
-	// // (* ramstyle = "M9K" *) reg[31:0] mem[0:`MEMORY_SIZE-1];
-	// reg[$clog2(`MEMORY_DELAY_CYCLES):0] cycles;
-	
-	// assign ready = cycles == 0;
-
-	// assign addr_output_mem = addr_in + (cycles % 3'd4);
-	// assign first_bit_out_current = 6'd32 * (cycles % 3'd4);
-
-	// integer i;
-	// always@(posedge clk) begin
-	// 	if(reset) begin 
-	// 		cycles <= 0;
-	// 	end else if (reset_mem_req) begin
-	// 		cycles <= 0;
-	// 	end else if ((ready && requested))begin
-	// 		cycles <= `MEMORY_DELAY_CYCLES;
-	// 	end else if(cycles!=0) begin
-	// 		cycles <= cycles-1'b1 ;
-	// 	end
-
-	// 	// if (we && requested && !is_loading_memory_into_core) begin
-	// 	// 	if(cycles == 4)
-	// 	// 		mem[addr_in] <= wr_data[31:0];
-	// 	// 	else if (cycles == 3) begin
-	// 	// 		mem[addr_in+1] <= wr_data[63:32];
-	// 	// 	end else if (cycles == 2) begin
-	// 	// 		mem[addr_in+2] <= wr_data[95:64];
-	// 	// 	end else if (cycles == 1) begin
-	// 	// 		mem[addr_in+3] <= wr_data[127:96];
-	// 	// 	end 
-	// 	// end else if(is_loading_memory_into_core) begin
-	// 	// 	mem[addr_to_core_mem] <= data_to_core_mem;
-	// 	// end
-
-	// 	// auxiliar_mem_out <= mem[addr_output_mem];
-	// 	first_bit_out_previous <= first_bit_out_current;
-	// 	rd_data_out[first_bit_out_previous +:32] <= auxiliar_mem_out;
-	// end
-
-	// wire[31:0] dummy_out;
-
-	// reg[19:0] addr_to_sram;
-
-	// always@(*) begin
-	// 	if (we && requested && !is_loading_memory_into_core) begin
-	// 		if(cycles == 4)
-	// 			addr_to_sram <= addr_in;
-	// 		else if (cycles == 3) begin
-	// 			addr_to_sram <= addr_in+1;
-	// 		end else if (cycles == 2) begin
-	// 			addr_to_sram <= addr_in+2;
-	// 		end else if (cycles == 1) begin
-	// 			addr_to_sram <= addr_in+3;
-	// 		end 
-	// 	end else if(is_loading_memory_into_core) begin
-	// 		addr_to_sram <= addr_to_core_mem;
-	// 	end else begin
-	// 		addr_to_sram <= addr_output_mem;
-	// 	end
-	// end
-
-	// reg[31:0] data_to_sram;
-	// always@(*) begin
-	// 	if (we && requested && !is_loading_memory_into_core) begin
-	// 		if(cycles == 4)
-	// 			data_to_sram <= wr_data[31:0];
-	// 		else if (cycles == 3) begin
-	// 			data_to_sram <= wr_data[63:32];
-	// 		end else if (cycles == 2) begin
-	// 			data_to_sram <= wr_data[95:64];
-	// 		end else if (cycles == 1) begin
-	// 			data_to_sram <= wr_data[127:96];
-	// 		end 
-	// 	end else if(is_loading_memory_into_core) begin
-	// 		data_to_sram <= data_to_core_mem;
-	// 	end else begin
-	// 		data_to_sram <= 32'b0;
-	// 	end
-	// end
-	
-
-	// sram_32_1024_sky130 CPURAM(
-	// 	`ifdef USE_POWER_PINS
-	// 	.vccd1(vccd1),
-	// 	.vssd1(vssd1),
-	// 	`endif
-	// 	.clk0(clk),
-	// 	.csb0(1'b0),
-	// 	.web0(!we),
-	// 	.spare_wen0(1'b0),
-	// 	.addr0(addr_to_sram),
-	// 	.din0(data_to_sram),
-	// 	.dout0(auxiliar_mem_out)
-	// );
-
-	// always @(*) begin
-	// 	auxiliar_mem_out <= we ? 32'b0 : data_to_sram;
-	// end
-
-	// OPENLANE
-	reg[31:0] mem[0:`MEMORY_SIZE-1];
-	reg[$clog2(`MEMORY_DELAY_CYCLES):0] cycles;
-	
-	assign ready = cycles == 0;
-
-	// integer i;
-	always@(posedge clk) begin
-		if(reset) begin 
-			cycles <= 0;
-		end else if (reset_mem_req) begin
-			cycles <= 0;
-		end else if ((ready && requested))begin
-			cycles <= `MEMORY_DELAY_CYCLES;
-		end else if(cycles!=0) begin
-			cycles <= cycles-1'b1 ;
-		end
-
-		if (we && requested && !is_loading_memory_into_core) begin
-			mem[addr_in+3] <= wr_data[127:96];
-			mem[addr_in+2] <= wr_data[95:64];
-			mem[addr_in+1] <= wr_data[63:32];
-			mem[addr_in] <= wr_data[31:0];
-		end else if(is_loading_memory_into_core) begin
-			mem[addr_to_core_mem] <= data_to_core_mem;
-		end
-	end
-
-	assign rd_data_out[127:96] = mem[addr_in+3];
-	assign rd_data_out[95:64] = mem[addr_in+2];
-	assign rd_data_out[63:32] = mem[addr_in+1];
-	assign rd_data_out[31:0] = mem[addr_in];
-	
-endmodule
diff --git a/verilog/rtl/elpis/regfile.v b/verilog/rtl/elpis/regfile.v
index b616590..92e1131 100644
--- a/verilog/rtl/elpis/regfile.v
+++ b/verilog/rtl/elpis/regfile.v
@@ -25,10 +25,8 @@
 	input[4:0] addr_a,		// source register A
 	input[4:0] addr_b,		// source register B
 	input[4:0] addr_d,		// destination register
-	output[31:0] a,		// read port A
-	output[31:0] b,		// read port B	
-	input[4:0] dest_read,
-	output[31:0] dest_value
+	output reg[31:0] a,		// read port A
+	output reg[31:0] b		// read port B	
 );
 
 	reg[31:0] registers[31:0];
@@ -44,9 +42,9 @@
 		end
 	end
 
-	assign a = registers[addr_a];
-	assign b = registers[addr_b];
-	assign dest_value = registers[dest_read];
+	always@(*) begin
+		a <= registers[addr_a];
+		b <= registers[addr_b];
+	end
 
 endmodule
-
diff --git a/verilog/rtl/elpis/sram_32_1024_sky130.v b/verilog/rtl/elpis/sram_32_1024_sky130.v
deleted file mode 100644
index 75a2d54..0000000
--- a/verilog/rtl/elpis/sram_32_1024_sky130.v
+++ /dev/null
@@ -1,77 +0,0 @@
-// OpenRAM SRAM model
-// Words: 1024
-// Word size: 32
-
-module sram_32_1024_sky130(
-`ifdef USE_POWER_PINS
-    vccd1,
-    vssd1,
-`endif
-// Port 0: RW
-    clk0,csb0,web0,spare_wen0,addr0,din0,dout0
-  );
-
-  parameter DATA_WIDTH = 33 ;
-  parameter ADDR_WIDTH = 11 ;
-  parameter RAM_DEPTH = 1 << ADDR_WIDTH;
-  // FIXME: This delay is arbitrary.
-  parameter DELAY = 3 ;
-  parameter VERBOSE = 1 ; //Set to 0 to only display warnings
-  parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary
-
-`ifdef USE_POWER_PINS
-    inout vccd1;
-    inout vssd1;
-`endif
-  input  clk0; // clock
-  input   csb0; // active low chip select
-  input  web0; // active low write control
-  input [ADDR_WIDTH-1:0]  addr0;
-  input           spare_wen0; // spare mask
-  input [DATA_WIDTH-1:0]  din0;
-  output [DATA_WIDTH-1:0] dout0;
-
-  reg  csb0_reg;
-  reg  web0_reg;
-  reg spare_wen0_reg;
-  reg [ADDR_WIDTH-1:0]  addr0_reg;
-  reg [DATA_WIDTH-1:0]  din0_reg;
-  reg [DATA_WIDTH-1:0]  dout0;
-
-  // All inputs are registers
-  always @(posedge clk0)
-  begin
-    csb0_reg = csb0;
-    web0_reg = web0;
-    spare_wen0_reg = spare_wen0;
-    addr0_reg = addr0;
-    din0_reg = din0;
-    #(T_HOLD) dout0 = 32'bx;
-    if ( !csb0_reg && web0_reg && VERBOSE ) 
-      $display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
-    if ( !csb0_reg && !web0_reg && VERBOSE )
-      $display($time," Writing %m addr0=%b din0=%b",addr0_reg,din0_reg);
-  end
-
-reg [DATA_WIDTH-1:0]    mem [0:RAM_DEPTH-1];
-
-  // Memory Write Block Port 0
-  // Write Operation : When web0 = 0, csb0 = 0
-  always @ (negedge clk0)
-  begin : MEM_WRITE0
-    if ( !csb0_reg && !web0_reg ) begin
-        mem[addr0_reg][30:0] = din0_reg[30:0];
-        if (spare_wen0_reg)
-                mem[addr0_reg][32] = din0_reg[32];
-    end
-  end
-
-  // Memory Read Block Port 0
-  // Read Operation : When web0 = 1, csb0 = 0
-  always @ (negedge clk0)
-  begin : MEM_READ0
-    if (!csb0_reg && web0_reg)
-       dout0 <= #(DELAY) mem[addr0_reg];
-  end
-
-endmodule
diff --git a/verilog/rtl/elpis/sram_wrapper.v b/verilog/rtl/elpis/sram_wrapper.v
index e0c31a0..94957b3 100644
--- a/verilog/rtl/elpis/sram_wrapper.v
+++ b/verilog/rtl/elpis/sram_wrapper.v
@@ -9,7 +9,11 @@
 * use. Full text of both licenses can be found in LICENSE file.
 */
 
-`include "definitions.v"
+`ifdef TESTS
+	`include "elpis/definitions.v"
+`else
+    `include "/project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v"
+`endif
 
 module sram_wrapper
 	(
@@ -41,7 +45,6 @@
 	reg[19:0] addr_to_sram;
 	reg[31:0] data_to_sram;
 
-	wire[19:0] addr_output_mem;
 	wire[7:0] first_bit_out_current;
 	reg[7:0] first_bit_out_previous;
 	reg[31:0] auxiliar_mem_out;
@@ -55,8 +58,6 @@
 	reg[$clog2(`MEMORY_DELAY_CYCLES):0] cycles;
 	
 	assign ready = cycles == 0;
-
-	assign addr_output_mem = addr_in + (cycles % 3'd4);
 	assign first_bit_out_current = 6'd32 * (cycles % 3'd4);
 
 	always@(posedge clk) begin
@@ -88,6 +89,9 @@
 			end else if (cycles == 1) begin
 				data_to_sram <= wr_data[127:96];
 				we_to_sram <= 1'b0;
+			end else begin
+				data_to_sram <= 32'b0;
+				we_to_sram <= 1'b1;
 			end 
 		end else if(is_loading_memory_into_core) begin
 			data_to_sram <= data_to_core_mem;
@@ -97,8 +101,20 @@
 			we_to_sram <= 1'b1;
 		end
 
-		if(!is_loading_memory_into_core) begin
+		if(!is_loading_memory_into_core && !we) begin
 			addr_to_sram <= addr_in + (cycles % 3'd4);
+		end else if(we && requested && !is_loading_memory_into_core) begin
+			if(cycles == 4) begin
+				addr_to_sram <= addr_in;
+			end else if (cycles == 3) begin
+				addr_to_sram <= addr_in + 1'b1;
+			end else if (cycles == 2) begin
+				addr_to_sram <= addr_in + 2'd2;
+			end else if (cycles == 1) begin
+				addr_to_sram <= addr_in + 2'd3;
+			end else begin
+				addr_to_sram <= addr_in;
+			end
 		end else begin
 			addr_to_sram <= addr_to_core_mem;
 		end
diff --git a/verilog/rtl/elpis/storebuffer.v b/verilog/rtl/elpis/storebuffer.v
index bc173fc..66fee0e 100644
--- a/verilog/rtl/elpis/storebuffer.v
+++ b/verilog/rtl/elpis/storebuffer.v
@@ -61,15 +61,13 @@
     integer i;
 	always@(*) begin
 		sb_hit = 1'b0;
+		hit_pos = 2'b0;
 		for (i = 0; (i < `SB_NUM_ENTRIES); i=i+1) begin
 			if (sb_valid[i] && (sb_addr[i] <= ld_first_byte) && ( (sb_addr[i] + (sb_size[i] ? 0 : 3'b11) ) >= ld_last_byte) ) begin
 				sb_hit = 1'b1;
 				hit_pos = i[1:0];
 			end
 		end
-		if (!sb_hit) begin
-			hit_pos = 2'b0;
-		end
 	end
 
 	always@(posedge clk) begin
diff --git a/verilog/rtl/elpis/tlb.v b/verilog/rtl/elpis/tlb.v
deleted file mode 100644
index af5e6d5..0000000
--- a/verilog/rtl/elpis/tlb.v
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-*
-* This file is part of the Elpis processor project.
-*
-* Copyright © 2020-present. All rights reserved.
-* Authors: Aurora Tomas and Rodrigo Huerta.
-*
-* This file is licensed under both the BSD-3 license for individual/non-commercial
-* use. Full text of both licenses can be found in LICENSE file.
-*/
-
-`default_nettype none
-
-`ifdef TESTS
-	`include "elpis/definitions.v"
-`else
-    `include "/project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v"
-`endif
-
-module tlb #(parameter CORE_ID=0, parameter CACHE_TYPE=`CACHE_TYPE_ICACHE)(
-    input clk,
-    input reset,
-    input[31:0] virtual_addr,
-    input[31:0] virtual_addr_write_in,
-    input privilege_mode,  // 0 - users, 1 - system
-    input tlb_we,
-    input tlb_re,
-    input[19:0] physical_addr_write_in,
-    input[19:0] physical_addr_in,
-    output [19:0] physical_addr_out,
-    output hit_tlb,
-    output exc_protected_page
-);
-
-    reg[19:0] tlb_pages[0:`NUM_TLB_LINES-1];
-    reg[7:0] tlb_frames[0:`NUM_TLB_LINES-1];
-    reg tlbValidBits[0:`NUM_TLB_LINES-1];
-    reg tlb_lru[0:`NUM_TLB_LINES-1];
-    
-    wire[19:0] page;
-    wire[19:0] candidate_physical_addr_out;
-    
-    assign exc_protected_page = (tlb_we && !privilege_mode) ? 1'b1 : 1'b0;
-    assign page = tlb_we ? virtual_addr_write_in[31:12] : virtual_addr[31:12];
-
-    wire[$clog2(`NUM_TLB_LINES)-1:0] id_candidate_write;
-    reg[$clog2(`NUM_TLB_LINES)-1:0] id_candidate_read, id_candidate_write_empty, id_candidate_write_no_empty, id_last_accessed;
-    reg found_read, found_write_empty;
-
-    integer i;
-    always@(*) begin : get_id_read
-        id_candidate_read = 4'b0;
-        found_read = 1'b0;
-        for (i=0; i < `NUM_TLB_LINES; i=i+1) begin
-            if ((page == tlb_pages[i]) && tlbValidBits[i]) begin
-                id_candidate_read = i[3:0];
-                found_read = 1'b1;
-            end
-        end
-    end
-
-    integer j;
-    always@(*) begin : get_id_write_empty
-        id_candidate_write_empty = 0;
-        found_write_empty = 0;
-        for (j=0; j < `NUM_TLB_LINES; j=j+1) begin
-            if ((tlbValidBits[j] == 0) && !found_write_empty) begin
-                found_write_empty = 1'b1;
-                id_candidate_write_empty = j[3:0];
-            end
-        end
-    end
-
-    integer k, n_1_lru;
-    always@(*) begin : get_id_candidate_write_no_empty
-        id_candidate_write_no_empty = 0;
-        for (k=0; k < `NUM_TLB_LINES; k=k+1) begin
-            if (tlb_lru[k] == 1'b0) begin
-                id_candidate_write_no_empty = k[$clog2(`NUM_TLB_LINES)-1:0];
-            end
-        end
-    end
-
-    integer u;
-    always@(posedge clk) begin : count_n_1_lru
-        if (reset) begin
-            n_1_lru = 0;
-        end else begin
-            n_1_lru = n_1_lru + (tlb_we && privilege_mode);
-        end
-    end
-
-    integer c;
-    always@(posedge clk) begin : plru_management
-        if (reset) begin
-            for (c=0; c < `NUM_TLB_LINES; c=c+1) begin
-                tlb_lru[c] <= 1'b0;
-            end 
-        end else begin
-            if(n_1_lru == `NUM_TLB_LINES) begin
-                for (c=0; c < `NUM_TLB_LINES; c=c+1) begin
-                    tlb_lru[c] <= id_last_accessed == c;
-                end
-            end
-            tlb_lru[id_last_accessed] <= 1'b1;
-        end
-    end
-
-    assign hit_tlb = found_read || privilege_mode; 
-    assign candidate_physical_addr_out = (tlb_re && !privilege_mode && found_read) ? {tlb_frames[id_candidate_read], virtual_addr[11:0]} : (privilege_mode ? virtual_addr[19:0] : 20'b0);
-    assign physical_addr_out = candidate_physical_addr_out;
-    assign id_candidate_write = found_write_empty ? id_candidate_write_empty : id_candidate_write_no_empty;
-
-    integer l;
-    always@(posedge clk) begin : write_tlb_structures
-        if (reset) begin
-            for (l=0; l < `NUM_TLB_LINES; l=l+1) begin
-                tlbValidBits[l] <= 0;
-            end
-        end else begin
-            if (tlb_we && privilege_mode) begin // TLBwrite
-                tlb_pages[id_candidate_write] <= page;
-                tlb_frames[id_candidate_write] <= physical_addr_write_in[19:12];
-                tlbValidBits[id_candidate_write] <= 1'b1;
-                id_last_accessed <= id_candidate_write;
-            end else if (tlb_re && !privilege_mode && found_read) begin // TLBRead
-                id_last_accessed <= id_candidate_read;
-            end
-        end
-    end
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/elpis/top.v b/verilog/rtl/elpis/top.v
index 3444a8a..f96327e 100644
--- a/verilog/rtl/elpis/top.v
+++ b/verilog/rtl/elpis/top.v
@@ -42,27 +42,42 @@
 	wire[127:0] read_data_from_mem, core0_to_mem_data;
 	wire is_mem_req;
 
-	// memory module
-	memory #(.MEMORY_FILE(MEMORY_FILE)) memory(
+	wire we_to_sram, csb0_to_sram, spare_wen0_to_sram;
+	wire[19:0] addr0_to_sram;
+	wire[31:0] din0_to_sram, dout0_to_sram;
+
+	custom_sram custom_sram(
+		.clk(clk),
+		.q(dout0_to_sram),
+		.a(addr0_to_sram),
+		.d(din0_to_sram),
+		.we(we_to_sram),
+		.csb0_to_sram(csb0_to_sram),
+		.spare_wen0_to_sram(spare_wen0_to_sram)
+	);
+
+	sram_wrapper sram_wrapper(
 		.clk(clk),
 		.reset(reset_chip),
 		.we(core0_is_mem_we),
 		.addr_in(core0_to_mem_address),
-		.wr_data(core0_to_mem_data), 
+		.wr_data(core0_to_mem_data),
 		.requested(is_mem_req),
 		.reset_mem_req(core0_need_reset_mem_req),
+    	.is_loading_memory_into_core(is_loading_memory_into_core),
+		.addr_to_core_mem(addr_to_core_mem),
+		.data_to_core_mem(data_to_core_mem),
 		.rd_data_out(read_data_from_mem),
 		.ready(is_mem_ready),
-		.is_loading_memory_into_core(is_loading_memory_into_core),
-		.addr_to_core_mem(addr_to_core_mem),
-		.data_to_core_mem(data_to_core_mem)
+	 	.we_to_sram(we_to_sram),
+    	.csb0_to_sram(csb0_to_sram),
+    	.spare_wen0_to_sram(spare_wen0_to_sram),
+    	.addr0_to_sram(addr0_to_sram),
+    	.din0_to_sram(din0_to_sram), 
+    	.dout0_to_sram(dout0_to_sram)
 	);
 
 	core #(.CORE_ID(0)) core0(
-		`ifdef USE_POWER_PINS
-			.vccd1 (vccd1),	    // User area 1 1.8V supply
-			.vssd1 (vssd1),	    // User area 1 digital ground
-		`endif
 		.clk(clk),
 		.rst(reset_core),
 		.read_interactive_value(data_out_to_core),
diff --git a/verilog/rtl/elpis/utils.v b/verilog/rtl/elpis/utils.v
index 7af7180..3d2e089 100644
--- a/verilog/rtl/elpis/utils.v
+++ b/verilog/rtl/elpis/utils.v
@@ -42,4 +42,3 @@
 	end
 
 endmodule
-
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
index 9d4c61e..1b9a0b8 100644
--- a/verilog/rtl/uprj_netlists.v
+++ b/verilog/rtl/uprj_netlists.v
@@ -21,7 +21,6 @@
     // Assume default net type to be wire because GL netlists don't have the wire definitions
     `default_nettype wire
     `include "gl/user_project_wrapper.v"
-    `include "gl/user_proj_example.v"
 `else
     `include "user_project_wrapper.v"
     `include "elpis/alu.v"
@@ -29,21 +28,19 @@
     `include "elpis/betweenStages.v"
     `include "elpis/branchComparer.v"
     `include "elpis/cache.v"
+    `include "elpis/chip_controller.v"
     `include "elpis/controlunit.v"
     `include "elpis/core.v"
+    `include "elpis/custom_sram.v"
     `include "elpis/datapath.v"
     `include "elpis/decoder.v"
     `include "elpis/definitions.v"
     `include "elpis/forwardingunit.v"
     `include "elpis/hazardDetectionUnit.v"
     `include "elpis/IO_arbiter.v"
-    `include "elpis/memory.v"
-    `include "elpis/sram_32_1024_sky130.v"
     `include "elpis/regfile.v"
     `include "elpis/specialreg.v"
+    `include "elpis/sram_wrapper.v"
     `include "elpis/storebuffer.v"
-    `include "elpis/tlb.v"
-    `include "elpis/top.v"
     `include "elpis/utils.v"
-    `include "user_proj_example.v"
 `endif
\ No newline at end of file
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 5ee1cee..82c6265 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -78,45 +78,160 @@
     output [2:0] user_irq
 );
 
-/*--------------------------------------*/
-/* User project is instantiated  here   */
-/*--------------------------------------*/
+    /*--------------------------------------*/
+    /* User project is instantiated  here   */
+    /*--------------------------------------*/
 
-user_proj_example mprj (
-`ifdef USE_POWER_PINS
-	.vccd1(vccd1),	// User area 1 1.8V power
-	.vssd1(vssd1),	// User area 1 digital ground
-`endif
+    wire print_hex_enable, req_out_core0, read_interactive_req_core0, is_ready_dataout_core0, is_ready_print_core0;
+	wire[31:0] core0_data_print;	
+	wire[31:0] print_output;
+	wire[31:0] data_out_to_core;
 
-    .wb_clk_i(wb_clk_i),
-    .wb_rst_i(wb_rst_i),
+	wire core0_need_reset_mem_req, need_reset_mem_req, is_mem_ready, core0_is_mem_we;
+	wire[19:0] core0_to_mem_address;
+	wire[127:0] read_data_from_mem, core0_to_mem_data;
+	wire is_mem_req;
 
-    // MGMT SoC Wishbone Slave
+	wire we_to_sram, csb0_to_sram, spare_wen0_to_sram;
+	wire[19:0] addr0_to_sram;
+	wire[31:0] din0_to_sram, dout0_to_sram;
 
-    .wbs_cyc_i(wbs_cyc_i),
-    .wbs_stb_i(wbs_stb_i),
-    .wbs_we_i(wbs_we_i),
-    .wbs_sel_i(wbs_sel_i),
-    .wbs_adr_i(wbs_adr_i),
-    .wbs_dat_i(wbs_dat_i),
-    .wbs_ack_o(wbs_ack_o),
-    .wbs_dat_o(wbs_dat_o),
+    wire clk, rst, reset_core,is_loading_memory_into_core;
+    wire[31:0] data_to_core_mem;
+    wire[19:0] addr_to_core_mem;
 
-    // Logic Analyzer
+    //SUSPICIOUS
+    wire read_enable_to_Elpis, output_enabled_from_controller_to_pico, output_enabled_from_elpis_to_controller;
+    wire[31:0] output_data_from_elpis_to_controller, read_value_to_Elpis;
 
-    .la_data_in(la_data_in),
-    .la_data_out(la_data_out),
-    .la_oenb (la_oenb),
 
-    // IO Pads
+    chip_controller chip_controller(
+        .output_data_from_elpis_to_controller(output_data_from_elpis_to_controller), //
+        .output_enabled_from_elpis_to_controller(output_enabled_from_elpis_to_controller), //
+        .wb_clk_i(wb_clk_i),
+        .wb_rst_i(wb_rst_i),
+        .la_data_in(la_data_in),
+        .la_oenb(la_oenb),
+        .la_data_out(la_data_out),
+        .clk(clk),
+        .rst(rst),
+        .reset_core(reset_core),
+        .is_loading_memory_into_core(is_loading_memory_into_core),
+        .read_enable_to_Elpis(read_enable_to_Elpis), //
+        .output_enabled_from_controller_to_pico(output_enabled_from_controller_to_pico), //
+        .data_to_core_mem(data_to_core_mem),
+        .read_value_to_Elpis(read_value_to_Elpis), //
+        .addr_to_core_mem(addr_to_core_mem),
+        .wbs_dat_o(wbs_dat_o)
+    );
 
-    .io_in (io_in),
-    .io_out(io_out),
-    .io_oeb(io_oeb),
+	custom_sram custom_sram(
+		.clk(clk),
+		.q(dout0_to_sram),
+		.a(addr0_to_sram),
+		.d(din0_to_sram),
+		.we(we_to_sram),
+		.csb0_to_sram(csb0_to_sram),
+		.spare_wen0_to_sram(spare_wen0_to_sram)
+	);
 
-    // IRQ
-    .irq(user_irq)
-);
+	sram_wrapper sram_wrapper(
+		.clk(clk),
+		.reset(rst),
+		.we(core0_is_mem_we),
+		.addr_in(core0_to_mem_address),
+		.wr_data(core0_to_mem_data),
+		.requested(is_mem_req),
+		.reset_mem_req(core0_need_reset_mem_req),
+    	.is_loading_memory_into_core(is_loading_memory_into_core),
+		.addr_to_core_mem(addr_to_core_mem),
+		.data_to_core_mem(data_to_core_mem),
+		.rd_data_out(read_data_from_mem),
+		.ready(is_mem_ready),
+	 	.we_to_sram(we_to_sram),
+    	.csb0_to_sram(csb0_to_sram),
+    	.spare_wen0_to_sram(spare_wen0_to_sram),
+    	.addr0_to_sram(addr0_to_sram),
+    	.din0_to_sram(din0_to_sram), 
+    	.dout0_to_sram(dout0_to_sram)
+	);
+
+	core #(.CORE_ID(0)) core0(
+		.clk(clk),
+		.rst(reset_core),
+		.read_interactive_value(data_out_to_core),
+		.read_interactive_ready(is_ready_dataout_core0),
+		.hex_out(core0_data_print),
+		.read_interactive_req(read_interactive_req_core0),
+		.hex_req(req_out_core0),
+		.is_print_done(is_ready_print_core0),
+		.is_memory_we(core0_is_mem_we),
+		.mem_addr_out(core0_to_mem_address),
+		.mem_data_out(core0_to_mem_data),
+		.is_mem_req_reset(core0_need_reset_mem_req),
+		.data_from_mem(read_data_from_mem),
+		.is_mem_ready(is_mem_ready),
+		.is_mem_req(is_mem_req)
+	);
+
+	assign output_data_from_elpis_to_controller = print_output;
+	assign output_enabled_from_elpis_to_controller = print_hex_enable;
+
+	io_input_arbiter io_input_arbiter(
+		.clk(clk),
+		.reset(rst),
+		.req_core0(read_interactive_req_core0),
+		.read_value(read_value_to_Elpis),
+		.read_enable(read_enable_to_Elpis),
+		.is_ready_core0(is_ready_dataout_core0),
+		.data_out(data_out_to_core)
+	);
+
+	io_output_arbiter io_output_arbiter(
+		.clk(clk),
+		.reset(rst),
+		.req_core0(req_out_core0),
+		.data_core0(core0_data_print),
+		.print_hex_enable(print_hex_enable),
+		.print_output(print_output),
+		.is_ready_core0(is_ready_print_core0)
+	);
+
+// user_proj_example mprj (
+// `ifdef USE_POWER_PINS
+// 	.vccd1(vccd1),	// User area 1 1.8V power
+// 	.vssd1(vssd1),	// User area 1 digital ground
+// `endif
+
+//     .wb_clk_i(wb_clk_i),
+//     .wb_rst_i(wb_rst_i),
+
+//     // MGMT SoC Wishbone Slave
+
+//     .wbs_cyc_i(wbs_cyc_i),
+//     .wbs_stb_i(wbs_stb_i),
+//     .wbs_we_i(wbs_we_i),
+//     .wbs_sel_i(wbs_sel_i),
+//     .wbs_adr_i(wbs_adr_i),
+//     .wbs_dat_i(wbs_dat_i),
+//     .wbs_ack_o(wbs_ack_o),
+//     .wbs_dat_o(wbs_dat_o),
+
+//     // Logic Analyzer
+
+//     .la_data_in(la_data_in),
+//     .la_data_out(la_data_out),
+//     .la_oenb (la_oenb),
+
+//     // IO Pads
+
+//     .io_in (io_in),
+//     .io_out(io_out),
+//     .io_oeb(io_oeb),
+
+//     // IRQ
+//     .irq(user_irq)
+// );
 
 endmodule	// user_project_wrapper