Commit cc4a9925 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

swcore: adding Switched-Multiported-RAM from github

https://github.com/AmeerAbdelhadi/Switched-Multiported-RAM
Commit 2a460ed
parent fbf88efd
......@@ -37,7 +37,7 @@ files = [
];
modules = {"local": ["mpm"]}
modules = {"local": ["mpm", "Switched-Multiported-RAM"]}
if (action == "simulation"):
......
Copyright (c) 2014, the University of British Columbia. 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 the University of British Columbia (UBC) 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 UNIVERSITY OF BRITISH COLUMBIA 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.
files = [ "utils.vh", "dpram.v", "dpram_bbs.v", "lvt_1ht.v", "lvt_bin.v",
"lvt_reg.v", "mpram_lvt.v", "mpram_reg.v", "mrram.v", "mrram_swt.v" ]
This diff is collapsed.
This diff is collapsed.
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// dpram.v: Generic dual-ported RAM //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module dpram
#( parameter MEMD = 16, // memory depth
parameter DATW = 32, // data width
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over FILE)
parameter FILE = "" // initialization hex file (don't pass extension), optional
)( input clk , // clock
input WEnb_A , // write enable for port A
input WEnb_B , // write enable for port B
input [`log2(MEMD)-1:0] Addr_A , // address for port A
input [`log2(MEMD)-1:0] Addr_B , // address for port B
input [DATW -1:0] WData_A, // write data for port A
input [DATW -1:0] WData_B, // write data for port B
output reg [DATW -1:0] RData_A, // read data for port A
output reg [DATW -1:0] RData_B // read data for port B
);
// initialize RAM, with zeros if ZERO or file if FILE.
integer i;
reg [DATW-1:0] mem [0:MEMD-1]; // memory array
initial
if (ZERO)
for (i=0; i<MEMD; i=i+1) mem[i] = {DATW{1'b0}};
else
if (FILE != "") $readmemh({FILE,".hex"}, mem);
// PORT A
always @(posedge clk) begin
// write/read; nonblocking statement to read old data
if (WEnb_A) begin
mem[Addr_A] <= WData_A; // Change into blocking statement (=) to read new data
RData_A <= WData_A; // flow-through
end else
RData_A <= mem[Addr_A]; //Change into blocking statement (=) to read new data
end
// PORT B
always @(posedge clk) begin
// write/read; nonblocking statement to read old data
if (WEnb_B) begin
mem[Addr_B] <= WData_B; // Change into blocking statement (=) to read new data
RData_B <= WData_B; // flow-through
end else
RData_B <= mem[Addr_B]; //Change into blocking statement (=) to read new data
end
endmodule
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// dpram_bbs.v: Generic dual-ported RAM with optional 1-stage or 2-stage bypass //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module dpram_bbs
#( parameter MEMD = 16, // memory depth
parameter DATW = 32, // data width
parameter BYPS = 1 , // bypass? 0:none; 1: single-stage; 2: two-stage
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over FILE)
parameter FILE = "" // initialization hex file (don't pass extension), optional
)( input clk , // clock
input WEnb_A , // write enable for port A
input WEnb_B , // write enable for port B
input [`log2(MEMD)-1:0] Addr_A , // write addresses - packed from nWP write ports
input [`log2(MEMD)-1:0] Addr_B , // write addresses - packed from nWP write ports
input [DATW -1:0] WData_A, // write data - packed from nRP read ports
input [DATW -1:0] WData_B, // write data - packed from nRP read ports
output reg [DATW -1:0] RData_A, // read data - packed from nRP read ports
output reg [DATW -1:0] RData_B // read data - packed from nRP read ports
);
wire [DATW-1:0] RData_Ai; // read ram data (internal) / port A
wire [DATW-1:0] RData_Bi; // read ram data (internal) - port B
dpram #( .MEMD (MEMD ), // memory depth
.DATW (DATW ), // data width
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over INITFILE)
.FILE (FILE )) // initializtion file, optional
dprami ( .clk (clk ), // clock
.WEnb_A (WEnb_A ), // write enable / port A - in
.WEnb_B (WEnb_B ), // write enable / port B - in
.Addr_A (Addr_A ), // write address / port A - in [`log2(MEMD)-1:0]
.Addr_B (Addr_B ), // write address / port B - in [`log2(MEMD)-1:0]
.WData_A(WData_A ), // write data / port A - in [DATW -1:0]
.WData_B(WData_B ), // write data / port B - in [DATW -1:0]
.RData_A(RData_Ai), // read data / port A - in [DATW -1:0]
.RData_B(RData_Bi)); // read data / port B - in [DATW -1:0]
// registers; will be removed if unused
reg WEnb_Ar;
reg WEnb_Br;
reg [`log2(MEMD)-1:0] Addr_Ar;
reg [`log2(MEMD)-1:0] Addr_Br;
reg [DATW-1:0] WData_Br;
reg [DATW-1:0] WData_Ar;
always @(posedge clk) begin
WEnb_Ar <= WEnb_A ;
WEnb_Br <= WEnb_B ;
Addr_Ar <= Addr_A;
Addr_Br <= Addr_B;
WData_Ar <= WData_A; // bypass register
WData_Br <= WData_B; // bypass register
end
// bypass: single-staeg, two-stage (logic will be removed if unused)
wire bypsA1,bypsA2,bypsB1,bypsB2;
assign bypsA1 = (BYPS >= 1) && WEnb_Br && !WEnb_Ar && (Addr_Br == Addr_Ar);
assign bypsA2 = (BYPS == 2) && WEnb_B && !WEnb_Ar && (Addr_B == Addr_Ar);
assign bypsB1 = (BYPS >= 1) && WEnb_Ar && !WEnb_Br && (Addr_Ar == Addr_Br);
assign bypsB2 = (BYPS == 2) && WEnb_A && !WEnb_Br && (Addr_A == Addr_Br);
// output mux (mux or mux inputs will be removed if unused)
always @*
if (bypsA2) RData_A = WData_B ;
else if (bypsA1) RData_A = WData_Br;
else RData_A = RData_Ai;
always @*
if (bypsB2) RData_B = WData_A ;
else if (bypsB1) RData_B = WData_Ar;
else RData_B = RData_Bi;
endmodule
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// lvt_1ht.v: Onehot-coded LVT (Live-Value-Table) //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module lvt_1ht
#( parameter MEMD = 16, // memory depth
parameter nRP = 1 , // number of reading ports
parameter nWP = 3 , // number of writing ports
parameter WAWB = 1 , // allow Write-After-Write (need to bypass feedback ram)
parameter RAWB = 1 , // new data for Read-after-Write (need to bypass output ram)
parameter RDWB = 0 , // new data for Read-During-Write
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over FILE)
parameter FILE = "" // initialization file, optional
)( input clk , // clock
input [ nWP-1:0] WEnb , // write enable for each writing port
input [`log2(MEMD)*nWP-1:0] WAddr, // write addresses - packed from nWP write ports
input [`log2(MEMD)*nRP-1:0] RAddr, // read addresses - packed from nRP read ports
output reg [nWP *nRP-1:0] RBank); // read bank selector - packed from nRP read ports
localparam ADRW = `log2(MEMD); // address width
localparam LVTW = nWP - 1 ; // required memory width
// Register write addresses, data and enables
reg [ADRW*nWP-1:0] WAddr_r; // registered write addresses - packed from nWP write ports
reg [ nWP-1:0] WEnb_r ; // registered write enable for each writing port
always @(posedge clk) begin
WAddr_r <= WAddr;
WEnb_r <= WEnb ;
end
// unpacked/pack addresses and data
reg [ADRW -1:0] WAddr2D [nWP-1:0] ; // write addresses / 2D
reg [ADRW -1:0] WAddr2D_r [nWP-1:0] ; // registered write addresses / 2D
wire [LVTW*nRP -1:0] RDataOut2D [nWP-1:0] ; // read data out / 2D
reg [LVTW -1:0] RDataOut3D [nWP-1:0][nRP -1:0]; // read data out / 3D
reg [ADRW*LVTW-1:0] RAddrFB2D [nWP-1:0] ; // read address fb / 2D
reg [ADRW -1:0] RAddrFB3D [nWP-1:0][LVTW-1:0]; // read address fb / 3D
wire [LVTW*LVTW-1:0] RDataFB2D [nWP-1:0] ; // read data fb / 2D
reg [LVTW -1:0] RDataFB3D [nWP-1:0][LVTW-1:0]; // read data fb / 3D
reg [LVTW -1:0] WDataFB2D [nWP-1:0] ; // write data / 2D
reg [LVTW -1:0] InvData2D [nWP-1:0] ; // write data / 2D
reg [nWP -1:0] RBank2D [nRP-1:0] ; // read bank selector / 2D
`ARRINIT;
always @* begin
// packing/unpacking arrays into 1D/2D/3D structures; see utils.vh for definitions
`ARR1D2D(nWP, ADRW, WAddr , WAddr2D );
`ARR1D2D(nWP, ADRW, WAddr_r , WAddr2D_r );
`ARR2D1D(nRP, nWP , RBank2D , RBank );
`ARR2D3D(nWP, nRP , LVTW, RDataOut2D, RDataOut3D);
`ARR3D2D(nWP, LVTW, ADRW, RAddrFB3D , RAddrFB2D );
`ARR2D3D(nWP, LVTW, LVTW, RDataFB2D , RDataFB3D );
end
// generate and instantiate mulriread BRAMs
genvar wpi;
generate
for (wpi=0 ; wpi<nWP ; wpi=wpi+1) begin: RPORTwpi
// feedback multiread ram instantiation
mrram #( .MEMD (MEMD ), // memory depth
.DATW (LVTW ), // data width
.nRP (nWP-1 ), // number of reading ports
.BYPS (WAWB||RDWB||RAWB), // bypass? 0:none; 1:single-stage; 2:two-stages
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over FILE)
.FILE (FILE )) // initialization file, optional
mrram_fdb ( .clk (clk ), // clock - in
.WEnb (WEnb_r[wpi] ), // write enable (1 port) - in
.WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0]
.WData (WDataFB2D[wpi] ), // write data (1 port) - in : [LVTW -1:0]
.RAddr (RAddrFB2D[wpi] ), // read addresses - packed from nRP read ports - in : [`log2(MEMD)*nRP-1:0]
.RData (RDataFB2D[wpi] )); // read data - packed from nRP read ports - out: [LVTW *nRP-1:0]
// output multiread ram instantiation
mrram #( .MEMD (MEMD ), // memory depth
.DATW (LVTW ), // data width
.nRP (nRP ), // number of reading ports
.BYPS (RDWB ? 2 : RAWB), // bypass? 0:none; 1:single-stage; 2:two-stages
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over FILE)
.FILE (FILE )) // initialization file, optional
mrram_out ( .clk (clk ), // clock - in
.WEnb (WEnb_r[wpi] ), // write enable (1 port) - in
.WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0]
.WData (WDataFB2D[wpi] ), // write data (1 port) - in : [LVTW -1:0]
.RAddr (RAddr ), // read addresses - packed from nRP read ports - in : [`log2(MEMD)*nRP-1:0]
.RData (RDataOut2D[wpi])); // read data - packed from nRP read ports - out: [LVTW *nRP-1:0]
end
endgenerate
// combinatorial logic for output and feedback functions
integer wp; // write port counter
integer wf; // write feedback counter
integer rf; // read feedback counter
integer rp; // read port counter
integer lv; // lvt bit counter
integer fi; // feedback bit index
always @* begin
// generate inversion vector
for(wp=0;wp<nWP;wp=wp+1) InvData2D[wp] = (1<<wp)-1; // 2^wp-1
// initialize output read bank
for(rp=0;rp<nRP;rp=rp+1)
for(wp=0;wp<nWP;wp=wp+1)
RBank2D[rp][wp] = 1;
// generate feedback functions
for(wp=0;wp<nWP;wp=wp+1) begin
wf = 0;
for(lv=0;lv<LVTW;lv=lv+1) begin
wf=wf+(lv==wp);
rf=wp-(wf<wp);
fi=wp-(InvData2D[wp][lv]);
RAddrFB3D[wp][lv] = WAddr2D[wf];
WDataFB2D[wp][lv] = RDataFB3D[wf][rf][fi] ^ InvData2D[wp][lv];
for(rp=0;rp<nRP;rp=rp+1) RBank2D[rp][wp] = RBank2D[rp][wp] && (( RDataOut3D[wf][rp][fi] ^ InvData2D[wp][lv]) == RDataOut3D[wp][rp][lv]);
wf=wf+1;
end
end
end
endmodule
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// lvt_bin.v: Binary-coded LVT (Live-Value-Table) //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module lvt_bin
#( parameter MEMD = 16, // memory depth
parameter nRP = 2 , // number of reading ports
parameter nWP = 2 , // number of writing ports
parameter WAWB = 1 , // allow Write-After-Write (need to bypass feedback ram)
parameter RAWB = 1 , // new data for Read-after-Write (need to bypass output ram)
parameter RDWB = 0 , // new data for Read-During-Write
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over FILE)
parameter FILE = "" // initialization file, optional
)( input clk , // clock
input [ nWP-1:0] WEnb , // write enable for each writing port
input [`log2(MEMD)*nWP-1:0] WAddr, // write addresses - packed from nWP write ports
input [`log2(MEMD)*nRP-1:0] RAddr, // read addresses - packed from nRP read ports
output reg [`log2(nWP )*nRP-1:0] RBank); // read data - packed from nRP read ports
localparam ADRW = `log2(MEMD); // address width
localparam LVTW = `log2(nWP ); // required memory width
// Generate Bank ID's to write into LVT
wire [LVTW-1:0] WData2D [nWP-1:0];
genvar gi;
generate
for (gi=0;gi<nWP;gi=gi+1) begin: GenerateID
assign WData2D[gi]=gi;
end
endgenerate
// Register write addresses, data and enables
reg [ADRW*nWP-1:0] WAddr_r; // registered write addresses - packed from nWP write ports
reg [ nWP-1:0] WEnb_r ; // registered write enable for each writing port
always @(posedge clk) begin
WAddr_r <= WAddr;
WEnb_r <= WEnb ;
end
// unpacked/pack addresses/data
reg [ADRW -1:0] WAddr2D [nWP-1:0] ; // write addresses / 2D
reg [ADRW -1:0] WAddr2D_r [nWP-1:0] ; // registered write addresses / 2D
wire [LVTW* nRP -1:0] RDataOut2D [nWP-1:0] ; // read data out / 2D
reg [LVTW -1:0] RDataOut3D [nWP-1:0][nRP-1:0]; // read data out / 3D
reg [ADRW*(nWP-1)-1:0] RAddrFB2D [nWP-1:0] ; // read address fb / 2D
reg [ADRW -1:0] RAddrFB3D [nWP-1:0][nWP-2:0]; // read address fb / 3D
wire [LVTW*(nWP-1)-1:0] RDataFB2D [nWP-1:0] ; // read data fb / 2D
reg [LVTW -1:0] RDataFB3D [nWP-1:0][nWP-2:0]; // read data fb / 3D
reg [LVTW -1:0] WDataFB2D [nWP-1:0] ; // write data / 2D
reg [LVTW -1:0] RBank2D [nRP-1:0] ; // read data / 2D
`ARRINIT;
always @* begin
// packing/unpacking arrays into 1D/2D/3D structures; see utils.vh for definitions
`ARR1D2D(nWP, ADRW,WAddr ,WAddr2D );
`ARR1D2D(nWP, ADRW,WAddr_r ,WAddr2D_r );
`ARR2D1D(nRP, LVTW,RBank2D ,RBank );
`ARR2D3D(nWP,nRP ,LVTW,RDataOut2D,RDataOut3D);
`ARR3D2D(nWP,nWP-1,ADRW,RAddrFB3D ,RAddrFB2D );
`ARR2D3D(nWP,nWP-1,LVTW,RDataFB2D ,RDataFB3D );
end
// generate and instantiate mulriread BRAMs
genvar wpi;
generate
for (wpi=0 ; wpi<nWP ; wpi=wpi+1) begin: RPORTwpi
// feedback multiread ram instantiation
mrram #( .MEMD (MEMD ), // memory depth
.DATW (LVTW ), // data width
.nRP (nWP-1 ), // number of reading ports
.BYPS (WAWB||RDWB||RAWB), // bypass? 0:none; 1:single-stage; 2:two-stages
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over FILE)
.FILE (FILE )) // initialization file, optional
mrram_fbk ( .clk (clk ), // clock - in
.WEnb (WEnb_r[wpi] ), // write enable (1 port) - in
.WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0]
.WData (WDataFB2D[wpi] ), // write data (1 port) - in : [LVTW -1:0]
.RAddr (RAddrFB2D[wpi] ), // read addresses - packed from nRP read ports - in : [`log2(MEMD)*nRP-1:0]
.RData (RDataFB2D[wpi] )); // read data - packed from nRP read ports - out: [LVTW *nRP-1:0]
// output multiread ram instantiation
mrram #( .MEMD (MEMD ), // memory depth
.DATW (LVTW ), // data width
.nRP (nRP ), // number of reading ports
.BYPS (RDWB ? 2 : RAWB), // bypass? 0:none; 1:single-stage; 2:two-stages
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over FILE)
.FILE (FILE )) // initialization file, optional
mrram_out ( .clk (clk ), // clock - in
.WEnb (WEnb_r[wpi] ), // write enable (1 port) - in
.WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0]
.WData (WDataFB2D[wpi] ), // write data (1 port) - in : [LVTW -1:0]
.RAddr (RAddr ), // read addresses - packed from nRP read ports - in : [`log2(MEMD)*nRP-1:0]
.RData (RDataOut2D[wpi])); // read data - packed from nRP read ports - out: [LVTW *nRP-1:0]
end
endgenerate
// combinatorial logic for output and feedback functions
integer i,j,k;
always @* begin
// generate output read functions
for(i=0;i<nRP;i=i+1) begin
RBank2D[i] = RDataOut3D[0][i];
for(j=1;j<nWP;j=j+1) RBank2D[i] = RBank2D[i] ^ RDataOut3D[j][i];
end
// generate feedback functions
for(i=0;i<nWP;i=i+1) WDataFB2D[i] = WData2D[i];
for(i=0;i<nWP;i=i+1) begin
k = 0;
for(j=0;j<nWP-1;j=j+1) begin
k=k+(j==i);
RAddrFB3D[i][j] = WAddr2D[k];
WDataFB2D[k] = WDataFB2D[k] ^ RDataFB3D[i][j];
k=k+1;
end
end
end
endmodule
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// lvt_reg.v: Register-based binary-coded LVT (Live-Value-Table) //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module lvt_reg
#( parameter MEMD = 16, // memory depth
parameter nRP = 2 , // number of reading ports
parameter nWP = 2 , // number of writing ports
parameter RDWB = 0 , // new data for Read-During-Write
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over FILE)
parameter FILE = "" // initialization file, optional
)( input clk , // clock
input [ nWP-1:0] WEnb , // write enable for each writing port
input [`log2(MEMD)*nWP-1:0] WAddr, // write addresses - packed from nWP write ports
input [`log2(MEMD)*nRP-1:0] RAddr, // read addresses - packed from nRP read ports
output [`log2(nWP )*nRP-1:0] RBank); // read bank selector - packed from nRP read ports
localparam ADRW = `log2(MEMD); // address width
localparam LVTW = `log2(nWP ); // required memory width
// Generate Bank ID's to write into LVT
reg [LVTW*nWP-1:0] WData1D ;
wire [LVTW -1:0] WData2D [nWP-1:0];
genvar gi;
generate
for (gi=0;gi<nWP;gi=gi+1) begin: GenerateID
assign WData2D[gi]=gi;
end
endgenerate
// packing/unpacking arrays into 1D/2D/3D structures; see utils.vh for definitions
// pack ID's into 1D array
`ARRINIT;
always @* `ARR2D1D(nWP,LVTW,WData2D,WData1D);
mpram_reg #( .MEMD (MEMD ), // memory depth
.DATW (LVTW ), // data width
.nRP (nRP ), // number of reading ports
.nWP (nWP ), // number of writing ports
.RDWB (RDWB ), // provide new data when Read-During-Write?
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over FILE)
.FILE (FILE )) // initialization file, optional
mpram_reg_ins ( .clk (clk ), // clock - in
.WEnb (WEnb ), // write enable for each writing port - in : [ nWP-1:0]
.WAddr (WAddr ), // write addresses - packed from nWP write ports - in : [ADRW*nWP-1:0]
.WData (WData1D), // write data - packed from nRP read ports - in : [LVTW*nWP-1:0]
.RAddr (RAddr ), // read addresses - packed from nRP read ports - in : [ADRW*nRP-1:0]
.RData (RBank )); // read data - packed from nRP read ports - out: [LVTW*nRP-1:0]
endmodule
This diff is collapsed.
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// mpram_reg.v: generic register-based multiported-RAM. //
// Reading addresses are registered and old data will be read in case of RAW. //
// Implemented in FF's if the number of reading or writing ports exceeds one. //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module mpram_reg
#( parameter MEMD = 16, // memory depth
parameter DATW = 32, // data width
parameter nRP = 3 , // number of reading ports
parameter nWP = 2 , // number of writing ports
parameter RDWB = 0 , // provide new data when Read-During-Write?
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over INITFILE)
parameter FILE = "" // initialization hex file (don't pass extension), optional
)( input clk , // clock
input [nWP-1:0 ] WEnb , // write enable for each writing port
input [`log2(MEMD)*nWP-1:0] WAddr, // write addresses - packed from nWP write ports
input [DATW *nWP-1:0] WData, // write data - packed from nRP read ports
input [`log2(MEMD)*nRP-1:0] RAddr, // read addresses - packed from nRP read ports
output reg [DATW *nRP-1:0] RData // read data - packed from nRP read ports
);
localparam ADRW = `log2(MEMD); // address width
integer i;
// initialize RAM, with zeros if ZERO or file if IFLE.
(* ramstyle = "logic" *) reg [DATW-1:0] mem [0:MEMD-1]; // memory array; implemented with logic cells (registers)
initial
if (ZERO)
for (i=0; i<MEMD; i=i+1) mem[i] = {DATW{1'b0}};
else
if (FILE != "") $readmemh({FILE,".hex"}, mem);
always @(posedge clk) begin
// write to nWP ports; nonblocking statement to read old data
for (i=1; i<=nWP; i=i+1)
if (WEnb[i-1])
if (RDWB) mem[WAddr[i*ADRW-1 -: ADRW]] = WData[i*DATW-1 -: DATW]; // blocking statement (= ) to read new data
else mem[WAddr[i*ADRW-1 -: ADRW]] <= WData[i*DATW-1 -: DATW]; // non-blocking statement (<=) to read old data
// Read from nRP ports; nonblocking statement to read old data
for (i=1; i<=nRP; i=i+1)
if (RDWB) RData[i*DATW-1 -: DATW] = mem[RAddr[i*ADRW-1 -: ADRW]]; // blocking statement (= ) to read new data
else RData[i*DATW-1 -: DATW] <= mem[RAddr[i*ADRW-1 -: ADRW]]; //non-blocking statement (<=) to read old data
end
endmodule
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// mpram_xor.v: Multiported-RAM based on XOR implementation //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module mpram_xor
#( parameter MEMD = 16, // memory depth
parameter DATW = 32, // data width
parameter nRP = 2 , // number of reading ports
parameter nWP = 2 , // number of writing ports
parameter WAWB = 1 , // allow Write-After-Write (need to bypass feedback ram)
parameter RAWB = 1 , // new data for Read-after-Write (need to bypass output ram)
parameter RDWB = 0 , // new data for Read-During-Write
parameter FILE = "" // initialization file, optional
)( input clk , // clock
input [nWP-1:0 ] WEnb , // write enable for each writing port
input [`log2(MEMD)*nWP-1:0] WAddr, // write addresses - packed from nWP write ports
input [DATW *nWP-1:0] WData, // write data - packed from nWP read ports
input [`log2(MEMD)*nRP-1:0] RAddr, // read addresses - packed from nRP read ports
output reg [DATW *nRP-1:0] RData); // read data - packed from nRP read ports
localparam ADRW = `log2(MEMD); // address width
// Register write addresses, data and enables
reg [ADRW*nWP-1:0] WAddr_r; // registered write addresses - packed from nWP write ports
reg [DATW*nWP-1:0] WData_r; // registered write data - packed from nWP read ports
reg [ nWP-1:0] WEnb_r ; // registered write enable for each writing port
always @(posedge clk) begin
WAddr_r <= WAddr;
WData_r <= WData;
WEnb_r <= WEnb ;
end
// unpacked/pack addresses/data
reg [ADRW -1:0] WAddr2D [nWP-1:0] ; // write addresses / 2D
reg [ADRW -1:0] WAddr2D_r [nWP-1:0] ; // registered write addresses / 2D
reg [DATW -1:0] WData2D [nWP-1:0] ; // write data / 2D
reg [DATW -1:0] WData2D_r [nWP-1:0] ; // registered write data / 2D
wire [DATW* nRP -1:0] RDataOut2D [nWP-1:0] ; // read data out / 2D
reg [DATW -1:0] RDataOut3D [nWP-1:0][nRP-1:0]; // read data out / 3D
reg [ADRW*(nWP-1)-1:0] RAddrFB2D [nWP-1:0] ; // read address fb / 2D
reg [ADRW -1:0] RAddrFB3D [nWP-1:0][nWP-2:0]; // read address fb / 3D
wire [DATW*(nWP-1)-1:0] RDataFB2D [nWP-1:0] ; // read data fb / 2D
reg [DATW -1:0] RDataFB3D [nWP-1:0][nWP-2:0]; // read data fb / 3D
reg [DATW -1:0] WDataFB2D [nWP-1:0] ; // write data / 2D
reg [DATW -1:0] RData2D [nRP-1:0] ; // read data / 2D
`ARRINIT;
always @* begin
// packing/unpacking arrays into 1D/2D/3D structures; see utils.vh for definitions
`ARR1D2D(nWP, ADRW,WAddr ,WAddr2D );
`ARR1D2D(nWP, ADRW,WAddr_r ,WAddr2D_r );
`ARR1D2D(nWP, DATW,WData ,WData2D );
`ARR1D2D(nWP, DATW,WData_r ,WData2D_r );
`ARR2D1D(nRP, DATW,RData2D ,RData );
`ARR2D3D(nWP,nRP ,DATW,RDataOut2D,RDataOut3D);
`ARR3D2D(nWP,nWP-1,ADRW,RAddrFB3D ,RAddrFB2D );
`ARR2D3D(nWP,nWP-1,DATW,RDataFB2D ,RDataFB3D );
end
// generate and instantiate mulriread RAM blocks
genvar wpi;
generate
for (wpi=0 ; wpi<nWP ; wpi=wpi+1) begin: RPORTwpi
// feedback multiread ram instantiation
mrram #( .MEMD (MEMD ), // memory depth
.DATW (DATW ), // data width
.nRP (nWP-1 ), // number of reading ports
.BYPS (WAWB || RDWB || RAWB), // bypass? 0:none; 1:single-stage; 2:two-stages
.ZERO ((wpi>0)&&(FILE!="") ), // binary / Initial RAM with zeros (has priority over FILE)
.FILE (FILE )) // initialization file, optional
mrram_fdb ( .clk (clk ), // clock - in
.WEnb (WEnb_r[wpi] ), // write enable (1 port) - in
.WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0]
.WData (WDataFB2D[wpi] ), // write data (1 port) - in : [DATW -1:0]
.RAddr (RAddrFB2D[wpi] ), // read addresses - packed from nRP read ports - in : [`log2(MEMD)*nRP-1:0]
.RData (RDataFB2D[wpi] )); // read data - packed from nRP read ports - out: [DATW *nRP-1:0]
// output multiread ram instantiation
mrram #( .MEMD (MEMD ), // memory depth
.DATW (DATW ), // data width
.nRP (nRP ), // number of reading ports
.BYPS (RDWB ? 2 : RAWB ), // bypass? 0:none; 1:single-stage; 2:two-stages
.ZERO ((wpi>0)&&(FILE!="") ), // binary / Initial RAM with zeros (has priority over FILE)
.FILE (FILE )) // initialization file, optional
mrram_out ( .clk (clk ), // clock - in
.WEnb (WEnb_r[wpi] ), // write enable (1 port) - in
.WAddr (WAddr2D_r[wpi] ), // write address (1 port) - in : [`log2(MEMD) -1:0]
.WData (WDataFB2D[wpi] ), // write data (1 port) - in : [DATW -1:0]
.RAddr (RAddr ), // read addresses - packed from nRP read ports - in : [`log2(MEMD)*nRP-1:0]
.RData (RDataOut2D[wpi] )); // read data - packed from nRP read ports - out: [DATW *nRP-1:0]
end
endgenerate
// combinatorial logic for output and feedback functions
integer i,j,k;
always @* begin
// generate output read functions
for(i=0;i<nRP;i=i+1) begin
RData2D[i] = RDataOut3D[0][i];
for(j=1;j<nWP;j=j+1) RData2D[i] = RData2D[i] ^ RDataOut3D[j][i];
end
// generate feedback functions
for(i=0;i<nWP;i=i+1) WDataFB2D[i] = WData2D_r[i];
for(i=0;i<nWP;i=i+1) begin
k = 0;
for(j=0;j<nWP-1;j=j+1) begin
k=k+(j==i);
RAddrFB3D[i][j] = WAddr2D[k];
WDataFB2D[k] = WDataFB2D[k] ^ RDataFB3D[i][j];
k=k+1;
end
end
end
endmodule
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// mrram.v: Multiread-RAM based on bank replication using generic dual-ported RAM //
// with optional single-stage or two-stage bypass/ for normal mode ports //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module mrram
#( parameter MEMD = 16, // memory depth
parameter DATW = 32, // data width
parameter nRP = 3 , // number of reading ports
parameter BYPS = 1 , // bypass? 0:none; 1: single-stage; 2:two-stages
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over FILE)
parameter FILE = "" // initialization mif file (don't pass extension), optional
)( input clk , // clock
input WEnb , // write enable (1 port)
input [`log2(MEMD) -1:0] WAddr, // write address (1 port)
input [DATW -1:0] WData, // write data (1 port)
input [`log2(MEMD)*nRP-1:0] RAddr, // read addresses - packed from nRP read ports
output reg [DATW *nRP-1:0] RData); // read data - packed from nRP read ports
localparam ADRW = `log2(MEMD); // address width
// unpacked read addresses/data
reg [ADRW-1:0] RAddr_upk [nRP-1:0]; // read addresses - unpacked 2D array
wire [DATW-1:0] RData_upk [nRP-1:0]; // read data - unpacked 2D array
// unpack read addresses; pack read data
`ARRINIT;
always @* begin
// packing/unpacking arrays into 1D/2D/3D structures; see utils.vh for definitions
`ARR1D2D(nRP,ADRW,RAddr,RAddr_upk);
`ARR2D1D(nRP,DATW,RData_upk,RData);
end
// generate and instantiate generic RAM blocks
genvar rpi;
generate
for (rpi=0 ; rpi<nRP ; rpi=rpi+1) begin: RPORTrpi
// generic dual-ported ram instantiation
dpram_bbs #( .MEMD (MEMD ), // memory depth
.DATW (DATW ), // data width
.BYPS (BYPS ), // bypass? 0: none; 1: single-stage; 2:two-stages
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over INITFILE)
.FILE (FILE )) // initialization file, optional
dpram_bbsi ( .clk (clk ), // clock - in
.WEnb_A (1'b0 ), // write enable - in
.WEnb_B (WEnb ), // write enable - in
.Addr_A (RAddr_upk[rpi]), // write address - in : [`log2(MEMD)-1:0]
.Addr_B (WAddr ), // write address - in : [`log2(MEMD)-1:0]
.WData_A ({DATW{1'b1}} ), // write data - in : [DATW -1:0] / constant
.WData_B (WData ), // write data - in : [DATW -1:0]
.RData_A (RData_upk[rpi]), // read data - out: [DATW -1:0]
.RData_B ( )); // read data - out: [DATW -1:0]
end
endgenerate
endmodule
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// mrram_swt.v: Multiread-RAM based on bank replication & generic dual-ported RAM //
// * switched read ports support //
// * optional single-stage or 2-stage bypass //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`include "utils.vh"
module mrram_swt
#( parameter MEMD = 16, // memory depth
parameter DATW = 32, // data width
parameter nRPF = 2 , // number of fixed read ports
parameter nRPS = 2 , // number of switched read ports
parameter BYPS = 1 , // bypass? 0:none; 1: single-stage; 2:two-stages
parameter ZERO = 0 , // binary / Initial RAM with zeros (has priority over FILE)
parameter FILE = "" // initialization mif file (don't pass extension), optional
)( input clk , // clock
input rdWr , // switch read/write (write is active low)
input WEnb , // write enable (1 port)
input [`log2(MEMD) -1:0] WAddr, // write address (1 port)
input [DATW -1:0] WData, // write data (1 port)
input [`log2(MEMD)*(nRPS+nRPF)-1:0] RAddr, // read addresses - packed from nRPF fixed & nRPS switched read ports
output reg [DATW *(nRPS+nRPF)-1:0] RData); // read data - packed from nRPF fixed & nRPS switched read ports
localparam nRPT = nRPS+nRPF ; // total number of read ports
localparam ADRW = `log2(MEMD); // address width
// unpacked read addresses/data
reg [ADRW-1:0] RAddr_upk [nRPT-1:0]; // read addresses - unpacked 2D array
wire [DATW-1:0] RData_upk [nRPT-1:0]; // read data - unpacked 2D array
// unpack read addresses; pack read data
`ARRINIT;
always @* begin
// packing/unpacking arrays into 1D/2D/3D structures; see utils.vh for definitions
`ARR1D2D(nRPT,ADRW,RAddr,RAddr_upk);
`ARR2D1D(nRPT,DATW,RData_upk,RData);
end
// generate and instantiate generic RAM blocks
genvar rpi;
generate
for (rpi=0 ; rpi<nRPF ; rpi=rpi+1) begin: RPORTrpi
// generic dual-ported ram instantiation
if (rpi<(nRPF-nRPS)) begin
dpram_bbs #( .MEMD (MEMD ), // memory depth
.DATW (DATW ), // data width
.BYPS (BYPS ), // bypass? 0: none; 1: single-stage; 2:two-stages
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over INITFILE)
.FILE (FILE )) // initialization file, optional
dpram_bbsi ( .clk (clk ), // clock - in
.WEnb_A (1'b0 ), // write enable - in
.WEnb_B (WEnb && (!rdWr)), // write enable - in
.Addr_A (RAddr_upk[rpi] ), // write address - in : [`log2(MEMD)-1:0]
.Addr_B (WAddr ), // write address - in : [`log2(MEMD)-1:0]
.WData_A ({DATW{1'b1}} ), // change to 1'b0
.WData_B (WData ), // write data - in : [DATW -1:0]
.RData_A (RData_upk[rpi] ), // read data - out: [DATW -1:0]
.RData_B ( )); // read data - out: [DATW -1:0]
end
else begin
dpram_bbs #( .MEMD (MEMD ), // memory depth
.DATW (DATW ), // data width
.BYPS (BYPS ), // bypass? 0: none; 1: single-stage; 2:two-stages
.ZERO (ZERO ), // binary / Initial RAM with zeros (has priority over INITFILE)
.FILE (FILE )) // initialization file, optional
dpram_bbsi ( .clk (clk ), // clock - in
.WEnb_A (1'b0 ), // write enable - in
.WEnb_B (WEnb && (!rdWr) ), // write enable - in
.Addr_A ( RAddr_upk[rpi] ), // write address - in : [`log2(MEMD)-1:0]
.Addr_B (rdWr?RAddr_upk[rpi+nRPS]:WAddr), // write address - in : [`log2(MEMD)-1:0]
.WData_A ({DATW{1'b1}} ), // change to 1'b0
.WData_B (WData ), // write data - in : [DATW -1:0]
.RData_A (RData_upk[rpi] ), // read data - out: [DATW -1:0]
.RData_B (RData_upk[rpi+nRPS] )); // read data - out: [DATW -1:0]
end
end
endgenerate
endmodule
####################################################################################
## Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. ##
####################################################################################
####################################################################################
## Synopsys Design Constraints File ( .sdc ) ##
## Design constraints and timing assignments ##
## ##
## Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) ##
## Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 ##
####################################################################################
# Clock constraints
create_clock -name "clk" -period 1.000ns [get_ports {clk}]
# Automatically constrain PLL and other generated clocks
derive_pll_clocks -create_base_clocks
# Automatically calculate clock uncertainty to jitter and other effects.
derive_clock_uncertainty
# tsu/th constraints
#set_input_delay -clock "clk" -max 0.8ns [get_ports {wAddr}]
#set_input_delay -clock "clk" -min 0.100ns [get_ports {wAddr}]
# tco constraints
#set_output_delay -clock "clk" -max 0.8ns [get_ports {rData}]
#set_output_delay -clock "clk" -min -0.100ns [get_ports {rData}]
# disable input/output combinatorial timing (all ports are registered)
set_disable_timing -from [all_inputs] *
set_disable_timing -to [all_outputs] *
This diff is collapsed.
This diff is collapsed.
////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014, University of British Columbia (UBC); 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 the University of British Columbia (UBC) 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 University of British Columbia (UBC) 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. //
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// utils.vh: Design utilities (pre-compile) //
// //
// Author: Ameer M.S. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
// Switched SRAM-based Multi-ported RAM; University of British Columbia, 2014 //
////////////////////////////////////////////////////////////////////////////////////
`ifndef __UTILS_VH__
`define __UTILS_VH__
`define DEBUG_MODE // debug mode, comment this line for other modes
`define VERBOSE // verbose debug, comment this line for other modes
// Initiate Array structure - use once before calling packing/unpacking modules
`define ARRINIT integer _i_,_j_
// pack/unpack 1D/2D/3D arrays; use in "always @*" if combinatorial
// ARR2D1D: converts an array of vectors (2D) into a vector (1D) - (2D to 1D packing )
// ARR1D2D: converts a vector (1D) into an array of vectors (2D) - (1D to 2D unpacking)
// ARR2D3D: converts an array of vectors (2D) into a 2D array of vectors (3D) - (2D to 3D unpacking)
// ARR3D2D: converts a 2D array of vectors (3D) into an array of vectors (2D) - (3D to 2D packing )
`define ARR2D1D(D1W,D2W, SRC,DST) for(_i_=1;_i_<=(D1W);_i_=_i_+1) DST[((D2W)*_i_-1)-:D2W] = SRC[_i_-1]
`define ARR1D2D(D1W,D2W, SRC,DST) for(_i_=1;_i_<=(D1W);_i_=_i_+1) DST[_i_-1] = SRC[((D2W)*_i_-1)-:D2W]
`define ARR2D3D(D1W,D2W,D3W,SRC,DST) for(_i_=0;_i_< (D1W);_i_=_i_+1) for(_j_=1;_j_<=(D2W);_j_=_j_+1) DST[_i_][_j_-1] = SRC[_i_][((D3W)*_j_-1)-:D3W]
`define ARR3D2D(D1W,D2W,D3W,SRC,DST) for(_i_=0;_i_< (D1W);_i_=_i_+1) for(_j_=1;_j_<=(D2W);_j_=_j_+1) DST[_i_][((D3W)*_j_-1)-:D3W] = SRC[_i_][_j_-1]
// print a 2-D array in a comma-delimited list
`define ARRPRN(ARRLEN,PRNSRC) for (_i_=(ARRLEN)-1;_i_>=0;_i_=_i_-1) $write("%c%h%c",(_i_==(ARRLEN)-1)?"[":"",PRNSRC[_i_],!_i_?"]":",")
// Initialize a vector with a specific width random number; extra bits are zero padded
`define GETRAND(RAND,RANDW) RAND=0; repeat ((RANDW)/32) RAND=(RAND<<32)|{$random}; RAND=(RAND<<((RANDW)%32))|({$random}>>(32-(RANDW)%32))
// factorial (n!)
`define fact(n) ( ( ((n) >= 2 ) ? 2 : 1) * \
( ((n) >= 3 ) ? 3 : 1) * \
( ((n) >= 4 ) ? 4 : 1) * \
( ((n) >= 5 ) ? 5 : 1) * \
( ((n) >= 6 ) ? 6 : 1) * \
( ((n) >= 7 ) ? 7 : 1) * \
( ((n) >= 8 ) ? 8 : 1) * \
( ((n) >= 9 ) ? 9 : 1) * \
( ((n) >= 10 ) ? 10 : 1) )
// ceiling of log2
`define log2(x) ( ( ((x) > 1 ) ? 1 : 0) + \
( ((x) > 2 ) ? 1 : 0) + \
( ((x) > 4 ) ? 1 : 0) + \
( ((x) > 8 ) ? 1 : 0) + \
( ((x) > 16 ) ? 1 : 0) + \
( ((x) > 32 ) ? 1 : 0) + \
( ((x) > 64 ) ? 1 : 0) + \
( ((x) > 128 ) ? 1 : 0) + \
( ((x) > 256 ) ? 1 : 0) + \
( ((x) > 512 ) ? 1 : 0) + \
( ((x) > 1024 ) ? 1 : 0) + \
( ((x) > 2048 ) ? 1 : 0) + \
( ((x) > 4096 ) ? 1 : 0) + \
( ((x) > 8192 ) ? 1 : 0) + \
( ((x) > 16384 ) ? 1 : 0) + \
( ((x) > 32768 ) ? 1 : 0) + \
( ((x) > 65536 ) ? 1 : 0) + \
( ((x) > 131072 ) ? 1 : 0) + \
( ((x) > 262144 ) ? 1 : 0) + \
( ((x) > 524288 ) ? 1 : 0) + \
( ((x) > 1048576) ? 1 : 0) + \
( ((x) > 2097152) ? 1 : 0) + \
( ((x) > 4194304) ? 1 : 0) )
// floor of log2
`define log2f(x) ( ( ((x) >= 2 ) ? 1 : 0) + \
( ((x) >= 4 ) ? 1 : 0) + \
( ((x) >= 8 ) ? 1 : 0) + \
( ((x) >= 16 ) ? 1 : 0) + \
( ((x) >= 32 ) ? 1 : 0) + \
( ((x) >= 64 ) ? 1 : 0) + \
( ((x) >= 128 ) ? 1 : 0) + \
( ((x) >= 256 ) ? 1 : 0) + \
( ((x) >= 512 ) ? 1 : 0) + \
( ((x) >= 1024 ) ? 1 : 0) + \
( ((x) >= 2048 ) ? 1 : 0) + \
( ((x) >= 4096 ) ? 1 : 0) + \
( ((x) >= 8192 ) ? 1 : 0) + \
( ((x) >= 16384 ) ? 1 : 0) + \
( ((x) >= 32768 ) ? 1 : 0) + \
( ((x) >= 65536 ) ? 1 : 0) + \
( ((x) >= 131072 ) ? 1 : 0) + \
( ((x) >= 262144 ) ? 1 : 0) + \
( ((x) >= 524288 ) ? 1 : 0) + \
( ((x) >= 1048576) ? 1 : 0) + \
( ((x) >= 2097152) ? 1 : 0) + \
( ((x) >= 4194304) ? 1 : 0) )
`endif //__UTILS_VH__
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment