/*
|
/*
|
Asynchronous SDM NoC
|
Asynchronous SDM NoC
|
(C)2011 Wei Song
|
(C)2011 Wei Song
|
Advanced Processor Technologies Group
|
Advanced Processor Technologies Group
|
Computer Science, the Univ. of Manchester, UK
|
Computer Science, the Univ. of Manchester, UK
|
|
|
Authors:
|
Authors:
|
Wei Song wsong83@gmail.com
|
Wei Song wsong83@gmail.com
|
|
|
License: LGPL 3.0 or later
|
License: LGPL 3.0 or later
|
|
|
Crossbar based SDM switch allocator
|
Crossbar based SDM switch allocator
|
*** SystemVerilog is used ***
|
*** SystemVerilog is used ***
|
|
|
References
|
References
|
For the detail structure, please refer to Section 6.3.1 of the thesis:
|
For the detail structure, please refer to Section 6.3.1 of the thesis:
|
Wei Song, Spatial parallelism in the routers of asynchronous on-chip networks, PhD thesis, the University of Manchester, 2011.
|
Wei Song, Spatial parallelism in the routers of asynchronous on-chip networks, PhD thesis, the University of Manchester, 2011.
|
|
|
History:
|
History:
|
28/09/2009 Initial version. <wsong83@gmail.com>
|
28/09/2009 Initial version. <wsong83@gmail.com>
|
25/05/2011 Clean up for opensource. <wsong83@gmail.com>
|
25/05/2011 Clean up for opensource. <wsong83@gmail.com>
|
|
|
*/
|
*/
|
|
|
// the router structure definitions
|
// the router structure definitions
|
`include "define.v"
|
`include "define.v"
|
|
|
module sdm_sch (/*AUTOARG*/
|
module sdm_sch (/*AUTOARG*/
|
// Outputs
|
// Outputs
|
sack, wack, nack, eack, lack, scfg, ncfg, wcfg, ecfg, lcfg,
|
sack, wack, nack, eack, lack, scfg, ncfg, wcfg, ecfg, lcfg,
|
// Inputs
|
// Inputs
|
sreq, nreq, lreq, wreq, ereq
|
sreq, nreq, lreq, wreq, ereq
|
);
|
);
|
|
|
parameter VCN = 2; // the number of virtual circuits per port
|
parameter VCN = 2; // the number of virtual circuits per port
|
|
|
// income requests
|
// income requests
|
input [VCN-1:0][3:0] sreq, nreq, lreq;
|
input [VCN-1:0][3:0] sreq, nreq, lreq;
|
input [VCN-1:0][1:0] wreq, ereq;
|
input [VCN-1:0][1:0] wreq, ereq;
|
|
|
// ack to input buffers
|
// ack to input buffers
|
output [VCN-1:0] sack, wack, nack, eack, lack;
|
output [VCN-1:0] sack, wack, nack, eack, lack;
|
|
|
// configuration to the crossbar
|
// configuration to the crossbar
|
output [VCN-1:0][1:0][VCN-1:0] scfg, ncfg;
|
output [VCN-1:0][1:0][VCN-1:0] scfg, ncfg;
|
output [VCN-1:0][3:0][VCN-1:0] wcfg, ecfg, lcfg;
|
output [VCN-1:0][3:0][VCN-1:0] wcfg, ecfg, lcfg;
|
|
|
input rst_n; // active low global reset
|
input rst_n; // active low global reset
|
|
|
// requests to arbiters
|
// requests to arbiters
|
`ifndef ENABLE_MRMA
|
`ifndef ENABLE_MRMA
|
wire [1:0][VCN-1:0][VCN-1:0] r2s, r2n; // shuffle the incoming request signals
|
wire [1:0][VCN-1:0][VCN-1:0] r2s, r2n; // shuffle the incoming request signals
|
wire [3:0][VCN-1:0][VCN-1:0] r2w, r2e, r2l;
|
wire [3:0][VCN-1:0][VCN-1:0] r2w, r2e, r2l;
|
`else
|
`else
|
wire [1:0][VCN-1:0] r2s, r2n; // shuffle the incoming request signals
|
wire [1:0][VCN-1:0] r2s, r2n; // shuffle the incoming request signals
|
wire [3:0][VCN-1:0] r2w, r2e, r2l;
|
wire [3:0][VCN-1:0] r2w, r2e, r2l;
|
`endif
|
`endif
|
|
|
// ack from arbiters
|
// ack from arbiters
|
wire [VCN-1:0][3:0] a2s, a2n, a2l;
|
wire [VCN-1:0][3:0] a2s, a2n, a2l;
|
wire [VCN-1:0][1:0] a2w, a2e;
|
wire [VCN-1:0][1:0] a2w, a2e;
|
|
|
// ack of the arbiters
|
// ack of the arbiters
|
wire [1:0][VCN-1:0] r2sa, r2na;
|
wire [1:0][VCN-1:0] r2sa, r2na;
|
wire [3:0][VCN-1:0] r2wa, r2ea, r2la;
|
wire [3:0][VCN-1:0] r2wa, r2ea, r2la;
|
|
|
`ifdef ENABLE_MRMA
|
`ifdef ENABLE_MRMA
|
wire [VCN:0] OPrst_n; // the buffered resets to avoid metastability
|
wire [VCN:0] OPrst_n; // the buffered resets to avoid metastability
|
wire [VCN-1:0] SOPrdy, SOPblk; // OP ready and blocked status
|
wire [VCN-1:0] SOPrdy, SOPblk; // OP ready and blocked status
|
wire [VCN-1:0] WOPrdy, WOPblk; // OP ready and blocked status
|
wire [VCN-1:0] WOPrdy, WOPblk; // OP ready and blocked status
|
wire [VCN-1:0] NOPrdy, NOPblk; // OP ready and blocked status
|
wire [VCN-1:0] NOPrdy, NOPblk; // OP ready and blocked status
|
wire [VCN-1:0] EOPrdy, EOPblk; // OP ready and blocked status
|
wire [VCN-1:0] EOPrdy, EOPblk; // OP ready and blocked status
|
wire [VCN-1:0] LOPrdy, LOPblk; // OP ready and blocked status
|
wire [VCN-1:0] LOPrdy, LOPblk; // OP ready and blocked status
|
`endif
|
`endif
|
|
|
genvar i,j;
|
genvar i,j;
|
|
|
// wire shuffle
|
// wire shuffle
|
generate for(i=0; i<VCN; i++) begin: SHUF
|
generate for(i=0; i<VCN; i++) begin: SHUF
|
`ifndef ENABLE_MRMA
|
`ifndef ENABLE_MRMA
|
for(j=0; j<VCN; j++) begin: CO
|
for(j=0; j<VCN; j++) begin: CO
|
assign r2s[0][i][j] = nreq[i][0];
|
assign r2s[0][i][j] = nreq[i][0];
|
assign r2s[1][i][j] = lreq[i][0];
|
assign r2s[1][i][j] = lreq[i][0];
|
assign r2w[0][i][j] = sreq[i][0];
|
assign r2w[0][i][j] = sreq[i][0];
|
assign r2w[1][i][j] = nreq[i][1];
|
assign r2w[1][i][j] = nreq[i][1];
|
assign r2w[2][i][j] = ereq[i][0];
|
assign r2w[2][i][j] = ereq[i][0];
|
assign r2w[3][i][j] = lreq[i][1];
|
assign r2w[3][i][j] = lreq[i][1];
|
assign r2n[0][i][j] = sreq[i][1];
|
assign r2n[0][i][j] = sreq[i][1];
|
assign r2n[1][i][j] = lreq[i][2];
|
assign r2n[1][i][j] = lreq[i][2];
|
assign r2e[0][i][j] = sreq[i][2];
|
assign r2e[0][i][j] = sreq[i][2];
|
assign r2e[1][i][j] = wreq[i][0];
|
assign r2e[1][i][j] = wreq[i][0];
|
assign r2e[2][i][j] = nreq[i][2];
|
assign r2e[2][i][j] = nreq[i][2];
|
assign r2e[3][i][j] = lreq[i][3];
|
assign r2e[3][i][j] = lreq[i][3];
|
assign r2l[0][i][j] = sreq[i][3];
|
assign r2l[0][i][j] = sreq[i][3];
|
assign r2l[1][i][j] = wreq[i][1];
|
assign r2l[1][i][j] = wreq[i][1];
|
assign r2l[2][i][j] = nreq[i][3];
|
assign r2l[2][i][j] = nreq[i][3];
|
assign r2l[3][i][j] = ereq[i][1];
|
assign r2l[3][i][j] = ereq[i][1];
|
end // block: CO
|
end // block: CO
|
`else // !`ifndef ENABLE_MRMA
|
`else // !`ifndef ENABLE_MRMA
|
assign r2s[0][i] = nreq[i][0];
|
assign r2s[0][i] = nreq[i][0];
|
assign r2s[1][i] = lreq[i][0];
|
assign r2s[1][i] = lreq[i][0];
|
assign r2w[0][i] = sreq[i][0];
|
assign r2w[0][i] = sreq[i][0];
|
assign r2w[1][i] = nreq[i][1];
|
assign r2w[1][i] = nreq[i][1];
|
assign r2w[2][i] = ereq[i][0];
|
assign r2w[2][i] = ereq[i][0];
|
assign r2w[3][i] = lreq[i][1];
|
assign r2w[3][i] = lreq[i][1];
|
assign r2n[0][i] = sreq[i][1];
|
assign r2n[0][i] = sreq[i][1];
|
assign r2n[1][i] = lreq[i][2];
|
assign r2n[1][i] = lreq[i][2];
|
assign r2e[0][i] = sreq[i][2];
|
assign r2e[0][i] = sreq[i][2];
|
assign r2e[1][i] = wreq[i][0];
|
assign r2e[1][i] = wreq[i][0];
|
assign r2e[2][i] = nreq[i][2];
|
assign r2e[2][i] = nreq[i][2];
|
assign r2e[3][i] = lreq[i][3];
|
assign r2e[3][i] = lreq[i][3];
|
assign r2l[0][i] = sreq[i][3];
|
assign r2l[0][i] = sreq[i][3];
|
assign r2l[1][i] = wreq[i][1];
|
assign r2l[1][i] = wreq[i][1];
|
assign r2l[2][i] = nreq[i][3];
|
assign r2l[2][i] = nreq[i][3];
|
assign r2l[3][i] = ereq[i][1];
|
assign r2l[3][i] = ereq[i][1];
|
`endif // !`ifndef ENABLE_MRMA
|
`endif // !`ifndef ENABLE_MRMA
|
assign a2s[i][0] = r2wa[0][i];
|
assign a2s[i][0] = r2wa[0][i];
|
assign a2s[i][1] = r2na[0][i];
|
assign a2s[i][1] = r2na[0][i];
|
assign a2s[i][2] = r2ea[0][i];
|
assign a2s[i][2] = r2ea[0][i];
|
assign a2s[i][3] = r2la[0][i];
|
assign a2s[i][3] = r2la[0][i];
|
assign a2w[i][0] = r2ea[1][i];
|
assign a2w[i][0] = r2ea[1][i];
|
assign a2w[i][1] = r2la[1][i];
|
assign a2w[i][1] = r2la[1][i];
|
assign a2n[i][0] = r2sa[0][i];
|
assign a2n[i][0] = r2sa[0][i];
|
assign a2n[i][1] = r2wa[1][i];
|
assign a2n[i][1] = r2wa[1][i];
|
assign a2n[i][2] = r2ea[2][i];
|
assign a2n[i][2] = r2ea[2][i];
|
assign a2n[i][3] = r2la[2][i];
|
assign a2n[i][3] = r2la[2][i];
|
assign a2e[i][0] = r2wa[2][i];
|
assign a2e[i][0] = r2wa[2][i];
|
assign a2e[i][1] = r2la[3][i];
|
assign a2e[i][1] = r2la[3][i];
|
assign a2l[i][0] = r2sa[1][i];
|
assign a2l[i][0] = r2sa[1][i];
|
assign a2l[i][1] = r2wa[3][i];
|
assign a2l[i][1] = r2wa[3][i];
|
assign a2l[i][2] = r2na[1][i];
|
assign a2l[i][2] = r2na[1][i];
|
assign a2l[i][3] = r2ea[3][i];
|
assign a2l[i][3] = r2ea[3][i];
|
assign sack[i] = |a2s[i];
|
assign sack[i] = |a2s[i];
|
assign wack[i] = |a2w[i];
|
assign wack[i] = |a2w[i];
|
assign nack[i] = |a2n[i];
|
assign nack[i] = |a2n[i];
|
assign eack[i] = |a2e[i];
|
assign eack[i] = |a2e[i];
|
assign lack[i] = |a2l[i];
|
assign lack[i] = |a2l[i];
|
|
|
end // block: SHUF
|
end // block: SHUF
|
endgenerate
|
endgenerate
|
|
|
// output port arbiter/allocators
|
// output port arbiter/allocators
|
`ifndef ENABLE_MRMA
|
`ifndef ENABLE_MRMA
|
mnma #(.N(2*VCN), .M(VCN))
|
mnma #(.N(2*VCN), .M(VCN))
|
SCBA (
|
SCBA (
|
.r ( r2s ),
|
.r ( r2s ),
|
.ra ( r2sa ),
|
.ra ( r2sa ),
|
.cfg ( scfg )
|
.cfg ( scfg )
|
);
|
);
|
|
|
mnma #(.N(4*VCN), .M(VCN))
|
mnma #(.N(4*VCN), .M(VCN))
|
WCBA (
|
WCBA (
|
.r ( r2w ),
|
.r ( r2w ),
|
.ra ( r2wa ),
|
.ra ( r2wa ),
|
.cfg ( wcfg )
|
.cfg ( wcfg )
|
);
|
);
|
|
|
mnma #(.N(2*VCN), .M(VCN))
|
mnma #(.N(2*VCN), .M(VCN))
|
NCBA (
|
NCBA (
|
.r ( r2n ),
|
.r ( r2n ),
|
.ra ( r2na ),
|
.ra ( r2na ),
|
.cfg ( ncfg )
|
.cfg ( ncfg )
|
);
|
);
|
|
|
mnma #(.N(4*VCN), .M(VCN))
|
mnma #(.N(4*VCN), .M(VCN))
|
ECBA (
|
ECBA (
|
.r ( r2e ),
|
.r ( r2e ),
|
.ra ( r2ea ),
|
.ra ( r2ea ),
|
.cfg ( ecfg )
|
.cfg ( ecfg )
|
);
|
);
|
|
|
mnma #(.N(4*VCN), .M(VCN))
|
mnma #(.N(4*VCN), .M(VCN))
|
LCBA (
|
LCBA (
|
.r ( r2l ),
|
.r ( r2l ),
|
.ra ( r2la ),
|
.ra ( r2la ),
|
.cfg ( lcfg )
|
.cfg ( lcfg )
|
);
|
);
|
`else // !`ifndef ENABLE_MRMA
|
`else // !`ifndef ENABLE_MRMA
|
mrma #(.N(2*VCN), .M(VCN))
|
mrma #(.N(2*VCN), .M(VCN))
|
SCBA (
|
SCBA (
|
.ca ( r2sa ),
|
.ca ( r2sa ),
|
.ra ( SOPblk ),
|
.ra ( SOPblk ),
|
.cfg ( scfg ),
|
.cfg ( scfg ),
|
.c ( r2s ),
|
.c ( r2s ),
|
.r ( SOPrdy ),
|
.r ( SOPrdy ),
|
.rst_n ( rst_n )
|
.rst_n ( rst_n )
|
);
|
);
|
|
|
mrma #(.N(4*VCN), .M(VCN))
|
mrma #(.N(4*VCN), .M(VCN))
|
WCBA (
|
WCBA (
|
.ca ( r2wa ),
|
.ca ( r2wa ),
|
.ra ( WOPblk ),
|
.ra ( WOPblk ),
|
.cfg ( wcfg ),
|
.cfg ( wcfg ),
|
.c ( r2w ),
|
.c ( r2w ),
|
.r ( WOPrdy ),
|
.r ( WOPrdy ),
|
.rst_n ( rst_n )
|
.rst_n ( rst_n )
|
);
|
);
|
|
|
mrma #(.N(2*VCN), .M(VCN))
|
mrma #(.N(2*VCN), .M(VCN))
|
NCBA (
|
NCBA (
|
.ca ( r2na ),
|
.ca ( r2na ),
|
.ra ( NOPblk ),
|
.ra ( NOPblk ),
|
.cfg ( ncfg ),
|
.cfg ( ncfg ),
|
.c ( r2n ),
|
.c ( r2n ),
|
.r ( NOPrdy ),
|
.r ( NOPrdy ),
|
.rst_n ( rst_n )
|
.rst_n ( rst_n )
|
);
|
);
|
|
|
mrma #(.N(4*VCN), .M(VCN))
|
mrma #(.N(4*VCN), .M(VCN))
|
ECBA (
|
ECBA (
|
.ca ( r2ea ),
|
.ca ( r2ea ),
|
.ra ( EOPblk ),
|
.ra ( EOPblk ),
|
.cfg ( ecfg ),
|
.cfg ( ecfg ),
|
.c ( r2e ),
|
.c ( r2e ),
|
.r ( EOPrdy ),
|
.r ( EOPrdy ),
|
.rst_n ( rst_n )
|
.rst_n ( rst_n )
|
);
|
);
|
|
|
mrma #(.N(4*VCN), .M(VCN))
|
mrma #(.N(4*VCN), .M(VCN))
|
LCBA (
|
LCBA (
|
.ca ( r2la ),
|
.ca ( r2la ),
|
.ra ( LOPblk ),
|
.ra ( LOPblk ),
|
.cfg ( lcfg ),
|
.cfg ( lcfg ),
|
.c ( r2l ),
|
.c ( r2l ),
|
.r ( LOPrdy ),
|
.r ( LOPrdy ),
|
.rst_n ( rst_n )
|
.rst_n ( rst_n )
|
);
|
);
|
|
|
generate
|
generate
|
for(i=0; i<VCN; i++) begin: OPC
|
for(i=0; i<VCN; i++) begin: OPC
|
delay DLY ( .q(OPrst_n[i+1]), .a(OPrst_n[i])); // dont touch
|
delay DLY ( .q(OPrst_n[i+1]), .a(OPrst_n[i])); // dont touch
|
assign SOPrdy[i] = (~SOPblk[i])&SOPrst_n[i+1];
|
assign SOPrdy[i] = (~SOPblk[i])&SOPrst_n[i+1];
|
assign WOPrdy[i] = (~WOPblk[i])&WOPrst_n[i+1];
|
assign WOPrdy[i] = (~WOPblk[i])&WOPrst_n[i+1];
|
assign NOPrdy[i] = (~NOPblk[i])&NOPrst_n[i+1];
|
assign NOPrdy[i] = (~NOPblk[i])&NOPrst_n[i+1];
|
assign EOPrdy[i] = (~EOPblk[i])&EOPrst_n[i+1];
|
assign EOPrdy[i] = (~EOPblk[i])&EOPrst_n[i+1];
|
assign LOPrdy[i] = (~LOPblk[i])&LOPrst_n[i+1];
|
assign LOPrdy[i] = (~LOPblk[i])&LOPrst_n[i+1];
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
`endif // !`ifndef ENABLE_MRMA
|
`endif // !`ifndef ENABLE_MRMA
|
|
|
endmodule // sdm_sch
|
endmodule // sdm_sch
|
|
|