Initial skeleton MemoryAccessStage with testbench.
This commit is contained in:
parent
b236439fbd
commit
c36dfd55ae
@ -16,9 +16,6 @@ interface FetchStage_Ifc#(numeric type xlen);
|
||||
endinterface
|
||||
|
||||
module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStage_Ifc#(xlen));
|
||||
Reg#(Bool) stall <- mkReg(False);
|
||||
Reg#(Bool) externalStall <- mkReg(False);
|
||||
|
||||
// Memory request output
|
||||
Reg#(Bool) memoryRequestInFlight <- mkReg(False);
|
||||
Wire#(ReadOnlyMemoryRequest#(xlen)) memoryRequest <- mkWire;
|
||||
@ -28,7 +25,7 @@ module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStage_Ifc#(xlen));
|
||||
FIFOF#(ReadOnlyMemoryResponse#(32)) memoryResponses <- mkUGFIFOF1;
|
||||
|
||||
//
|
||||
// processMemoryResponse - takes a memory response and returns an IF_ID containing
|
||||
// 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)
|
||||
//
|
||||
@ -53,6 +50,10 @@ module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStage_Ifc#(xlen));
|
||||
return if_id;
|
||||
endfunction
|
||||
|
||||
//
|
||||
// step - Execute fetch step by sending an instruction memory request if one isn't already in flight and
|
||||
// responding to any responses that have returned. If a request is in flight, a bubble is returned.
|
||||
//
|
||||
method ActionValue#(IF_ID#(xlen)) step(PC_IF#(xlen) pc_if);
|
||||
IF_ID#(xlen) if_id = defaultValue;
|
||||
if (!pc_if.isBubble) begin
|
||||
|
||||
@ -26,14 +26,6 @@ module mkTopModule(Empty);
|
||||
|
||||
mkConnection(fetchStage32.memoryClient.request, toPut(asIfc(memoryRequests32)));
|
||||
|
||||
// 64 bit
|
||||
IsaCfg#(64) rv64 = IsaCfg{
|
||||
extN: False,
|
||||
extS: False,
|
||||
extU: False
|
||||
};
|
||||
FetchStage_Ifc#(64) fetchStage64 <- mkFetchStage(rv64);
|
||||
|
||||
(* no_implicit_conditions *)
|
||||
rule test;
|
||||
PC_IF#(32) pc_if = defaultValue;
|
||||
|
||||
43
src/Cpu/MemoryAccessStage.bsv
Normal file
43
src/Cpu/MemoryAccessStage.bsv
Normal file
@ -0,0 +1,43 @@
|
||||
import IsaCfg::*;
|
||||
import PipelineRegisters::*;
|
||||
import RV_ISA::*;
|
||||
import Trap::*;
|
||||
|
||||
import Assert::*;
|
||||
import ClientServer::*;
|
||||
import FIFOF::*;
|
||||
import GetPut::*;
|
||||
import Memory::*;
|
||||
|
||||
interface MemoryAccessStage_Ifc#(numeric type xlen);
|
||||
method ActionValue#(MEM_WB#(xlen)) step(EX_MEM#(xlen) ex_mem);
|
||||
interface MemoryClient#(xlen, xlen) memoryClient;
|
||||
endinterface
|
||||
|
||||
module mkMemoryAccessStage#(IsaCfg#(xlen) cfg)(MemoryAccessStage_Ifc#(xlen));
|
||||
// Memory request output
|
||||
Reg#(Bool) memoryRequestInFlight <- mkReg(False);
|
||||
Wire#(MemoryRequest#(xlen, xlen)) memoryRequest <- mkWire;
|
||||
|
||||
// Memory response input (FIFO)
|
||||
// Note: This is an unguarded FIFO so status much be checked before attempting to enq() and deq().
|
||||
FIFOF#(MemoryResponse#(xlen)) memoryResponses <- mkUGFIFOF1;
|
||||
|
||||
//
|
||||
// step - Execute memory access step by sending a data memory request (if needed) if one isn't already in flight and
|
||||
// responding to any responses that have returned. If a request is in flight, a bubble is returned.
|
||||
//
|
||||
method ActionValue#(MEM_WB#(xlen)) step(EX_MEM#(xlen) ex_mem);
|
||||
return defaultValue;
|
||||
endmethod
|
||||
|
||||
interface MemoryClient memoryClient;
|
||||
interface Get request = toGet(memoryRequest);
|
||||
interface Put response;
|
||||
method Action put(MemoryResponse#(xlen) response);
|
||||
dynamicAssert(memoryResponses.notFull, "MemoryStage - attempt to put a memory respnose on a full queue");
|
||||
memoryResponses.enq(response);
|
||||
endmethod
|
||||
endinterface
|
||||
endinterface
|
||||
endmodule
|
||||
50
src/Cpu/MemoryAccessStage_tb.bsv
Normal file
50
src/Cpu/MemoryAccessStage_tb.bsv
Normal file
@ -0,0 +1,50 @@
|
||||
import MemoryAccessStage::*;
|
||||
import IsaCfg::*;
|
||||
import PipelineRegisters::*;
|
||||
import RV_ISA::*;
|
||||
import Trap::*;
|
||||
|
||||
import Assert::*;
|
||||
import ClientServer::*;
|
||||
import Connectable::*;
|
||||
import FIFOF::*;
|
||||
import GetPut::*;
|
||||
import Memory::*;
|
||||
|
||||
module mkTopModule(Empty);
|
||||
Reg#(Bit#(20)) testNumber <- mkReg(0);
|
||||
|
||||
// 32 bit
|
||||
IsaCfg#(32) rv32 = IsaCfg{
|
||||
extN: False,
|
||||
extS: False,
|
||||
extU: False
|
||||
};
|
||||
MemoryAccessStage_Ifc#(32) memoryAccessStage32 <- mkMemoryAccessStage(rv32);
|
||||
|
||||
FIFOF#(MemoryRequest#(32, 32)) memoryRequests32 <- mkUGFIFOF1();
|
||||
|
||||
mkConnection(memoryAccessStage32.memoryClient.request, toPut(asIfc(memoryRequests32)));
|
||||
|
||||
(* no_implicit_conditions *)
|
||||
rule test;
|
||||
EX_MEM#(32) ex_mem = defaultValue;
|
||||
|
||||
case(testNumber)
|
||||
// Simple bubble passthrough
|
||||
0: begin
|
||||
let mem_wb <- memoryAccessStage32.step(ex_mem);
|
||||
dynamicAssert(mem_wb == defaultValue, "MemoryAccess - Bubble passthrough check");
|
||||
end
|
||||
|
||||
default: begin
|
||||
$display(">>>PASS");
|
||||
$finish();
|
||||
end
|
||||
endcase
|
||||
endrule
|
||||
|
||||
rule increment_test_number;
|
||||
testNumber <= testNumber + 1;
|
||||
endrule
|
||||
endmodule
|
||||
Loading…
x
Reference in New Issue
Block a user