void data type!

U

unfrostedpoptart

Guest
I just had a great idea for a System Verilog addition. They've already addede void functions and tasks. How about a void data type:

void [3:0] i_dont_care;

This would be very useful for output ports of modules that are not being used. Instead of just leaving them empty, which could get confused with just forgetting to connect a signal, and causing lint issues, you would just connect a void signal. All the tool would know that you don't care about what's driving this and you know it doesn't go anywhere.

It would also be really handy when you only need some of the bits of an output port:

module abcd (output logic [15:0] status_bits);
assign status_bits[10] = OV
endmodule
....
logic OV; // overflow status
void [15:11] nc_status1;
void [9:0] nc_status2;

abcd abcd_0 (.status_buts({nc_status1, OV, nc_status2});

Lots of warnings about unused bits would go away!

Thoughts? How do I submit this to the IEEE 1800 committee?

David
 
unfrostedpoptart a écrit :
I just had a great idea for a System Verilog addition. They've already add=
ede void functions and tasks. How about a void data type:

void [3:0] i_dont_care;

This would be very useful for output ports of modules that are not being us=
ed. Instead of just leaving them empty, which could get confused with just=
forgetting to connect a signal, and causing lint issues, you would just co=
nnect a void signal. All the tool would know that you don't care about what=
's driving this and you know it doesn't go anywhere. =20

It would also be really handy when you only need some of the bits of an out=
put port:

module abcd (output logic [15:0] status_bits);
assign status_bits[10] =3D OV
endmodule
....
logic OV; // overflow status
void [15:11] nc_status1;
void [9:0] nc_status2;

abcd abcd_0 (.status_buts({nc_status1, OV, nc_status2});

Lots of warnings about unused bits would go away!

Thoughts? How do I submit this to the IEEE 1800 committee?
If you define an output, that's because you might need it. Even if in all of the
instances you're not using the output, at least one instance is using it. If
none of the instance is using the output then it should be removed (as it is
useless).

So to conclude, I don't see any added value because to me if an output is never
used, it should be removed.
 
unfrostedpoptart a écrit :
On Thursday, August 18, 2011 11:56:37 AM UTC-7, Vince wrote:
unfrostedpoptart a écrit :
If you define an output, that's because you might need it. Even if in all of
the
instances you're not using the output, at least one instance is using it. If
none of the instance is using the output then it should be removed (as it is
useless).

So to conclude, I don't see any added value because to me if an output is
never
used, it should be removed.

I don't agree at all. You are assuming all the modules in a design
are written by yourself, or at least someone in your company. First,
in many of cases, the module in question is vendor IP designed for
general use, not your specific design.
But in that case you will not modify the vendor IP to replace declarations with
"voids", right?

It will likely have inputs
and outputs you don't use. I'm using lots of ASIC RAMs that have
multiple outputs that will likely never all be used in a single design.

Second, your own statement contradicts your own argument: you could
have a module you wrote used in multiple instances and in some of
them one or more outputs are not used. For the ones where not all
the outputs are used, my idea would be helpful.
No because for the instance(s) where all outputs are connected, you will connect
to "void" outputs. And if you think that's right, it means that you suggest to
declare everything as void.

So tell us what is the good solution for you in this case:

module mymodule
(input CLK,
input RST_N,
input MYINPUT,
output MYOUT0,
output MYOUT1,
output MYOUT2);

// ...
endmodule

module mytop
(input CLK,
input RST_n,
...);

mymodule
mymodule0
(.CLK(CLK),
.RST_N(RST_N),
.MYINPUT(myinput),
.MYOUT0(),
.MYOUT1(out1),
.MYOUT2());

mymodule
mymodule1
(.CLK(CLK),
.RST_N(RST_N),
.MYINPUT(myinput),
.MYOUT0(out0),
.MYOUT1(),
.MYOUT2());

mymodule
mymodule2
(.CLK(CLK),
.RST_N(RST_N),
.MYINPUT(myinput),
.MYOUT0(out2),
.MYOUT1(out3),
.MYOUT2(out4));

// ...

endmodule
 
On Thursday, August 18, 2011 11:56:37 AM UTC-7, Vince wrote:
unfrostedpoptart a écrit :

If you define an output, that's because you might need it. Even if in all of the
instances you're not using the output, at least one instance is using it. If
none of the instance is using the output then it should be removed (as it is
useless).

So to conclude, I don't see any added value because to me if an output is never
used, it should be removed.
I don't agree at all. You are assuming all the modules in a design are written by yourself, or at least someone in your company. First, in many of cases, the module in question is vendor IP designed for general use, not your specific design. It will likely have inputs and outputs you don't use. I'm using lots of ASIC RAMs that have multiple outputs that will likely never all be used in a single design.

Second, your own statement contradicts your own argument: you could have a module you wrote used in multiple instances and in some of them one or more outputs are not used. For the ones where not all the outputs are used, my idea would be helpful.

David
 
On Thursday, August 18, 2011 1:27:36 PM UTC-7, Vince wrote:
unfrostedpoptart a ďż crit :
On Thursday, August 18, 2011 11:56:37 AM UTC-7, Vince wrote:
unfrostedpoptart a ďż crit :
If you define an output, that's because you might need it. Even if in all of
the
instances you're not using the output, at least one instance is using it. If
none of the instance is using the output then it should be removed (as it is
useless).

So to conclude, I don't see any added value because to me if an output is
never
used, it should be removed.

I don't agree at all. You are assuming all the modules in a design
are written by yourself, or at least someone in your company. First,
in many of cases, the module in question is vendor IP designed for
general use, not your specific design.

But in that case you will not modify the vendor IP to replace declarations with
"voids", right?
Correct. Customers are not allowed to modify vendor IP.
It will likely have inputs
and outputs you don't use. I'm using lots of ASIC RAMs that have
multiple outputs that will likely never all be used in a single design.

Second, your own statement contradicts your own argument: you could
have a module you wrote used in multiple instances and in some of
them one or more outputs are not used. For the ones where not all
the outputs are used, my idea would be helpful.

No because for the instance(s) where all outputs are connected, you will connect
to "void" outputs. And if you think that's right, it means that you suggest to
declare everything as void.
No. You aren't following me. I guess my orignal post might not have been completely clear, so I'll try again.
For the instance where all outputs are used, then they're connected to normal signals, as we do now.
It's only the unused outputs that would connect to the new type.

So tell us what is the good solution for you in this case:


module mymodule
(input CLK,
input RST_N,
input MYINPUT,
output MYOUT0,
output MYOUT1,
output MYOUT2);

// ...
endmodule

module mytop
(input CLK,
input RST_n,
...);
logic out1; // same as now

void not_used0, not_used2; // new

mymodule
mymodule0
(.CLK(CLK),
.RST_N(RST_N),
.MYINPUT(myinput),
.MYOUT0(not_used0), // new
.MYOUT1(out1), // same as now
.MYOUT2(not_used2)); // new
logic out0; // same as now

void not_used3, not_used4; // new

mymodule
mymodule1
(.CLK(CLK),
.RST_N(RST_N),
.MYINPUT(myinput),
.MYOUT0(out0), // same as now
.MYOUT1(not_used3), // new
.MYOUT2(not_used4)); // new
logic out2, out3, out4; // same as now

mymodule
mymodule2
(.CLK(CLK),
.RST_N(RST_N),
.MYINPUT(myinput),
.MYOUT0(out2), // same as now
.MYOUT1(out3), // same as now
.MYOUT2(out4)); // same as now

// ...

endmodule
I hope this is clear now. The point is to have a data type that can be explicitly connected to output ports (and probably other places) so that tools don't report errors and warnings about unconnected outputs / unloaded signals.

The tools would know that signals not_used0-4 are specifically for unused outputs. In fact, they should report an error if any signal of type void is used as a module/task/function input or on the RHS of an assignment.

David
 
Oops - one more possible area of misunderstanding:

module mymodule
(input CLK,
input RST_N,
input MYINPUT,
output reg MYOUT0,
output wire MYOUT1,
output logic MYOUT2);

The outputs of 'mymodule' would be declared as an existing type (e.g. wire, reg, or logic). You wouldn't declare these as type void. You would declare the signals connected to these ports in the instantiation of 'mymodule' as type void for outputs you don't care about.

David
 
unfrostedpoptart wrote:
The tools would know that signals not_used0-4 are specifically for unused
outputs. In fact, they should report an error if any signal of type void is
used as a module/task/function input or on the RHS of an assignment.
And why not just create special rules for lint tools?
 
On Thursday, August 18, 2011 9:59:52 PM UTC-7, Vince wrote:
unfrostedpoptart wrote:
The tools would know that signals not_used0-4 are specifically for unused
outputs. In fact, they should report an error if any signal of type void is
used as a module/task/function input or on the RHS of an assignment.

And why not just create special rules for lint tools?
For the same reason System Verilog added always_ff, always_comb, etc: to help make the designers intentions clear in the code and not require special rules and pragmas and other work-arounds that aren't defined in the language and could be interpreted differently (or not at all) by different tools.

David
 
On Aug 19, 12:59 am, Vince <debo...@free.fr> wrote:
unfrostedpoptart wrote:
The tools would know that signals not_used0-4 are specifically for unused
outputs. In fact, they should report an error if any signal of type void is
used as a module/task/function input or on the RHS of an assignment.  

And why not just create special rules for lint tools?
Note that there is already a way of explicitly indicating that a port
is deliberately connected to nothing, rather than missed by accident:

mymodule mymodule2 (.MYOUT1(out1), .MYOUT2(), .MYOUT3());

Admittedly, this doesn't work for parts of vector ports. But with
your void suggestion, how do you know how many bits the void is
connected to? Presumably you could connect a void to a vector port,
indicating that the entire port is unconnected, so a void doesn't
necessarily represent a single bit. And a void cast will discard a
return value of any data type. Saying that a void matches a
connection to a single bit would be treating void as specifically
matching a logic scalar data type; this isn't consistent with the
existing uses of void. So it isn't clear that your suggestion is very
clean for parts of vector ports either.
 
On Friday, September 2, 2011 9:51:57 PM UTC-7, Steven Sharp wrote:
Note that there is already a way of explicitly indicating that a port
is deliberately connected to nothing, rather than missed by accident:

mymodule mymodule2 (.MYOUT1(out1), .MYOUT2(), .MYOUT3());
Yeah, that works. I use all the AUTOINST/AUTOLOGIC in the emacs verilog-mode, which helpfully - except in this case - declares signals for all output ports of instantiated modules. I guess I could use the template feature of it to tell it not to do this for ports I know won't be used.

Admittedly, this doesn't work for parts of vector ports. But with
your void suggestion, how do you know how many bits the void is
connected to?
The kind of case I was thinking of, and have run into, is where an IP block would output an address bus and a data bus, e.g. addr[31:0], data[31:0], but the client module only needs 8 bits of address and 16 bits of data. I would propose something like this:

module a (output logic [31:0] addr, output logic [31:0]); ... endmodule

module b;
logic [7:0] addr_used;
logic [15:0] data_used;
void [31:8] addr_nc;
void [31:16] data_nc;

a a_0 (
..addr ({addr_nc, addr_used}),
..data ({data_nc, data_used})
);

If, for some reason, you're only using a few, non-contiguous bits in a vector, then it could get messy.

David
 

Welcome to EDABoard.com

Sponsor

Back
Top