Partial local dtim in lsu configuration.

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

View File

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

View File

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

View File

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

View File

@ -271,7 +271,7 @@ module ifu (
assign ICacheFetchLine = 0; assign ICacheFetchLine = 0;
assign ICacheBusAdr = 0; assign ICacheBusAdr = 0;
assign ICacheStallF = 0; assign ICacheStallF = 0;
assign FinalInstrRawF = 0; if(!`MEM_IROM) assign FinalInstrRawF = 0;
assign ICacheAccess = CacheableF; assign ICacheAccess = CacheableF;
assign ICacheMiss = CacheableF; assign ICacheMiss = CacheableF;
end end
@ -283,26 +283,42 @@ module ifu (
.s(SelUncachedAdr), .s(SelUncachedAdr),
.y(InstrRawF)); .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; if (`MEM_IROM == 1) begin : irom
assign IFUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIFUBusAdr; 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) assign BusStall = 0;
busfsm(.clk, .reset, .IgnoreRequest, assign IFUBusRead = 0;
.LSURWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0), assign ICacheBusAck = 0;
.LSUBusAck(IFUBusAck), assign SelUncachedAdr = 0;
.CPUBusy, .CacheableM(CacheableF),
.BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), .DCacheBusAck(ICacheBusAck), end else begin : bus
.BusCommittedM(), .SelUncachedAdr(SelUncachedAdr), .WordCount); 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 IFUStallF = ICacheStallF | BusStall | SelNextSpill;
assign CPUBusy = StallF & ~SelNextSpill; assign CPUBusy = StallF & ~SelNextSpill;

View File

@ -316,7 +316,7 @@ module lsu
.CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0)); .CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0));
end else begin : passthrough end else begin : passthrough
assign ReadDataWordM = 0; if(!`MEM_DTIM) assign ReadDataWordM = 0;
assign DCacheStall = 0; assign DCacheStall = 0;
assign DCacheMiss = CacheableM; assign DCacheMiss = CacheableM;
assign DCacheAccess = CacheableM; assign DCacheAccess = CacheableM;
@ -357,35 +357,56 @@ module lsu
.HWDATAIN(FinalAMOWriteDataM), .HWDATAIN(FinalAMOWriteDataM),
.HWDATA(FinalWriteDataM)); .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; if (`MEM_DTIM == 1) begin : dtim
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer ram #(
flopen #(`XLEN) fb(.clk, .BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.en(LSUBusAck & LSUBusRead & (index == WordCount)), .HCLK(clk), .HRESETn(~reset),
.d(LSUBusHRDATA), .HSELRam(1'b1), .HADDR(LSUPAdrM[31:0]),
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN])); .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 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 endmodule

View File

@ -56,6 +56,8 @@ module ram #(parameter BASE=0, RANGE = 65535) (
if(`FPGA) begin:ram if(`FPGA) begin:ram
initial begin 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); //$readmemh(PRELOAD, RAM);
RAM[0] = 64'h94e1819300002197; RAM[0] = 64'h94e1819300002197;
RAM[1] = 64'h4281420141014081; RAM[1] = 64'h4281420141014081;

View File

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