Commit 0f1a7547 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

Merge branch 'greg-swcore' into proposed_master

parents 5f6ac509 1a662f42
......@@ -8,6 +8,8 @@
files = [
"swc_wbgen2_pkg.vhd",
"swc_wishbone_slave.vhd",
"swc_core.vhd",
"swc_multiport_linked_list.vhd",
......@@ -35,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__
......@@ -83,7 +83,6 @@ entity swc_multiport_page_allocator is
g_special_res_num_pages : integer := 256;
g_resource_num : integer := 3; -- this include 1 for unknown
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer := 10*3;
g_with_RESOURCE_MGR : boolean := false
);
port (
......@@ -137,7 +136,8 @@ entity swc_multiport_page_allocator is
set_usecnt_succeeded_o : out std_logic_vector(g_num_ports -1 downto 0);
res_full_o : out std_logic_vector(g_num_ports * g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_num_ports * g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0)
free_pages_o : out std_logic_vector(g_page_addr_width downto 0);
afull_thr_i : in std_logic_vector(g_page_addr_width downto 0)
-- tap_out_o : out std_logic_vector(62 + 49 downto 0)
);
......@@ -160,8 +160,7 @@ architecture syn of swc_multiport_page_allocator is
g_special_res_num_pages : integer := 256;
g_resource_num : integer := 3; -- this include: unknown, special and x* normal , so
-- g_resource_num = 2+x
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer );
g_resource_num_width : integer := 2);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
......@@ -191,7 +190,8 @@ architecture syn of swc_multiport_page_allocator is
set_usecnt_succeeded_o : out std_logic;
res_full_o : out std_logic_vector(g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0);
free_pages_o : out std_logic_vector(g_page_addr_width downto 0);
afull_thr_i : in std_logic_vector(g_page_addr_width downto 0);
-----------------------
dbg_double_free_o : out std_logic;
dbg_double_force_free_o : out std_logic;
......@@ -474,8 +474,7 @@ begin -- syn
g_max_pck_size => g_max_pck_size,
g_special_res_num_pages => g_special_res_num_pages,
g_resource_num => g_resource_num,
g_resource_num_width => g_resource_num_width,
g_num_dbg_vector_width => g_num_dbg_vector_width)
g_resource_num_width => g_resource_num_width)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......@@ -505,7 +504,8 @@ begin -- syn
rescnt_page_num_i => pg_rescnt_page_num,
res_full_o => pg_res_full,
res_almost_full_o => pg_res_almost_full,
dbg_o => dbg_o,
free_pages_o => free_pages_o,
afull_thr_i => afull_thr_i,
-------------------------------
dbg_double_force_free_o => dbg_double_force_free,
dbg_double_free_o => dbg_double_free,
......
......@@ -100,8 +100,7 @@ entity swc_page_allocator_new is
g_special_res_num_pages : integer := 256;
g_resource_num : integer := 3; -- this include: unknown, special and x* normal , so
-- g_resource_num = 2+x
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer
g_resource_num_width : integer := 2
);
port (
......@@ -201,8 +200,8 @@ entity swc_page_allocator_new is
res_full_o : out std_logic_vector(g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0);
free_pages_o : out std_logic_vector(g_page_addr_width downto 0);
afull_thr_i : in std_logic_vector(g_page_addr_width downto 0);
----------------------------------------------------------------------
......@@ -567,8 +566,7 @@ begin -- syn
resource_o <= (others => '0');
set_usecnt_succeeded_o <= '1';
res_full_o <= (others => std_logic(out_nomem or initializing));
dbg_o (g_page_addr_width+1-1 downto 0) <= std_logic_vector(free_pages);
dbg_o (g_num_dbg_vector_width-1 downto g_page_addr_width+1) <= (others =>'0');
free_pages_o <= std_logic_vector(free_pages);
set_usecnt_allowed_p1 <= '1';
p_gen_almost_full : process(clk_i)
begin
......@@ -576,7 +574,7 @@ begin -- syn
if rst_n_i = '0' then
res_almost_full_o <= (others => '0');
else
if(free_pages < to_unsigned(40, free_blocks'length) ) then
if(free_pages < unsigned(afull_thr_i) ) then
res_almost_full_o <= (others => '1');
else
res_almost_full_o <= (others => '0');
......@@ -629,8 +627,7 @@ begin -- syn
g_total_num_pages_width => g_page_addr_width,
g_special_res_num_pages => g_special_res_num_pages,
g_resource_num => g_resource_num,
g_resource_num_width => g_resource_num_width,
g_num_dbg_vector_width => g_num_dbg_vector_width
g_resource_num_width => g_resource_num_width
)
port map (
clk_i => clk_i,
......@@ -642,7 +639,7 @@ begin -- syn
rescnt_page_num_i => alloc_req_d1.rescnt_page_num,
res_full_o => res_full_o,
res_almost_full_o => res_almost_full,
dbg_o => dbg_o
dbg_o => open --dbg_o
);
resource_o <= rescnt_rddata_p1;
......
......@@ -136,7 +136,7 @@ entity swc_alloc_resource_manager is
g_resource_num : integer := 3; -- this include 1 for unknown
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer
g_num_dbg_vector_width : integer := 30
);
port (
......
......@@ -73,8 +73,7 @@ entity swc_core is
g_mpm_fifo_size : integer ;
g_mpm_fetch_next_pg_in_advance : boolean ;
g_drop_outqueue_head_on_full : boolean ;
g_num_global_pause : integer ;
g_num_dbg_vector_width : integer
g_num_global_pause : integer
);
port (
clk_i : in std_logic;
......@@ -132,15 +131,8 @@ entity swc_core is
-------------------------------------------------------------------------------
pp_req_i : in std_logic_vector(g_num_ports - 1 downto 0);
pp_quanta_i : in std_logic_vector(g_num_ports*16 - 1 downto 0);
pp_classes_i : in std_logic_vector(g_num_ports*8 - 1 downto 0);
------------------------------------------------------------------------------
-- I/F misc
-------------------------------------------------------------------------------
dbg_o : out std_logic_vector(g_num_dbg_vector_width -1 downto 0);
shaper_drop_at_hp_ena_i : in std_logic
);
pp_classes_i : in std_logic_vector(g_num_ports*8 - 1 downto 0)
);
end swc_core;
architecture rtl of swc_core is
......@@ -178,8 +170,7 @@ architecture rtl of swc_core is
g_mpm_fifo_size => g_mpm_fifo_size,
g_mpm_fetch_next_pg_in_advance => g_mpm_fetch_next_pg_in_advance,
g_drop_outqueue_head_on_full => g_drop_outqueue_head_on_full,
g_num_global_pause => g_num_global_pause,
g_num_dbg_vector_width => g_num_dbg_vector_width
g_num_global_pause => g_num_global_pause
)
port map(
clk_i => clk_i,
......@@ -192,13 +183,9 @@ architecture rtl of swc_core is
src_i => src_i,
src_o => src_o,
shaper_drop_at_hp_ena_i => shaper_drop_at_hp_ena_i,
global_pause_i => global_pause_i,
perport_pause_i=> perport_pause_i,
dbg_o => dbg_o,
rtu_rsp_i => rtu_rsp_i,
rtu_ack_o => rtu_rsp_ack_o
);
......
......@@ -69,11 +69,8 @@ entity swc_multiport_pck_pg_free_module is
ob_free_done_o : out std_logic_vector(g_num_ports-1 downto 0);
ob_free_pgaddr_i : in std_logic_vector(g_num_ports * g_page_addr_width - 1 downto 0);
ll_read_addr_o : out std_logic_vector(g_num_ports * g_page_addr_width -1 downto 0);
ll_read_data_i : in std_logic_vector(g_num_ports * g_data_width - 1 downto 0);
--ll_read_data_i : in std_logic_vector(g_page_addr_width - 1 downto 0);
ll_read_req_o : out std_logic_vector(g_num_ports-1 downto 0);
ll_read_valid_data_i : in std_logic_vector(g_num_ports-1 downto 0);
ll_i : in t_ll2fp_array(g_num_ports-1 downto 0);
ll_o : out t_fp2ll_array(g_num_ports-1 downto 0);
mmu_resource_i : in std_logic_vector(g_num_ports * g_resource_num_width -1 downto 0);
......@@ -123,10 +120,10 @@ begin -- syn
ob_free_done_o => ob_free_done_o(i),
ob_free_pgaddr_i => ob_free_pgaddr_i((i+1)*g_page_addr_width - 1 downto i * g_page_addr_width),
ll_read_addr_o => ll_read_addr_o((i+1)*g_page_addr_width - 1 downto i * g_page_addr_width),
ll_read_data_i => ll_read_data_i((i+1)*g_data_width - 1 downto i * g_data_width),
ll_read_req_o => ll_read_req_o(i),
ll_read_valid_data_i => ll_read_valid_data_i(i),
ll_read_addr_o => ll_o(i).adr,
ll_read_data_i => ll_i(i).data,
ll_read_req_o => ll_o(i).rd_req,
ll_read_valid_data_i => ll_i(i).rd_done,
mmu_resource_i => mmu_resource_i((i+1)*g_resource_num_width -1 downto i *g_resource_num_width),
......
This diff is collapsed.
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Switching core
---------------------------------------------------------------------------------------
-- File : swc_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wrsw_swcore.wb
-- Created : Tue Sep 13 14:08:37 2016
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrsw_swcore.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package swc_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_swc_in_registers is record
csr_mpm_afull_i : std_logic;
csr_mpm_full_i : std_logic;
stat_min_fpg_i : std_logic_vector(15 downto 0);
stat_max_fpg_i : std_logic_vector(15 downto 0);
cur_fpg_i : std_logic_vector(31 downto 0);
afull_thr_i : std_logic_vector(31 downto 0);
end record;
constant c_swc_in_registers_init_value: t_swc_in_registers := (
csr_mpm_afull_i => '0',
csr_mpm_full_i => '0',
stat_min_fpg_i => (others => '0'),
stat_max_fpg_i => (others => '0'),
cur_fpg_i => (others => '0'),
afull_thr_i => (others => '0')
);
-- Output registers (WB slave -> user design)
type t_swc_out_registers is record
csr_new_stat_o : std_logic;
afull_thr_o : std_logic_vector(31 downto 0);
afull_thr_load_o : std_logic;
hp_ob_drop_mask_o : std_logic_vector(18 downto 0);
end record;
constant c_swc_out_registers_init_value: t_swc_out_registers := (
csr_new_stat_o => '0',
afull_thr_o => (others => '0'),
afull_thr_load_o => '0',
hp_ob_drop_mask_o => (others => '0')
);
function "or" (left, right: t_swc_in_registers) return t_swc_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
end package;
package body swc_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if x(i) = '1' then
tmp(i):= '1';
else
tmp(i):= '0';
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_swc_in_registers) return t_swc_in_registers is
variable tmp: t_swc_in_registers;
begin
tmp.csr_mpm_afull_i := f_x_to_zero(left.csr_mpm_afull_i) or f_x_to_zero(right.csr_mpm_afull_i);
tmp.csr_mpm_full_i := f_x_to_zero(left.csr_mpm_full_i) or f_x_to_zero(right.csr_mpm_full_i);
tmp.stat_min_fpg_i := f_x_to_zero(left.stat_min_fpg_i) or f_x_to_zero(right.stat_min_fpg_i);
tmp.stat_max_fpg_i := f_x_to_zero(left.stat_max_fpg_i) or f_x_to_zero(right.stat_max_fpg_i);
tmp.cur_fpg_i := f_x_to_zero(left.cur_fpg_i) or f_x_to_zero(right.cur_fpg_i);
tmp.afull_thr_i := f_x_to_zero(left.afull_thr_i) or f_x_to_zero(right.afull_thr_i);
return tmp;
end function;
end package body;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Switching core
---------------------------------------------------------------------------------------
-- File : swc_wishbone_slave.vhd
-- Author : auto-generated by wbgen2 from wrsw_swcore.wb
-- Created : Tue Sep 13 14:08:37 2016
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrsw_swcore.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.swc_wbgen2_pkg.all;
entity swc_wishbone_slave is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(2 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
regs_i : in t_swc_in_registers;
regs_o : out t_swc_out_registers
);
end swc_wishbone_slave;
architecture syn of swc_wishbone_slave is
signal swc_csr_new_stat_dly0 : std_logic ;
signal swc_csr_new_stat_int : std_logic ;
signal swc_hp_ob_drop_mask_int : std_logic_vector(18 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
swc_csr_new_stat_int <= '0';
regs_o.afull_thr_load_o <= '0';
swc_hp_ob_drop_mask_int <= "0000000000000000000";
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
swc_csr_new_stat_int <= '0';
regs_o.afull_thr_load_o <= '0';
ack_in_progress <= '0';
else
regs_o.afull_thr_load_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(2 downto 0) is
when "000" =>
if (wb_we_i = '1') then
swc_csr_new_stat_int <= wrdata_reg(0);
end if;
rddata_reg(0) <= '0';
rddata_reg(30) <= regs_i.csr_mpm_afull_i;
rddata_reg(31) <= regs_i.csr_mpm_full_i;
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "001" =>
if (wb_we_i = '1') then
end if;
rddata_reg(15 downto 0) <= regs_i.stat_min_fpg_i;
rddata_reg(31 downto 16) <= regs_i.stat_max_fpg_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "010" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.cur_fpg_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "011" =>
if (wb_we_i = '1') then
regs_o.afull_thr_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= regs_i.afull_thr_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "100" =>
if (wb_we_i = '1') then
swc_hp_ob_drop_mask_int <= wrdata_reg(18 downto 0);
end if;
rddata_reg(18 downto 0) <= swc_hp_ob_drop_mask_int;
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- Lock MMU free pages stats
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
swc_csr_new_stat_dly0 <= '0';
regs_o.csr_new_stat_o <= '0';
elsif rising_edge(clk_sys_i) then
swc_csr_new_stat_dly0 <= swc_csr_new_stat_int;
regs_o.csr_new_stat_o <= swc_csr_new_stat_int and (not swc_csr_new_stat_dly0);
end if;
end process;
-- MPM almost full
-- MPM Full
-- min pages
-- max pages
-- pages
-- pages
regs_o.afull_thr_o <= wrdata_reg(31 downto 0);
-- Port mask
regs_o.hp_ob_drop_mask_o <= swc_hp_ob_drop_mask_int;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
-- -*- Mode: LUA; tab-width: 2 -*-
-- White-Rabbit Watchdog Module
-- author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
--
-- Use wbgen2 to generate code, documentation and more.
-- wbgen2 is available at:
-- http://www.ohwr.org/projects/wishbone-gen
--
peripheral {
name = "WR Switching core";
description = "The module is responsible for Ethernet switching with special treatment for High Priority traffic";
hdl_entity = "swc_wishbone_slave";
prefix = "swc";
reg {
name = "SWcore control & status register";
description = "Various control and status bits of the Swcore";
prefix = "CSR";
field {
name = "Lock MMU free pages stats";
description = "write 1: lock new values of MPM_AFULL, MPM_FULL and STAT register \
write 0: no effect";
prefix = "NEW_STAT";
size = 1;
type = MONOSTABLE;
access_dev = READ_ONLY;
access_bus = WRITE_ONLY;
};
field {
name = "MPM almost full";
description = "Bit is 1 if since the last request of stats (NEW_STAT bit) the MMU has reported that MPM is almost full. \
This means we lost some best efford traffic, but not yet the HP traffic.";
prefix = "MPM_AFULL";
size = 1;
align = 30;
type = BIT;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "MPM Full";
description = "Bit is 1 if since the last request of stats (NEW_STAT bit) the MMU had no free pages to allocate - MPM was full. \
This usually means we have lost some frames (also HP frames).";
prefix = "MPM_FULL";
size = 1;
align = 31;
type = BIT;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Free pages in MPM stats";
description = "Values refreshed each time new stats are requested with a NEW_STAT bit";
prefix = "STAT";
field {
name = "min pages";
prefix = "MIN_FPG";
size = 16;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "max pages";
prefix = "MAX_FPG";
size = 16;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Current free pages in MPM";
description = "Exports the current number of free pages in the MPM";
prefix = "CUR_FPG";
field {
name = "pages";
size = 32;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
load = LOAD_EXT;
};
};
reg {
name = "MPM almost full threshold";
description = "Number of free pages in MPM when Almost Full flag is set.";
prefix = "AFULL_THR";
field {
name = "pages";
size = 32;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "HP OB register";
description = "Enables dropping regular traffic at the output of swcore ports when HP traffic is queued.";
prefix = "HP_OB";
field {
name = "Port mask";
prefix = "DROP_MASK";
size = 19;
type = SLV;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
};
};
This diff is collapsed.
......@@ -284,6 +284,7 @@ architecture behavoural of xswc_output_block_new is
signal cycle_frozen_cnt : unsigned(9 downto 0);
signal current_tx_prio : std_logic_vector(g_queue_num - 1 downto 0);
signal new_tx_prio : std_logic_vector(g_queue_num - 1 downto 0);
signal hp_prio_mask : std_logic_vector(g_queue_num - 1 downto 0);
signal zero_prio_mask : std_logic_vector(g_queue_num - 1 downto 0);
......@@ -570,19 +571,23 @@ begin -- behavoural
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
current_tx_prio <= (others => '0');
new_tx_prio <= (others => '0');
else
if(rd_valid = '1') then
current_tx_prio <= read_array;
new_tx_prio <= rd_array;
elsif((s_send_pck = S_EOF) and (s_prep_to_send = S_IDLE)) then
current_tx_prio <= (others => '0');
new_tx_prio <= (others => '0');
end if;
end if;
end if;
end process p_track_tx_prio;
-- deciding whether to drop currently tx-ed frame
hp_in_queuing <= '1' when ((read_array and hp_prio_mask) /= zero_prio_mask) else '0';
hp_in_queuing <= '1' when ((read_array and hp_prio_mask) /= zero_prio_mask) else
'1' when ((new_tx_prio and hp_prio_mask) /= zero_prio_mask) else
--'1' when ((new_tx_prio and hp_prio_mask) /= zero_prio_mask and (new_tx_prio /= current_tx_prio)) else
'0';
--non_hp_txing <= '1' when ((new_tx_prio and (not hp_prio_mask)) /= zero_prio_mask) else '0';
non_hp_txing <= '1' when ((current_tx_prio and (not hp_prio_mask)) /= zero_prio_mask) else '0';
abord_tx_at_hp <= non_hp_txing and -- we are currently sending frame which is not HP
......@@ -661,7 +666,7 @@ begin -- behavoural
--===========================================================================================
when S_NEWPCK_PAGE_SET_IN_ADVANCE =>
--===========================================================================================
if(request_retry = '1') then
if(request_retry = '1' or (abord_tx_at_hp = '1' and mpm_pg_req_i = '0')) then
mpm_abort <= '1';
s_prep_to_send <= S_RETRY_PREPARE;
mpm_pg_addr_memorized_valid <= '1';
......@@ -701,7 +706,13 @@ begin -- behavoural
when S_RETRY_PREPARE =>
--===========================================================================================
if(mpm_pg_req_i = '1') then
mpm_pg_addr <= pck_start_pgaddr;
--mpm_pg_addr <= pck_start_pgaddr;
if(mpm_pg_addr_memorized_valid = '1') then
mpm_pg_addr <= mpm_pg_addr_memorized;
mpm_pg_addr_memorized_valid <= '0';
else
mpm_pg_addr <= pck_start_pgaddr;
end if;
mpm_pg_valid <= '1';
s_prep_to_send <= S_RETRY_READY;
end if;
......@@ -760,6 +771,7 @@ begin -- behavoural
tmp_dat <= (others => '0');
tmp_sel <= (others => '0');
page_set_in_advance <= '0';
current_tx_prio <= (others => '0');
--========================================
else
-- default values
......@@ -773,10 +785,12 @@ begin -- behavoural
when S_IDLE =>
--===========================================================================================
if(s_prep_to_send = S_NEWPCK_PAGE_READY and src_i.err = '0' and src_i.stall = '0' and ifg_count = x"0") then
if((s_prep_to_send = S_NEWPCK_PAGE_READY or s_prep_to_send = S_RETRY_READY)
and src_i.err = '0' and src_i.stall = '0' and ifg_count = x"0") then
src_out_int.cyc <= '1';
s_send_pck <= S_DATA;
pck_start_pgaddr <= mpm_pg_addr;
current_tx_prio <= new_tx_prio;
end if;
--===========================================================================================
......@@ -866,7 +880,9 @@ begin -- behavoural
src_out_int.cyc <= '1';
s_send_pck <= S_DATA;
pck_start_pgaddr <= mpm_pg_addr;
current_tx_prio <= new_tx_prio;
else
current_tx_prio <= (others=>'0');
s_send_pck <= S_IDLE;
end if;
else
......@@ -891,7 +907,9 @@ begin -- behavoural
src_out_int.cyc <= '1';
s_send_pck <= S_DATA;
pck_start_pgaddr <= mpm_pg_addr;
current_tx_prio <= new_tx_prio;
else
current_tx_prio <= (others=>'0');
s_send_pck <= S_IDLE;
end if;
end if;
......
......@@ -188,7 +188,7 @@ end scb_top_bare;
architecture rtl of scb_top_bare is
constant c_GW_VERSION : std_logic_vector(31 downto 0) := x"20_02_14_00"; --DD_MM_YY_VV
constant c_NUM_WB_SLAVES : integer := 14;
constant c_NUM_WB_SLAVES : integer := 15;
constant c_NUM_PORTS : integer := g_num_ports;
constant c_MAX_PORTS : integer := 18;
constant c_NUM_GL_PAUSE : integer := 2; -- number of output global PAUSE sources for SWcore
......@@ -220,6 +220,7 @@ architecture rtl of scb_top_bare is
constant c_SLAVE_PSTATS : integer := 11;
constant c_SLAVE_HWIU : integer := 12;
constant c_SLAVE_WDOG : integer := 13;
constant c_SLAVE_SWC : integer := 14;
--constant c_SLAVE_DUMMY : integer := 13;
......@@ -799,6 +800,8 @@ begin
U_Swcore : xswc_core
generic map (
g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_prio_num => 8,
g_output_queue_num => 8,
g_max_pck_size => 10 * 1024,
......@@ -817,8 +820,7 @@ begin
g_mpm_fifo_size => 8,
g_mpm_fetch_next_pg_in_advance => false,
g_drop_outqueue_head_on_full => true,
g_num_global_pause => c_NUM_GL_PAUSE,
g_num_dbg_vector_width => c_DBG_V_SWCORE)
g_num_global_pause => c_NUM_GL_PAUSE)
port map (
clk_i => clk_sys,
clk_mpm_core_i => clk_aux_i,
......@@ -829,19 +831,16 @@ begin
snk_i => swc_snk_in,
snk_o => swc_snk_out,
shaper_drop_at_hp_ena_i => shaper_drop_at_hp_ena,
-- pause stuff
global_pause_i => global_pause,
perport_pause_i => fc_rx_pause,
dbg_o => dbg_n_regs(32+c_DBG_V_SWCORE-1 downto 32),
rtu_rsp_i => rtu_rsp,
rtu_ack_o => swc_rtu_ack,
rtu_abort_o =>rtu_rsp_abort,-- open --rtu_rsp_abort
wdog_o => swc_wdog_out
);
wdog_o => swc_wdog_out,
wb_i => cnx_master_out(c_SLAVE_SWC),
wb_o => cnx_master_in(c_SLAVE_SWC));
-- SWcore global pause nr=0 assigned to TRU
global_pause(0) <= swc2tru_req;
......
......@@ -220,6 +220,22 @@ package wrs_sdb_pkg is
date => x"20150630",
name => "WRSW WATCHDOG ")));
constant c_xswc_swcore_sdb: t_sdb_device := (
abi_class => x"0000",
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7",
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"00000000000000ff",
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"5783046b", -- echo -n "xswc_core" | md5sum - | cut -c1-8
version => x"00000001",
date => x"20160810",
name => "WRSW SWCORE ")));
-- RT subsystem crossbar
constant c_rtbar_layout : t_sdb_record_array(7 downto 0) :=
(0 => f_sdb_embed_device(f_xwb_dpram(16384), x"00000000"),
......@@ -259,7 +275,7 @@ package wrs_sdb_pkg is
f_xwb_bridge_layout_sdb(true, c_epbar_layout, c_epbar_sdb_address);
-- WRS main crossbar
constant c_layout : t_sdb_record_array(13+4 downto 0) :=
constant c_layout : t_sdb_record_array(14+4 downto 0) :=
(0 => f_sdb_embed_bridge(c_rtbar_bridge_sdb, x"00000000"), --RT subsystem
1 => f_sdb_embed_device(c_xwrsw_nic_sdb, x"00020000"), --NIC
2 => f_sdb_embed_bridge(c_epbar_bridge_sdb, x"00030000"), --Endpoints
......@@ -274,10 +290,11 @@ package wrs_sdb_pkg is
11 => f_sdb_embed_device(c_xwrsw_pstats_sdb, x"00058000"), --PSTATS
12 => f_sdb_embed_device(c_xwrsw_hwiu_sdb, x"00059000"), --HWIU
13 => f_sdb_embed_device(c_xwrsw_watchdog_sdb, x"0005a000"), --Watchdog
14 => f_sdb_embed_repo_url(c_sdb_repo_url),
15 => f_sdb_embed_synthesis(c_sdb_top_syn_info),
16 => f_sdb_embed_synthesis(c_sdb_general_cores_syn_info),
17 => f_sdb_embed_synthesis(c_sdb_wr_cores_syn_info));
14 => f_sdb_embed_device(c_xswc_swcore_sdb, x"0005b000"), --SWcore
15 => f_sdb_embed_repo_url(c_sdb_repo_url),
16 => f_sdb_embed_synthesis(c_sdb_top_syn_info),
17 => f_sdb_embed_synthesis(c_sdb_general_cores_syn_info),
18 => f_sdb_embed_synthesis(c_sdb_wr_cores_syn_info));
constant c_sdb_address : t_wishbone_address := x"00070000";
end wrs_sdb_pkg;
......@@ -264,6 +264,8 @@ package wrsw_components_pkg is
component xswc_core is
generic(
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
g_address_granularity : t_wishbone_address_granularity := BYTE;
g_prio_num : integer ;
g_output_queue_num : integer ;
g_max_pck_size : integer ;
......@@ -284,8 +286,7 @@ package wrsw_components_pkg is
g_mpm_fifo_size : integer ;
g_mpm_fetch_next_pg_in_advance : boolean ;
g_drop_outqueue_head_on_full : boolean ;
g_num_global_pause : integer ;
g_num_dbg_vector_width : integer := 32
g_num_global_pause : integer
);
port (
clk_i : in std_logic;
......@@ -300,14 +301,13 @@ package wrsw_components_pkg is
global_pause_i : in t_global_pause_request_array(g_num_global_pause-1 downto 0);
perport_pause_i : in t_pause_request_array(g_num_ports-1 downto 0);
shaper_drop_at_hp_ena_i : in std_logic := '0';
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0);
rtu_rsp_i : in t_rtu_response_array(g_num_ports - 1 downto 0);
rtu_ack_o : out std_logic_vector(g_num_ports - 1 downto 0);
rtu_abort_o : out std_logic_vector(g_num_ports - 1 downto 0);
wdog_o : out t_swc_fsms_array(g_num_ports-1 downto 0);
nomem_o : out std_logc
);
nomem_o : out std_logc;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out);
end component;
component xwrsw_rtu
generic (
......
......@@ -324,6 +324,8 @@ package wrsw_top_pkg is
end component;
component xswc_core is
generic(
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
g_address_granularity : t_wishbone_address_granularity := BYTE;
g_prio_num : integer ;--:= c_swc_output_prio_num; [works only for value of 8, output_block-causes problem]
g_output_queue_num : integer ;
g_max_pck_size : integer ;-- in 16bits words --:= c_swc_max_pck_size
......@@ -358,14 +360,14 @@ package wrsw_top_pkg is
global_pause_i : in t_global_pause_request_array(g_num_global_pause-1 downto 0);
perport_pause_i : in t_pause_request_array(g_num_ports-1 downto 0);
shaper_drop_at_hp_ena_i : in std_logic := '0';
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0);
rtu_rsp_i : in t_rtu_response_array(g_num_ports - 1 downto 0);
rtu_ack_o : out std_logic_vector(g_num_ports - 1 downto 0);
rtu_abort_o : out std_logic_vector(g_num_ports - 1 downto 0);
wdog_o : out t_swc_fsms_array(g_num_ports-1 downto 0);
nomem_o : out std_logic
);
nomem_o : out std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out);
end component;
component xwrsw_rtu
......
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