wishbone: make async connector zero-overhead

main
q3k 2022-03-13 14:11:03 +01:00
parent 58d17944af
commit f443b5f575
2 changed files with 25 additions and 6 deletions

View File

@ -39,7 +39,7 @@ endfunction
(* synthesize *)
module mkTbConnectors(Empty);
Wishbone::SlaveConnector#(32, 24, 4) slave <- mkSyncSlaveConnector;
Wishbone::SlaveConnector#(32, 24, 4) slave <- mkAsyncSlaveConnector;
Wishbone::MasterConnector#(32, 24, 4) master <- mkMasterConnector;
mkConnection(slave.slave, master.master);
@ -68,6 +68,7 @@ module mkTbConnectors(Empty);
slave.client.response.put(resp);
endrule
Reg#(Bit#(32)) i <- mkReg(0);
Stmt test = seq
doRead(master, 0);
expectResponse(master, 32'hdeadbeef, "wanted deadbeef");
@ -92,6 +93,10 @@ module mkTbConnectors(Empty);
doRead(master, 1337);
endpar
expectResponse(master, 10, "wanted 10");
for (i <= 0; i < 12; i <= i + 1) seq
noAction;
endseq
endseq;
mkAutoFSM(test);
endmodule

View File

@ -50,7 +50,7 @@ typedef struct {
, numeric type adrSize
, numeric type selSize
)
deriving (Bits);
deriving (Bits, FShow);
typedef struct {
Maybe#(Bit#(datSize)) readData;
@ -157,11 +157,25 @@ module mkSlaveConnector#(Bool sync) (SlaveConnector#(datSize, adrSize, selSize))
let probeDataOut <- mkProbe;
let probeAck <- mkProbe;
rule process_incoming;
Reg#(Bool) pending <- mkReg(False);
Reg#(Bool) pendingFast <- mkWire;
rule process_incoming(!pending);
pending <= True;
pendingFast <= True;
fReq.enq(incoming);
endrule
rule process_outgoing;
if (!sync) begin
rule process_outgoing_fast(pendingFast);
pending <= False;
fRes.deq();
outgoing <= tagged Valid fRes.first();
endrule
end
rule process_outgoing(pending);
pending <= False;
fRes.deq();
outgoing <= tagged Valid fRes.first();
endrule
@ -232,7 +246,7 @@ interface MasterConnector#( numeric type datSize
endinterface
module mkMasterConnector (MasterConnector#(datSize, adrSize, selSize));
FIFO#(SlaveRequest#(datSize, adrSize, selSize)) fReq <- mkPipelineFIFO;
FIFO#(SlaveRequest#(datSize, adrSize, selSize)) fReq <- mkBypassFIFO;
FIFO#(SlaveResponse#(datSize)) fRes <- mkBypassFIFO;
Reg#(Maybe#(SlaveRequest#(datSize, adrSize, selSize))) outgoing <- mkDWire(tagged Invalid);
Reg#(Maybe#(Bit#(datSize))) incoming <- mkDWire(tagged Invalid);
@ -244,7 +258,7 @@ module mkMasterConnector (MasterConnector#(datSize, adrSize, selSize));
rule process_incoming (incoming matches tagged Valid .data);
let pending = fReq.first();
fReq.deq();
let resp = SlaveResponse { readData: tagged Invalid };
if (pending.writeData matches tagged Invalid) begin
resp.readData = tagged Valid data;