Verilog: Accessing wire in sub-module instance - verilog

I would like to know if there is a syntax in Verilog to access a wire in a sub-module without making that wire an output.
For example, if have the following modules:
module Module_Sub(a,b);
input a,b;
wire c;
...
endmodule
module Module_Top(d, e);
input d,e;
wire f;
Module_Sub sm(d,e);
...
endmodule
Now, I want to access the wire 'c' in the instance 'sm' from the scope of Module_Top.
Is there a way to do it?
maybe something like:
assign f = sm/c;
(This syntax obviously didn't work for me).
P.S:
I know this isn't the best practice, but in my case it will make things a lot easier.
Thanks!
edit: I want it for a synthesis-able code.

You were very close. Use dot, not slash:
module Module_Sub(a,b);
input a,b;
wire c;
endmodule
module Module_Top(d, e);
input d,e;
wire f = sm.c;
Module_Sub sm(d,e);
endmodule
Refer to IEEE Std 1800-2012, section 23.7 "Member selects and hierarchical names".

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

Verilog module instantiation reg input output

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.

How do I fix Error: adder_out is an unknown type

I need an Add operation in my circuit.
I tried designing a simple adder as below:
`timescale 1ns / 1ps
module adder(
input [7:0] adder_in1,
input [7:0] adder_in2,
output reg [7:0] adder_out
);
adder_out = adder_in1 + adder_in2;
endmodule
But, this code is giving me an error as below. I am really not sure how to correct this code. Please help.
One way to fix the error is to drop the reg declaration, and use the assign keyword:
module adder(
input [7:0] adder_in1,
input [7:0] adder_in2,
output [7:0] adder_out
);
assign adder_out = adder_in1 + adder_in2;
endmodule
When you make assignments to signals, you either have to be continuous assignments using the assign keyword as shown, or they need to be procedural assignments using always, initial, etc. In your case, it is simpler to use a continuous assignment.

Verilog: Interface Module Input With a Reg

In the following code:
wire a;
reg b;
assign a = b;
ModuleName foo(a, other wire inputs, ... , wire outputs);
Assume that they are part of a top level module.
I wanted to run an always# block but make changes in the input of a module instantiated in this module.
always#(*) b = c^d; //Some Logic
The thing is, they are wires and cannot be on the LHS in an always# block. Can I make changes to band expect to see them in a i.e. the input of the Module foo.
Yes. Every time you change b, a will change too. That is what an assign statement does. Remember this is hardware. The statement
assign a = b;
means 'drive wire a with whatever value reg b has for all time'.

Tasktop.v(10): (vlog-2110) Illegal reference to net "b"

I am writing a program in verilog. Total 3 AND Gates, the output of first 2 AND Gates is input to the 3rd Gate, and i am required the output of 3rd Gate. Please let me know what is the problem with my program. I am attaching my Program
//enter Top Module
module TOP;
wire a,b;
reg out;
initial
begin
#3 a=1;
#3 b=1;
#3 b=0;
end
Two_AND s(a,b,out);
endmodule
//.....................
//Main Program
module Two_AND (a,b,out);
input a,b;
output out;
reg out;
and g1(out1,a,b);
and g2(out2,b,c);
and g3(out3,out1,out2);
endmodule
In module Two_AND (a,b,out); you have these lines:
and g2(out2,b,c);
c is not defined.
out1, out2 and out3 are also not defined but are outputs and will be created as 1 bit wires by default which is ok in this instance.
but your output out is not driven, where you have used out3 you need to use out.
module Two_AND (
input a,
input b,
input c,
output out
);
wire out1,out2;
and g1(out1,a,b);
and g2(out2,b,c);
and g3(out,out1,out2);
endmodule
#Morgan is right.
However, the error you get is because there is something wrong with your TOP module.
You should have defined a and b as reg and out as wire.
Only regs can be assigned within an initial or always block.
And outputs of modules should be connected to wires.
Also, since an input c is added to your module, you should consider it while you are instantiating your Two_AND in your TOP module.
I think the previous answers were very instructive and helpful. I only want to add a small tip. I recommend you that always add `default_nettype none to your verilog codes. for example you have used "out1" and "out2" wires but you haven't define them. if you don't want to be confused, you should add that to your codes.

Resources