From 97d85b2f7740673f3fbd4cb994646e21b9aca51d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergiusz=20=27q3k=27=20Baza=C5=84ski?= Date: Sun, 7 Sep 2014 17:02:25 +0200 Subject: [PATCH] First memory backend in icache --- rtl/verilog/qm_icache.v | 86 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/rtl/verilog/qm_icache.v b/rtl/verilog/qm_icache.v index 1638158..3b1a7c1 100644 --- a/rtl/verilog/qm_icache.v +++ b/rtl/verilog/qm_icache.v @@ -1,11 +1,29 @@ +/* verilator lint_off UNUSED */ module qm_icache( input wire [31:0] address, input wire reset, input wire clk, + // to the consumer (CPU fetch stage) output wire hit, output wire stall, - output wire [31:0] data + output wire [31:0] data, + + // to the memory controller (no wishbone yet...) + output wire mem_cmd_clk, // we will keep this synchronous to the input clock + output wire mem_cmd_en, + output wire [2:0] mem_cmd_instr, + output wire [5:0] mem_cmd_bl, + output wire [29:0] mem_cmd_addr, + input wire mem_cmd_full, + input wire mem_cmd_empty, + + output wire mem_rd_clk, + output wire mem_rd_en, + input wire [6:0] mem_rd_count, + input wire mem_rd_full, + input wire [31:0] mem_rd_data, + input wire mem_rd_empty ); @@ -28,6 +46,8 @@ assign index_tag = lines[index][143:128]; assign address_tag = address[31:16]; assign address_word = address[3:2]; +assign mem_rd_clk = clk; +assign mem_cmd_clk = clk; // reset condition generate @@ -40,9 +60,16 @@ generate end end endgenerate -always @(posedge clk) - if (reset) +always @(posedge clk) begin + if (reset) begin valid_bit <= 1; + memory_read_state <= 0; + mem_cmd_en <= 0; + mem_cmd_bl <= 0; + mem_cmd_instr <= 0; + mem_rd_en <= 0; + end +end // read condition always @(address) begin @@ -63,4 +90,57 @@ always @(address) begin end end +// if we are stalling, it means that our consumer is waiting for us to +// read memory and provide it data +reg [2:0] memory_read_state; +always @(posedge clk) begin + if (stall && !reset) begin + case (memory_read_state) + 0: begin // assert command + mem_cmd_instr <= 1; // read + mem_cmd_bl <= 4; // four words + mem_cmd_addr <= address[29:0]; // from the address we are being asserted + mem_cmd_en <= 0; + memory_read_state <= 1; + end + 1: begin // assert enable + mem_cmd_en <= 1; + memory_read_state <= 2; + mem_rd_en <= 1; + end + 2: begin // wait for first word + mem_cmd_en <= 0; + if (!mem_rd_empty) begin + lines[index][31:0] <= mem_rd_data; + memory_read_state <= 3; + end + end + 3: begin // wait for second word + if (!mem_rd_empty) begin + lines[index][63:32] <= mem_rd_data; + memory_read_state <= 4; + end + end + 4: begin // wait for third word + if (!mem_rd_empty) begin + lines[index][95:64] <= mem_rd_data; + memory_read_state <= 5; + end + end + 5: begin // wait for fourth word + if (!mem_rd_empty) begin + lines[index][127:96] <= mem_rd_data; + memory_read_state <= 0; + mem_rd_en <= 0; + // write tag + lines[index][143:128] <= address_tag; + // and valid bit - our cominatorial logic will now turn + // off stalling and indicate a hit to the consumer + lines[index][144] <= valid_bit; + end + end + endcase + end +end + endmodule