Verilog module instantiation reg input output - verilog

While implementing Verilog code in behavioral modeling we are using reg as output. But, when I have to use module instantiation and connect it using a wire, it's showing an error while implementation. Is there any other way where I can use module instantiation to connect outputs of different module instances to implement combinational logic as it's illegal to connect the reg output of the previous model to a wire? Note that I have to apply behavioral modeling hence no assignment statements are allowed. This is an example to connect two half adders to one full adder.
module half_adder(input wire a,b,output reg sum,output reg carry);
always#(a or b)
begin
sum = a^b ;
carry= a & b ;
end
endmodule
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1,c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,sum,c2);
always#(a or b or c)
begin
carry = c1|c2;
end
endmodule
Error (10663): Verilog HDL Port Connection error at full_adder.v(14):
output or inout port "sum" must be connected to a structural net
expression

In standard old verilog a reg cannot be connected to a reg using module connection or a continuous assignment. System verilog allows it. So, one of the solutions could be to switch to system verilog.
As for verilog, in half_adder port sum is declared as a reg. Instance gate2 connects variable of type reg to the port of type reg. This is illegal. This type of an assignment can only happen inside a procedural (i.e. always) block. Instance gate1 bypasses this issue by connecting port to the wire s1.
So, you can follow the similar path. Create another wire s2 as in the following example.
module full_adder(input wire a,b,c,output reg sum,output reg carry);
wire s1,c1, s2, c2;
half_adder gate1(a,b,s1,c1);
half_adder gate2(s1,c,s2,c2); // use s2 here
always#*
carry = c1|c2;
always #*
sum = s2; // now you can s2 assign to the 'sum' port
endmodule
Another way is to declare the 'sum' port as a wire. A register can be connected to a wire, using port connections or continuous assignment.
module full_adder(input wire a,b,c,
output sum, // declares it as a wire
output reg carry);
...
half_adder gate2(s1,c,sum,c2); // now it works this way.
And btw, do not use #(a,b,c). It is always error prone and is just wrong in your case. It should be #(c1,c2). But it is much better to use #*.

You should not declare sum as a reg in the full_adder module because it is not being assigned inside a procedural block (such as always). A reg is not a "net" type. Change:
module full_adder(input wire a,b,c,output reg sum,output reg carry);
to:
module full_adder(input wire a,b,c,output sum,output reg carry);
You also have an incorrect sensitivity list. Change:
always#(a or b or c)
to:
always #*
Now, the always block will trigger when the signals on the RHS of the assignments change.

Related

Simple assignment of wire to output led in verilog doesn't synthesis with yosis

The following code will not build exiting with Error Code -6
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = wire1;
endmodule
But making this small change builds properly. Can you not just assign a wire to an output without modifying it in some way?
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = ~wire1;
endmodule
I've seen this before. Some synthesis tools don't handle well the case of there being zero gates in the design, as that means there's zero die area needed before routing. I'm guessing the tool is hitting some internal divide-by-0.
So yes, you can simply connect a wire to an output. That by itself is perfectly valid. And you can even connect an input directly to an output. As long as you have any other gates in the design, even unrelated/unconnected to the ports/nets in your example, the synthesizer would be happy, as there'd be non-zero die area.
So I bet this would work fine:
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = wire1;
assign io_led[1] = ~io_button[1]; // added line, just to infer a gate somewhere
endmodule

I am getting unknown value when doing a 4 bit shifter verilog (gate level)

I am trying to implement a 4 bit right shifter using gate level but i got unknown result for some reason, my mux work ok but when i try testbench for my shifter it give back something like this:
a=0010 b=01 c=0000
a=1111 b=01 c=00xx
Please help!!!! Thank you very much
module mux2(a,b,sel,c);
output c;
input a,b,sel;
wire net0,net1,net2;
not m1(net0,sel);
and m2(net1,a,net0);
and m3(net2,b,sel);
or m4(c,net1,net2);
endmodule
module mux4(a,sel,c);
output c;
input [1:0]sel;
input[3:0]a;
wire mux_1,mux_2;
mux2 m1(a[3],a[2],sel[0],mux_1);
mux2 m2(a[1],a[0],sel[0],mux_2);
mux2 m3(mux_1,mux_2,sel[1],c);
endmodule
module shift4bitright(c,a,b);
output [3:0]c;
input [3:0]a;
input [1:0]b;
wire [3:0]d=4'h0,d1=4'h0,d2=4'h0,d3=4'h0;
assign d[0]=a[3];
assign d1[0]=a[2]; assign d1[1]=a[3];
assign d2[0]=a[1]; assign d2[1]=a[2]; assign d2[2]=a[3];
assign d3[0]=a[0]; assign d3[1]=a[1];assign d3[2]=a[2];assign d3[3]=a[3];
mux4 m1(d,b,c[3]);
mux4 m2(d1,b,c[2]);
mux4 m3(d2,b,c[1]);
mux4 m4(d3,b,c[0]);
endmodule
`timescale 10ns/1ns
module shift4bitright_tb;
wire [3:0]c;
reg [3:0]a;
reg [1:0]b;
shift4bitright s1(.c(c),.a(a),.b(b));
initial begin
$monitor("a=%b b=%b c=%b",a,b,c);
a=4'h2;
b=2'd1;
#50
a=4'hf;
b=2'd1;
end
endmodule
This statement declared a wire type signal d as well as its driver cone (NOT initial value), which is a constant 0 in this case:
wire [3:0]d=4'h0;
Just below it, there's another a[3] driving d[0]:
assign d[0]=a[3];
This creates a multi-driven logic, hence x occurs.
To solve it, change it similar to:
wire [3:0] d;
assign d = {3'h0, a[3]};

inout with reg type in verilog

I have used inout with c, but for c to be on the LHS of procedural assignment, it needs to be a reg type variable. Can anyone help me out with this code?
module multiedgeclk(input clk ,[7:0] a,b,d, inout [7:0] c, output reg [7:0]f);
always #(posedge clk)
c <= a + b;
always #(negedge clk)
f = c & d;
endmodule
In verilog inout is the direction of the port. wire or reg is the type of the signal.
If you want to drive a bi-directional port, it should be declare as inout wire or inout and drive it with enable signal
Here is a example of bi-directional port.
module ABC( inout [7:0] c );
reg [7:0] c_out;
reg out_en;
assign c = out_en ? 8'hz : c_out;
/* something here
...
*/
endmodule
An inout port cannot be procedurally assigned. There is nothing to indicate how long to hold that value on the port. This is the problem for any wire. But wires have a strength mechanism for multiple continuous drivers, the highest strength wins. So you can use a continuous assignment to selectively drive a value or turn it off by driving a z value.
wire c;
reg c_reg;
assign c = c_reg;
Now you can procedurally assign c_reg to a value or 8'bz
See my article for more info about wires and reg types.

writing a ripple carry adder in verilog

I'm attempting to write a ripple carry adder in verilog.
module half_adder(a,b,sum,carry);
input a,b;
output sum,carry;
assign sum=a^b;
assign carry=a&b;
endmodule
module full_adder(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
wire t1,t2;
half_adder h(a,b,t1,t2);
assign cout=t1&cin;
assign sum=t1^cin;
assign cout=t2|cout;
endmodule // full_adder
module ripple_carry_adder(input1,input2,answer);
input [31:0] input1,input2;
output [31:0] answer;
integer carry,t;
genvar i;
initial begin
assign carry=1'b0;
end
for(i=0;i<=31;i=i+1)
begin
full_adder f(input1[i],input2[i],carry,answer[i],t);
assign carry=t;
end
endmodule
however when i compile using the iverilog simulator, the following error log shows up(repetitive errors removed) :
ripple_carry_adder.v:28: warning: Couldn't build unique name for unnamed generate block - using internal name $gen1
ripple_carry_adder.v:30: warning: Port 3 (cin) of full_adder expects 1 bits, got 32.
ripple_carry_adder.v:30: : Pruning (signed) 31 high bits of the expression.
ripple_carry_adder.v:30: error: reg t; cannot be driven by primitives or continuous assignment.
ripple_carry_adder.v:30: error: Output port expression must support continuous assignment.
ripple_carry_adder.v:30: : Port cout of full_adder is connected to t
ripple_carry_adder.v:31: error: reg carry; cannot be driven by primitives or continuous assignment.
ripple_carry_adder.v:28: warning: Couldn't build unique name for unnamed generate block - using internal name $gen1
ripple_carry_adder.v:30: warning: Port 3 (cin) of full_adder expects 1 bits, got 32.
ripple_carry_adder.v:30: : Pruning (signed) 31 high bits of the expression.
ripple_carry_adder.v:30: error: reg t; cannot be driven by primitives or continuous assignment.
ripple_carry_adder.v:30: error: Output port expression must support continuous assignment.
ripple_carry_adder.v:30: : Port cout of full_adder is connected to t
ripple_carry_adder.v:31: error: reg carry; cannot be driven by primitives or continuous assignment.
Where am I going wrong?
EDIT: Using the generate statement now.Still have doubt about the type of carry.
module ripple_carry_adder(input1,input2,answer);
input [31:0] input1,input2;
output [31:0] answer;
wire carry;
wire t;
initial begin
carry=1'b0;
end
genvar i;
generate for(i=0;i<=31;i=i+1)
begin
full_adder f(input1[i],input2[i],carry,answer[i],t);
carry=t;
end endgenerate
endmodule
You should get rid of the initial block. You can drop t. Then using an generate block:
wire [31:0] carry;
genvar i;
full_adder f(input1[0],input2[0],1'b0,answer[0],carry[0]);
generate // optional in IEEE std 1364-2005 and IEEE std 1800
for(i=1;i<=31;i=i+1)
begin
full_adder f(input1[i],input2[i],carry[i-1],answer[i],carry[i]);
//assign carry=t;
end
endgenerate
endmodule
Alternatively, something that worked with the old 1364-1995 style:
full_adder f[31:0](input1[31:0],input2[31:0],{carry[30:0],1'b0},answer[31:0],carry[31:0]);
assign statements are not to be used inside of statement blocks. Anytime you have a begin/end block, the left-hand side of the statement gets set without using the assign keyword. e.g.:
initial begin
carry = 1'b0
end
You cannot instantiate modules inside a procedural block or for-loop (e.g. full_adder), you need to use a generate statement instead. You declared a genvar, so I think you meant to do this, but you don't seem to have the generate statement.
You cannot drive a reg/integer type from the output of a module, reg/integers can only be driven from a procedural block. Change type t from an integer to a wire[31:0] instead.

Having trouble with Verilog inout wires

For the record, I'm a complete Verilog newbie. I'm writing a module that uses a few bidirectional buses.
inout wire [KEY_SIZE-1:0] prevKey;
inout wire [TAG_SIZE-1:0] prevTag;
inout wire [KEY_SIZE-1:0] nextKey;
inout wire [TAG_SIZE-1:0] nextTag;
I know how I read things off of the bus, but how do I write something onto it? If I use an assign statement to a reg, will the value of the reg get clobbered when new data comes onto the wire? Is dealing with an inout port worth the hassle, or should I just make an input and and output bus for each?
If I use an assign statement to a reg...
This statement doesn't really make sense, you don't do assignments to regs, you do assignments to wires.
Simple example of driving an inout wire:
inout wire bidir_wire;
reg drive_value;
reg drive_enable;
reg something;
assign bidir_wire = drive_enable ? drive_value : 1'bz;
always #(posedge clk) begin
drive_value <= ... ; //assign a drive value based on some criteria
drive_enable <= ...;
something <= bidir_wire; //do something with the input value
end

Resources