Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
* Added support for `bufif0`, `bufif1`, `notif0`, `notif1`, `cmos`, `rcmos`,
`nmos`, `pmos`, `rnmos`, and `rpmos`.

### Bug Fixes

* Fixed conversion of struct field accesses when the struct's field widths
depend on a member of a struct-typed parameter

### Other Enhancements

* `always_comb` blocks with sensitivities inherited from called functions or
Expand Down
8 changes: 5 additions & 3 deletions src/Convert/Struct.hs
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,12 @@ convertSubExpr scopes (Dot e x) =
where
(subExprType, e') = convertSubExpr scopes e
(isHier, fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x
base = fst bounds
len = rangeSize bounds
-- the offset and size are derived from the struct layout, whose field
-- widths may contain member accesses that must themselves be lowered
(_, base) = convertSubExpr scopes $ fst bounds
(_, len) = convertSubExpr scopes $ rangeSize bounds
undotted = if null dims || rangeSize (head dims) == RawNum 1
then Bit e' (fst bounds)
then Bit e' base
else Range e' IndexedMinus (base, len)
-- retain signedness of fields which would otherwise be lost via the
-- resulting bit or range selection
Expand Down
26 changes: 26 additions & 0 deletions test/core/class_paramstruct.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package P;
typedef struct packed { int unsigned a; int unsigned b; } cfg_t;
localparam cfg_t cfg = '{a: 8, b: 4};
typedef enum logic [1:0] { S_A, S_B } enum_e;
endpackage

class C #(parameter P::cfg_t cfg = P::cfg);
typedef logic [$clog2(cfg.a) - 1:0] x_t;
typedef logic [cfg.b - 1:0] y_t;
typedef struct packed { P::enum_e e; x_t x; y_t y; } s_t;
endclass

module child #(
parameter P::cfg_t cfg = P::cfg,
parameter type s_t = C#(cfg)::s_t,
localparam type x_t = C#(cfg)::x_t
) (
input s_t ins,
output x_t out
);
always_comb
unique case (ins.e)
P::S_A: out = ins.x;
default: out = '0;
endcase
endmodule
11 changes: 11 additions & 0 deletions test/core/class_paramstruct.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module child(
input wire [8:0] inp,
output reg [2:0] out
);
always @* begin
case (inp[8:7])
2'd0: out = inp[6:4];
default: out = 3'd0;
endcase
end
endmodule
11 changes: 11 additions & 0 deletions test/core/class_paramstruct_tb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module top;
reg [8:0] inp;
wire [2:0] out;
child c(inp, out);
initial begin
$monitor("%2d %b %b", $time, inp, out);
inp = 9'b00_101_0000; #1;
inp = 9'b00_010_1111; #1;
inp = 9'b01_111_0000; #1;
end
endmodule
Loading