diff --git a/wally-pipelined/src/dmem/dcache.sv b/wally-pipelined/src/dmem/dcache.sv deleted file mode 100644 index fec70ef4..00000000 --- a/wally-pipelined/src/dmem/dcache.sv +++ /dev/null @@ -1,184 +0,0 @@ -/////////////////////////////////////////// -// dcache.sv -// -// Written: jaallen@g.hmc.edu 2021-04-15 -// Modified: -// -// Purpose: Cache memory for the dmem so it can access memory less often, saving cycles -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - -`include "wally-config.vh" - -module dcache( - // Basic pipeline stuff - input logic clk, reset, - input logic StallW, - input logic FlushW, - // Upper bits of physical address - input logic [`PA_BITS-1:12] UpperPAdrM, - // Lower 12 bits of virtual address, since it's faster this way - input logic [11:0] LowerVAdrM, - // Write to the dcache - input logic [`XLEN-1:0] DCacheWriteDataM, - input logic DCacheReadM, DCacheWriteM, - // Data read in from the ebu unit - input logic [`XLEN-1:0] ReadDataW, - input logic MemAckW, - // Access requested from the ebu unit - output logic [`PA_BITS-1:0] MemPAdrM, - output logic MemReadM, MemWriteM, - // High if the dcache is requesting a stall - output logic DCacheStallW, - // The data that was requested from the cache - output logic [`XLEN-1:0] DCacheReadW -); - - // Configuration parameters - // TODO Move these to a config file - localparam integer DCACHELINESIZE = 256; - localparam integer DCACHENUMLINES = 512; - - // Input signals to cache memory - logic FlushMem; - logic [`PA_BITS-1:12] DCacheMemUpperPAdr; - logic [11:0] DCacheMemLowerAdr; - logic DCacheMemWriteEnable; - logic [DCACHELINESIZE-1:0] DCacheMemWriteData; - logic [`XLEN-1:0] DCacheMemWritePAdr; - logic EndFetchState; - // Output signals from cache memory - logic [`XLEN-1:0] DCacheMemReadData; - logic DCacheMemReadValid; - - wtdirectmappedmem #(.LINESIZE(DCACHELINESIZE), .NUMLINES(DCACHENUMLINES), .WORDSIZE(`XLEN)) cachemem( - .*, - // Stall it if the pipeline is stalled, unless we're stalling it and we're ending our stall - .stall(StallW), - .flush(FlushMem), - .ReadUpperPAdr(DCacheMemUpperPAdr), - .ReadLowerAdr(DCacheMemLowerAdr), - .LoadEnable(DCacheMemWriteEnable), - .LoadLine(DCacheMemWriteData), - .LoadPAdr(DCacheMemWritePAdr), - .DataWord(DCacheMemReadData), - .DataValid(DCacheMemReadValid), - .WriteEnable(0), - .WriteWord(0), - .WritePAdr(0), - .WriteSize(2'b10) - ); - - dcachecontroller #(.LINESIZE(DCACHELINESIZE)) controller(.*); - - // For now, assume no writes to executable memory - assign FlushMem = 1'b0; -endmodule - -module dcachecontroller #(parameter LINESIZE = 256) ( - // Inputs from pipeline - input logic clk, reset, - input logic StallW, - input logic FlushW, - - // Input the address to read - // The upper bits of the physical pc - input logic [`PA_BITS-1:12] DCacheMemUpperPAdr, - // The lower bits of the virtual pc - input logic [11:0] DCacheMemLowerAdr, - - // Signals to/from cache memory - // The read coming out of it - input logic [`XLEN-1:0] DCacheMemReadData, - input logic DCacheMemReadValid, - // Load data into the cache - output logic DCacheMemWriteEnable, - output logic [LINESIZE-1:0] DCacheMemWriteData, - output logic [`XLEN-1:0] DCacheMemWritePAdr, - - // The read that was requested - output logic [31:0] DCacheReadW, - - // Outputs to pipeline control stuff - output logic DCacheStallW, EndFetchState, - - // Signals to/from ahblite interface - // A read containing the requested data - input logic [`XLEN-1:0] ReadDataW, - input logic MemAckW, - // The read we request from main memory - output logic [`PA_BITS-1:0] MemPAdrM, - output logic MemReadM, MemWriteM -); - - // Cache fault signals - logic FaultStall; - - // Handle happy path (data in cache) - - always_comb begin - DCacheReadW = DCacheMemReadData; - end - - - // Handle cache faults - - localparam integer WORDSPERLINE = LINESIZE/`XLEN; - localparam integer LOGWPL = $clog2(WORDSPERLINE); - localparam integer OFFSETWIDTH = $clog2(LINESIZE/8); - - logic FetchState, BeginFetchState; - logic [LOGWPL:0] FetchWordNum, NextFetchWordNum; - logic [`PA_BITS-1:0] LineAlignedPCPF; - - flopr #(1) FetchStateFlop(clk, reset, BeginFetchState | (FetchState & ~EndFetchState), FetchState); - flopr #(LOGWPL+1) FetchWordNumFlop(clk, reset, NextFetchWordNum, FetchWordNum); - - genvar i; - generate - for (i=0; i < WORDSPERLINE; i++) begin - flopenr #(`XLEN) flop(clk, reset, FetchState & (i == FetchWordNum), ReadDataW, DCacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN]); - end - endgenerate - - // Enter the fetch state when we hit a cache fault - always_comb begin - BeginFetchState = ~DCacheMemReadValid & ~FetchState & (FetchWordNum == 0); - end - // Exit the fetch state once the cache line has been loaded - flopr #(1) EndFetchStateFlop(clk, reset, DCacheMemWriteEnable, EndFetchState); - - // Machinery to request the correct addresses from main memory - always_comb begin - MemReadM = FetchState & ~EndFetchState & ~DCacheMemWriteEnable; - LineAlignedPCPF = {DCacheMemUpperPAdr, DCacheMemLowerAdr[11:OFFSETWIDTH], {OFFSETWIDTH{1'b0}}}; - MemPAdrM = LineAlignedPCPF + FetchWordNum*(`XLEN/8); - NextFetchWordNum = FetchState ? FetchWordNum+MemAckW : {LOGWPL+1{1'b0}}; - end - - // Write to cache memory when we have the line here - always_comb begin - DCacheMemWritePAdr = LineAlignedPCPF; - DCacheMemWriteEnable = FetchWordNum == {1'b1, {LOGWPL{1'b0}}} & FetchState & ~EndFetchState; - end - - // Stall the pipeline while loading a new line from memory - always_comb begin - DCacheStallW = FetchState | ~DCacheMemReadValid; - end -endmodule diff --git a/wally-pipelined/src/dmem/dmem.sv b/wally-pipelined/src/dmem/dmem.sv deleted file mode 100644 index 7f19bc78..00000000 --- a/wally-pipelined/src/dmem/dmem.sv +++ /dev/null @@ -1,197 +0,0 @@ -/////////////////////////////////////////// -// dmem.sv -// -// Written: David_Harris@hmc.edu 9 January 2021 -// Modified: -// -// Purpose: Data memory -// Top level of the memory-stage hart logic -// Contains data cache, DTLB, subword read/write datapath, interface to external bus -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - -`include "wally-config.vh" - -// *** Ross Thompson amo misalignment check? -module dmem ( - input logic clk, reset, - input logic StallM, FlushM, StallW, FlushW, - //output logic DataStall, - // Memory Stage - input logic [1:0] MemRWM, - input logic [`XLEN-1:0] MemAdrM, - input logic [2:0] Funct3M, - //input logic [`XLEN-1:0] ReadDataW, - input logic [`XLEN-1:0] WriteDataM, - input logic [1:0] AtomicM, - input logic CommitM, - output logic [`PA_BITS-1:0] MemPAdrM, - output logic MemReadM, MemWriteM, - output logic [1:0] AtomicMaskedM, - output logic DataMisalignedM, - output logic CommittedM, - // Writeback Stage - input logic MemAckW, - input logic [`XLEN-1:0] ReadDataW, - output logic SquashSCW, - // faults - input logic NonBusTrapM, - input logic DataAccessFaultM, - output logic DTLBLoadPageFaultM, DTLBStorePageFaultM, - output logic LoadMisalignedFaultM, LoadAccessFaultM, - output logic StoreMisalignedFaultM, StoreAccessFaultM, - - // mmu management - input logic [1:0] PrivilegeModeW, - input logic [`XLEN-1:0] PageTableEntryM, - input logic [1:0] PageTypeM, - input logic [`XLEN-1:0] SATP_REGW, - input logic STATUS_MXR, STATUS_SUM, - input logic DTLBWriteM, DTLBFlushM, - output logic DTLBMissM, DTLBHitM, - - // PMA/PMP (inside mmu) signals - input logic [31:0] HADDR, // *** replace all of these H inputs with physical adress once pma checkers have been edited to use paddr as well. - input logic [2:0] HSIZE, HBURST, - input logic HWRITE, - input logic AtomicAccessM, WriteAccessM, ReadAccessM, // execute access is hardwired to zero in this mmu because we're only working with data in the M stage. - input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem - input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // *** this one especially has a large note attached to it in pmpchecker. - - output logic PMALoadAccessFaultM, PMAStoreAccessFaultM, - output logic PMPLoadAccessFaultM, PMPStoreAccessFaultM, // *** can these be parameterized? we dont need the m stage ones for the immu and vice versa. - - output logic DSquashBusAccessM, - output logic [5:0] DHSELRegionsM - -); - - logic SquashSCM; - logic DTLBPageFaultM; - logic MemAccessM; - logic [1:0] CurrState, NextState; - logic preCommittedM; - - localparam STATE_READY = 0; - localparam STATE_FETCH = 1; - localparam STATE_FETCH_AMO = 2; - localparam STATE_STALLED = 3; - - logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem - // *** if you're allowed to parameterize outputs/ inputs existence, these are an easy delete. - - mmu #(.ENTRY_BITS(`DTLB_ENTRY_BITS), .IMMU(0)) dmmu(.TLBAccessType(MemRWM), .VirtualAddress(MemAdrM), .Size(Funct3M[1:0]), - .PTEWriteVal(PageTableEntryM), .PageTypeWriteVal(PageTypeM), - .TLBWrite(DTLBWriteM), .TLBFlush(DTLBFlushM), - .PhysicalAddress(MemPAdrM), .TLBMiss(DTLBMissM), - .TLBHit(DTLBHitM), .TLBPageFault(DTLBPageFaultM), - - .ExecuteAccessF(1'b0), - .SquashBusAccess(DSquashBusAccessM), .HSELRegions(DHSELRegionsM), - .*); // *** the pma/pmp instruction acess faults don't really matter here. is it possible to parameterize which outputs exist? - - // Specify which type of page fault is occurring - assign DTLBLoadPageFaultM = DTLBPageFaultM & MemRWM[1]; - assign DTLBStorePageFaultM = DTLBPageFaultM & MemRWM[0]; - - // Determine if an Unaligned access is taking place - always_comb - case(Funct3M[1:0]) - 2'b00: DataMisalignedM = 0; // lb, sb, lbu - 2'b01: DataMisalignedM = MemAdrM[0]; // lh, sh, lhu - 2'b10: DataMisalignedM = MemAdrM[1] | MemAdrM[0]; // lw, sw, flw, fsw, lwu - 2'b11: DataMisalignedM = |MemAdrM[2:0]; // ld, sd, fld, fsd - endcase - - // Squash unaligned data accesses and failed store conditionals - // *** this is also the place to squash if the cache is hit - // Changed DataMisalignedM to a larger combination of trap sources - // NonBusTrapM is anything that the bus doesn't contribute to producing - // By contrast, using TrapM results in circular logic errors - assign MemReadM = MemRWM[1] & ~NonBusTrapM & CurrState != STATE_STALLED; - assign MemWriteM = MemRWM[0] & ~NonBusTrapM && ~SquashSCM & CurrState != STATE_STALLED; - assign AtomicMaskedM = CurrState != STATE_STALLED ? AtomicM : 2'b00 ; - assign MemAccessM = |MemRWM; - - // Determine if M stage committed - // Reset whenever unstalled. Set when access successfully occurs - flopr #(1) committedMreg(clk,reset,(CommittedM | CommitM) & StallM,preCommittedM); - assign CommittedM = preCommittedM | CommitM; - - // Determine if address is valid - assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1]; - assign LoadAccessFaultM = DataAccessFaultM & MemRWM[1]; - assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0]; - assign StoreAccessFaultM = DataAccessFaultM & MemRWM[0]; - - // Handle atomic load reserved / store conditional - generate - if (`A_SUPPORTED) begin // atomic instructions supported - logic [`PA_BITS-1:2] ReservationPAdrW; - logic ReservationValidM, ReservationValidW; - logic lrM, scM, WriteAdrMatchM; - - assign lrM = MemReadM && AtomicM[0]; - assign scM = MemRWM[0] && AtomicM[0]; - assign WriteAdrMatchM = MemRWM[0] && (MemPAdrM[`PA_BITS-1:2] == ReservationPAdrW) && ReservationValidW; - assign SquashSCM = scM && ~WriteAdrMatchM; - always_comb begin // ReservationValidM (next value of valid reservation) - if (lrM) ReservationValidM = 1; // set valid on load reserve - else if (scM || WriteAdrMatchM) ReservationValidM = 0; // clear valid on store to same address or any sc - else ReservationValidM = ReservationValidW; // otherwise don't change valid - end - flopenrc #(`PA_BITS-2) resadrreg(clk, reset, FlushW, lrM, MemPAdrM[`PA_BITS-1:2], ReservationPAdrW); // could drop clear on this one but not valid - flopenrc #(1) resvldreg(clk, reset, FlushW, lrM, ReservationValidM, ReservationValidW); - flopenrc #(1) squashreg(clk, reset, FlushW, ~StallW, SquashSCM, SquashSCW); - end else begin // Atomic operations not supported - assign SquashSCM = 0; - assign SquashSCW = 0; - end - endgenerate - - // Data stall - //assign DataStall = 0; - - // Ross Thompson April 22, 2021 - // for now we need to handle the issue where the data memory interface repeately - // requests data from memory rather than issuing a single request. - - - flopr #(2) stateReg(.clk(clk), - .reset(reset), - .d(NextState), - .q(CurrState)); - - always_comb begin - case (CurrState) - STATE_READY: if (MemRWM[1] & MemRWM[0]) NextState = STATE_FETCH_AMO; // *** should be some misalign check - else if (MemAccessM & ~DataMisalignedM) NextState = STATE_FETCH; - else NextState = STATE_READY; - STATE_FETCH_AMO: if (MemAckW) NextState = STATE_FETCH; - else NextState = STATE_FETCH_AMO; - STATE_FETCH: if (MemAckW & ~StallW) NextState = STATE_READY; - else if (MemAckW & StallW) NextState = STATE_STALLED; - else NextState = STATE_FETCH; - STATE_STALLED: if (~StallW) NextState = STATE_READY; - else NextState = STATE_STALLED; - default: NextState = STATE_READY; - endcase // case (CurrState) - end - -endmodule - diff --git a/wally-pipelined/src/mmu/adrdec.sv b/wally-pipelined/src/mmu/adrdec.sv deleted file mode 100644 index 7e4423ec..00000000 --- a/wally-pipelined/src/mmu/adrdec.sv +++ /dev/null @@ -1,44 +0,0 @@ -/////////////////////////////////////////// -// adrdec.sv -// -// Written: David_Harris@hmc.edu 29 January 2021 -// Modified: -// -// Purpose: Address decoder -// -// A component of the Wally configurable RISC-V project. -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - -`include "wally-config.vh" - -module adrdec ( - input logic [31:0] HADDR, - input logic [31:0] Base, Range, - output logic HSEL -); - - logic [31:0] match; - - // determine if an address is in a range starting at the base - // for example, if Base = 0x04002000 and range = 0x00000FFF, - // then anything address between 0x04002000 and 0x04002FFF should match (HSEL=1) - - assign match = (HADDR ~^ Base) | Range; - assign HSEL = &match; - -endmodule - diff --git a/wally-pipelined/src/mmu/pmpadrdec.sv b/wally-pipelined/src/mmu/pmpadrdec.sv index f9e86cdc..f3e874a3 100644 --- a/wally-pipelined/src/mmu/pmpadrdec.sv +++ b/wally-pipelined/src/mmu/pmpadrdec.sv @@ -65,7 +65,9 @@ module pmpadrdec ( assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP; // Naturally aligned four-byte region - adrdec na4dec(HADDR, CurrentAdrFull, (2**2)-1, NA4Match); + // *** need to switch to Physical Address and extend to proper number of bits + assign NA4Match = &(HADDR[31:2] ~^ CurrentAdrFull[31:2]); // check if address matches all but bottom 2 bits; + //adrdec na4dec(HADDR, CurrentAdrFull, (2**2)-1, NA4Match); generate if (`XLEN == 32 || `XLEN == 64) begin @@ -116,7 +118,8 @@ module pmpadrdec ( // *** Range should not be truncated... but our physical address space is // currently only 32 bits wide. - adrdec napotdec(HADDR, CurrentAdrFull, Range[31:0], NAPOTMatch); + // with a bit of combining of range selection, this could be shared with NA4Match *** + assign NAPOTMatch = &((HADDR ~^ CurrentAdrFull) | Range[31:0]); assign Match = (AdrMode == TOR) ? TORMatch : (AdrMode == NA4) ? NA4Match : diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index b63fbc21..232c7a03 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -163,7 +163,7 @@ module wallypipelinedhart ( mux2 #(`XLEN) OutputInput2mux(WriteDataM, FWriteDataM, FMemRWM[0], WriteDatatmpM); - dmem dmem(.MemRWM(MemRWM|FMemRWM), .WriteDataM(WriteDatatmpM),.*); // data cache unit + lsu lsu(.MemRWM(MemRWM|FMemRWM), .WriteDataM(WriteDatatmpM),.*); // data cache unit ahblite ebu( //.InstrReadF(1'b0),