Partial local dtim in lsu configuration.

This commit is contained in:
Ross Thompson 2022-01-13 17:00:46 -06:00
parent d356a0d29f
commit 9f7e3f147b
7 changed files with 97 additions and 54 deletions

View File

@ -49,7 +49,7 @@
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
`define MEM_DTIM 1
`define MEM_DTIM 0
`define MEM_DCACHE 1
`define MEM_IROM 1
`define MEM_ICACHE 1

View File

@ -49,10 +49,10 @@
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
`define MEM_DTIM 1
`define MEM_DTIM 0
`define MEM_DCACHE 0
`define MEM_IROM 1
`define MEM_ICACHE 0
`define MEM_IROM 0
`define MEM_ICACHE 1
`define MEM_VIRTMEM 0
`define VECTORED_INTERRUPTS_SUPPORTED 1

View File

@ -50,7 +50,7 @@
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
`define MEM_DTIM 1
`define MEM_DTIM 0
`define MEM_DCACHE 1
`define MEM_IROM 1
`define MEM_ICACHE 1

View File

@ -271,7 +271,7 @@ module ifu (
assign ICacheFetchLine = 0;
assign ICacheBusAdr = 0;
assign ICacheStallF = 0;
assign FinalInstrRawF = 0;
if(!`MEM_IROM) assign FinalInstrRawF = 0;
assign ICacheAccess = CacheableF;
assign ICacheMiss = CacheableF;
end
@ -283,26 +283,42 @@ module ifu (
.s(SelUncachedAdr),
.y(InstrRawF));
// always present
genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
flopen #(`XLEN) fb(.clk(clk),
.en(IFUBusAck & IFUBusRead & (index == WordCount)),
.d(IFUBusHRDATA),
.q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
end
assign LocalIFUBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
assign IFUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIFUBusAdr;
if (`MEM_IROM == 1) begin : irom
ram #(
.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.HCLK(clk), .HRESETn(~reset),
.HSELRam(1'b1), .HADDR(PCPF[31:0]),
.HWRITE(1'b0), .HREADY(1'b1),
.HTRANS(2'b10), .HWDATA(0), .HREADRam(FinalInstrRawF),
.HRESPRam(), .HREADYRam());
busfsm #(WordCountThreshold, LOGWPL, `MEM_ICACHE)
busfsm(.clk, .reset, .IgnoreRequest,
.LSURWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0),
.LSUBusAck(IFUBusAck),
.CPUBusy, .CacheableM(CacheableF),
.BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), .DCacheBusAck(ICacheBusAck),
.BusCommittedM(), .SelUncachedAdr(SelUncachedAdr), .WordCount);
assign BusStall = 0;
assign IFUBusRead = 0;
assign ICacheBusAck = 0;
assign SelUncachedAdr = 0;
end else begin : bus
genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
flopen #(`XLEN) fb(.clk(clk),
.en(IFUBusAck & IFUBusRead & (index == WordCount)),
.d(IFUBusHRDATA),
.q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
end
assign LocalIFUBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
assign IFUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIFUBusAdr;
busfsm #(WordCountThreshold, LOGWPL, `MEM_ICACHE)
busfsm(.clk, .reset, .IgnoreRequest,
.LSURWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0),
.LSUBusAck(IFUBusAck),
.CPUBusy, .CacheableM(CacheableF),
.BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), .DCacheBusAck(ICacheBusAck),
.BusCommittedM(), .SelUncachedAdr(SelUncachedAdr), .WordCount);
end
assign IFUStallF = ICacheStallF | BusStall | SelNextSpill;
assign CPUBusy = StallF & ~SelNextSpill;

View File

@ -316,7 +316,7 @@ module lsu
.CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0));
end else begin : passthrough
assign ReadDataWordM = 0;
if(!`MEM_DTIM) assign ReadDataWordM = 0;
assign DCacheStall = 0;
assign DCacheMiss = CacheableM;
assign DCacheAccess = CacheableM;
@ -357,35 +357,56 @@ module lsu
.HWDATAIN(FinalAMOWriteDataM),
.HWDATA(FinalWriteDataM));
// Bus Side logic
// register the fetch data from the next level of memory.
// This register should be necessary for timing. There is no register in the uncore or
// ahblite controller between the memories and this cache.
logic [LOGWPL-1:0] WordCount;
genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
flopen #(`XLEN) fb(.clk,
.en(LSUBusAck & LSUBusRead & (index == WordCount)),
.d(LSUBusHRDATA),
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
if (`MEM_DTIM == 1) begin : dtim
ram #(
.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.HCLK(clk), .HRESETn(~reset),
.HSELRam(1'b1), .HADDR(LSUPAdrM[31:0]),
.HWRITE(LSURWM[0]), .HREADY(1'b1),
.HTRANS(|LSURWM ? 2'b10 : 2'b00), .HWDATA(FinalWriteDataM), .HREADRam(ReadDataWordM),
.HRESPRam(), .HREADYRam());
// since we have a local memory the bus connections are all disabled.
// There are no peripherals supported.
assign BusStall = 0;
assign LSUBusWrite = 0;
assign LSUBusRead = 0;
assign DCacheBusAck = 0;
assign BusCommittedM = 0;
assign SelUncachedAdr = 0;
end else begin : bus
// Bus Side logic
// register the fetch data from the next level of memory.
// This register should be necessary for timing. There is no register in the uncore or
// ahblite controller between the memories and this cache.
logic [LOGWPL-1:0] WordCount;
genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
flopen #(`XLEN) fb(.clk,
.en(LSUBusAck & LSUBusRead & (index == WordCount)),
.d(LSUBusHRDATA),
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
end
assign LocalLSUBusAdr = SelUncachedAdr ? LSUPAdrM : DCacheBusAdr ;
assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr;
assign PreLSUBusHWDATA = ReadDataLineSetsM[WordCount];
// exclude the subword write for uncached. We don't read the data first so we cannot
// select the subword by masking. Subword write also exists inside the uncore to
// suport subword masking for i/o. I'm not sure if this is necessary.
assign LSUBusHWDATA = SelUncachedAdr ? FinalAMOWriteDataM : PreLSUBusHWDATA;
if (`XLEN == 32) assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b010;
else assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b011;
busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE)
busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine,
.LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusRead,
.DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);
end
assign LocalLSUBusAdr = SelUncachedAdr ? LSUPAdrM : DCacheBusAdr ;
assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr;
assign PreLSUBusHWDATA = ReadDataLineSetsM[WordCount];
// exclude the subword write for uncached. We don't read the data first so we cannot
// select the subword by masking. Subword write also exists inside the uncore to
// suport subword masking for i/o. I'm not sure if this is necessary.
assign LSUBusHWDATA = SelUncachedAdr ? FinalAMOWriteDataM : PreLSUBusHWDATA;
if (`XLEN == 32) assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b010;
else assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b011;
busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE)
busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine,
.LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusRead,
.DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);
endmodule

View File

@ -56,6 +56,8 @@ module ram #(parameter BASE=0, RANGE = 65535) (
if(`FPGA) begin:ram
initial begin
// *** need to address this preload for fpga. It should work as a preload file
// but for some reason vivado is not synthesizing the preload.
//$readmemh(PRELOAD, RAM);
RAM[0] = 64'h94e1819300002197;
RAM[1] = 64'h4281420141014081;

View File

@ -185,9 +185,9 @@ logic [3:0] dummy;
else meminit = 64'hFEDCBA9876543210;
// *** broken because DTIM also drives RAM
if (`TESTSBP) begin
for (i=MemStartAddr; i<MemEndAddr; i = i+1) begin
dut.uncore.ram.ram.RAM[i] = meminit;
end
for (i=MemStartAddr; i<MemEndAddr; i = i+1) begin
dut.uncore.ram.ram.RAM[i] = meminit;
end
end
// read test vectors into memory
pathname = tvpaths[tests[0].atoi()];
@ -196,6 +196,7 @@ logic [3:0] dummy;
else pathname = tvpaths[1]; */
memfilename = {pathname, tests[test], ".elf.memfile"};
$readmemh(memfilename, dut.uncore.ram.ram.RAM);
//if(`MEM_DTIM == 1) $readmemh(memfilename, dut.hart.lsu.dtim.ram.RAM);
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
$display("Read memfile %s", memfilename);
@ -249,6 +250,7 @@ logic [3:0] dummy;
//$display("signature[%h] = %h", i, signature[i]);
// *** have to figure out how to exclude shadowram when not using a dcache.
if (signature[i] !== dut.uncore.ram.ram.RAM[testadr+i] &
//if (signature[i] !== dut.hart.lsu.dtim.ram.RAM[testadr+i] &
(signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin
if (signature[i+4] !== 'bx | signature[i] !== 32'hFFFFFFFF) begin
// report errors unless they are garbage at the end of the sim
@ -256,6 +258,7 @@ logic [3:0] dummy;
errors = errors+1;
$display(" Error on test %s result %d: adr = %h sim (D$) %h sim (TIM) = %h, signature = %h",
tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.uncore.ram.ram.RAM[testadr+i], signature[i]);
// tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.hart.lsu.dtim.ram.RAM[testadr+i], signature[i]);
$stop;//***debug
end
end
@ -279,6 +282,7 @@ logic [3:0] dummy;
//pathname = tvpaths[tests[0]];
memfilename = {pathname, tests[test], ".elf.memfile"};
$readmemh(memfilename, dut.uncore.ram.ram.RAM);
//if(`MEM_DTIM == 1) $readmemh(memfilename, dut.hart.lsu.dtim.ram.RAM);
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
$display("Read memfile %s", memfilename);