Subject: [sv-bc] RE: SV-EC Proposal: Implicit Universal Data Type - Cliff Cummings to champion the proposal
From: Clifford E. Cummings (cliffc@sunburst-design.com)
Date: Mon Feb 03 2003 - 15:57:53 PST
At 11:03 AM 2/3/03 -0800, Michael McNamara wrote:
> > My proposal is to allow wires, declared or implicit, to allow EITHER
> > procedural assignments OR continuous assignments within a module and that
> > the behavior of the identifier is consistent with either wires or regs,
> > depending on how they are used in the module. Advantages:
> >
> > (1) I don't add any new keywords
> > (2) I don't have to change the declaration when I change from
> > procedural to continuous assignments or vice versa - wire can
> > now be used as a generic, sized variable
> > (3) Wire is already the default type
> > (4) I get the size that I need (which is really all I care about)
> > (5) Resolved data type within the module if I make multiple-driver
> > assignments to the identifier
> > (6) Syntax error if I try to mix procedural and driver assignments to
> > the same variable
> > (7) Does not break any existing designs
> >
> > Sell me rope and I will help sell your rope to the users (this should
> be an
> > easy sell).
>
>I have been quietly following this debate over the years.
>
>I am curious why you want #6. All along I thought you and Stefen and
>Adam wanted this magic type polymorphisim so that adding a procedural
>writer to a wire would automagically create the shadow register and
>assignment. Hence if the original code looked like:
>
>module a(inout [31:0]j,k);
> thing [31:0] t;
> assign t = j+k;
>endmodule
>
>And I changed it to:
>
>module a(inout [31:0]j,k);
> thing [31:0] t;
> assign t = j+k;
> initial begin
> t = 0; #1 t = 31'bz;
> end
>endmodule
>
>the compiler would automagically act as if I had instead written the
>1364-2001 equivalent code:
>
>module a(inout [31:0]j,k);
> wire [31:0] t;
> assign t = j+k;
>
> reg _t_r;
> assign t = _t_r;
> initial begin
> _t_r = 0; #1 _t_r = 31'bz;
> end
>endmodule
>
>Given your requirement #6, the above would be an error; ...
I can't speak for Adam and Stefen, but I have never wanted this behavior.
Explanation below.
>... and the user
>would have to write:
>
>module a(inout [31:0]j,k);
> thing [31:0] t;
> assign t = j+k;
> thing [31:0] g;
> assign t = g;
> initial begin
> g= 0; #1 g = 31'bz;
> end
>endmodule
>
>which will be really hard to explain to a user:
>
>"Well, yes, Grasshopper, you a correct that 't' and 'g' are both 32
>bit things, but becuase there is an continuous assignement elsewhere
>in the design to the thing t, you can't make a procedural assignement
>to it in the same module. Instead you can get what you want by making
>a procedural assignment to another thing, which is the same size,
>which we will call 'g', and then we assign g to t, and everything
>works as you desired. Another way you could get what you want is by
>passing 't' to another module, which can not see this continuous
>assign, and make a procedural assigment there."
We do have to explain shadow registers to describe how to build a testbench
that interacts with an inout port of an instantiated module, but this is
the only place they are really needed (IMO). And this concept is not real
difficult to grasp.
>In my humble opinion, the current requirements are much more logical:
>procedural assignemnts can ONLY be made to registers. Registers hold
>a value until it is changed.
>
>Wires ONLY reflect the value of their drivers. If you want to drive a
>value onto a wire, write the value to a register that is driving the
>wire.
Yeeesssss, but ... now when I change an assignment from a continuous
assignment to a procedural assignment or vice versa, I also have to change
the declarations. What's more, an ANSI style port declaration for a
procedural assignment that goes to an output is "output reg y" while the
same ANSI style port declaration for a continuous assignment output is
either "output wire y" or "output y."
I can live with the last-assignment-wins (within a module) nature of
variables, and I like the resolved driver behavior of a net, and I like the
restriction that the two shall never meet (you are not allowed to do both
to the same identifier within a module). I just don't want to change
declarations after some RTL assignment changes and I don't want to even
declare the critters except for internal vectors. Wire is already the
default, so I have backed its candidacy for years.
Maybe I start with the following:
module busand2 (output [7:0] y, input [7:0] a, b);
assign y = a & b;
endmodule
And for some reason I decide this should be a procedural assignment:
module busand2 (output reg [7:0] y, input [7:0] a, b);
always @*
y = a & b;
endmodule
Aside from satisfying a compiler requirement, what value was added by
changing the output declaration to include reg? None. And in fact, often, I
forget the output declaration change and compile to a syntax error the
first time I make the change. I know this is easy to fix. The hundreds of
these mistakes that I make each year are all easy to fix, but they are
exceptionally annoying, and they are really annoying to new users and VHDL
users who are also trying to pick up Verilog.
If I can make procedural assignments to wires and have vendors treat the
assignments like a reg-variable assignment, I'm a happy camper and the HDL
user community will sing praises to the SV and IEEE Verilog committees and
peace will come to the Middle East (perhaps I exaggerate a little ;-)
>-mac
Regards - Cliff
----------------------------------------------------
Cliff Cummings - Sunburst Design, Inc.
14314 SW Allen Blvd., PMB 501, Beaverton, OR 97005
Phone: 503-641-8446 / FAX: 503-641-8486
cliffc@sunburst-design.com / www.sunburst-design.com
Expert Verilog, Synthesis and Verification Training
This archive was generated by hypermail 2b28 : Mon Feb 03 2003 - 15:57:57 PST