From ed1cf08c9be16cdcabff940b2ddd38617a91bdff Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 25 Jul 2018 04:58:25 +0100 Subject: [PATCH] add libraries --- src/lib/QuadMem.bsv | 58 +++ src/lib/Stack.bsv | 41 ++ src/lib/TxRx.bsv | 300 +++++++++++++ ...xBus_Slave_to_AXI4_Master_Fabric_Types.bsv | 399 ++++++++++++++++++ src/testbench/Memory_AXI4.bsv | 147 +++++++ 5 files changed, 945 insertions(+) create mode 100644 src/lib/QuadMem.bsv create mode 100644 src/lib/Stack.bsv create mode 100644 src/lib/TxRx.bsv create mode 100644 src/testbench/FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv create mode 100644 src/testbench/Memory_AXI4.bsv diff --git a/src/lib/QuadMem.bsv b/src/lib/QuadMem.bsv new file mode 100644 index 0000000..438f559 --- /dev/null +++ b/src/lib/QuadMem.bsv @@ -0,0 +1,58 @@ +/* +Copyright (c) 2013, IIT Madras +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +*/ +package QuadMem; + import defined_types::*; + import BUtils::*; + `include "defined_parameters.bsv" + + interface Ifc_QuadMem; + method Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) response_portA; + method Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) response_portB; + method Action write_portA(Bit#(TMul#(`DCACHE_BLOCK_SIZE,`DCACHE_WORD_SIZE)) we, Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) data); + method Action write_portB(Bit#(TMul#(`DCACHE_BLOCK_SIZE,`DCACHE_WORD_SIZE)) we, Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) data); + endinterface + + (*synthesize*) + module mkQuadMem(Ifc_QuadMem); + Reg#(Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE))) data_reg[3] <-mkCReg(3,0); + + method Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) response_portA; + return data_reg[0]; + endmethod + method Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) response_portB; + return data_reg[1]; + endmethod + method Action write_portA(Bit#(TMul#(`DCACHE_BLOCK_SIZE,`DCACHE_WORD_SIZE)) we, Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) data); + Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) mask=0; + for(Integer i=0;i<32;i=i+1)begin + Bit#(8) ex_we=duplicate(we[i]); + mask[(i*8)+7:i*8]=ex_we; + end + Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) x = mask& data; + Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) y = ~mask& data_reg[0]; + data_reg[0]<=x|y; + endmethod + method Action write_portB(Bit#(TMul#(`DCACHE_BLOCK_SIZE,`DCACHE_WORD_SIZE)) we, Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) data); + Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) mask=0; + for(Integer i=0;i<32;i=i+1)begin + Bit#(8) ex_we=duplicate(we[i]); + mask[(i*8)+7:i*8]=ex_we; + end + Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) x = mask& data; + Bit#(TMul#(TMul#(8,`DCACHE_WORD_SIZE),`DCACHE_BLOCK_SIZE)) y = ~mask& data_reg[1]; + data_reg[1]<=x|y; + endmethod + + endmodule +endpackage diff --git a/src/lib/Stack.bsv b/src/lib/Stack.bsv new file mode 100644 index 0000000..876d628 --- /dev/null +++ b/src/lib/Stack.bsv @@ -0,0 +1,41 @@ +/* +Copyright (c) 2013, IIT Madras +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +*/ +package Stack; + import defined_types::*; + import RegFile::*; + `include "defined_parameters.bsv" + interface Ifc_Stack; + method Action push(Bit#(`VADDR) addr); + method ActionValue#(Bit#(`VADDR)) top; + method Bool empty; + method Action flush; + endinterface + +// (*synthesize*) + module mkStack(Ifc_Stack); + Reg#(Bit#(TLog#(`RAS_DEPTH))) top_index[2] <-mkCReg(2,0); + RegFile#(Bit#(TLog#(`RAS_DEPTH)),Bit#(`VADDR)) array_reg <-mkRegFileWCF(0,fromInteger(`RAS_DEPTH-1)); + method ActionValue#(Bit#(`VADDR)) top; + top_index[0]<=top_index[0]-1; + return array_reg.sub(top_index[0]-1); + endmethod + method Action push(Bit#(`VADDR) addr); + array_reg.upd(top_index[1],addr); + top_index[1]<=top_index[1]+1; + endmethod + method Bool empty; + return (top_index[0]==0); + endmethod + endmodule +endpackage diff --git a/src/lib/TxRx.bsv b/src/lib/TxRx.bsv new file mode 100644 index 0000000..b75a43d --- /dev/null +++ b/src/lib/TxRx.bsv @@ -0,0 +1,300 @@ +/* +Copyright (c) 2013, IIT Madras +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +*/ +// Copyright (c) 2013-2017 Bluespec, Inc. All Rights Reserved + +package TxRx; + +// ================================================================ +// This package allows a separately synthesized module to have direct +// access to an external communication channel via FIFOF-like interfaces +// (methods: notFull, enq, notEmpty, first, deq), +// without the overhead or latency of an internal FIFOs. + +// THE PROBLEM: suppose we want module M1 to send messages to M2 +// Inside M1, we can instantiate a FIFO f1, and enqueue into it, +// and return g1 = toGet (f1) as part of M1's interface. +// Inside M2, we can instantiate a FIFO f2, and dequeue from it, +// and return p2 = toPut (f2) as part of M2's interface. +// Outside, we connect them with mkConnection(g1,p2). +// Problem 1: there are 2 ticks of latency in the communication +// Problem 2: there are at least 2 state elements to hold messages +// Ideally, we'd like to instantiate a FIFO externally, +// and pass it as a parameter to M1 and M2 +// so that M1 can enq to it, and M2 can dequeue from it. +// But then M1 and M2 cannot be separately synthesized. + +// This package provides a solution. +// Terminology: the channel has a tail (enq side) and a head (deq side). +// Inside M1 (for outgoing data): +// Instantiate: TX #(t) tx <- mkTX; +// Use tx.u to send data (methods enq, notFull). +// Export tx.e as part of M1's interface. +// Inside M2 (for incoming data): +// Instantiate: RX #(t) rx <- mkRX; +// Use rx.u to receive data (methods first, deq, notEmpty). +// Export rx.e as part of M2's interface. +// +// Outside, use 'mkChan (buffer_fifof, m1.txe, m2.rxe)' to make an external +// communication channel, passing in a module with a FIFOF +// interface to instantiate the intermediate buffer. +// The buffer could be mkFIFOF, mkPipelineFIFOF, mkSizedFIFOF, ... +// +// You can also connect each to a FIFOF: +// mkConnection (m1.txe, fifof) +// mkConnection (fifof, m2.rxe) + +// ================================================================ +// BSV library imports + +import FIFOF :: *; +import GetPut :: *; +import Connectable :: *; + +// ================================================================ +// TX (sender side) + +// This interface is used by the sender + +interface TXu #(type t); + method Bool notFull; + method Action enq (t x); +endinterface + +instance ToPut #(TXu #(t), t); + function Put #(t) toPut (TXu #(t) f_in); + return interface Put; + method Action put (t x); + f_in.enq (x); + endmethod + endinterface; + endfunction +endinstance + +// This interface is exported by the sender + +(* always_enabled, always_ready *) +interface TXe #(type t); + method Action notFull (Bool b); + method Action enq_rdy (Bool b); + method Bool enq_ena; + method t enq_data; +endinterface + +// ---------------------------------------------------------------- +// Connecting a TXe to an ordinary FIFOF + +instance Connectable #(FIFOF #(t), TXe #(t)); + module mkConnection #(FIFOF #(t) fifo, TXe #(t) txe) + (Empty); + (* fire_when_enabled, no_implicit_conditions *) + rule connect_notFull; + txe.notFull (fifo.notFull); + endrule + + (* fire_when_enabled, no_implicit_conditions *) + rule connect_rdy; + txe.enq_rdy (fifo.notFull); + endrule + + rule connect_ena_data (txe.enq_ena); + fifo.enq (txe.enq_data); + endrule + endmodule +endinstance + +instance Connectable #(TXe #(t), FIFOF #(t)); + module mkConnection #(TXe #(t) txe, FIFOF #(t) fifo) + (Empty); + mkConnection (fifo, txe); + endmodule +endinstance + +// ---------------------------------------------------------------- +// Transactor from TXu to TXe interface + +interface TX #(type t); + interface TXu #(t) u; + interface TXe #(t) e; +endinterface + +module mkTX (TX #(t)) + provisos (Bits #(t, tsz)); + + Wire #(Bool) w_notFull <- mkBypassWire; + Wire #(Bool) w_rdy <- mkBypassWire; + Wire #(Bool) w_ena <- mkDWire (False); + Wire #(t) w_data <- mkDWire (?); + + interface TXu u; + method Bool notFull; + return w_notFull; + endmethod + + method Action enq (t x) if (w_rdy); + w_ena <= True; + w_data <= x; + endmethod + endinterface + + interface TXe e; + method Action notFull (Bool b); + w_notFull <= b; + endmethod + + method Action enq_rdy (Bool b); + w_rdy <= b; + endmethod + + method Bool enq_ena; + return w_ena; + endmethod + + method t enq_data; + return w_data; + endmethod + endinterface +endmodule: mkTX + +// ================================================================ +// RX (receiver side) + +// This interface is used by the receiver + +interface RXu #(type t); + method Bool notEmpty; + method t first; + method Action deq; +endinterface + +instance ToGet #(RXu #(t), t); + function Get #(t) toGet (RXu #(t) f_out); + return interface Get; + method ActionValue #(t) get; + f_out.deq; + return f_out.first; + endmethod + endinterface; + endfunction +endinstance + +// This interface is exported by the receiver + +(* always_enabled, always_ready *) +interface RXe #(type t); + method Action notEmpty (Bool b); + method Action first_deq_rdy (Bool b); + method Action first (t x); + method Bool deq_ena; +endinterface + +// ---------------------------------------------------------------- +// Connecting an ordinary FIFOF to an RXe + +instance Connectable #(FIFOF #(t), RXe #(t)); + module mkConnection #(FIFOF #(t) fifo, RXe #(t) rxe) + (Empty); + (* fire_when_enabled, no_implicit_conditions *) + rule connect_notEmpty; + rxe.notEmpty (fifo.notEmpty); + endrule + + (* fire_when_enabled, no_implicit_conditions *) + rule connect_rdy; + rxe.first_deq_rdy (fifo.notEmpty); + endrule + + rule connect_first; + let data = (fifo.notEmpty ? fifo.first : ?); + rxe.first (data); + endrule + + rule connect_ena (rxe.deq_ena); + fifo.deq; + endrule + endmodule +endinstance + +instance Connectable #(RXe #(t), FIFOF #(t)); + module mkConnection #(RXe #(t) rxe, FIFOF #(t) fifo) + (Empty); + mkConnection (fifo, rxe); + endmodule +endinstance + +// ---------------------------------------------------------------- +// Transactor from RXe to RXu interface + +interface RX #(type t); + interface RXu #(t) u; + interface RXe #(t) e; +endinterface + +module mkRX (RX #(t)) + provisos (Bits #(t, tsz)); + + Wire #(Bool) w_notEmpty <- mkBypassWire; + Wire #(Bool) w_rdy <- mkBypassWire; + Wire #(Bool) w_ena <- mkDWire (False); + Wire #(t) w_data <- mkDWire (?); + + interface RXu u; + method Bool notEmpty; + return w_notEmpty; + endmethod + + method t first if (w_rdy); + return w_data; + endmethod + + method Action deq () if (w_rdy); + w_ena <= True; + endmethod + endinterface + + interface RXe e; + method Action notEmpty (Bool b); + w_notEmpty <= b; + endmethod + + method Action first_deq_rdy (Bool b); + w_rdy <= b; + endmethod + + method Action first (t x); + w_data <= x; + endmethod + + method Bool deq_ena; + return w_ena; + endmethod + endinterface +endmodule: mkRX + +// ================================================================ +// Function to connect TXe to RXe, passing in the +// desired FIFOF constructor for the intermediate buffer + +module mkChan #(module #(FIFOF #(t)) mkFIFOF, + TXe #(t) txe, + RXe #(t) rxe) + (Empty); + + let fifof <- mkFIFOF; + let empty_txe_to_fifof <- mkConnection (txe, fifof); + let empty_fifof_to_rxe <- mkConnection (fifof, rxe); +endmodule: mkChan + +// ================================================================ + +endpackage diff --git a/src/testbench/FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv b/src/testbench/FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv new file mode 100644 index 0000000..e28b5f7 --- /dev/null +++ b/src/testbench/FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv @@ -0,0 +1,399 @@ + +package FlexBus_Slave_to_AXI4_Master_Fabric_Types; + +// ================================================================ +// Exports + +export + +FlexBus_Slave_to_AXI4_Master_Fabric_IFC (..), + +// Transactors from RTL-level interfacecs to FIFO-like interfaces. +mkFlexBus_Slave_to_AXI4_Master_Fabric; + +// ================================================================ +// BSV library imports + +import ConfigReg ::*; +import FIFOF :: *; +import SpecialFIFOs::*; +import Connectable :: *; +import TriState ::*; +`include "defined_parameters.bsv" + +// ---------------- +// BSV additional libs + +import Semi_FIFOF :: *; + +import FlexBus_Types :: *; +import AXI4_Types :: *; + +function Bit#(wd_addr) address_increment(Bit#(8) arlen, Bit#(3) arsize, Bit#(2) arburst, Bit#(wd_addr) address) +provisos( + Add#(a__, 4, wd_addr), + Add#(b__, 3, wd_addr), + Add#(c__, 2, wd_addr)); + // bit_width_size= (2^arsize)*8 + // arburst = 0(FIXED), 1(INCR) and 2(WRAP) + if(arburst==0) // FIXED + return address; + else if(arburst==1)begin // INCR + return address+ (('b1)<