2021-03-11 19:22:19 -05:00
// DESCRIPTION: Verilator: Verilog Test module
//
2026-01-26 20:24:34 -05:00
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2021 Wilson Snyder
2021-03-11 19:22:19 -05:00
// SPDX-License-Identifier: CC0-1.0
2026-03-09 21:38:29 -04:00
// verilog_format: off
2021-03-11 19:22:19 -05:00
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
2026-03-09 21:38:29 -04:00
// verilog_format: on
2021-03-11 19:22:19 -05:00
interface intf ();
2026-03-09 21:38:29 -04:00
integer value ;
2021-03-11 19:22:19 -05:00
endinterface
2026-03-09 21:38:29 -04:00
module fanout #(
parameter int N = 1
) (
2021-03-11 19:22:19 -05:00
intf upstream ,
intf downstream [ N - 1 : 0 ]
2026-03-09 21:38:29 -04:00
);
2021-03-11 19:22:19 -05:00
2026-03-09 21:38:29 -04:00
genvar i ;
for ( i = 0 ; i < N ; i = i + 1 ) assign downstream [ i ]. value = upstream . value ;
2021-03-11 19:22:19 -05:00
endmodule
2026-03-09 21:38:29 -04:00
module xbar (
input logic clk ,
input int cyc ,
intf Masters [ 1 : 0 ]
);
localparam NUM_DEMUX_OUT = 2 * 4 ;
localparam NUM_MUX_IN = 2 * 4 ;
intf demuxOut [ NUM_DEMUX_OUT - 1 : 0 ] ();
intf muxIn [ NUM_MUX_IN - 1 : 0 ] ();
//fan out master connections to the crossbar matrix
fanout #(
. N ( 4 )
) fanout_inst0 (
. upstream ( Masters [ 0 ]),
. downstream ( demuxOut [ 3 : 0 ])
);
fanout #(
. N ( 4 )
) fanout_inst1 (
. upstream ( Masters [ 1 ]),
. downstream ( demuxOut [ 7 : 4 ])
);
//the crossbar matrix assignments, done as 1D arrays because verilator doesn't currently support >1D arrays of interfaces
genvar slv , mst ;
for ( slv = 0 ; slv < 4 ; slv = slv + 1 ) begin
for ( mst = 0 ; mst < 2 ; mst = mst + 1 ) begin
localparam int muxIdx = ( slv * 2 ) + mst ;
localparam int demuxIdx = slv + ( mst * 4 );
assign muxIn [ muxIdx ]. value = demuxOut [ demuxIdx ]. value ;
end
end
always @( posedge clk ) begin
if ( cyc == 5 ) begin
`checkh ( Masters [ 0 ]. value , 2 );
`checkh ( Masters [ 1 ]. value , 1 );
// The first 4 demuxOut values should have the value of the first Master
`checkh ( demuxOut [ 0 ]. value , Masters [ 0 ]. value );
`checkh ( demuxOut [ 1 ]. value , Masters [ 0 ]. value );
`checkh ( demuxOut [ 2 ]. value , Masters [ 0 ]. value );
`checkh ( demuxOut [ 3 ]. value , Masters [ 0 ]. value );
// The next 4 demuxOut values should have the value of the second Master
`checkh ( demuxOut [ 4 ]. value , Masters [ 1 ]. value );
`checkh ( demuxOut [ 5 ]. value , Masters [ 1 ]. value );
`checkh ( demuxOut [ 6 ]. value , Masters [ 1 ]. value );
`checkh ( demuxOut [ 7 ]. value , Masters [ 1 ]. value );
// Each 2 mux inputs should have one input from each master, in order from low to high
`checkh ( muxIn [ 0 ]. value , Masters [ 0 ]. value );
`checkh ( muxIn [ 1 ]. value , Masters [ 1 ]. value );
`checkh ( muxIn [ 2 ]. value , Masters [ 0 ]. value );
`checkh ( muxIn [ 3 ]. value , Masters [ 1 ]. value );
`checkh ( muxIn [ 4 ]. value , Masters [ 0 ]. value );
`checkh ( muxIn [ 5 ]. value , Masters [ 1 ]. value );
`checkh ( muxIn [ 6 ]. value , Masters [ 0 ]. value );
`checkh ( muxIn [ 7 ]. value , Masters [ 1 ]. value );
$write ( "*-* All Finished *-* \n " );
$finish ;
end
end
2021-03-11 19:22:19 -05:00
endmodule
2026-03-09 21:38:29 -04:00
module t (
clk
);
input clk ;
2021-03-11 19:22:19 -05:00
2026-03-09 21:38:29 -04:00
intf masters [ 1 : 0 ] ();
2021-03-11 19:22:19 -05:00
2026-03-09 21:38:29 -04:00
int cyc ;
2021-03-11 19:22:19 -05:00
2026-03-09 21:38:29 -04:00
xbar sub (
. clk ,
2021-03-11 19:22:19 -05:00
. cyc ,
2026-03-09 21:38:29 -04:00
. Masters ( masters )
);
always @( posedge clk ) begin
cyc <= cyc + 1 ;
if ( cyc == 1 ) begin
masters [ 0 ]. value <= 2 ;
masters [ 1 ]. value <= 1 ;
end
end
2021-03-11 19:22:19 -05:00
endmodule