I have a verilog module that has a very long list of inputs and outputs that are required.
module mymodule(clock,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16,S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24);
I am trying to write a test bench for this module. Is there a smart way to supply the arguments as an array. About half of the arguments are inputs where the other half is outputs. I tried to do something like this based on my limited verilog experience.
reg clk = 0;
reg inputs[16:0] = 0;
wire outputs[23:0];
mymodule tc(clk, inputs, outputs);
I want the variable "inputs" to act as an array that will hold all the inputs, and "outputs" will also do the same.
I also want to be able to set all the inputs to random
inputs = $random;
Is there a way to do this in Verilog or do I have to initialize all the variables manually?
Since the module is defined with individual ports, each port must be connected to individually. Verilog does not provided built in way to auto connect ports.
SystemVerilog has .*
connections, but it only works when the net/var name matches the port name. So with SystemVerilog you could connect with intermediate assignment. (Note: all modern Verilog simulators support most, if not all, SystemVerilog features. Simply change the file extinction from .v
to .sv
to enable)
logic clock;
logic [15:0] inputs;
wire [22:0] outputs;
wire m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16;
wire S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24;
assign {m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16} = inputs;
assign outputs = {S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24};
mymodule tc( .* );
For a cleaner solution, I recommend the Emacs plugin Verilog-Mode (vim wrapper exists). This tool was specifically created to simplify long port list connectivity and other repetitive tasks that are common to Verilog projects. For example, the below would expand to an index to index connection
/* mymodule AUTO_TEMPLATE (
.m@ (inputs[\1]),
.S@ (outputs[\1]),
); */
mymodule dut (/*AUTOINST*/);
The below two templates would expand with a offset except for m18
which explicitly connects to inputs[13]
. (I picked m18
because I noticed there is no m14
and it is defined between m13
and m15
)
/* mymodule AUTO_TEMPLATE (
.m@ (inputs[@"(- \1 1)"]),
.S@ (outputs[@"(- \1 6)"]),
); */
mymodule dut (
.m18 (inputs[13]),
/*AUTOINST*/);
or
/* mymodule AUTO_TEMPLATE (
.m18 (inputs[13]),
.m@ (inputs[@"(- \1 1)"]),
.S@ (outputs[@"(- \1 6)"]),
); */
mymodule dut (/*AUTOINST*/);