data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v
1: b'%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:17: Cannot find include file: /project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v\n    `include "/project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v" \n             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/422650017/verilog/rtl/elpis,data/full_repos/permissive/422650017//project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v\n             data/full_repos/permissive/422650017/verilog/rtl/elpis,data/full_repos/permissive/422650017//project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v.v\n             data/full_repos/permissive/422650017/verilog/rtl/elpis,data/full_repos/permissive/422650017//project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v.sv\n             /project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v\n             /project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v.v\n             /project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v.sv\n             obj_dir//project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v\n             obj_dir//project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v.v\n             obj_dir//project/openlane/user_proj_example/../../verilog/rtl/elpis/definitions.v.sv\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:20: Define or directive not defined: \'`CACHE_TYPE_ICACHE\'\nmodule cache #(parameter CORE_ID = 0, parameter CACHE_TYPE = `CACHE_TYPE_ICACHE)(input clk, input reset, input[31:0] address_in, input[31:0] data_in, input write_enable_in,\n                                                             ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:20: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\nmodule cache #(parameter CORE_ID = 0, parameter CACHE_TYPE = `CACHE_TYPE_ICACHE)(input clk, input reset, input[31:0] address_in, input[31:0] data_in, input write_enable_in,\n                                                                               ^\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:23: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n 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,\n                                 ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:23: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n 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,\n                                                     ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:23: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n 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,\n                                                                                    ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:23: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n 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,\n                                                                                                                    ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:23: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n 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,\n                                                                                                                                        ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:24: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n output reg hit_tlb, output reg exc_protected_page_tlb);\n ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:24: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n output reg hit_tlb, output reg exc_protected_page_tlb);\n                     ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:29: syntax error, unexpected always\n always@(*) begin\n ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:35: Define or directive not defined: \'`ITLB_BASE_ADDRESS_SHIFT_CORE0\'\n wire[19:0] i_address_candidate = `ITLB_BASE_ADDRESS_SHIFT_CORE0 + address_in[19:0];\n                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:36: Define or directive not defined: \'`DTLB_BASE_ADDRESS_SHIFT_CORE0\'\n wire[19:0] d_address_candidate = `DTLB_BASE_ADDRESS_SHIFT_CORE0 + address_in[19:0];\n                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:37: syntax error, unexpected assign\n assign phys_addr_out = privilege_mode ? address_in[19:0] : ( (CACHE_TYPE == `CACHE_TYPE_DCACHE) ? d_address_candidate : i_address_candidate);\n ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:37: Define or directive not defined: \'`CACHE_TYPE_DCACHE\'\n assign phys_addr_out = privilege_mode ? address_in[19:0] : ( (CACHE_TYPE == `CACHE_TYPE_DCACHE) ? d_address_candidate : i_address_candidate);\n                                                                             ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:39: Define or directive not defined: \'`NUM_CACHE_LINES\'\n reg[0:0] cacheValidBits[0:`NUM_CACHE_LINES-1];\n                           ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:40: Define or directive not defined: \'`NUM_CACHE_LINES\'\n reg[0:0] cacheDirtyBits[0:`NUM_CACHE_LINES-1];\n                           ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:41: Define or directive not defined: \'`CACHE_TAG_SIZE\'\n reg[`CACHE_TAG_SIZE-1:0] cacheTag[0:`NUM_CACHE_LINES-1];\n     ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:41: Define or directive not defined: \'`NUM_CACHE_LINES\'\n reg[`CACHE_TAG_SIZE-1:0] cacheTag[0:`NUM_CACHE_LINES-1];\n                                     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:42: Define or directive not defined: \'`CACHE_LINE_SIZE\'\n reg[`CACHE_LINE_SIZE-1:0] cacheData[0:`NUM_CACHE_LINES-1];\n     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:42: Define or directive not defined: \'`NUM_CACHE_LINES\'\n reg[`CACHE_LINE_SIZE-1:0] cacheData[0:`NUM_CACHE_LINES-1];\n                                       ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:45: Define or directive not defined: \'`CACHE_TAG_SIZE\'\n reg[`CACHE_TAG_SIZE-1:0]  sram_addr_in_port;\n     ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:46: Define or directive not defined: \'`CACHE_TAG_SIZE\'\n wire[`CACHE_TAG_SIZE-1:0]  sram_addr_out_port;\n      ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:47: Define or directive not defined: \'`CACHE_LINE_SIZE\'\n reg[`CACHE_LINE_SIZE-1:0]  sram_data_in_port;\n     ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:48: Define or directive not defined: \'`CACHE_LINE_SIZE\'\n wire[`CACHE_LINE_SIZE-1:0]  sram_data_out_port;\n      ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:51: Define or directive not defined: \'`CACHE_TAG_SIZE\'\n wire[`CACHE_TAG_SIZE-1:0] tag;\n      ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:55: syntax error, unexpected assign\n assign tag = phys_addr_out[19:6]; \n ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:63: syntax error, unexpected always\n always@(posedge clk)\n ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:66: Define or directive not defined: \'`IDLE_STATE\'\n   cache_state <= `IDLE_STATE;\n                  ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:77: syntax error, unexpected always\n always@(cache_state or read_enable_in or write_enable_in or reset_mem_req or no_need_write_back or need_write_back or mem_ready_in or is_hit_tlb or hit_out) begin\n ^~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:79: Define or directive not defined: \'`IDLE_STATE\'\n   `IDLE_STATE:begin\n   ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:82: Define or directive not defined: \'`IDLE_STATE\'\n      next_cache_state <= `IDLE_STATE;\n                          ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:85: Define or directive not defined: \'`IDLE_STATE\'\n      next_cache_state <= `IDLE_STATE;\n                          ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:88: Define or directive not defined: \'`ALLOCATE_STATE\'\n      next_cache_state <= `ALLOCATE_STATE;\n                          ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:91: Define or directive not defined: \'`WRITE_BACK_STATE\'\n      next_cache_state <= `WRITE_BACK_STATE;\n                          ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:93: Define or directive not defined: \'`IDLE_STATE\'\n      next_cache_state <= `IDLE_STATE;\n                          ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:97: Define or directive not defined: \'`IDLE_STATE\'\n     next_cache_state <= `IDLE_STATE;\n                         ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:100: Define or directive not defined: \'`ALLOCATE_STATE\'\n   `ALLOCATE_STATE: begin\n   ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:101: Define or directive not defined: \'`IDLE_STATE\'\n    if (reset_mem_req) next_cache_state <= `IDLE_STATE;\n                                           ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:102: Define or directive not defined: \'`ALLOCATE_STATE\'\n    else if (!mem_ready_in) next_cache_state <= `ALLOCATE_STATE;\n                                                ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:103: Define or directive not defined: \'`IDLE_STATE\'\n    else next_cache_state <= `IDLE_STATE;\n                             ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:105: Define or directive not defined: \'`WRITE_BACK_STATE\'\n   `WRITE_BACK_STATE: begin\n   ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:106: Define or directive not defined: \'`IDLE_STATE\'\n    if (reset_mem_req) next_cache_state <= `IDLE_STATE;\n                                           ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:107: Define or directive not defined: \'`WRITE_BACK_STATE\'\n    else if (!mem_ready_in) next_cache_state <= `WRITE_BACK_STATE;\n                                                ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:109: Define or directive not defined: \'`ALLOCATE_STATE\'\n    else next_cache_state <= `ALLOCATE_STATE;\n                             ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:111: Define or directive not defined: \'`IDLE_STATE\'\n   default: next_cache_state <= `IDLE_STATE;\n                                ^~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:117: Define or directive not defined: \'`NUM_CACHE_LINES\'\n   for(i = 0; i < `NUM_CACHE_LINES; i=i+1) begin\n                  ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:122: Define or directive not defined: \'`ALLOCATE_STATE\'\n   if (sram_we_port || (cache_state == `ALLOCATE_STATE && mem_ready_in) ) begin\n                                       ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:123: Define or directive not defined: \'`ALLOCATE_STATE\'\n    cacheTag[index] <= (cache_state == `ALLOCATE_STATE) ? tag : sram_addr_in_port;\n                                       ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/422650017/verilog/rtl/elpis/cache.v:124: Define or directive not defined: \'`ALLOCATE_STATE\'\n    cacheData[index] <= (cache_state == `ALLOCATE_STATE) ? mem_data_in : sram_data_in_port;\n                                        ^~~~~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module cache #(parameter CORE_ID = 0, parameter CACHE_TYPE = `CACHE_TYPE_ICACHE)(input clk, input reset, input[31:0] address_in, input[31:0] data_in, input write_enable_in,
	input read_enable_in, input mem_ready_in, input[127:0] mem_data_in, input is_byte, input reset_mem_req, input privilege_mode, input tlb_we, input tlb_re, 
	input[19:0] physical_addr_in, input[31:0] virtual_addr_write_tlb_in, input[19:0] physical_addr_write_tlb_in,
	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_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_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];
	reg[`CACHE_LINE_SIZE-1:0] cacheData[0:`NUM_CACHE_LINES-1];


	reg[`CACHE_TAG_SIZE-1:0] 	sram_addr_in_port;
	wire[`CACHE_TAG_SIZE-1:0] 	sram_addr_out_port;
	reg[`CACHE_LINE_SIZE-1:0] 	sram_data_in_port;
	wire[`CACHE_LINE_SIZE-1:0] 	sram_data_out_port;
	wire sram_we_port, sram_we_valid, sram_we_dirty, sram_value_valid, sram_value_dirty;
	
	wire[`CACHE_TAG_SIZE-1:0] tag;
	wire[1:0] index;
	wire[3:0] offset;
	
	assign tag = phys_addr_out[19:6]; 
	assign index = address_in[5:4];
	assign offset = address_in[3:0];
	
	reg[2:0] cache_state, next_cache_state;
	
	integer i;
	
	always@(posedge clk)
	begin
		if (reset) begin
			cache_state <= `IDLE_STATE;
		end
		else cache_state <= next_cache_state;
	end

	wire[31:0] auxAL = phys_addr_out>>2;
	wire[31:0] auxWB = {sram_addr_out_port, index, 2'b0};

	wire no_need_write_back = (!hit_out & !cacheDirtyBits[index]);
	wire need_write_back = (!hit_out & cacheDirtyBits[index]);
	
	always@(cache_state or read_enable_in or write_enable_in or reset_mem_req or no_need_write_back or need_write_back or mem_ready_in or is_hit_tlb or hit_out) begin
		case(cache_state)
			`IDLE_STATE:begin
				if ((read_enable_in | write_enable_in) && is_hit_tlb) begin
					if (hit_out) begin
						next_cache_state <= `IDLE_STATE;
					end
					else if (reset_mem_req) begin
						next_cache_state <= `IDLE_STATE;
					end
					else if (no_need_write_back) begin
						next_cache_state <= `ALLOCATE_STATE;
					end
					else if (need_write_back) begin
						next_cache_state <= `WRITE_BACK_STATE;
					end else begin
						next_cache_state <= `IDLE_STATE;
					end
				end
				else begin
					next_cache_state <= `IDLE_STATE;
				end
			end
			`ALLOCATE_STATE: begin
				if (reset_mem_req) next_cache_state <= `IDLE_STATE;
				else if (!mem_ready_in) next_cache_state <= `ALLOCATE_STATE;
				else next_cache_state <= `IDLE_STATE;
			end
			`WRITE_BACK_STATE: begin
				if (reset_mem_req) next_cache_state <= `IDLE_STATE;
				else if (!mem_ready_in) next_cache_state <= `WRITE_BACK_STATE;

				else next_cache_state <= `ALLOCATE_STATE;
			end
			default: next_cache_state <= `IDLE_STATE;
		endcase
	end

	always@(posedge clk) begin
		if (reset) begin
			for(i = 0; i < `NUM_CACHE_LINES; i=i+1) begin
				cacheValidBits[i] <= 1'b0;
				cacheDirtyBits[i] <= 1'b0;
			end
		end else begin
			if (sram_we_port || (cache_state == `ALLOCATE_STATE && mem_ready_in) ) begin
				cacheTag[index] <= (cache_state == `ALLOCATE_STATE) ? tag : sram_addr_in_port;
				cacheData[index] <= (cache_state == `ALLOCATE_STATE) ? mem_data_in : sram_data_in_port;
			end
			if (sram_we_valid || (cache_state == `ALLOCATE_STATE && mem_ready_in) ) begin
				cacheValidBits[index] <= (cache_state == `ALLOCATE_STATE) ? 1'b1 : sram_value_valid;
			end
			if (sram_we_dirty || (cache_state == `ALLOCATE_STATE && mem_ready_in)) begin
				cacheDirtyBits[index] <= (cache_state == `ALLOCATE_STATE) ? 1'b0 : sram_value_dirty;
			end

		end		
	end

	assign sram_addr_out_port = (cache_state == `ALLOCATE_STATE && mem_ready_in) ? tag : cacheTag[index];
	assign sram_data_out_port = (cache_state == `ALLOCATE_STATE && mem_ready_in) ? mem_data_in : cacheData[index];

	assign sram_we_port = ((hit_out && write_enable_in) || (cache_state == `ALLOCATE_STATE && mem_ready_in)) ? 1'b1 : 1'b0;
	assign sram_we_dirty = ((hit_out && write_enable_in) || (cache_state == `ALLOCATE_STATE && mem_ready_in)) ? 1'b1 : 1'b0;
	assign sram_we_valid = ((hit_out && write_enable_in) || (cache_state == `ALLOCATE_STATE && mem_ready_in)) ? 1'b1 : 1'b0;
	assign sram_value_valid = 1'b1;
	assign sram_value_dirty = (cacheDirtyBits[index] | write_enable_in);

	always@(*) begin
		if (reset) begin
			mem_data_out <= 128'b0;
			req_mem <= 0;
			mem_we_out <= 0;
			mem_addr_out <= 20'b0;
			sram_data_in_port <= 128'b0;
			sram_addr_in_port <= 'b0;
		end else begin
			case(cache_state)
				`IDLE_STATE: begin
					mem_data_out <= 128'b0;
					mem_addr_out <= 20'b0; 
					req_mem <= 0;
					mem_we_out <= 0;
					if (write_enable_in) begin
						sram_addr_in_port <= tag;
						if (is_byte) begin
							case(offset)
								4'b0000:sram_data_in_port <= {sram_data_out_port[127:8], data_in[7:0]};
								4'b0001:sram_data_in_port <= {sram_data_out_port[127:16], data_in[7:0], sram_data_out_port[7:0]};
								4'b0010:sram_data_in_port <= {sram_data_out_port[127:24], data_in[7:0], sram_data_out_port[15:0]};
								4'b0011:sram_data_in_port <= {sram_data_out_port[127:32], data_in[7:0], sram_data_out_port[23:0]};
								4'b0100:sram_data_in_port <= {sram_data_out_port[127:40], data_in[7:0], sram_data_out_port[31:0]};
								4'b0101:sram_data_in_port <= {sram_data_out_port[127:48], data_in[7:0], sram_data_out_port[39:0]};
								4'b0110:sram_data_in_port <= {sram_data_out_port[127:56], data_in[7:0], sram_data_out_port[47:0]};
								4'b0111:sram_data_in_port <= {sram_data_out_port[127:64], data_in[7:0], sram_data_out_port[55:0]};
								4'b1000:sram_data_in_port <= {sram_data_out_port[127:72], data_in[7:0], sram_data_out_port[63:0]};
								4'b1001:sram_data_in_port <= {sram_data_out_port[127:80], data_in[7:0], sram_data_out_port[71:0]};
								4'b1010:sram_data_in_port <= {sram_data_out_port[127:88], data_in[7:0], sram_data_out_port[79:0]};
								4'b1011:sram_data_in_port <= {sram_data_out_port[127:96], data_in[7:0], sram_data_out_port[87:0]};
								4'b1100:sram_data_in_port <= {sram_data_out_port[127:104], data_in[7:0], sram_data_out_port[95:0]};
								4'b1101:sram_data_in_port <= {sram_data_out_port[127:112], data_in[7:0], sram_data_out_port[103:0]};
								4'b1110:sram_data_in_port <= {sram_data_out_port[127:120], data_in[7:0], sram_data_out_port[111:0]};
								4'b1111:sram_data_in_port <= {data_in[7:0], sram_data_out_port[119:0]};
								default: sram_data_in_port <= 128'b0;
							endcase 
						end else begin
							case(offset)
								4'b0000:sram_data_in_port <= {sram_data_out_port[127:32], data_in};
								4'b0100:sram_data_in_port <= {sram_data_out_port[127:64], data_in, sram_data_out_port[31:0]};
								4'b1000:sram_data_in_port <= {sram_data_out_port[127:96], data_in, sram_data_out_port[63:0]};
								4'b1100:sram_data_in_port <= {data_in, sram_data_out_port[95:0]};
								default: sram_data_in_port <= 128'b0;
							endcase 
						end
					end else begin
						sram_addr_in_port <= 'b0;
						sram_data_in_port <= 128'b0;
					end
				end
				`ALLOCATE_STATE: begin
					mem_data_out <= 128'b0;
					mem_addr_out <= {auxAL[17:2],2'b00};
					mem_we_out <= 1'b0;
					if (mem_ready_in) begin
						req_mem  <= 1'b0;
						sram_data_in_port <= mem_data_in;
						sram_addr_in_port <= tag;
					end else begin
						req_mem  <= 1'b1;
						sram_data_in_port <= 128'b0;
						sram_addr_in_port <= 'b0;
					end
				end
				`WRITE_BACK_STATE: begin
					req_mem <= 1'b1;
					mem_we_out <= 1'b1;
					mem_addr_out <= auxWB[19:0];
					mem_data_out <= sram_data_out_port;
					sram_data_in_port <= 128'b0;
					sram_addr_in_port <= 'b0;
				end
				default: begin
					sram_addr_in_port <= 'b0;
					sram_data_in_port <= 128'b0;
					mem_data_out <= 128'b0;
					mem_addr_out <= 20'b0;
				end
			endcase
		end
	end


	always@(*) begin
		if (read_enable_in) begin
			if (is_byte) begin
				read_data_out <= {24'b0, sram_data_out_port[offset*8+:8]};
			end else begin
				read_data_out <= sram_data_out_port[offset*8+:32];
			end
		end else begin
			read_data_out <= 0;
		end
	end

	always@(*) begin : hit_cache_logic
   		if (read_enable_in | write_enable_in) begin
			if (cache_state != `IDLE_STATE) begin
				hit_out <= 1'b0;
			end else begin
				if(write_enable_in) begin
					hit_out <= (sram_addr_out_port == tag) && cacheValidBits[index] && is_hit_tlb;
				end else begin
					hit_out <= (sram_addr_out_port == tag) && cacheValidBits[index] && is_hit_tlb;
				end
				
			end
	  	end
		else hit_out <= 1;
	end
	
endmodule
module cache #(parameter CORE_ID = 0, parameter CACHE_TYPE = `CACHE_TYPE_ICACHE)(input clk, input reset, input[31:0] address_in, input[31:0] data_in, input write_enable_in,
	input read_enable_in, input mem_ready_in, input[127:0] mem_data_in, input is_byte, input reset_mem_req, input privilege_mode, input tlb_we, input tlb_re, 
	input[19:0] physical_addr_in, input[31:0] virtual_addr_write_tlb_in, input[19:0] physical_addr_write_tlb_in,
	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_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_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];
	reg[`CACHE_LINE_SIZE-1:0] cacheData[0:`NUM_CACHE_LINES-1];


	reg[`CACHE_TAG_SIZE-1:0] 	sram_addr_in_port;
	wire[`CACHE_TAG_SIZE-1:0] 	sram_addr_out_port;
	reg[`CACHE_LINE_SIZE-1:0] 	sram_data_in_port;
	wire[`CACHE_LINE_SIZE-1:0] 	sram_data_out_port;
	wire sram_we_port, sram_we_valid, sram_we_dirty, sram_value_valid, sram_value_dirty;
	
	wire[`CACHE_TAG_SIZE-1:0] tag;
	wire[1:0] index;
	wire[3:0] offset;
	
	assign tag = phys_addr_out[19:6]; 
	assign index = address_in[5:4];
	assign offset = address_in[3:0];
	
	reg[2:0] cache_state, next_cache_state;
	
	integer i;
	
	always@(posedge clk)
	begin
		if (reset) begin
			cache_state <= `IDLE_STATE;
		end
		else cache_state <= next_cache_state;
	end

	wire[31:0] auxAL = phys_addr_out>>2;
	wire[31:0] auxWB = {sram_addr_out_port, index, 2'b0};

	wire no_need_write_back = (!hit_out & !cacheDirtyBits[index]);
	wire need_write_back = (!hit_out & cacheDirtyBits[index]);
	
	always@(cache_state or read_enable_in or write_enable_in or reset_mem_req or no_need_write_back or need_write_back or mem_ready_in or is_hit_tlb or hit_out) begin
		case(cache_state)
			`IDLE_STATE:begin
				if ((read_enable_in | write_enable_in) && is_hit_tlb) begin
					if (hit_out) begin
						next_cache_state <= `IDLE_STATE;
					end
					else if (reset_mem_req) begin
						next_cache_state <= `IDLE_STATE;
					end
					else if (no_need_write_back) begin
						next_cache_state <= `ALLOCATE_STATE;
					end
					else if (need_write_back) begin
						next_cache_state <= `WRITE_BACK_STATE;
					end else begin
						next_cache_state <= `IDLE_STATE;
					end
				end
				else begin
					next_cache_state <= `IDLE_STATE;
				end
			end
			`ALLOCATE_STATE: begin
				if (reset_mem_req) next_cache_state <= `IDLE_STATE;
				else if (!mem_ready_in) next_cache_state <= `ALLOCATE_STATE;
				else next_cache_state <= `IDLE_STATE;
			end
			`WRITE_BACK_STATE: begin
				if (reset_mem_req) next_cache_state <= `IDLE_STATE;
				else if (!mem_ready_in) next_cache_state <= `WRITE_BACK_STATE;

				else next_cache_state <= `ALLOCATE_STATE;
			end
			default: next_cache_state <= `IDLE_STATE;
		endcase
	end

	always@(posedge clk) begin
		if (reset) begin
			for(i = 0; i < `NUM_CACHE_LINES; i=i+1) begin
				cacheValidBits[i] <= 1'b0;
				cacheDirtyBits[i] <= 1'b0;
			end
		end else begin
			if (sram_we_port || (cache_state == `ALLOCATE_STATE && mem_ready_in) ) begin
				cacheTag[index] <= (cache_state == `ALLOCATE_STATE) ? tag : sram_addr_in_port;
				cacheData[index] <= (cache_state == `ALLOCATE_STATE) ? mem_data_in : sram_data_in_port;
			end
			if (sram_we_valid || (cache_state == `ALLOCATE_STATE && mem_ready_in) ) begin
				cacheValidBits[index] <= (cache_state == `ALLOCATE_STATE) ? 1'b1 : sram_value_valid;
			end
			if (sram_we_dirty || (cache_state == `ALLOCATE_STATE && mem_ready_in)) begin
				cacheDirtyBits[index] <= (cache_state == `ALLOCATE_STATE) ? 1'b0 : sram_value_dirty;
			end

		end		
	end

	assign sram_addr_out_port = (cache_state == `ALLOCATE_STATE && mem_ready_in) ? tag : cacheTag[index];
	assign sram_data_out_port = (cache_state == `ALLOCATE_STATE && mem_ready_in) ? mem_data_in : cacheData[index];

	assign sram_we_port = ((hit_out && write_enable_in) || (cache_state == `ALLOCATE_STATE && mem_ready_in)) ? 1'b1 : 1'b0;
	assign sram_we_dirty = ((hit_out && write_enable_in) || (cache_state == `ALLOCATE_STATE && mem_ready_in)) ? 1'b1 : 1'b0;
	assign sram_we_valid = ((hit_out && write_enable_in) || (cache_state == `ALLOCATE_STATE && mem_ready_in)) ? 1'b1 : 1'b0;
	assign sram_value_valid = 1'b1;
	assign sram_value_dirty = (cacheDirtyBits[index] | write_enable_in);

	always@(*) begin
		if (reset) begin
			mem_data_out <= 128'b0;
			req_mem <= 0;
			mem_we_out <= 0;
			mem_addr_out <= 20'b0;
			sram_data_in_port <= 128'b0;
			sram_addr_in_port <= 'b0;
		end else begin
			case(cache_state)
				`IDLE_STATE: begin
					mem_data_out <= 128'b0;
					mem_addr_out <= 20'b0; 
					req_mem <= 0;
					mem_we_out <= 0;
					if (write_enable_in) begin
						sram_addr_in_port <= tag;
						if (is_byte) begin
							case(offset)
								4'b0000:sram_data_in_port <= {sram_data_out_port[127:8], data_in[7:0]};
								4'b0001:sram_data_in_port <= {sram_data_out_port[127:16], data_in[7:0], sram_data_out_port[7:0]};
								4'b0010:sram_data_in_port <= {sram_data_out_port[127:24], data_in[7:0], sram_data_out_port[15:0]};
								4'b0011:sram_data_in_port <= {sram_data_out_port[127:32], data_in[7:0], sram_data_out_port[23:0]};
								4'b0100:sram_data_in_port <= {sram_data_out_port[127:40], data_in[7:0], sram_data_out_port[31:0]};
								4'b0101:sram_data_in_port <= {sram_data_out_port[127:48], data_in[7:0], sram_data_out_port[39:0]};
								4'b0110:sram_data_in_port <= {sram_data_out_port[127:56], data_in[7:0], sram_data_out_port[47:0]};
								4'b0111:sram_data_in_port <= {sram_data_out_port[127:64], data_in[7:0], sram_data_out_port[55:0]};
								4'b1000:sram_data_in_port <= {sram_data_out_port[127:72], data_in[7:0], sram_data_out_port[63:0]};
								4'b1001:sram_data_in_port <= {sram_data_out_port[127:80], data_in[7:0], sram_data_out_port[71:0]};
								4'b1010:sram_data_in_port <= {sram_data_out_port[127:88], data_in[7:0], sram_data_out_port[79:0]};
								4'b1011:sram_data_in_port <= {sram_data_out_port[127:96], data_in[7:0], sram_data_out_port[87:0]};
								4'b1100:sram_data_in_port <= {sram_data_out_port[127:104], data_in[7:0], sram_data_out_port[95:0]};
								4'b1101:sram_data_in_port <= {sram_data_out_port[127:112], data_in[7:0], sram_data_out_port[103:0]};
								4'b1110:sram_data_in_port <= {sram_data_out_port[127:120], data_in[7:0], sram_data_out_port[111:0]};
								4'b1111:sram_data_in_port <= {data_in[7:0], sram_data_out_port[119:0]};
								default: sram_data_in_port <= 128'b0;
							endcase 
						end else begin
							case(offset)
								4'b0000:sram_data_in_port <= {sram_data_out_port[127:32], data_in};
								4'b0100:sram_data_in_port <= {sram_data_out_port[127:64], data_in, sram_data_out_port[31:0]};
								4'b1000:sram_data_in_port <= {sram_data_out_port[127:96], data_in, sram_data_out_port[63:0]};
								4'b1100:sram_data_in_port <= {data_in, sram_data_out_port[95:0]};
								default: sram_data_in_port <= 128'b0;
							endcase 
						end
					end else begin
						sram_addr_in_port <= 'b0;
						sram_data_in_port <= 128'b0;
					end
				end
				`ALLOCATE_STATE: begin
					mem_data_out <= 128'b0;
					mem_addr_out <= {auxAL[17:2],2'b00};
					mem_we_out <= 1'b0;
					if (mem_ready_in) begin
						req_mem  <= 1'b0;
						sram_data_in_port <= mem_data_in;
						sram_addr_in_port <= tag;
					end else begin
						req_mem  <= 1'b1;
						sram_data_in_port <= 128'b0;
						sram_addr_in_port <= 'b0;
					end
				end
				`WRITE_BACK_STATE: begin
					req_mem <= 1'b1;
					mem_we_out <= 1'b1;
					mem_addr_out <= auxWB[19:0];
					mem_data_out <= sram_data_out_port;
					sram_data_in_port <= 128'b0;
					sram_addr_in_port <= 'b0;
				end
				default: begin
					sram_addr_in_port <= 'b0;
					sram_data_in_port <= 128'b0;
					mem_data_out <= 128'b0;
					mem_addr_out <= 20'b0;
				end
			endcase
		end
	end


	always@(*) begin
		if (read_enable_in) begin
			if (is_byte) begin
				read_data_out <= {24'b0, sram_data_out_port[offset*8+:8]};
			end else begin
				read_data_out <= sram_data_out_port[offset*8+:32];
			end
		end else begin
			read_data_out <= 0;
		end
	end

	always@(*) begin : hit_cache_logic
   		if (read_enable_in | write_enable_in) begin
			if (cache_state != `IDLE_STATE) begin
				hit_out <= 1'b0;
			end else begin
				if(write_enable_in) begin
					hit_out <= (sram_addr_out_port == tag) && cacheValidBits[index] && is_hit_tlb;
				end else begin
					hit_out <= (sram_addr_out_port == tag) && cacheValidBits[index] && is_hit_tlb;
				end
				
			end
	  	end
		else hit_out <= 1;
	end
	
endmodule