2021-03-12 01:22:19 +01:00
// DESCRIPTION: Verilator: Verilog Test module
//
2026-01-27 02:24:34 +01:00
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2021 Wilson Snyder
2021-03-12 01:22:19 +01:00
// SPDX-License-Identifier: CC0-1.0
2026-03-10 02:38:29 +01:00
// verilog_format: off
2021-03-12 01:22:19 +01: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-10 02:38:29 +01:00
// verilog_format: on
2021-03-12 01:22:19 +01:00
interface intf ( ) ;
2026-03-10 02:38:29 +01:00
integer value ;
2021-03-12 01:22:19 +01:00
endinterface
2026-03-10 02:38:29 +01:00
module fanout # (
parameter int N = 1
) (
2021-03-12 01:22:19 +01:00
intf upstream ,
intf downstream [ N - 1 : 0 ]
2026-03-10 02:38:29 +01:00
) ;
2021-03-12 01:22:19 +01:00
2026-03-10 02:38:29 +01:00
genvar i ;
for ( i = 0 ; i < N ; i = i + 1 ) assign downstream [ i ] . value = upstream . value ;
2021-03-12 01:22:19 +01:00
endmodule
2026-03-10 02:38:29 +01: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-12 01:22:19 +01:00
endmodule
2026-03-10 02:38:29 +01:00
module t (
clk
) ;
input clk ;
2021-03-12 01:22:19 +01:00
2026-03-10 02:38:29 +01:00
intf masters [ 1 : 0 ] ( ) ;
2021-03-12 01:22:19 +01:00
2026-03-10 02:38:29 +01:00
int cyc ;
2021-03-12 01:22:19 +01:00
2026-03-10 02:38:29 +01:00
xbar sub (
. clk ,
2021-03-12 01:22:19 +01:00
. cyc ,
2026-03-10 02:38:29 +01: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-12 01:22:19 +01:00
endmodule