Skip to content

Commit

Permalink
Merge pull request #156 from zeroasiccorp/no_loopback
Browse files Browse the repository at this point in the history
Adding path mask parameter to umi_switch
  • Loading branch information
aolofsson authored Aug 26, 2024
2 parents 6c5ce39 + fe7fd28 commit fab2eb0
Showing 1 changed file with 137 additions and 18 deletions.
155 changes: 137 additions & 18 deletions umi/sumi/rtl/umi_switch.v
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,33 @@
* [1] = input 1 requesting output 0
* [2] = input 2 requesting output 0
* [N-1] = input N-1 requesting output 0
*
* [N] = input 0 requesting output 1
* [N+1] = input 1 requesting output 1
* [N+2] = input 2 requesting output 1
* [2*N-1] = input N-1 requesting output 1
*
* Testing:
*
* >> iverilog umi_switch.v -DTB_UMI_SWITCH -y . -y $LAMBDALIB/vectorlib/rtl
* >> ./a.out
*
******************************************************************************/

module umi_switch
#(parameter DW = 256, // umi data width
parameter CW = 32, // umi command width
parameter AW = 64, // umi adress width
parameter N = 3, // number of input ports
parameter M = 6 // number of outputs ports
#(
parameter N = 4, // number of input ports
parameter M = 4, // number of outputs ports
parameter [M*N-1:0] MASK = 0, // static disable of input to output path
parameter DW = 128, // umi data width
parameter CW = 32, // umi command width
parameter AW = 64 // umi adress width
)
(// controls
input clk,
input nreset,
input [1:0] arbmode, // arbiter mode (0=fixed)
input [N*M-1:0] arbmask, // (1=mask/disable path)
input [N*M-1:0] arbmask, // dynamic input mask (1=disable)
// Incoming UMI
input [N*M-1:0] umi_in_valid,
input [N*CW-1:0] umi_in_cmd,
Expand All @@ -61,25 +68,33 @@ module umi_switch
input [M-1:0] umi_out_ready
);

genvar i;
genvar i,j;

wire [M*N-1:0] umi_ready;
wire [M*N-1:0] umi_ready;
wire [N*M-1:0] umi_valid;

//#######################################################
// Output Ports
//#######################################################

// data broadcasted to all output ports for M inputs
// N individual valids sent to each port
// M*N ready signals generated
// disable loopback
for (i=0;i<M;i=i+1)
begin: mask
for (j=0;j<N;j=j+1)
if(MASK[i*N+j])
assign umi_valid[i*N+j] = 1'b0;
else
assign umi_valid[i*N+j] = umi_in_valid[i*N+j];
end

// instantiate M output ports
for (i=0;i<M;i=i+1)
begin
begin: port
umi_port #(.N(N),
.DW(DW),
.CW(CW),
.AW(AW))
out (// Outputs
i0 (// Outputs
.umi_in_ready (umi_ready[i*N+:N]),
.umi_out_valid (umi_out_valid[i]),
.umi_out_cmd (umi_out_cmd[i*CW+:CW]),
Expand All @@ -91,7 +106,7 @@ module umi_switch
.nreset (nreset),
.arbmode (arbmode[1:0]),
.arbmask (arbmask[i*N+:N]),
.umi_in_valid (umi_in_valid[i*N+:N]),
.umi_in_valid (umi_valid[i*N+:N]),
.umi_in_cmd (umi_in_cmd[N*CW-1:0]),
.umi_in_dstaddr (umi_in_dstaddr[N*AW-1:0]),
.umi_in_srcaddr (umi_in_srcaddr[N*AW-1:0]),
Expand All @@ -103,13 +118,117 @@ module umi_switch
// Merge ready signals from all ports
//##########################################

integer j,k;
integer n,m;
always @(*)
begin
umi_in_ready[N-1:0] = {N{1'b1}};
for (j=0;j<N;j=j+1)
for (k=0;k<M;k=k+1)
umi_in_ready[j] = umi_in_ready[j] & umi_ready[j+N*k];
for (n=0;n<N;n=n+1)
for (m=0;m<M;m=m+1)
umi_in_ready[n] = umi_in_ready[n] & umi_ready[n+N*m];
end

endmodule

//#####################################################################
// A SIMPLE TESTBENCH
//#####################################################################

`ifdef TB_UMI_SWITCH
module tb();

// sim params
parameter PERIOD = 2;
parameter TIMEOUT = PERIOD * 50;

// dut params
parameter CW = 32;
parameter AW = 64;
parameter DW = 128;
parameter M = 4;
parameter N = 4;
parameter MASK = 16'h8421; // disable loopback

// control block
initial
begin
$timeformat(-9, 0, " ns", 20);
$dumpfile("dump.vcd");
$dumpvars(0, tb);
#(TIMEOUT)
$finish;
end

// test program
initial
begin
#(1)
clk = 'b0;
nreset = 'b0;
umi_out_ready = {(N){1'b1}};
umi_in_valid = {(N*M){1'b1}};
umi_in_cmd = 'b0;
umi_in_dstaddr = 'b0;
umi_in_srcaddr = 'b0;
umi_in_data = 'b0;
#(PERIOD * 10)
nreset = 1'b1;
end

// clk
always
#(PERIOD/2) clk = ~clk;

/*AUTOREGINPUT*/
// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)
reg [N*M-1:0] arbmask;
reg [1:0] arbmode;
reg clk;
reg nreset;
reg [N*CW-1:0] umi_in_cmd;
reg [N*DW-1:0] umi_in_data;
reg [N*AW-1:0] umi_in_dstaddr;
reg [N*AW-1:0] umi_in_srcaddr;
reg [N*M-1:0] umi_in_valid;
reg [M-1:0] umi_out_ready;
// End of automatics

/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [N-1:0] umi_in_ready;
wire [M*CW-1:0] umi_out_cmd;
wire [M*DW-1:0] umi_out_data;
wire [M*AW-1:0] umi_out_dstaddr;
wire [M*AW-1:0] umi_out_srcaddr;
wire [M-1:0] umi_out_valid;
// End of automatics

umi_switch #(/*AUTOINSTPARAM*/
// Parameters
.N (N),
.M (M),
.MASK (MASK[M*N-1:0]),
.DW (DW),
.CW (CW),
.AW (AW))
umi_switch(/*AUTOINST*/
// Outputs
.umi_in_ready (umi_in_ready[N-1:0]),
.umi_out_valid (umi_out_valid[M-1:0]),
.umi_out_cmd (umi_out_cmd[M*CW-1:0]),
.umi_out_dstaddr (umi_out_dstaddr[M*AW-1:0]),
.umi_out_srcaddr (umi_out_srcaddr[M*AW-1:0]),
.umi_out_data (umi_out_data[M*DW-1:0]),
// Inputs
.clk (clk),
.nreset (nreset),
.arbmode (arbmode[1:0]),
.arbmask (arbmask[N*M-1:0]),
.umi_in_valid (umi_in_valid[N*M-1:0]),
.umi_in_cmd (umi_in_cmd[N*CW-1:0]),
.umi_in_dstaddr (umi_in_dstaddr[N*AW-1:0]),
.umi_in_srcaddr (umi_in_srcaddr[N*AW-1:0]),
.umi_in_data (umi_in_data[N*DW-1:0]),
.umi_out_ready (umi_out_ready[M-1:0]));

endmodule
`endif

0 comments on commit fab2eb0

Please sign in to comment.