diff --git a/src/Cpu/FetchStage.bsv b/src/Cpu/FetchStage.bsv index 7237920..616359b 100644 --- a/src/Cpu/FetchStage.bsv +++ b/src/Cpu/FetchStage.bsv @@ -1,5 +1,5 @@ import IsaCfg::*; -import MemoryTypes::*; +import MemoryIO::*; import PipelineRegisters::*; import RV_ISA::*; import Trap::*; @@ -10,6 +10,8 @@ import FIFOF::*; import GetPut::*; import Memory::*; +typedef ReadOnlyMemoryRequest#(xlen, 32) InstructionMemoryRequest#(numeric type xlen); + interface FetchStageIfc#(numeric type xlen); method ActionValue#(IF_ID#(xlen)) step(PC_IF#(xlen) pc_if); @@ -23,19 +25,19 @@ module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStageIfc#(xlen)); Reg#(Epoch) requestEpoch <- mkRegU; // Holds the epoch of the initiating request. // Memory request output - Reg#(Maybe#(ReadOnlyMemoryRequest#(xlen))) inflightMemoryRequest <- mkReg(tagged Invalid); - Wire#(ReadOnlyMemoryRequest#(xlen)) memoryRequest <- mkWire; + Reg#(Maybe#(InstructionMemoryRequest#(xlen))) inflightMemoryRequest <- mkReg(tagged Invalid); + Wire#(InstructionMemoryRequest#(xlen)) memoryRequest <- mkWire; // Memory response input (FIFO) // Note: This is an unguarded FIFO so status must be checked before attempting to enq() and deq(). - FIFOF#(ReadOnlyMemoryResponse#(32)) memoryResponses <- mkUGFIFOF1; + FIFOF#(FallibleMemoryResponse#(32)) memoryResponses <- mkUGFIFOF1; // // processMemoryResponse - Takes a memory response and returns an IF_ID containing // the encoded instruction (or a trap if the original request // was denied by the memory system) // - function IF_ID#(xlen) processMemoryResponse(ReadOnlyMemoryResponse#(32) response); + function IF_ID#(xlen) processMemoryResponse(FallibleMemoryResponse#(32) response); IF_ID#(xlen) if_id = defaultValue; if_id.common.pc = inflightMemoryRequest.Valid.address; if_id.npc = updatedPc + 4; @@ -99,8 +101,9 @@ module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStageIfc#(xlen)); if_id.common.trap = tagged Valid(trap); end else begin // Construct a memory request and send it out. - ReadOnlyMemoryRequest#(xlen) request = ReadOnlyMemoryRequest { - address: updatedPc_ + InstructionMemoryRequest#(xlen) request = ReadOnlyMemoryRequest { + address: updatedPc_, + byteen: 'b1111 }; memoryRequest <= request; inflightMemoryRequest <= tagged Valid request; @@ -115,7 +118,7 @@ module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStageIfc#(xlen)); interface ReadOnlyMemoryClient memoryClient; interface Get request = toGet(memoryRequest); interface Put response; - method Action put(ReadOnlyMemoryResponse#(32) response); + method Action put(FallibleMemoryResponse#(32) response); dynamicAssert(memoryResponses.notFull, "FetchStage - attempt to put a memory respnose on a full queue"); memoryResponses.enq(response); endmethod diff --git a/src/Cpu/FetchStage_tb.bsv b/src/Cpu/FetchStage_tb.bsv index 8c574ee..6600fcb 100644 --- a/src/Cpu/FetchStage_tb.bsv +++ b/src/Cpu/FetchStage_tb.bsv @@ -1,6 +1,6 @@ import FetchStage::*; import IsaCfg::*; -import MemoryTypes::*; +import MemoryIO::*; import PipelineRegisters::*; import RV_ISA::*; import Trap::*; @@ -22,7 +22,7 @@ module mkTopModule(Empty); }; FetchStageIfc#(32) fetchStage32 <- mkFetchStage(rv32); - FIFOF#(ReadOnlyMemoryRequest#(32)) memoryRequests32 <- mkUGFIFOF1(); + FIFOF#(InstructionMemoryRequest#(32)) memoryRequests32 <- mkUGFIFOF1(); mkConnection(fetchStage32.memoryClient.request, toPut(asIfc(memoryRequests32))); (* no_implicit_conditions *) @@ -64,7 +64,7 @@ module mkTopModule(Empty); memoryRequests32.deq; dynamicAssert(memoryRequest.address == 'h100, "Fetch - Memory request denied trap check - memory request should have correct address"); - fetchStage32.memoryClient.response.put(ReadOnlyMemoryResponse { + fetchStage32.memoryClient.response.put(FallibleMemoryResponse { data: 'h-1, accessFault: True }); @@ -105,7 +105,7 @@ module mkTopModule(Empty); memoryRequests32.deq; dynamicAssert(memoryRequest.address == 'h100, "Fetch - Normal request - memory request should have correct address"); - fetchStage32.memoryClient.response.put(ReadOnlyMemoryResponse { + fetchStage32.memoryClient.response.put(FallibleMemoryResponse { data: 'haabb_ccdd, accessFault: False }); @@ -146,7 +146,7 @@ module mkTopModule(Empty); memoryRequests32.deq; dynamicAssert(memoryRequest.address == 'h8000, "Fetch - Redirect check - memory request should have correct address"); - fetchStage32.memoryClient.response.put(ReadOnlyMemoryResponse { + fetchStage32.memoryClient.response.put(FallibleMemoryResponse { data: 'haabb_ccee, accessFault: False }); diff --git a/src/Memory/MemoryIO.bsv b/src/Memory/MemoryIO.bsv new file mode 100644 index 0000000..134cec7 --- /dev/null +++ b/src/Memory/MemoryIO.bsv @@ -0,0 +1,25 @@ +import ClientServer::*; +import GetPut::*; +import Memory::*; + +typedef struct { + Bit#(dataSz) data; + Bool accessFault; // The memory request faulted +} FallibleMemoryResponse#(numeric type dataSz) deriving(Bits, Eq, FShow); + +// +// ReadWriteMemory +// +typedef Client#(MemoryRequest#(addrSz, dataSz), FallibleMemoryResponse#(dataSz)) ReadWriteMemoryClient#(numeric type addrSz, numeric type dataSz); +typedef Server#(MemoryRequest#(addrSz, dataSz), FallibleMemoryResponse#(dataSz)) ReadWriteMemoryServer#(numeric type addrSz, numeric type dataSz); + +// +// ReadOnlyMemory +// +typedef struct { + Bit#(TDiv#(dataSz,8)) byteen; + Bit#(addrSz) address; +} ReadOnlyMemoryRequest#(numeric type addrSz, numeric type dataSz) deriving(Bits, Eq, FShow); + +typedef Client#(ReadOnlyMemoryRequest#(addrSz, dataSz), FallibleMemoryResponse#(dataSz)) ReadOnlyMemoryClient#(numeric type addrSz, numeric type dataSz); +typedef Server#(ReadOnlyMemoryRequest#(addrSz, dataSz), FallibleMemoryResponse#(dataSz)) ReadOnlyMemoryServer#(numeric type addrSz, numeric type dataSz); diff --git a/src/Memory/MemoryTypes.bsv b/src/Memory/MemoryTypes.bsv deleted file mode 100644 index 1223f95..0000000 --- a/src/Memory/MemoryTypes.bsv +++ /dev/null @@ -1,13 +0,0 @@ -import ClientServer::*; - -typedef struct { - Bit#(a) address; -} ReadOnlyMemoryRequest#(numeric type a) deriving(Bits, Eq); - -typedef struct { - Bit#(d) data; - Bool accessFault; -} ReadOnlyMemoryResponse#(numeric type d) deriving(Bits, Eq); - -typedef Client#(ReadOnlyMemoryRequest#(a), ReadOnlyMemoryResponse#(d)) - ReadOnlyMemoryClient#(numeric type a, numeric type d);