Verilog: connect a port of modules without creating a new wire
Is there a way to connect two module ports without creating a new wire?
small example:
module comparator(max,min,in0,in1);
input[7:0] in0,in1;
output[7:0] max,min;
wire[7:0] in0;
wire[7:0] in1;
wire[7:0] max;
wire[7:0] min;
assign max = (in0>in1) ? in0 : in1;
assign min = (in0<in1) ? in0 : in1;
endmodule
I want to connect 2 comparator modules without using a new wire, is there some implicit connection? I really need a way to do a thing like this to make this network:
there are many wires between the modules.
source to share
I am assuming that you want one module to create the module many times comparator
in a way that looks like your diagram. You will need an array (two dimensional in my solution) - this is a parameter driven width for maximum flexibility. Within the block, generate
use the commands for-loops
and if-else
to create connections. My solution uses a slice of an array, eg. +:
...
This follows IEEE Std (1800-2009) and should also be true for IEEE Std (1800-2005).
module comparator_list #(parameter int SIZE=10) (input logic [7:0] in [SIZE-1:0], output logic [7:0] out [SIZE-1:0]);
generate
if (SIZE==1) begin : pass_through
always_comb out = in;
end : pass_through
else if (SIZE==2) begin : simple
comparator c0 ( .max(out[0]), .min(out[1]), .in0(in[0]), .in1(in[1]) );
end : simple
else if (SIZE%2==1) begin : odd_list
logic [7:0] in_buf [SIZE:0];
logic [7:0] out_buf [SIZE:0];
always_comb begin : link_in
foreach(in[idx]) in_buf[idx] = in[idx];
in_buf[SIZE] = 8'h00; // force last entry to 'h0 if unasigned, 'h80 if signed
end : link_in
always_comb begin : link_out
foreach(out[idx]) out[idx] = out_buf[idx];
// Note: out_buf[SIZE] is don't care
end : link_out
comparator_list #(SIZE+1) cl (.in(in_buf), .out(out_buf));
end : odd_list
else begin : even_list
logic [(SIZE/2)*8-1:0] top [SIZE+1];
logic [(SIZE/2)*8-1:0] bot [SIZE+1];
for(genvar idx=0; idx<SIZE/2; idx+=1) begin : map
always_comb {top[0][idx*8+:8],bot[0][idx*8+:8]} = {in[2*idx],in[2*idx+1]};
always_comb {out[2*idx],out[2*idx+1]} = {top[SIZE][idx*8+:8],bot[SIZE][idx*8+:8]};
end : map
for(genvar stage=0; stage<SIZE; stage++) begin : link
if(stage%2==0) begin : even
comparator c0[SIZE/2-1:0] (
.max(top[stage+1][0+:(SIZE/2)*8]), .in0(top[stage][0+:(SIZE/2)*8]),
.min(bot[stage+1][0+:(SIZE/2)*8]), .in1(bot[stage][0+:(SIZE/2)*8]) );
end : even
else begin : odd
assign top[stage+1][7:0] = top[stage][7:0];
comparator c1[SIZE/2-2:0] (
.max(bot[stage+1][0+:(SIZE/2-1)*8]),
.min(top[stage+1][8+:(SIZE/2-1)*8]),
.in0(bot[stage][0+:(SIZE/2-1)*8]),
.in1(top[stage][8+:(SIZE/2-1)*8])
);
assign bot[stage+1][(SIZE/2-1)*8+:8] = bot[stage][(SIZE/2-1)*8+:8];
end : odd
end : link
end : even_list
endgenerate
endmodule : comparator_list
source to share
IEEE Std (1364-2001) introduced a construct generate
to allow multiple instances to be combined together.
IEEE Std (1800-2005) introduced the point-to-star ( .*
) syntax , also known as implicit port connections, to reduce wires. If you are using modern tools, they should support this SystemVerilog syntax.
source to share