How can I build a chain of modules? - verilog

I am having trouble in building a chain of modules. I can connect models manually listing all the modules but need more concise representation. The following code has been tried but doesn't work? How can I correct the codes?
module network(
input signed [31:0] xi,
output signed [31:0] yo,
input clk,
input reset
);
wire signed [31:0] x0, x1, x2, y0, y1, y2, xo;
wire [3:1] t;
//working code for chain of pe
// pe u0(xi, x0, 0, y0, clk, reset);
// pe u1(x0, x1, y0, y1, clk, reset);
// pe u2(x1, x2, y1, y2, clk, reset);
// pe u3(x2, xo, y2, yo, clk, reset);
//chain of array not working! how!
pe p[1:4] ((xi,t), (t, x), (0, t), (t,yo),clk,reset); <- want to improve
endmodule
Here, pe (input,output,input,output,clk,reset).

Try this. It should work in all version of Verilog. In this instance the parameter PE_NUM must be an int with a value of 2 or more. A generate block must be use if a 1 pe instance is desired, which requires Verilog-2001 or SystemVerilog. Some simulators may have an hit a memory limitation when PE_NUM gets big (ex 2**16).
/*All Verilog*/
module network(
input signed [31:0] xi,
output signed [31:0] yo,
input clk,
input reset
);
parameter PE_NUM = 4; // limitation PE_NUM must be greater then 1
wire signed [31:0] xo;
wire signed [0:PE_NUM-2] [31:0] xN;
wire signed [0:PE_NUM-2] [31:0] yN;
pe p[0:PE_NUM-1] ({xi,xN}, {xN,xo}, {32'b0,yN}, {yN,yo}, clk,reset);
endmodule
The following is an example with generate:
/*Verilog-2001 or SystemVerilog*/
module network(
input signed [31:0] xi,
output signed [31:0] yo,
input clk,
input reset
);
parameter PE_NUM = 4; // no limitation
wire signed [31:0] xo;
generate
if(PE_NUM <2) begin
pe p (xi, xo, 32'b0, yo, clk,reset);
end
else begin
wire signed [0:PE_NUM-2] [31:0] xN;
wire signed [0:PE_NUM-2] [31:0] yN;
pe p[0:PE_NUM-1] ({xi,xN}, {xN,xo}, {32'b0,yN}, {yN,yo}, clk,reset);
end
endgenerate
endmodule

Related

How can I fix this error 'Unknown module type'?

My top model:
module top (G1, Y1, R1, G2, Y2, R2, BT1, BT2, clk, rst);
input BT1, BT2, clk, rst;
output G1, Y1, R1, G2, Y2, R2;
wire En1, En2, En3, CNT_RES, FF_RES, TC_30, TC_5, GE_15, B1, B2, request;
Controll_Unit c1(G1, Y1, R1, G2, Y2, R2, CNT_RES, FF_RES, B1, B2, BT1, BT2, clk, rst, En1, En2, En3);
Counter t1(TC_30, TC_5, GE_15, CNT_RES, FF_RES, rst, clk);
dff_sr q1(GE_15, clk, request);
assign En1=TC_30||GE_15&&B1;
assign En2=TC_30||GE_15&&B2;
assign En3=TC_5;
assign request = BT1||BT2;
endmodule
My dff model:
module dff_sr(output GE_15 ,input clk, request);
reg GE_15;
always #(posedge clk)
begin
if(request)
GE_15<=1;
end
endmodule
Why does my dff_sr code have this unknown error? I want this problem quickly solved.
You have mixed up ANSI and non-ANSI module port declarations. Change:
module dff_sr(output GE_15 ,input clk, request);
reg GE_15;
to:
module dff_sr(output reg GE_15 ,input clk, request);
This uses ANSI style. I don't get the same error as you do, but I do get this compile warning on Cadence:
reg GE_15;
| xmvlog: *W,ILLPDX : Multiple declarations for a port not allowed
in module with ANSI list of port declarations (port 'GE_15') [12.3.4(IEEE-2001)].
Refer to IEEE Std 1800-2017, section 23.2.2 Port declarations.

Connect 5-bit bus to 32-bit output bus

My design needs multiple multiplexers, all of them have two inputs and most are 32 bits wide. I started with designing the 32 bit, 2:1 multiplexer.
Now I need a 5 bit, 2:1 multiplexer and I want to reuse my 32 bit design. Connecting the inputs is easy (see code below), but I struggle to connect the output.
This is my code:
reg [4:0] a, b; // Inputs to the multiplexer.
reg select; // Select multiplexer output.
wire [4:0] result; // Output of the multiplexer.
multiplex32_2 mul({27'h0, a}, {27'h0, b}, select, result);
When I run the code through iverilog, I get a warning that says that the multiplexer expects a 32 bit output, but the connected bus is only 5 bit wide. The simulation shows the expected results, but I want to get rid of the warning.
Is there a way to tell iverilog to ignore the 27 unused bits of the multiplexer output or do I have to connect a 32 bit wide bus to the output of the multiplexer?
I don't know of a #pragma or something like that (similar to #pragma argsused from C) that can be used in Verilog.
Xilinx ISE, for example, has a feature called "message filtering", which allows the designer to silence specific warning messages. You find them once, select them, choose to ignore, and subsequent synthesis won't trigger those warnings.
Maybe you can design your multiplexer in a way you don't need to "waste" connections (not actually wasted though, as the synthesizer will prune unused connections from the netlist). A more elegant solution would be to use a parametrized module, and instantiate it with the required width. Something like this:
module mux #(parameter WIDTH=32) (
input wire [WIDTH-1:0] a,
input wire [WIDTH-1:0] b,
input wire sel,
output wire [WIDTH-1:0] o
);
assign o = (sel==1'b0)? a : b;
endmodule
This module has been tested with this simple test bench, which shows you how to instantiate a module with params:
module tb;
reg [31:0] a1,b1;
reg sel;
wire [31:0] o1;
reg [4:0] a2,b2;
wire [4:0] o2;
mux #(32) mux32 (a1,b1,sel,o1);
mux #(5) mux5 (a2,b2,sel,o2);
// Best way to instantiate them:
// mux #(.WIDTH(32)) mux32 (.a(a1),.b(b1),.sel(sel),o(o1));
// mux #(.WIDTH(5)) mux5 (.a(a2),.b(b2),.sel(sel),.o(o2));
initial begin
$dumpfile ("dump.vcd");
$dumpvars (1, tb);
a1 = 32'h01234567;
b1 = 32'h89ABCDEF;
a2 = 5'b11111;
b2 = 5'b00000;
repeat (4) begin
sel = 1'b0;
#10;
sel = 1'b1;
#10;
end
end
endmodule
You can test it yourself using this Eda Playground link:
http://www.edaplayground.com/x/Pkz
I think the problem relates to the output of the multiplexer which is still 5 bits wide. You can solve it by doing something like this:
reg [4:0] a, b; // Inputs to the multiplexer.
reg select; // Select multiplexer output.
wire [31:0] temp;
wire [4:0] result; // Output of the multiplexer.
multiplex32_2 mul({27'h0, a}, {27'h0, b}, select, temp);
assign result = temp[4:0];
This can be easily tested in http://www.edaplayground.com/ using the code below:
( I have re-used #mcleod_ideafix's code)
// Code your testbench here
// or browse Examples
module mux #(parameter WIDTH=32) (
input wire [WIDTH-1:0] a,
input wire [WIDTH-1:0] b,
input wire sel,
output wire [WIDTH-1:0] o
);
assign o = (sel==1'b0)? a : b;
endmodule
module tb;
reg [31:0] a,b;
wire [31:0] o;
wire [4:0] r;
reg sel;
initial begin
$dumpfile("dump.vcd"); $dumpvars;
a = 10; b = 20; sel = 1;
end
mux MM(a,b,sel,o);
assign r = o[4:0];
endmodule
Let me know if you are still getting a warning.

How I can find maximum number in verilog array

So, I have a reg[7:0] corr_Output[0:63]; which is filled with values in my module. How I can find maximum number in this array at one CLK cycle?
I wrote a 8 bit comparator:
module Comparator2D(
input [7:0] X1,
input [7:0] indexX1,
input [7:0] X2,
input [7:0] indexX2,
output [7:0] Y,
output [7:0] indexY
);
always begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
But I dont know how I should instantiate this module in my top design? I think I should use "for loop", or even write another module which will concatenate my Comparator2D module in pyramid form, but as I found I cant pass whole array to input port of module, so Im a little stuck..
You can do it by using for/generate, like in this code sample, in which I can compare 8 bytes at a time.
The key point is that I cannot pass a memory as input (an array of registers), but I can pass an array of bits that hold the current values from memory.
// This is just your compare module.
module C2D (
input wire [7:0] X1,
input wire [7:0] indexX1,
input wire [7:0] X2,
input wire [7:0] indexX2,
output reg [7:0] Y,
output reg [7:0] indexY
);
always #* begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
// Compare 8 bytes at a time
module greatest8bytes (
input wire [63:0] array, // 8 byte array
output wire [7:0] indexG,
output wire [7:0] valueG
);
wire [7:0] value_l1[0:3];
wire [7:0] index_l1[0:3];
genvar i;
generate
for (i=0;i<8;i=i+2) begin :gen_comps_l1
C2D cl1 (array[i*8+7:i*8],
i,
array[(i+1)*8+7:(i+1)*8],
(i+1),
value_l1[i/2],
index_l1[i/2]
);
end
endgenerate
wire [7:0] value_l2[0:1];
wire [7:0] index_l2[0:1];
generate
for (i=0;i<4;i=i+2) begin :gen_comps_l2
C2D cl2 (value_l1[i],
index_l1[i],
value_l1[i+1],
index_l1[i+1],
value_l2[i/2],
index_l2[i/2]
);
end
endgenerate
wire [7:0] value_l3[0:0];
wire [7:0] index_l3[0:0];
generate
for (i=0;i<2;i=i+2) begin :gen_comps_l3
C2D cl3 (value_l2[i],
index_l2[i],
value_l2[i+1],
index_l2[i+1],
value_l3[i/2],
index_l3[i/2]
);
end
endgenerate
assign indexG = index_l3[0];
assign valueG = value_l3[0];
endmodule
The greatest8bytes module is synthesized the way you expect: as a pyramid-like arrangement of comparators:
To connect an array of regs (a memory) to the input of this module, create a wire of the desired number of bits (64 in this example) and concatenate all elements of memory, like in this example module:
module findgreatest (
input wire clk,
input wire [2:0] addr,
input wire [7:0] data,
input wire we,
output wire [2:0] indexG,
output wire [7:0] valueG
);
reg [7:0] memory[0:7]; // 8 bytes
// To load data from the outside so the synthesizer won't throw away memory
always #(posedge clk) begin
if (we)
memory[addr] <= data;
end
wire [63:0] array = {memory[7],memory[6],memory[5],memory[4],
memory[3],memory[2],memory[1],memory[0]};
greatest8bytes compar (array, indexG, valueG);
endmodule
Not sure if this is synthesizable, but it is good to know that SystemVerilog has built in min and max functions:
module maximum ();
reg[7:0] corr_Output[0:63] = '{0:8'd112, 2:8'd250, 3:8'd37, 4:8'd15, default:8'd25};
reg[7:0] max_i[$];
reg[7:0] min_i[$];
initial begin
max_i = corr_Output.max;
min_i = corr_Output.min;
$display ("max=%d, min=%d", max_i[0], min_i[0]);
end
endmodule
Output:
# max=250, min= 15
Alternatively, it is probably shorter to just use this classic and synthesizable for-loop of comparisons:
always_comb begin
max = corr_Output[0];
for (c = 0; c <= 63; c++)
begin
if (corr_Output[c] > max)
begin
max = array[c];
index = c;
end
end

replication operator for ignoring bit

Is it is possible to selectively map bits from an output of a module? For example:
module A (
input wire [4:0] X,
output wire [4:0] Y
)
endmodule
module B (
..
)
(
wire [2:0] w;
wire [2:0] v;
A I1 (
.X ({{2{1'b1}},w}),
.Y (??????,v)
);
endmodule
Is there any syntax that would allow me to pick desired bits for wire v without having to create an additional wire and using assign statements?
You could just make this connection:
.Y (v)
but you'll likely get compile warnings from your simulator.
To avoid the warnings, you could create a wire, but there is no need for an assign:
module A (
input wire [4:0] X,
output wire [4:0] Y
);
endmodule
module B;
wire [2:0] w;
wire [2:0] v;
wire [1:0] noconn;
A I1 (
.X ({{2{1'b1}},w}),
.Y ({noconn, v})
);
endmodule

How do I instantiate two modules with one module in Verilog?

How can I instantiate copies of two different modules by a third module?
module instantiate (modx, mody);
// ?
endmodule
Just instantiate them. add instantiated twice with block names of add_0 add_1. for different modules just instantiate them as you would a your main block in a testharness.
module add(
input [31:0] i, //32 bit unsigned
input [31:0] j, //32 bit unsigned
output reg [31:0] y //32 bit unsigned
);
always #* begin
y = i + j;
end
endmodule
module instantiate (modx, mody);
reg [31:0] a; //reg or wire depending on how it is driven
reg [31:0] b;
reg [31:0] c;
reg [31:0] d;
wire [31:0] sum1; //wire or logic as driven from an output port
wire [31:0] sum2;
add add_0(
.i( a ),
.j( b ),
.y( sum1 )
);
add add_1(
.i( c ),
.j( d ),
.y( sum2 )
);
endmodule

Resources