Subject: Re: [sv-bc] Proposal to change interface ref-port default mode -or- documentation
From: Peter Flake (Peter.Flake@synopsys.com)
Date: Mon Sep 01 2003 - 06:48:04 PDT
Cliff,
The ref port feature is not intended for RTL designers, so it is not
surprising that no RTL designer has asked for it.
It is for behavioral and transaction level modeling, before the detailed
control logic has been designed.
Subsequent RTL implementation could be a tri-state bus, requiring design of
the enable logic for each driver and the replacement of the shared variable
by the driven wires.
One of the aims of the interface construct is to remove the brittleness of
hierarchical names. If you remove the ref port, the only way to get shared
variable behavior is to use hierarchical names. Similarly, the behavior of
hierarchical names seems the natural default for interfaces.
BTW some people liked the abstract FSM construct that you did not. However
the weakness that you found was that it did not map well to the RTL
implementation.
Regards,
Peter.
At 14:13 29/08/2003 -0700, Clifford E. Cummings wrote:
>Dave -
>
>I took a few days to cool off before responding to the snide remarks
>below. Responses shown.
>
>At 10:05 PM 8/20/03 -0700, Dave Rich wrote:
>>Cliff,
>>
>>For the proposal on 9.6, why not add the fact that three continuous
>>assignments are not allowed; when there are two instances a module with
>>ref ports connected together. You might also want add that four
>>continuous assignments are not allowed when there are two ref ports and
>>one hierarchical reference.
>>
>>I did not add an emoticon to the above so it would add more punch,
>>otherwise I would have typed it in. (Call me if you still don't get it).
>
>I get it.
>
>>The point is that maybe we didn't do a good enough job explaining the ref
>>port semantics.
>
>There is no "maybe" about it. The ref port semantics are very poorly
>described. I made an attempt to at least semi-remedy the situation.
>
>>Its not supposed to change any of the rules that apply to variables. Only
>>one continuous assignment means only one continuous assignment, whether
>>it be directly to the variable, via a plain hierarchical reference,
>>through ref port of a module, or through a ref argument of a
>>task/function. (A ref argument of a task/function could only place a
>>procedural assignment on the variable, which could still create an
>>illegal combination of assignments).
>
>The point is, ref-ports are a whole new critter. SystemVerilog now permits
>one continuous assignment to a variable. If the variable assignment is
>through a ref-port, it seemed to me that the continuous assignment through
>a ref-port was a short-hand method for making a procedural assignment to a
>variable at a higher level of hierarchy, much like a VHDL concurrent
>signal assignment is a shorthand for a process assignment, and both are
>permitted to std_logic type variables.
>
>As I showed below, ref-ports now make it possible to compile sub-blocks
>with the top-level module successfully, and fail when the sub-blocks are
>compiled together, something that has never been possible before.
>
>Since ref-port behavior is so new and unique, I thought it was not too
>much to ask to clarify the 2-3 terse descriptions related to ref-ports.
>
>>The example you show is EXACTLY the behavior users have been asking for
>>years.
>
>In all the years I have taught Verilog and Verilog synthesis, nobody has
>ever asked for this behavior. Do you have reference papers or customers
>that would be willing to email me and explain why they have wanted this
>behavior because I have never seen this request before.
>
>>The two modules, sub1 and sub2 work fine in a testbench independently,
>>but as soon as you try to connect the two of them together, you get a
>>compiler error.
>
>Why would an engineer want this late-error-detection behavior?
>
>I know you have alluded to cache modeling being easier to do using
>ref-ports but without a concrete example to rebuff and re-code using
>better coding styles, it is hard to debate the merits of this feature that
>engineers have "been asking for years."
>
>For the SV 3.0 effort, I was able to take all of the working FSM examples
>that used the now defunct "transition" keyword and show why the coding
>styles were poor and to show superior replacement coding styles. This work
>helped us to kill a rather useless transition coding style that would have
>added clutter and confusion to SV. I would like to prove to myself that
>ref-ports really are or are not a good idea, but I keep getting abstract
>nebulous descriptions of how ref-ports are great for architectural
>modeling. It is hard to debate a "trust-me" model.
>
>If you have customers that use and love ref-ports, you may want them to
>email me and convince me that I should not try to kill this strange
>enhancement. Tell your customers that Cliff thinks ref-ports suck and he
>is trying to kill them.
>
>Ref-ports have two very distasteful side effects (in addition to the
>late-error-detection side effect mentioned in my previous email):
>
>(1) ref-ports introduce a new form of race condition when two sub-modules
>try to make ref-port assignments in the same time-step (as if we didn't
>have enough race conditions in Verilog without this "enhancement"). See
>the first example below.
>
>(2) ref-ports are used to change the values of a variable in a parent
>module, a rather dangerous practice even in Verilog, except it is now
>easier to do (no hierarchical references required) and the ability is now
>the default mode when interfaces are used. Verilog lets you do this today
>but it requires explicit hierarchical references and therefore is harder
>to screw up. See the second example below.
>
>Per Karen's request, I will re-submit my proposal in "WAS-PROPOSED"
>format. If you can think of a better way of clarifying the functionality
>of a ref-port using different changes, I will not be offended.
>
>>Dave
>
>Regards - Cliff
>
>========= First Example with ref-ports and race conditions ==========
>
>interface ff_if (bit clk, rst_n);
> logic q; // a is a ref-port (no modport)
> logic d1, d2; // ref-ports
>endinterface
>
>module dff1 (ff_if a);
> always @(posedge a.clk or negedge a.rst_n)
> if (!a.rst_n) a.q <= 0;
> else a.q <= a.d1;
>endmodule
>
>module dff2 (ff_if b);
> always @(posedge b.clk or negedge b.rst_n)
> if (!b.rst_n) b.q <= 0;
> else b.q <= b.d2;
>endmodule
>
>// +define+I2 for second instantiation order
>`ifdef I2
>module topr2;
>`else
>module topr1;
>`endif
> bit clk, rst_n;
>
> ff_if x_if (.clk(clk), .rst_n(rst_n));
>
> initial begin
> clk <= 0;
> forever #10 clk++;
> end
>
> // +define+I2 for second instantiation order
> `ifdef I2
> initial $display("===============================\n",
> "*** Running %m +define+I2 ***\n",
> "===============================");
> dff2 u2 (.d2(d2), .clk(clk), .rst_n(rst_n));
> dff1 u1 (.d1(d1), .clk(clk), .rst_n(rst_n));
> `else
> initial $display("=========================================\n",
> "*** Running %m (without +define+I2) ***\n",
> "=========================================");
> dff1 u1 (.d1(d1), .clk(clk), .rst_n(rst_n));
> dff2 u2 (.d2(d2), .clk(clk), .rst_n(rst_n));
> `endif
>
> initial $monitor("%m: q=%b d1=%b d2=%b clk=%b rst_n=%b",
> x_if.q, x_if.d1, x_if.d2, clk, rst_n);
>
> initial begin
> rst_n <= 0;
> d1 = 0;
> d2 = 1;
> @(posedge clk);
> @(negedge clk) rst_n = 1;
> repeat (4) @(negedge clk) {d1,d2} = ~{d1,d2};
> $finish;
> end
>endmodule
>
>
>========= Second Example with hierarchical references - still a race
>condition ==========
>
>module dff1 (input d1, clk, rst_n);
> always @(posedge clk or negedge rst_n)
> if (!rst_n) toph.q <= 0;
> else toph.q <= d1;
>endmodule
>
>module dff2 (input d2, clk, rst_n);
> always @(posedge clk or negedge rst_n)
> if (!rst_n) toph.q <= 0;
> else toph.q <= d2;
>endmodule
>
>module toph;
> reg clk, rst_n;
> reg d1, d2;
> reg q;
>
> initial begin
> clk <= 0;
> forever #10 clk = ~clk;
> end
>
> // +define+I2 for second instantiation order
> `ifdef I2
> initial $display("===============================\n",
> "*** Running %m +define+I2 ***\n",
> "===============================");
> dff2 u2 (.d2(d2), .clk(clk), .rst_n(rst_n));
> dff1 u1 (.d1(d1), .clk(clk), .rst_n(rst_n));
> `else
> initial $display("=========================================\n",
> "*** Running %m (without +define+I2) ***\n",
> "=========================================");
> dff1 u1 (.d1(d1), .clk(clk), .rst_n(rst_n));
> dff2 u2 (.d2(d2), .clk(clk), .rst_n(rst_n));
> `endif
>
> initial $monitor("%m: q=%b d1=%b d2=%b clk=%b rst_n=%b",
> q, d1, d2, clk, rst_n);
>
> initial begin
> rst_n <= 0;
> d1 = 0;
> d2 = 1;
> @(posedge clk);
> @(negedge clk) rst_n = 1;
> repeat (4) @(negedge clk) {d1,d2} = ~{d1,d2};
> $finish;
> end
>endmodule
>
>----------------------------------------------------
>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 Sep 01 2003 - 06:52:06 PDT