unified_memory.sv (1337B)
1 module unified_memory 2 import rv32g_pkg::*; 3 (input logic clk, 4 5 // instruction port 6 input logic [31:0] imem_addr, 7 output logic [31:0] imem_data, 8 output logic imem_valid, 9 10 // data port 11 input logic [31:0] dmem_addr, 12 input logic dmem_we, 13 input logic [3:0] dmem_be, 14 input logic [31:0] dmem_wdata, 15 output logic [31:0] dmem_rdata, 16 output logic dmem_valid); 17 18 localparam IDX_WIDTH = $clog2(CACHE_DEPTH); 19 20 logic [31:0] mem [0:CACHE_DEPTH-1]; 21 logic [IDX_WIDTH-1:0] imem_idx, dmem_idx; 22 logic imem_in_range, dmem_in_range; 23 24 // initial $readmemh("rom.txt", mem); 25 26 always_comb begin 27 imem_idx = imem_addr[IDX_WIDTH+1:2]; 28 dmem_idx = dmem_addr[IDX_WIDTH+1:2]; 29 imem_in_range = imem_addr[31:IDX_WIDTH+2] == BASE_ADDR[31:IDX_WIDTH+2]; 30 dmem_in_range = dmem_addr[31:IDX_WIDTH+2] == BASE_ADDR[31:IDX_WIDTH+2]; 31 end 32 33 always_ff @(posedge clk) begin 34 imem_valid <= imem_in_range; 35 dmem_valid <= dmem_in_range; 36 37 imem_data <= imem_in_range ? mem[imem_idx] : '0; 38 dmem_rdata <= dmem_in_range ? mem[dmem_idx] : '0; 39 40 // for self-modifying memory 41 if (dmem_we && dmem_in_range) begin 42 for (int b = 0; b < 4; b++) begin 43 if (dmem_be[b]) mem[dmem_idx][b << 3 +: 8] <= dmem_wdata[b << 3 +: 8]; 44 end 45 end 46 end 47 48 endmodule