Why are output nets also required to be redeclared as either 'wire' or 'reg'? - verilog

Why do we have to take the same variable name of an output and also wire for getting the value? eg:
module TEST(INP1,INP2,CIN,COUT,SUM);
input [31:0] INP1;
input [31:0] INP2;
output [31:0] SUM;
input CIN;
output COUT;
wire [31:0] SUM;// Again redefined
wire COUT; // Again Redefined
assign {COUT,SUM} = INP1 + INP2 + CIN ;
Example for getting the Carry-out and the Sum of two numbers and Carry-In taken as the input.

Verilog 1995 did require the port direction to be listed after. Output wire types were implicit and regs could be declared inline with direction.
module TEST(A,B,C,D);
input [31:0] A;
input [31:0] B;
output [31:0] C;
output D;
reg D;
could be written as:
module TEST(A,B,C,D);
input [31:0] A;
input [31:0] B;
output [31:0] C;
output reg D; //Only declared twice
Since Verilog 2001 the extra definition is no longer required and they can be declared inline (ANSI-Style).
module TEST(
input [31:0] A,
input [31:0] B,
output [31:0] C,
output reg D // Declared Once
);
From SystemVerilog (2009) we have the logic type, you no longer have to switch between reg and wire types. The only requirement is that if you need to tri-state use wire or tri.
module TEST(
input [31:0] A,
input [31:0] B,
output logic [31:0] C,
output logic D
);
My understanding of the original requirement for having reg and wire types was for simulation speed or ease of simulator design. The value of a wire is evaluated every simulation delta cycle while a reg is only evaluated when triggered by the sensitivity list.

It is not necessary to declare an output also as a wire. Furthermore, you can avoid duplicating the port list by using ANSI-stlye port declarations:
module TEST (
input [31:0] INP1,
input [31:0] INP2,
output [31:0] SUM,
input CIN,
output COUT
);
assign {COUT,SUM} = INP1 + INP2 + CIN ;
endmodule
In your example, you do not need to declare outputs as reg. But, if you need to for another circuit, you can declare the type on the same line, such as:
output reg [31:0] Q;

Because just declaring a net as output doesn't describe if it is a reg type or a wire type.
An output can either be driven by a wire or reg, you have to tell it what type the driver is going to be.

Related

Verilog If else "Signal not a constant" error

I am trying to instantiate modules inside various if else statements but i am getting the error with the first argument in the if parenthesis "signal is not a constant".All my arguments in the parenthesis of my if and if else statements are input wires,and i can't figure whats wrong
Thanks
I've tried passing the signals from a matrix to a single input for each position of the matrix but that didn't work either
Heres my some of my code below
The error is as follows:[Synth 8-35] 'neuron_valid11' is not a constant
`include "include.v"
module FeedForward(
//Input
input wire[`dataWidth-1:0] sensor1,
input wire[`dataWidth-1:0] sensor2,
input wire[`dataWidth-1:0] sensor3,
input wire[`dataWidth-1:0] sensor4,
input wire[`dataWidth-1:0] sensor5,
input wire[`dataWidth-1:0] sensor6,
input wire neuron_valid11,
input wire neuron_valid12,
input wire neuron_valid13,
input wire neuron_valid14,
input wire neuron_valid15,
input wire neuron_valid16,
input wire neuron_valid17,
input wire neuron_valid18,
input wire neuron_valid21,
input wire neuron_valid22,
input wire neuron_valid23,
input wire neuron_valid24,
input wire neuron_valid25,
input wire neuron_valid26,
input wire neuron_valid27,
input wire neuron_valid28,
input wire[(`dataWidth/2)-1:0] targetVals
);
wire [7:0] weightValue;
wire [7:0] biasValue;
wire [7:0] out;
integer Loop;
wire ActiveN1;
wire ActiveN2;
wire ActiveN3;
wire ActiveN4;
wire ActiveN5;
wire ActiveN6;
wire ActiveN7;
wire ActiveN8;
wire reset;
localparam IDLE = 'd0,
SEND = 'd1;
wire [`numNeuronLayer1-1:0] o1_valid;
wire [`numNeuronLayer1*`dataWidth-1:0] x1_out;
reg [`numNeuronLayer1*`dataWidth-1:0] holdData_1;
reg [`dataWidth-1:0] out_data_1;
reg data_out_valid_1;
if(neuron_valid11==1&&neuron_valid12==1&&neuron_valid13==1&&neuron_valid14==0&&neuron_valid15==1&&neuron_valid16==0&&neuron_valid17==0&&neuron_valid18==0)begin
Layer_1 #(.NN(`numNeuronLayer1),.numWeight(`numWeightLayer1),.dataWidth(`dataWidth),.layerNum(1),.sigmoidSize(`sigmoidSize),.weightIntWidth(`weightIntWidth),.actType(`Layer1ActType)) l1(
.ActiveN1(1),
.ActiveN2(1),
.ActiveN3(1),
.ActiveN4(0),
.ActiveN5(1),
.ActiveN6(0),
.ActiveN7(0),
.ActiveN8(0),
.clk(s_axi_aclk),
.rst(reset),
.weightValue(weightValue),
.biasValue(biasValue),
.sensor1(sensor1),
.sensor2(sensor2),
.sensor3(sensor3),
.sensor4(sensor4),
.sensor5(sensor5),
.sensor6(sensor6),
.o_valid(o1_valid),
.x_out(x1_out)
);
end
What you have written is
// If a wire equals 1
if(neuron_valid11==1...)begin
// Declare a module instance
Layer_1 #(..)(...);
end
You can't say 'while the design is running, if this wire has a certain value==1 then these modules exist in my design' - doesn't make sense. The module is a physical thing, fixed there or not, not popping in and out of existence.
You can at compile time do 'if MY_PARAM=SOMETHING begin, then instantiate your module' as long as the value is constant (as your error says). See https://www.chipverify.com/verilog/verilog-generate-block.
Or perhaps you want to select/mux signals into your module (maybe you want it disconnected/disabled sometimes and not others based on some condition). You would do that inside a always block, ex. checking if(neuron_valid11==1 and driving signals that connect to your (always-existing) module instance. https://www.chipverify.com/verilog/verilog-4to1-mux

Leaving some bits in the port vector disconnected. Verilog module instantiation

Lets say I have a Verilog module with bit vector ports. How do I
instantiate it with some bits left unconnected?
I tried something like this but it didn't work:
module sub (in,out)
input [3:0] in;
output [3:0] out;
endmodule
module top;
wire [1:0] a1;
wire [1:0] c1;
sub Sub1(
.in[2:1](a1[1:0]),
.out[2:1](c1[1:0])
);
endomdule
It would be much easier to just declare signals of the correct size and use a continuous assignment
module top;
wire [1:0] a1;
wire [1:0] c1;
wire [3:0] pin;
wire [3:0] pout;
assign pin[2:1] = a1;
assign c1 = pout[2:1];
sub Sub1(
.in(pin),
.out(pout)
);
endomdule
In general, it is not a good idea to leave input ports floating. You could use a concatenation in the assignment, or directly in the port connection.
sub Sub1(
.in({1'b0,a1,1'b0}),
.out({pout[3],c1,pout[0]})
);
SystemVerilog has a net aliasing construct that makes thing even simpler
module top;
wire [3:0] pin;
wire [3:0] pout;
alias pin[2:1] = a1;
alias pout[2:1] = c1;
sub Sub1(
.in(pin),
.out(pout)
);
endomdule
Found LRM reference on why you cannot connect parts of ports.
LRM 1800-2012 Section 23.3.2.2 Connecting module instance ports by name:
The port_name shall be the name specified in the module declaration. The port name cannot be a bit-select, a part-select, or a concatenation of ports.
you cannot connect/disconnect parts of a port. You can do it with the whole port though. so, in your case you nedd to split your port in several parts, something like the following:
module sub (in1, in2, out1, out2);
input [2:1] in1;
input [1:0] in2;
output [2:1] out1;
output [1:0] out2;
endmodule
module top;
wire [1:0] a1;
wire [1:0] c1;
sub Sub1(
.in1(a1[1:0]),
.in2(),
.out1(c1[1:0]),
.out2()
);
endmodule
My code connect 4-bits to module's 8-bit outputs, upper/lower even middle part.
It does work, but what the hell is the 's'(or anything)?
It works in both Quartus Prime 18.0pro and Lattice Diamond 3.10(Symplify Pro).
module dff8
(
input clk,
input [7:0] a,
output reg [7:0] b
);
always # (posedge clk) begin
b <= a;
end
endmodule
module top
(
input clk,
input [7:0] x,
output [3:0] y,
output [3:0] z
);
dff8 u0 (.clk(clk), .a(x), .b({y,s,s,s,s}));
dff8 u1 (.clk(clk), .a(x), .b({s,s,s,s,z}));
endmodule

Confused with ripple carry adder output

I am working on a ripple carry adder using structural verilog, which is supposed to take in two random inputs and calculate accordingly.
The general rca I created calculated correctly, but for some reason I get weird outputs when I add a for loop and use the $random to generate.
Could someone kindly explain where I'm going wrong? Below is my code:
module full_adder(x,y,z,v,cout);
parameter delay = 1;
input x,y,z; //input a, b and c
output v,cout; //sum and carry out
xor #delay x1(w1,x,y);
xor #delay x2(v,w1,z);
and #delay a1(w2,z,y);
and #delay a2(w3,z,x);
and #delay a3(w4,x,y);
or #delay o1(cout, w2,w3,w4);
endmodule
module four_bit_adder(a,b,s,cout,cin);//four_bit_adder
input [15:0] a,b; //input a, b
input cin; //carry in
output [15:0] s; //output s
output cout; //carry out
wire [15:0] c;
full_adder fa1(a[0],b[0],cin,s[0],c0);
full_adder fa2(a[1],b[1],c0,s[1],c1);
.
.
.
full_adder fa16(a[15],b[15],c14,s[15],cout);
endmodule
module testAdder(a,b,s,cout,cin);
input [15:0] s;
input cout;
output [15:0] a,b;
output cin;
reg [15:0] a,b;
reg cin;
integer i;
integer seed1=4;
integer seed2=5;
initial begin
for(i=0; i<5000; i=i+1) begin
a = $random(seed1);
b = $random(seed2);
$monitor("a=%d, b=%d, cin=%d, s=%d, cout=%d",a,b,cin,s,cout);
$display("a=%d, b=%d, cin=%d, s=%d, cout=%d",a,b,cin,s,cout);
end
end
endmodule
Here are two lines from the output that I get:
a=38893, b=58591, cin=x, s= z, cout=z
a=55136, b=58098, cin=x, s= z, cout=z
This is a combinational circuit, so the output changes instantaneously as the input changes. But, here you are apply all the inputs at same timestamp which should not be done since the full_adder module provides 1-timestamp delay. This may not cause problems in this module, but may cause issues while modelling sequential logic. Add a minimum of #10 delay between inputs.
Also, $monitor executes on each change in the signal list, so no need to use it in for loop. Just initialize $monitor in initial condition.
cin is also not driven from the testbench. Default value of reg is 'x and that of wire is 'z. Here, cin is reg, so the default value is displayed, that is 'x
One more thing, you must instantiate the design in your testbench. And connect respective ports. The outputs from testbench act as inputs to your design and vice-versa. This is just like you instantiate full_adder module in four_bit_adder module in design.
Consider testadder as top level module and instantiate design in it. No need of declaring ports as input and output in this module. Declare the design input ports as reg or wire(example: reg [15:0] a when a is design input port) and output ports as wire (example: wire [15:0] sum when sum is design input port).
Referring to your question:
The general rca I created calculated correctly, but for some reason I get weird outputs when I add a for loop and use the $random to generate.
Instead of using $random, use $urandom_range() to generate random numbers in some range. Using SystemVerilog constraints constructs can also help. Refer this link.
Using $urandom_range shall eliminate use of seed1 and seed2, it shall generate random values with some random machine seed.
Following is the module testadder with some of the changes required:
module testAdder();
wire [15:0] s;
wire cout;
// output [15:0] a,b;
// output cin;
reg [15:0] a,b;
reg cin;
integer i;
integer seed1=4;
integer seed2=5;
// Instantiate design here
four_bit_adder fa(a,b,s,cout,cin);
initial begin
// Monitor here, only single time
$monitor("a=%d, b=%d, cin=%d, s=%d, cout=%d",a,b,cin,s,cout);
for(i=0; i<5000; i=i+1) begin
// Drive inputs with some delays.
#10;
// URANDOM_RANGE for input generation in a range
a = $urandom_range(0,15);
b = $urandom_range(0,15);
// a = $random(seed1);
// b = $random(seed2);
// Drive cin randomly.
cin = $random;
$display("a=%d, b=%d, cin=%d, s=%d, cout=%d",a,b,cin,s,cout);
end
end
endmodule
For more information, have a look at sample testbench at this link.

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.

Verilog generate statement issue

I was trying to use the generate function in Verilog. The code compiled successfully, but it couldn't simulate. I get the following errors:
Illegal output or inout port connection for "port 'sum'".
Illegal output or inout port connection for "port 'carry'".
Could anyone tell me what am I doing wrong?
module test(input wire [2:0] a,
input wire [2:0] b,
output reg [2:0] s,
output reg [2:0] c);
genvar i;
generate
for(i=0;i<3;i=i+1)
adder_half inst(.sum(s[i]),.carry(c[i]),.a(a[i]),.b(b[i]));
endgenerate
endmodule
module adder_half(
output sum,carry,
input a,b
);
xor(sum,a,b);
and(carry,a,b);
endmodule
The reg type is only used for procedural assignments, but instance connections are treated more like continuous assignments.
Remove the reg keyword from your outputs. Change:
output reg [2:0] s,
output reg [2:0] c);
to:
output [2:0] s,
output [2:0] c);

Resources