mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge pull request #1084 from jordancarlin/configurable_fetch_buffer
Fetch buffer works with configurable number of entries
This commit is contained in:
commit
c17e15e7fa
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user