mirror of https://github.com/zachjs/sv2v.git
fix struct member accesses within field select bounds (#330)
This commit is contained in:
parent
1a89e8b986
commit
493a88f930
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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…
Reference in New Issue