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
|
endinterface
|
||||||
|
|
||||||
module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStage_Ifc#(xlen));
|
module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStage_Ifc#(xlen));
|
||||||
Reg#(Bool) stall <- mkReg(False);
|
|
||||||
Reg#(Bool) externalStall <- mkReg(False);
|
|
||||||
|
|
||||||
// Memory request output
|
// Memory request output
|
||||||
Reg#(Bool) memoryRequestInFlight <- mkReg(False);
|
Reg#(Bool) memoryRequestInFlight <- mkReg(False);
|
||||||
Wire#(ReadOnlyMemoryRequest#(xlen)) memoryRequest <- mkWire;
|
Wire#(ReadOnlyMemoryRequest#(xlen)) memoryRequest <- mkWire;
|
||||||
@ -28,7 +25,7 @@ module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStage_Ifc#(xlen));
|
|||||||
FIFOF#(ReadOnlyMemoryResponse#(32)) memoryResponses <- mkUGFIFOF1;
|
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
|
// the encoded instruction (or a trap if the original request
|
||||||
// was denied by the memory system)
|
// was denied by the memory system)
|
||||||
//
|
//
|
||||||
@ -53,6 +50,10 @@ module mkFetchStage#(IsaCfg#(xlen) cfg)(FetchStage_Ifc#(xlen));
|
|||||||
return if_id;
|
return if_id;
|
||||||
endfunction
|
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);
|
method ActionValue#(IF_ID#(xlen)) step(PC_IF#(xlen) pc_if);
|
||||||
IF_ID#(xlen) if_id = defaultValue;
|
IF_ID#(xlen) if_id = defaultValue;
|
||||||
if (!pc_if.isBubble) begin
|
if (!pc_if.isBubble) begin
|
||||||
|
|||||||
@ -26,14 +26,6 @@ module mkTopModule(Empty);
|
|||||||
|
|
||||||
mkConnection(fetchStage32.memoryClient.request, toPut(asIfc(memoryRequests32)));
|
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 *)
|
(* no_implicit_conditions *)
|
||||||
rule test;
|
rule test;
|
||||||
PC_IF#(32) pc_if = defaultValue;
|
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