Is it legal to have modports that do not include all wires of an interface?
Yes, refer to IEEE Std 1800-2012 § 25.5.4 Modport expressions:
A modport expression allows elements of arrays and structures, concatenations of elements, and assignment pattern expressions of elements declared in an interface to be included in a modport list. This modport expression is explicitly named with a port identifier, visible only through the modport connection.
Like explicitly named ports in a module port declaration, port identifiers exist in their own name space for each modport list. When a modport item is just a simple port identifier, that identifier is used as both a reference to an interface item and a port identifier. Once a port identifier has been defined, there shall not be another port definition with this same name.
For example:
interface I;
logic [7:0] r;
const int x=1;
bit R;
modport A (output .P(r[3:0]), input .Q(x), R);
modport B (output .P(r[7:4]), input .Q(2), R);
endinterface
module M ( interface i);
initial i.P = i.Q;
endmodule
module top;
I i1 ();
M u1 (i1.A);
M u2 (i1.B);
initial #1 $display("%b", i1.r); // displays 00100001
endmodule
Not all simulators/synthesizer support modeport expressions, so you will have to experiment. Modeport expressions are not new, they are also described in IEEE Std 1800-2005. Maybe the Accellera SystemVerilog 3.1a as well (I'd need to dig up the old LRM to verify).
Can one have assignments in an interface?
Yes. Synthesis support may be limited for some tools; you'll need to experiment. For simulations, assign statements in an interface can be used to control data for tri-state buses.
interface I;
bit drive_en;
tri [15:0] io;
logic [15:0] io_drv;
assign io = drive_en ? io_drv : 'z;
endinterface
Interfaces can also contain their own tasks and functions. If you are using the interface for design, then generally you want to limit keep the interface simple: mostly signals and modports. This is not a rule, just a recommended guideline.
Or could I do some magic
to cause a write to a member in a union to result in updates of other members of the union that do not share bits?
More power to you if you got the magic
to pull it off. Probably not worth the effort.
You want to use the let
statement instead of a union
. The let statement is like a macro, except it is limited to a scope, and limited by substituting expressions, not any arbitrary text.
module example #(int ITEMS=3)(output logic[4:0] result);
let systemstatus = result[4];
let itemStatus = result[ITEMS-1:0];
...
endmodule
If you still want do this using a union, you can get what you want by creating your union with two structs. Also note that you need to use a packed union and struct to guarantee bit alignment.
union packed {
logic [4:0] result;
struct packed {
logic status;
logic [3:0] padding;
} system;
struct packed {
logic [4: 1+4-ITEMS] padding;
logic [ITEMS-1:0] status;
} item;
} myStruct;
Now you can refer to mystruct.system.status
and mystruct.item.status
.
Best Answer
Based on the IEEE Std 1800-2005,
ended
is used inside an assertion, property, or another sequence (§ 17.7.10, ex@(posedge clk) reset ##1 inst ##1 my_seq.ended
).triggered
is is the equivalent toended
and is allowed outside of an assertion (§ 10.11, exwait(my_seq.triggered)
).ended
has been depreciated in IEEE Std 1800-2012 as mentioned in § C.2.3:Few if any simulators are 1800-2012 complaint, so follow with 1800-2005 for now.