verilog_mode autoreginput behavior when using assignment - emacs

I wonder if the following case is possible.
I have :
module a(
input [2:0] a_i
);
endmodule
module b ();
/*AUTOREGINPUTS*/
a u_a(/*AUTOINST*/)
endmodule
It expands to:
module b ();
/*AUTOREGINPUTS*/
reg [2:0] a_i;
a u_a(/*AUTOINST*/
.a_i(a_i))
endmodule
But if I modify adding the line assign a_i = '0;, then it does not expands AUTOREGINPUTS anymore. Is there a way to expand it even if I'm doing an assignment ?

The short answer is because when running verilog-auto to fill in /*AUTOREGINPUT*/ will exclude any signal that is already declared and by adding assign a_i = '0;, you are declaring a_i.
In Verilog, explicit variable declarations are not required and will take on the default nettype if left undeclared under certain circumstances. So, if I had the following:
module x;
assign myVar = '0;
endmodule
myVar will be implicitly declared to be a net with the default nettype (which by default is wire). You can read more in the System-Verilog LRM (IEEE1800-2009 Section 6.10). One recommendation to avoid typos generating implicitly declared variables is to change the default nettype with the `default_nettype macro to none (ie `default_nettype none on the top of every file); doing this forces all variables to be explicitly declared or the compiler/synthesizer will throw an error.
verilog-mode mode in emacs is aware of implicit declaration and, as such, will not autogenerate anything declared. Thus, when you add the assign statement, you are declaring a_i and so the autogenerator will not "redefine" a_i.
To avoid this, I can only recommend running the generator before you assign any of the variables to be autogenerated. Im not sure if it handles `default_nettype none correctly, but I would assume not.
Also note, it should be /*AUTOREGINPUT*/, not /*AUTOREGINPUTS*/, no 's' at the end.

Related

-svinputport option in modelsim

I am using modlesim for my design and in this we are passing an option -svinputport=var, what is the use of this option? we are passing `default_nettype none before compiling each design files. Does these both are dependent? Could anyone help me with an example.
The description is as below for the option
svinputport=net|var|compat|relaxed
Select the default kind for an input port that is
declared with a type, but without the var keyword.
Select 'net' for strict LRM compliance, where the
kind always defaults to wire. Select 'var' for
non-compliant behavior, where the kind always defaults
to var. Select 'compat', where only types compatible with
net declarations default to wire. The default is 'relaxed',
where only a type that is a 4-state scalar or 4-state single
dimension vector type defaults to wire.
Question (2)
Thank you very much for the detailed explanation. I have one more doubt related to this. I am getting a warning when I run the following code:
`default_nettype none
module test(
input reg sig1,
output logic sig2);
reg [1:0] ab;
endmodule
xmvlog: *W,NODNTW (test.sv,4|14): Implicit net port (sig1) is not allowed since `default_nettype is declared as 'none'; 'wire' used instead [19.2(IEEE 2001)]. why it is referring input reg sig1 as an implicit net port, I already explicitly declared it as reg? As per the message it is changing to wire so will the statement be like "input wire reg sig1" ?
Can we declare input reg a; in systemverilog(input port with reg type) ? Is this implicitly equivalent to input wire reg a; (if I dont use `default_nettype none)
Verilog is littered with implicit defaults all over the place. When you write
module m(a);
initial $disaply(a);
endmodule
this is implicitly the same as
// direction kind type range signal
module m(inout wire logic [0:0] a);
initial $disaply(a);
endmodule
For inout and input directions, if you omit the kind the default is wire or taken from the `default_nettype setting. The none setting generates an error. However, the default kind for an output is different. As soon as you add a datatype to an output, the default kind goes to var, which is similar to non-port declarations. See this post for more details and examples.
However, very early versions of SystemVerilog/Superlog had input and inout with the same kind default as output. The -svinputport=var switch was added for a very large microprocessor developer customer whose name I cannot mention who did not want to change their code. The =net options is the behavior I mentioned above and is the way current LRM is defined.
The other two options are hybrids between the var/net options, mainly for lazy people using the default_nettype none options and don't want to see errors in their port declarations.

How do I sign extend in SystemVerilog?

Below is the code I have for my module:
module sext(input in[3:0], output out[7:0]);
always_comb
begin
if(in[3]==1'b0)
assign out = {4'b0000,in};
else
assign out = {4'b1111,in};
end
endmodule
For some reason this is not working. Instead of sign extending it is zero extending. Any ideas to why this might be the case?
I'm going to assume you meant (input [3:0] in, output [7:0] out). If that is true, then all you needed to write is
module sext(input signed [3:0] in, output signed [7:0] out);
assign out = in;
endmodule
You could also write
module sext(input [3:0] in, output [7:0] out);
assign out = 8'(signed'(in));
endmodule
And perhaps you don't even need to write this as a separate module.
Few things you need to take care is,
you haven't declared a data type for in and out, so by default they are wire and wire can't be used at LHS inside procedural block. Refer Section 6.5 Nets and variables (SV LRM 1800-2012). So either use a continuous assignment or declare it as a variable (i.e. reg/logic etc.).
The assignment of unpacked array is illegal in your example, so either use packed array or follow the instructions given in Section 10.10 Unpacked array concatenation (SV LRM 1800-2012)
It is not illegal syntax but assign used inside an always block probably does not do what you think it does. Use assign for wires and do not use it inside initial or always.
You have defined your port ranges after the name, this results in 4 and 8 1-bit arrays rather than a 4 and 8 bit value.
You have used {} for concatination, but they can also be used for replication ie {4{1'b1}}.
module sext(
input [3:0] in,
output reg [7:0] out ); //ranged defined before name
//No assign in always
//concatenation with replication
always_comb begin
out = { {4{in[3]}}, in};
end
endmodule
Or :
module sext(
input [3:0] in,
output [7:0] out ); //out left as wire
assign out = { {4{in[3]}}, in};
endmodule
I have seen your code.
There are some mistake in your code that you have to take care whiling writing the code.
You have use unpacked array so your targeted elements and actual elements are not match.
ERROR : Number of elements in target expression does not match the number of
elements in source expression.
This error can solve by using packed array.So, your targeted elements and actual elements are matched.
Here is link from where you will get better understanding regarding packed and unpacked array.
LINK : [http://www.testbench.in/SV_09_ARRAYS.html][1]
2.Another thing that you have to take care is you are storing some value in out signal(variable) like assign out = {4'b0000,in};
So you have to use reg data type to sore the value.
ERROR : Non reg type is not valid on the left hand side of this assignment
When you use reg data type then you can store value in out data type.
So, your problem is solved.
Here I also provide code which will run fine.
module sext(input [3:0]in, output reg [7:0]out);
always_comb
begin
if(in[3]==1'b0)
assign out = {4'b0000,in};
else
assign out = {4'b1111,in};
end
endmodule

What is difference between pass by ref and pass by val in systemverilog?

what is difference between pass by ref and pass by val in systemverilog?
I just want to know what is difference between pass by ref and pass by val in systemverilog?
I can't find any example.also expecially, what is this? Does anyone know what is this and explain?
interface xxx
...
event yyy;
event ggg;
modport io_bus ( ref yyy,
ref ggg,
....
);
endinterface
What is the purpose "ref yyy" in the modport ?
The two code blocks below summarize the difference.
value = 1;
IncreaseByOne(ref value); //pass by reference
//value will be set to 2
value = 1;
IncreaseByOne(value); //pass by value
//value will still be 1
Passing by reference means that the method which gets the parameter is able to change the variable such that the original variable is also changed. Passing by value means that a copy of the value is passed, and any change to that copy does not reflect back on the original variable.
Pass by value
In SystemVerilog, Pass by value is the default mechanism for passing arguments to subroutines. This argument passing mechanism works by copying each argument into the subroutine area. If the subroutine is automatic, then the subroutine retains a local copy of the arguments in its stack.
Pass by reference
Arguments passed by reference are not copied into the subroutine area, rather, a reference to the original argument is passed to the subroutine.
The subroutine can then access the argument data via the reference. No casting shall be permitted.
Also note, It shall be illegal to use argument passing by reference for subroutines with a lifetime of static.
Only the following shall be legal to pass by reference:
— A variable,
— A class property,
— A member of an unpacked structure, or
— An element of an unpacked array.
Nets and selects into nets shall not be passed by reference
For your question
What is the purpose "ref yyy" in the modport ?
There are some performance improvement when you use reference to an event when different events gets triggered multiple times, but it is a good practice to use only when considerable performance optimizations are required/necessary. One recommended example to use pass by reference can be found in the link
Here I've shown one way of how modport with ref event is used.
interface intf(input clk);
event out_event;
logic clk;
modport dut(input clk,ref out_event);
always #(out_event)
$display ($time,"ns"," out_event triggered");
endinterface
module dut( intf.dut d);
reg [2:0] count;
initial
count = 0;
always # (posedge d.clk)begin
count = count + 1'b1;
if ( count == 'd2)
-> d.out_event;
end
endmodule
module top (input clk);
intf int_f(.clk(clk));
dut u0(.d(int_f.dut));
endmodule
The above working example can be found in the link EDA-Playground
For more details about Pass by value refer Section 13.5.1 of SystemVerilog LRM IEEE 1800-2012 and for Pass by reference refer Section 13.5.2

How to pass a class between two modules?

I have two modules and a class and I would like to move that class from one module to the other. Something like this:
class foo;
int x;
int y;
endclass
module mod_A(output foo foo_inst, output event trig);
initial begin
foo my_foo = new;
my_foo.x = 1;
my_foo.y = 2;
foo_inst = my_foo;
->trig;
end
endmodule
module mod_B(input foo foo_inst, input event trig);
always #(trig) begin
$display("%d%d, is a funky number.", foo_inst.x, foo_inst.y);
end
endmodule
module top();
event trig;
foo foo_inst;
mod_A mod_A(.trig, .foo_inst);
mod_B mod_B(.trig, .foo_inst);
endmodule
Of course there're also some functions defined in the class which are used in each module.
The issue with this setup is that I'm seeing errors for each ports of mod_B:
Error-[RIPLIP] Register in low conn of input port
Non-net variable 'foo_inst' cannot be an input or inout port.
Non-net variable 'trig' cannot be an input or inout port.
EDAplayground does not support class objects as module ports and 1800-2012 only mentions interface declarations, events, arrays structures or unions in Port declarations (23.2.2) so my questions are:
Is it even legal to pass classes through ports? If not, what is an elegant
method of accomplishing this?
What does "Register in low conn of
input port" mean? I'm aware that this might be a compiler specific
error and nothing indicative but if I knew what it was trying to tell me I might be a step closer to fixing this.
A variable of any type can be an input or output port. You might have to write for your compiler
input var foo foo_inst,
But it would be better to use a ref when a port is really a handle.
module mod_A(ref foo foo_inst, ref event trig);
Note that you have a typo with foo_o or foo_inst and a race condition between a trigger ->trig and an event control #(trig).

Can I use bind inside generate block

I've a simple assertion:
Lets say
assert #(posedge clk) (a |=> b);
I generally connect it with design signals using separate binding module
module bind_module;
bind dut assertion a1 (.*);
endmodule
I've a situation: dut has a bus of 45bits, each bit is generated / driven individually but all of them follow same assertion.
Can I use bind statement inside generate block? (for a range of 0 to 44) and then instead of .* use .a (in_bus[i]), .b (out_bus[i])
Assuming you intend the following:
genvar i;
generate
for(i=0; i<45; i=i+1) begin : gen_asrt
bind dut assertion a1( .a(in_bus[i]), .b(out_bus[i]), .* );
end
This will not work for 2 reasons:
The instance name a1 is being clobbered on each loop. Each instance name within a module needs to be unique. Quoting from IEEE std 1800-2012 § 23.11 'Binding auxiliary code to scopes or instances':
It is legal for more than one bind statement to bind a bind_instantiation into the same target scope. However, it shall be an error for a bind_instantiation to introduce an instance name that clashes with another name in the module name space of the target scope (see 3.13). This applies to both preexisting names as well as instance names introduced by other bind statements. The latter situation will occur if the design contains more than one instance of a module containing a bind statement.
i in the bind statement is referring to an i variable name within the scope of dut, not the genvar i. Again, quoting from IEEE std 1800-2012 § 23.11 'Binding auxiliary code to scopes or instances':
When an instance is bound into a target scope, the effect will be as if the instance was present at the very end of the target scope. In other words, all declarations present in the target scope or imported into the target scope are visible to the bound instance. Wildcard import candidates that have been imported into the scope are visible, but a bind statement cannot cause the import of a wildcard candidate. Declarations present or imported into $unit are not visible in the bind statement.
How to bind this kind of checker:
You could create one module that handles the generate statements, then instantiate that module with a bind statement. Example:
module bind_assertions #(parameter SIZE=1) ( input clock, input [SIZE-1:0] a,b );
genvar i;
generate
for(i=0; i<SIZE; i=i+1) begin : gen_asrt
assertion a1_even( .a(a[i]), .b(b[i]), .* );
end
endgenerate
endmodule
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
Technically, you could bind an array of instances. It is legal syntax according to &sect 23.11's Syntax 23-9 plus Appendix A.4.1.1 'Module instantiation'. However it this seems to fail on all the simulators I currently have access to. Example (if it works on your simulator):
bind dut assertion a1[44:0]( .a(in_bus[44:0]), .b(out_bus[44:0]), .* );
Can bind exist within a generate block?
IEEE std 1800-2012 § 27.3 'Generate construct syntax' does mention bind_directive within the syntax for generate constructs is given in Syntax 27-1. Like binding an array of instances, not all simulators support this feature yet. IEEE std 1800-2009 § 27.3 also mentions bind_directive but IEEE std 1800-2005 (first IEEE version of SystemVerilog) does not. Example (if it works on your simulator):
parameter DO_BIND=1;
generate
if(DO_BIND==1) begin
bind dut bind_assertions#(45) a1( .a(in_bus), .b(out_bus), .* );
end
endgenerate