From a54c23148998b563ab06c15ed7362e0832741be5 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 3 May 2021 12:03:17 -0500 Subject: [PATCH] Eliminated extra register and fixed ports to icache. Still need to support physical tag check and write in icache memory. Still need to reduce to 1 port SRAM in icache. I would like to refactor the icache code. --- wally-pipelined/regression/wave.do | 59 +++++----- wally-pipelined/src/cache/dmapped.sv | 122 -------------------- wally-pipelined/src/ifu/icache.sv | 164 +++------------------------ wally-pipelined/src/ifu/icacheMem.sv | 124 ++++++++++++++++++++ wally-pipelined/src/ifu/ifu.sv | 8 +- 5 files changed, 175 insertions(+), 302 deletions(-) create mode 100644 wally-pipelined/src/ifu/icacheMem.sv diff --git a/wally-pipelined/regression/wave.do b/wally-pipelined/regression/wave.do index 94e955fe..962f2581 100644 --- a/wally-pipelined/regression/wave.do +++ b/wally-pipelined/regression/wave.do @@ -3,6 +3,7 @@ quietly virtual function -install /testbench/dut/hart/ifu/icache/cachemem -env / quietly WaveActivateNextPane {} 0 add wave -noupdate /testbench/clk add wave -noupdate /testbench/reset +add wave -noupdate /testbench/memfilename add wave -noupdate -expand -group {Execution Stage} /testbench/FunctionName/FunctionName/FunctionName add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName @@ -20,13 +21,13 @@ add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StorePageFaultM add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InterruptM -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/BPPredWrongE -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/RetM -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/TrapM -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/LoadStallD -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/DataStall -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/MulDivStallD +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/RetM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/TrapM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/DataStall +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/MulDivStallD add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushD add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE @@ -37,25 +38,25 @@ add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbe add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallE add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallM add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallW -add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BPPredF -add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BTBValidF -add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BPInstrClassF -add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BTBPredPCF -add wave -noupdate -expand -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/RASPCF -add wave -noupdate -expand -group Bpred -expand -group update -expand -group dir /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/UpdatePC -add wave -noupdate -expand -group Bpred -expand -group update -expand -group dir /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/UpdateEN -add wave -noupdate -expand -group Bpred -expand -group update -expand -group dir /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/UpdatePrediction -add wave -noupdate -expand -group Bpred -expand -group update -expand -group BTB /testbench/dut/hart/ifu/bpred/bpred/TargetPredictor/UpdateEN -add wave -noupdate -expand -group Bpred -expand -group update -expand -group BTB /testbench/dut/hart/ifu/bpred/bpred/TargetPredictor/UpdatePC -add wave -noupdate -expand -group Bpred -expand -group update -expand -group BTB /testbench/dut/hart/ifu/bpred/bpred/TargetPredictor/UpdateTarget -add wave -noupdate -expand -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/TargetWrongE -add wave -noupdate -expand -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/FallThroughWrongE -add wave -noupdate -expand -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/PredictionPCWrongE -add wave -noupdate -expand -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/InstrClassE -add wave -noupdate -expand -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/PredictionInstrClassWrongE -add wave -noupdate -expand -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/BPPredClassNonCFIWrongE -add wave -noupdate -expand -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/BPPredWrongE -add wave -noupdate -expand -group Bpred /testbench/dut/hart/ifu/bpred/bpred/BPPredWrongE +add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BPPredF +add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BTBValidF +add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BPInstrClassF +add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/BTBPredPCF +add wave -noupdate -group Bpred -expand -group prediction /testbench/dut/hart/ifu/bpred/bpred/RASPCF +add wave -noupdate -group Bpred -expand -group update -expand -group dir /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/UpdatePC +add wave -noupdate -group Bpred -expand -group update -expand -group dir /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/UpdateEN +add wave -noupdate -group Bpred -expand -group update -expand -group dir /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/UpdatePrediction +add wave -noupdate -group Bpred -expand -group update -expand -group BTB /testbench/dut/hart/ifu/bpred/bpred/TargetPredictor/UpdateEN +add wave -noupdate -group Bpred -expand -group update -expand -group BTB /testbench/dut/hart/ifu/bpred/bpred/TargetPredictor/UpdatePC +add wave -noupdate -group Bpred -expand -group update -expand -group BTB /testbench/dut/hart/ifu/bpred/bpred/TargetPredictor/UpdateTarget +add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/TargetWrongE +add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/FallThroughWrongE +add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/PredictionPCWrongE +add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/InstrClassE +add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/PredictionInstrClassWrongE +add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/BPPredClassNonCFIWrongE +add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/BPPredWrongE +add wave -noupdate -group Bpred /testbench/dut/hart/ifu/bpred/bpred/BPPredWrongE add wave -noupdate -expand -group {instruction pipeline} /testbench/InstrFName add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrD add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrE @@ -223,8 +224,8 @@ add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDRD add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 2} {5792261 ns} 0} {{Cursor 4} {1318991 ns} 0} -quietly wave cursor active 2 +WaveRestoreCursors {{Cursor 2} {5796691 ns} 0} {{Cursor 4} {1318991 ns} 0} +quietly wave cursor active 1 configure wave -namecolwidth 250 configure wave -valuecolwidth 513 configure wave -justifyvalue left @@ -239,4 +240,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {1311008 ns} {1321254 ns} +WaveRestoreZoom {5795108 ns} {5798036 ns} diff --git a/wally-pipelined/src/cache/dmapped.sv b/wally-pipelined/src/cache/dmapped.sv index 34864d39..f40da412 100644 --- a/wally-pipelined/src/cache/dmapped.sv +++ b/wally-pipelined/src/cache/dmapped.sv @@ -125,128 +125,6 @@ module rodirectmappedmem #(parameter NUMLINES=512, parameter LINESIZE = 256, par assign DataValid = DataValidBit && (DataTag == ReadTag); endmodule -module rodirectmappedmemre #(parameter NUMLINES=512, parameter LINESIZE = 256, parameter WORDSIZE = `XLEN) ( - // Pipeline stuff - input logic clk, - input logic reset, - input logic re, - // If flush is high, invalidate the entire cache - input logic flush, - // Select which address to read (broken for efficiency's sake) - input logic [`XLEN-1:12] ReadUpperPAdr, - input logic [11:0] ReadLowerAdr, - // Write new data to the cache - input logic WriteEnable, - input logic [LINESIZE-1:0] WriteLine, - input logic [`XLEN-1:0] WritePAdr, - // Output the word, as well as if it is valid - output logic [31:0] DataWord, // *** was WORDSIZE-1 - output logic DataValid -); - - // Various compile-time constants - localparam integer WORDWIDTH = $clog2(WORDSIZE/8); - localparam integer OFFSETWIDTH = $clog2(LINESIZE/WORDSIZE); - localparam integer SETWIDTH = $clog2(NUMLINES); - localparam integer TAGWIDTH = `XLEN - OFFSETWIDTH - SETWIDTH - WORDWIDTH; - - localparam integer OFFSETBEGIN = WORDWIDTH; - localparam integer OFFSETEND = OFFSETBEGIN+OFFSETWIDTH-1; - localparam integer SETBEGIN = OFFSETEND+1; - localparam integer SETEND = SETBEGIN + SETWIDTH - 1; - localparam integer TAGBEGIN = SETEND + 1; - localparam integer TAGEND = TAGBEGIN + TAGWIDTH - 1; - - // Machinery to read from and write to the correct addresses in memory - logic [`XLEN-1:0] ReadPAdr; - logic [`XLEN-1:0] OldReadPAdr; - logic [OFFSETWIDTH-1:0] ReadOffset, WriteOffset; - logic [SETWIDTH-1:0] ReadSet, WriteSet; - logic [TAGWIDTH-1:0] ReadTag, WriteTag; - logic [LINESIZE-1:0] ReadLine; - logic [LINESIZE/WORDSIZE-1:0][WORDSIZE-1:0] ReadLineTransformed; - - // Machinery to check if a given read is valid and is the desired value - logic [TAGWIDTH-1:0] DataTag; - logic [NUMLINES-1:0] ValidOut; - logic DataValidBit; - - flopenr #(`XLEN) ReadPAdrFlop(clk, reset, re, ReadPAdr, OldReadPAdr); - - // Assign the read and write addresses in cache memory - always_comb begin - ReadOffset = OldReadPAdr[OFFSETEND:OFFSETBEGIN]; - ReadPAdr = {ReadUpperPAdr, ReadLowerAdr}; - ReadSet = ReadPAdr[SETEND:SETBEGIN]; - ReadTag = OldReadPAdr[TAGEND:TAGBEGIN]; - - WriteOffset = WritePAdr[OFFSETEND:OFFSETBEGIN]; - WriteSet = WritePAdr[SETEND:SETBEGIN]; - WriteTag = WritePAdr[TAGEND:TAGBEGIN]; - end - - // Depth is number of bits in one "word" of the memory, width is number of such words - Sram1Read1Write #(.DEPTH(LINESIZE), .WIDTH(NUMLINES)) cachemem ( - .*, - .ReadAddr(ReadSet), - .ReadData(ReadLine), - .WriteAddr(WriteSet), - .WriteData(WriteLine) - ); - Sram1Read1Write #(.DEPTH(TAGWIDTH), .WIDTH(NUMLINES)) cachetags ( - .*, - .ReadAddr(ReadSet), - .ReadData(DataTag), - .WriteAddr(WriteSet), - .WriteData(WriteTag) - ); - - // Pick the right bits coming out the read line - //assign DataWord = ReadLineTransformed[ReadOffset]; - //logic [31:0] tempRD; - always_comb begin - case (OldReadPAdr[4:1]) - 0: DataWord = ReadLine[31:0]; - 1: DataWord = ReadLine[47:16]; - 2: DataWord = ReadLine[63:32]; - 3: DataWord = ReadLine[79:48]; - - 4: DataWord = ReadLine[95:64]; - 5: DataWord = ReadLine[111:80]; - 6: DataWord = ReadLine[127:96]; - 7: DataWord = ReadLine[143:112]; - - 8: DataWord = ReadLine[159:128]; - 9: DataWord = ReadLine[175:144]; - 10: DataWord = ReadLine[191:160]; - 11: DataWord = ReadLine[207:176]; - - 12: DataWord = ReadLine[223:192]; - 13: DataWord = ReadLine[239:208]; - 14: DataWord = ReadLine[255:224]; - 15: DataWord = {16'b0, ReadLine[255:240]}; - endcase - end - genvar i; - generate - for (i=0; i < LINESIZE/WORDSIZE; i++) begin - assign ReadLineTransformed[i] = ReadLine[(i+1)*WORDSIZE-1:i*WORDSIZE]; - end - endgenerate - - // Correctly handle the valid bits - always_ff @(posedge clk, posedge reset) begin - if (reset || flush) begin - ValidOut <= {NUMLINES{1'b0}}; - end else begin - if (WriteEnable) begin - ValidOut[WriteSet] <= 1; - end - end - DataValidBit <= ValidOut[ReadSet]; - end - assign DataValid = DataValidBit && (DataTag == ReadTag); -endmodule // Write-through direct-mapped memory module wtdirectmappedmem #(parameter NUMLINES=512, parameter LINESIZE = 256, parameter WORDSIZE = `XLEN) ( diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index f524be38..5821b655 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -27,26 +27,24 @@ module icache( // Basic pipeline stuff - input logic clk, reset, - input logic StallF, StallD, - input logic FlushD, - // Upper bits of physical address for PC - input logic [`XLEN-1:12] UpperPCNextPF, - // Lower 12 bits of virtual PC address, since it's faster this way - input logic [11:0] LowerPCNextF, + input logic clk, reset, + input logic StallF, StallD, + input logic FlushD, + input logic [`XLEN-1:0] PCNextF, + input logic [`XLEN-1:0] PCPF, // Data read in from the ebu unit - input logic [`XLEN-1:0] InstrInF, - input logic InstrAckF, + input logic [`XLEN-1:0] InstrInF, + input logic InstrAckF, // Read requested from the ebu unit - output logic [`XLEN-1:0] InstrPAdrF, - output logic InstrReadF, + output logic [`XLEN-1:0] InstrPAdrF, + output logic InstrReadF, // High if the instruction currently in the fetch stage is compressed - output logic CompressedF, + output logic CompressedF, // High if the icache is requesting a stall - output logic ICacheStallF, + output logic ICacheStallF, // The raw (not decompressed) instruction that was requested // If this instruction is compressed, upper 16 bits may be the next 16 bits or may be zeros - output logic [31:0] InstrRawD + output logic [31:0] InstrRawD ); // Configuration parameters @@ -96,10 +94,8 @@ module icachecontroller #(parameter LINESIZE = 256) ( // Input the address to read // The upper bits of the physical pc - input logic [`XLEN-1:12] UpperPCNextPF, - // The lower bits of the virtual pc - input logic [11:0] LowerPCNextF, - + input logic [`XLEN-1:0] PCNextF, + input logic [`XLEN-1:0] PCPF, // Signals to/from cache memory // The read coming out of it input logic [31:0] ICacheMemReadData, @@ -198,7 +194,7 @@ module icachecontroller #(parameter LINESIZE = 256) ( logic [LOGWPL:0] FetchCount, NextFetchCount; - logic [`XLEN-1:0] PCPreFinalF, PCPFinalF, PCSpillF, PCNextPF; + logic [`XLEN-1:0] PCPreFinalF, PCPFinalF, PCSpillF; logic [`XLEN-1:OFFSETWIDTH] PCPTrunkF; @@ -215,7 +211,7 @@ module icachecontroller #(parameter LINESIZE = 256) ( //logic FlushDLastCycleN; //logic PCPMisalignedF; localparam [31:0] NOP = 32'h13; - logic [`XLEN-1:0] PCPF; + //logic [`XLEN-1:0] PCPF; logic reset_q; @@ -224,18 +220,15 @@ module icachecontroller #(parameter LINESIZE = 256) ( //logic MisalignedStall; // Cache fault signals //logic FaultStall; - - assign PCNextPF = {UpperPCNextPF, LowerPCNextF}; - flopenl #(`XLEN) PCPFFlop(clk, reset, SavePC & ~StallF, PCPFinalF, `RESET_VECTOR, PCPF); + //flopenl #(`XLEN) PCPFFlop(clk, reset, SavePC & ~StallF, PCPFinalF, `RESET_VECTOR, PCPF); // on spill we want to get the first 2 bytes of the next cache block. // the spill only occurs if the PCPF mod BlockByteLength == -2. Therefore we can // simply add 2 to land on the next cache block. assign PCSpillF = PCPF + 2'b10; // now we have to select between these three PCs - assign PCPreFinalF = PCMux[0] | StallF ? PCPF : PCNextPF; // *** don't like the stallf - //assign PCPreFinalF = PCMux[0] ? PCPF : PCNextPF; // *** don't like the stallf + assign PCPreFinalF = PCMux[0] | StallF ? PCPF : PCNextF; // *** don't like the stallf assign PCPFinalF = PCMux[1] ? PCSpillF : PCPreFinalF; @@ -247,127 +240,6 @@ module icachecontroller #(parameter LINESIZE = 256) ( assign CompressedF = FinalInstrRawF[1:0] != 2'b11; - // Handle happy path (data in cache, reads aligned) -/* -----\/----- EXCLUDED -----\/----- - - generate - if (`XLEN == 32) begin - assign AlignedInstrRawF = PCPF[1] ? MisalignedInstrRawF : ICacheMemReadData; - //assign PCPMisalignedF = PCPF[1] && ~CompressedF; - end else begin - assign AlignedInstrRawF = PCPF[2] - ? (PCPF[1] ? MisalignedInstrRawF : ICacheMemReadData[63:32]) - : (PCPF[1] ? ICacheMemReadData[47:16] : ICacheMemReadData[31:0]); - //assign PCPMisalignedF = PCPF[2] && PCPF[1] && ~CompressedF; - end - endgenerate - -----/\----- EXCLUDED -----/\----- */ - - //flopenr #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, AlignedInstrRawF, AlignedInstrRawD); - //flopr #(1) FlushDLastCycleFlop(clk, reset, ~FlushD & (FlushDLastCycleN | ~StallF), FlushDLastCycleN); - - //mux2 #(32) InstrRawDMux(AlignedInstrRawD, NOP, ~FlushDLastCycleN, InstrRawD); - - // Stall for faults or misaligned reads -/* -----\/----- EXCLUDED -----\/----- - always_comb begin - assign ICacheStallF = FaultStall | MisalignedStall; - end - -----/\----- EXCLUDED -----/\----- */ - - - // Handle misaligned, noncompressed reads - -/* -----\/----- EXCLUDED -----\/----- - logic MisalignedState, NextMisalignedState; - logic [15:0] MisalignedHalfInstrF; - logic [15:0] UpperHalfWord; - -----/\----- EXCLUDED -----/\----- */ - -/* -----\/----- EXCLUDED -----\/----- - flopenr #(16) MisalignedHalfInstrFlop(clk, reset, ~FaultStall & (PCPMisalignedF & MisalignedState), AlignedInstrRawF[15:0], MisalignedHalfInstrF); - flopenr #(1) MisalignedStateFlop(clk, reset, ~FaultStall, NextMisalignedState, MisalignedState); - -----/\----- EXCLUDED -----/\----- */ - - // When doing a misaligned read, swizzle the bits correctly -/* -----\/----- EXCLUDED -----\/----- - generate - if (`XLEN == 32) begin - assign UpperHalfWord = ICacheMemReadData[31:16]; - end else begin - assign UpperHalfWord = ICacheMemReadData[63:48]; - end - endgenerate - always_comb begin - if (MisalignedState) begin - assign MisalignedInstrRawF = {16'b0, UpperHalfWord}; - end else begin - assign MisalignedInstrRawF = {ICacheMemReadData[15:0], MisalignedHalfInstrF}; - end - end - -----/\----- EXCLUDED -----/\----- */ - - // Manage internal state and stall when necessary -/* -----\/----- EXCLUDED -----\/----- - always_comb begin - assign MisalignedStall = PCPMisalignedF & MisalignedState; - assign NextMisalignedState = ~PCPMisalignedF | ~MisalignedState; - end - -----/\----- EXCLUDED -----/\----- */ - - // Pick the correct address to read -/* -----\/----- EXCLUDED -----\/----- - generate - if (`XLEN == 32) begin - assign ICacheMemReadLowerAdr = {LowerPCNextF[11:2] + (PCPMisalignedF & ~MisalignedState), 2'b00}; - end else begin - assign ICacheMemReadLowerAdr = {LowerPCNextF[11:3] + (PCPMisalignedF & ~MisalignedState), 3'b00}; - end - endgenerate - -----/\----- EXCLUDED -----/\----- */ - // TODO Handle reading instructions that cross page boundaries - //assign ICacheMemReadUpperPAdr = UpperPCNextPF; - - - // Handle cache faults - - -/* -----\/----- EXCLUDED -----\/----- - logic FetchState, BeginFetchState; - logic [LOGWPL:0] FetchWordNum, NextFetchWordNum; - logic [`XLEN-1:0] LineAlignedPCPF; - - flopr #(1) FetchStateFlop(clk, reset, BeginFetchState | (FetchState & ~EndFetchState), FetchState); - flopr #(LOGWPL+1) FetchWordNumFlop(clk, reset, NextFetchWordNum, FetchWordNum); - - - // Enter the fetch state when we hit a cache fault - always_comb begin - BeginFetchState = ~ICacheMemReadValid & ~FetchState & (FetchWordNum == 0); - end - // Exit the fetch state once the cache line has been loaded - flopr #(1) EndFetchStateFlop(clk, reset, ICacheMemWriteEnable, EndFetchState); - - // Machinery to request the correct addresses from main memory - always_comb begin - InstrReadF = FetchState & ~EndFetchState & ~ICacheMemWriteEnable; // next stage logic - LineAlignedPCPF = {ICacheMemReadUpperPAdr, ICacheMemReadLowerAdr[11:OFFSETWIDTH], {OFFSETWIDTH{1'b0}}}; // the fetch address for abh? - InstrPAdrF = LineAlignedPCPF + FetchWordNum*(`XLEN/8); // ? - NextFetchWordNum = FetchState ? FetchWordNum+InstrAckF : {LOGWPL+1{1'b0}}; // convert to enable - end - - // Write to cache memory when we have the line here - always_comb begin - ICacheMemWritePAdr = LineAlignedPCPF; - ICacheMemWriteEnable = FetchWordNum == {1'b1, {LOGWPL{1'b0}}} & FetchState & ~EndFetchState; - end - - // Stall the pipeline while loading a new line from memory - always_comb begin - FaultStall = FetchState | ~ICacheMemReadValid; - end - -----/\----- EXCLUDED -----/\----- */ - // the FSM is always runing, do not stall. flopr #(5) stateReg(.clk(clk), .reset(reset), diff --git a/wally-pipelined/src/ifu/icacheMem.sv b/wally-pipelined/src/ifu/icacheMem.sv new file mode 100644 index 00000000..345e5e45 --- /dev/null +++ b/wally-pipelined/src/ifu/icacheMem.sv @@ -0,0 +1,124 @@ +`include "wally-config.vh" + +module rodirectmappedmemre #(parameter NUMLINES=512, parameter LINESIZE = 256, parameter WORDSIZE = `XLEN) ( + // Pipeline stuff + input logic clk, + input logic reset, + input logic re, + // If flush is high, invalidate the entire cache + input logic flush, + // Select which address to read (broken for efficiency's sake) + input logic [`XLEN-1:12] ReadUpperPAdr, // physical address Must come one cycle later + input logic [11:0] ReadLowerAdr, // virtual address + // Write new data to the cache + input logic WriteEnable, + input logic [LINESIZE-1:0] WriteLine, + input logic [`XLEN-1:0] WritePAdr, + // Output the word, as well as if it is valid + output logic [31:0] DataWord, // *** was WORDSIZE-1 + output logic DataValid +); + + // Various compile-time constants + localparam integer WORDWIDTH = $clog2(WORDSIZE/8); + localparam integer OFFSETWIDTH = $clog2(LINESIZE/WORDSIZE); + localparam integer SETWIDTH = $clog2(NUMLINES); + localparam integer TAGWIDTH = `XLEN - OFFSETWIDTH - SETWIDTH - WORDWIDTH; + + localparam integer OFFSETBEGIN = WORDWIDTH; + localparam integer OFFSETEND = OFFSETBEGIN+OFFSETWIDTH-1; + localparam integer SETBEGIN = OFFSETEND+1; + localparam integer SETEND = SETBEGIN + SETWIDTH - 1; + localparam integer TAGBEGIN = SETEND + 1; + localparam integer TAGEND = TAGBEGIN + TAGWIDTH - 1; + + // Machinery to read from and write to the correct addresses in memory + logic [`XLEN-1:0] ReadPAdr; + logic [`XLEN-1:0] OldReadPAdr; + logic [OFFSETWIDTH-1:0] ReadOffset, WriteOffset; + logic [SETWIDTH-1:0] ReadSet, WriteSet; + logic [TAGWIDTH-1:0] ReadTag, WriteTag; + logic [LINESIZE-1:0] ReadLine; + logic [LINESIZE/WORDSIZE-1:0][WORDSIZE-1:0] ReadLineTransformed; + + // Machinery to check if a given read is valid and is the desired value + logic [TAGWIDTH-1:0] DataTag; + logic [NUMLINES-1:0] ValidOut; + logic DataValidBit; + + flopenr #(`XLEN) ReadPAdrFlop(clk, reset, re, ReadPAdr, OldReadPAdr); + + // Assign the read and write addresses in cache memory + always_comb begin + ReadOffset = OldReadPAdr[OFFSETEND:OFFSETBEGIN]; + ReadPAdr = {ReadUpperPAdr, ReadLowerAdr}; + ReadSet = ReadPAdr[SETEND:SETBEGIN]; + ReadTag = OldReadPAdr[TAGEND:TAGBEGIN]; + + WriteOffset = WritePAdr[OFFSETEND:OFFSETBEGIN]; + WriteSet = WritePAdr[SETEND:SETBEGIN]; + WriteTag = WritePAdr[TAGEND:TAGBEGIN]; + end + + // Depth is number of bits in one "word" of the memory, width is number of such words + Sram1Read1Write #(.DEPTH(LINESIZE), .WIDTH(NUMLINES)) cachemem ( + .*, + .ReadAddr(ReadSet), + .ReadData(ReadLine), + .WriteAddr(WriteSet), + .WriteData(WriteLine) + ); + Sram1Read1Write #(.DEPTH(TAGWIDTH), .WIDTH(NUMLINES)) cachetags ( + .*, + .ReadAddr(ReadSet), + .ReadData(DataTag), + .WriteAddr(WriteSet), + .WriteData(WriteTag) + ); + + // Pick the right bits coming out the read line + //assign DataWord = ReadLineTransformed[ReadOffset]; + //logic [31:0] tempRD; + always_comb begin + case (OldReadPAdr[4:1]) + 0: DataWord = ReadLine[31:0]; + 1: DataWord = ReadLine[47:16]; + 2: DataWord = ReadLine[63:32]; + 3: DataWord = ReadLine[79:48]; + + 4: DataWord = ReadLine[95:64]; + 5: DataWord = ReadLine[111:80]; + 6: DataWord = ReadLine[127:96]; + 7: DataWord = ReadLine[143:112]; + + 8: DataWord = ReadLine[159:128]; + 9: DataWord = ReadLine[175:144]; + 10: DataWord = ReadLine[191:160]; + 11: DataWord = ReadLine[207:176]; + + 12: DataWord = ReadLine[223:192]; + 13: DataWord = ReadLine[239:208]; + 14: DataWord = ReadLine[255:224]; + 15: DataWord = {16'b0, ReadLine[255:240]}; + endcase + end + genvar i; + generate + for (i=0; i < LINESIZE/WORDSIZE; i++) begin + assign ReadLineTransformed[i] = ReadLine[(i+1)*WORDSIZE-1:i*WORDSIZE]; + end + endgenerate + + // Correctly handle the valid bits + always_ff @(posedge clk, posedge reset) begin + if (reset || flush) begin + ValidOut <= {NUMLINES{1'b0}}; + end else begin + if (WriteEnable) begin + ValidOut[WriteSet] <= 1; + end + end + DataValidBit <= ValidOut[ReadSet]; + end + assign DataValid = DataValidBit && (DataTag == ReadTag); +endmodule diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 37120505..25fc478d 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -105,11 +105,9 @@ module ifu ( // jarred 2021-03-14 Add instrution cache block to remove rd2 assign PCNextPF = PCNextF; // Temporary workaround until iTLB is live - icache icache( - .*, - .UpperPCNextPF(PCNextPF[`XLEN-1:12]), - .LowerPCNextF(PCNextPF[11:0]) - ); + icache icache(.*); + + assign PrivilegedChangePCM = RetM | TrapM;