Merge pull request #1084 from jordancarlin/configurable_fetch_buffer

Fetch buffer works with configurable number of entries
This commit is contained in:
David Harris 2024-11-11 06:12:53 -08:00 committed by GitHub
commit c17e15e7fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 44 additions and 20 deletions

View File

@ -116,6 +116,9 @@ localparam logic VIRTMEM_SUPPORTED = 0;
localparam logic VECTORED_INTERRUPTS_SUPPORTED = 0;
localparam logic BIGENDIAN_SUPPORTED = 0;
// Fetch buffer configuration
localparam FETCHBUFFER_ENTRIES =32'd0;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd0;
localparam DTLB_ENTRIES = 32'd0;

View File

@ -116,6 +116,9 @@ localparam logic VIRTMEM_SUPPORTED = 1;
localparam logic VECTORED_INTERRUPTS_SUPPORTED = 1;
localparam logic BIGENDIAN_SUPPORTED = 1;
// Fetch buffer configuration
localparam FETCHBUFFER_ENTRIES = 32'd3;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd32;
localparam DTLB_ENTRIES = 32'd32;

View File

@ -116,6 +116,9 @@ localparam logic VIRTMEM_SUPPORTED = 0;
localparam logic VECTORED_INTERRUPTS_SUPPORTED = 1;
localparam logic BIGENDIAN_SUPPORTED = 0;
// Fetch buffer configuration
localparam FETCHBUFFER_ENTRIES = 32'd3;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd32;
localparam DTLB_ENTRIES = 32'd32;

View File

@ -116,6 +116,9 @@ localparam logic VIRTMEM_SUPPORTED = 0;
localparam logic VECTORED_INTERRUPTS_SUPPORTED = 1;
localparam logic BIGENDIAN_SUPPORTED = 0;
// Fetch buffer configuration
localparam FETCHBUFFER_ENTRIES = 32'd3;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd0;
localparam DTLB_ENTRIES = 32'd0;

View File

@ -116,6 +116,9 @@ localparam logic VIRTMEM_SUPPORTED = 1;
localparam logic VECTORED_INTERRUPTS_SUPPORTED = 1;
localparam logic BIGENDIAN_SUPPORTED = 1;
// Fetch buffer configuration
localparam FETCHBUFFER_ENTRIES = 32'd3;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd32;
localparam DTLB_ENTRIES = 32'd32;

View File

@ -116,6 +116,9 @@ localparam logic VIRTMEM_SUPPORTED = 0;
localparam logic VECTORED_INTERRUPTS_SUPPORTED = 1;
localparam logic BIGENDIAN_SUPPORTED = 0;
// Fetch buffer configuration
localparam FETCHBUFFER_ENTRIES = 32'd3;
// TLB configuration. Entries should be a power of 2
localparam ITLB_ENTRIES = 32'd0;
localparam DTLB_ENTRIES = 32'd0;

View File

@ -45,6 +45,7 @@ localparam cvw_t P = '{
ICACHE_WAYSIZEINBYTES : ICACHE_WAYSIZEINBYTES,
ICACHE_LINELENINBITS : ICACHE_LINELENINBITS,
CACHE_SRAMLEN : CACHE_SRAMLEN,
FETCHBUFFER_ENTRIES : FETCHBUFFER_ENTRIES,
IDIV_BITSPERCYCLE : IDIV_BITSPERCYCLE,
IDIV_ON_FPU : IDIV_ON_FPU,
PMP_ENTRIES : PMP_ENTRIES,

View File

@ -74,6 +74,9 @@ typedef struct packed {
logic DCACHE_SUPPORTED;
logic ICACHE_SUPPORTED;
// Fetch Buffer Configuration
int FETCHBUFFER_ENTRIES;
// TLB configuration. Entries should be a power of 2
int ITLB_ENTRIES;
int DTLB_ENTRIES;

View File

@ -34,38 +34,35 @@ module fetchbuffer import cvw::*; #(parameter cvw_t P) (
output logic FetchBufferStallF
);
localparam [31:0] nop = 32'h00000013;
logic [31:0] Readf0, Readf1, Readf2, ReadFetchBuffer;
logic [2:0] ReadPtr, WritePtr;
logic [31:0] ReadReg [P.FETCHBUFFER_ENTRIES-1:0];
logic [31:0] ReadFetchBuffer;
logic [P.FETCHBUFFER_ENTRIES-1:0] ReadPtr, WritePtr;
logic Empty, Full;
assign Empty = |(ReadPtr & WritePtr); // Bitwise and the read&write ptr, and or the bits of the result together
assign Full = |({WritePtr[1:0], WritePtr[2]} & ReadPtr); // Same as above but left rotate WritePtr to "add 1"
assign Full = |({WritePtr[P.FETCHBUFFER_ENTRIES-2:0], WritePtr[P.FETCHBUFFER_ENTRIES-1]} & ReadPtr); // Same as above but left rotate WritePtr to "add 1"
assign FetchBufferStallF = Full;
// will go in a generate block once this is parameterized
flopenl #(32) f0 (.clk, .load(reset | FlushD), .en(WritePtr[0]), .d(WriteData), .val(nop), .q(Readf0));
flopenl #(32) f1 (.clk, .load(reset | FlushD), .en(WritePtr[1]), .d(WriteData), .val(nop), .q(Readf1));
flopenl #(32) f2 (.clk, .load(reset | FlushD), .en(WritePtr[2]), .d(WriteData), .val(nop), .q(Readf2));
flopenl #(32) fbEntries[P.FETCHBUFFER_ENTRIES-1:0] (.clk, .load(reset | FlushD), .en(WritePtr), .d(WriteData), .val(nop), .q(ReadReg));
// Fetch buffer entries anded with read ptr for AO Muxing
logic [31:0] DaoArr [2:0];
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Make parameterizable
assign DaoArr[0] = ReadPtr[0] ? Readf0 : '0;
assign DaoArr[1] = ReadPtr[1] ? Readf1 : '0;
assign DaoArr[2] = ReadPtr[2] ? Readf2 : '0;
logic [31:0] DaoArr [P.FETCHBUFFER_ENTRIES-1:0];
or_rows #(3, 32) ReadFBAOMux(.a(DaoArr), .y(ReadFetchBuffer));
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Make parameterizable
for (genvar i = 0; i < P.FETCHBUFFER_ENTRIES; i++) begin
assign DaoArr[i] = ReadPtr[i] ? ReadReg[i] : '0;
end
or_rows #(P.FETCHBUFFER_ENTRIES, 32) ReadFBAOMux(.a(DaoArr), .y(ReadFetchBuffer));
assign ReadData = Empty ? nop : ReadFetchBuffer;
always_ff @(posedge clk) begin : shiftRegister
if (reset) begin
WritePtr <= 3'b001;
ReadPtr <= 3'b001;
WritePtr <= {{P.FETCHBUFFER_ENTRIES-1{1'b0}}, 1'b1};
ReadPtr <= {{P.FETCHBUFFER_ENTRIES-1{1'b0}}, 1'b1};
end else begin
WritePtr <= ~(Full | StallF) ? {WritePtr[1:0], WritePtr[2]} : WritePtr;
ReadPtr <= ~(StallD | Empty) ? {ReadPtr[1:0], ReadPtr[2]} : ReadPtr;
WritePtr <= ~(Full | StallF) ? {WritePtr[P.FETCHBUFFER_ENTRIES-2:0], WritePtr[P.FETCHBUFFER_ENTRIES-1]} : WritePtr;
ReadPtr <= ~(StallD | Empty) ? {ReadPtr[P.FETCHBUFFER_ENTRIES-2:0], ReadPtr[P.FETCHBUFFER_ENTRIES-1]} : ReadPtr;
end
end
endmodule

View File

@ -303,8 +303,12 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign IFUStallF = IFUCacheBusStallF | SelSpillNextF;
assign GatedStallD = StallD & ~SelSpillNextF;
// flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD);
if (P.FETCHBUFFER_ENTRIES != 0) begin : fetchbuffer
fetchbuffer #(P) fetchbuff(.clk, .reset, .StallF, .StallD, .FlushD, .WriteData(PostSpillInstrRawF), .ReadData(InstrRawD), .FetchBufferStallF);
end else begin
flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD);
assign FetchBufferStallF = '0;
end
////////////////////////////////////////////////////////////////////////////////////////////////
// PCNextF logic

View File

@ -67,6 +67,7 @@ module riscvassertions import cvw::*; #(parameter cvw_t P);
assert ((P.ZCD_SUPPORTED == 0) | (P.D_SUPPORTED == 1)) else $fatal(1, "ZCD requires D");
assert ((P.LLEN == P.XLEN) | (P.DCACHE_SUPPORTED & P.DTIM_SUPPORTED == 0)) else $fatal(1, "LLEN > XLEN (D on RV32 or Q on RV64) requires data cache");
assert ((P.ZICCLSM_SUPPORTED == 0) | (P.DCACHE_SUPPORTED == 1)) else $fatal(1, "ZICCLSM requires DCACHE_SUPPORTED");
assert ((P.FETCHBUFFER_ENTRIES == 0) | (P.FETCHBUFFER_ENTRIES >= 3)) else $fatal(1, "FETCHBUFFER_ENTRIES must be 0 (disabled) or at least 3");
end
endmodule