Skip to content

Commit afaf420

Browse files
committed
Fix use of enums in concatenation expressions. #230
1 parent ba258b1 commit afaf420

File tree

4 files changed

+76
-15
lines changed

4 files changed

+76
-15
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ jobs:
261261
- build_sdist
262262

263263
runs-on: ubuntu-latest
264+
environment: release
264265

265266
# Only publish when a GitHub Release is created.
266267
if: github.event_name == 'release'
@@ -271,6 +272,3 @@ jobs:
271272
path: dist
272273

273274
- uses: pypa/gh-action-pypi-publish@release/v1
274-
with:
275-
user: __token__
276-
password: ${{ secrets.pypi_password }}

src/systemrdl/ast/sequence.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,11 @@ def __init__(self, env: 'RDLEnvironment', src_ref: 'OptionalSourceRef', elements
1515
self.elements = elements
1616
self.type = None # type: Union[Type[int], Type[str]]
1717

18-
def predict_type(self):
19-
# type: () -> Union[Type[int], Type[str]]
20-
21-
# Get type of first element
18+
def predict_type(self) -> Union[Type[int], Type[str]]:
2219
element_iter = iter(self.elements)
23-
element_type = next(element_iter).predict_type()
2420

25-
# All remaining elements shall match
26-
for element in element_iter:
27-
if element_type != element.predict_type():
28-
self.msg.fatal(
29-
"Elements of a concatenation shall be the same type",
30-
self.src_ref
31-
)
21+
# first element defines the type of the concatenation
22+
element_type = next(element_iter).predict_type()
3223
if is_castable(element_type, int):
3324
self.type = int
3425
elif is_castable(element_type, str):
@@ -38,6 +29,14 @@ def predict_type(self):
3829
"Concatenation operator can only be used for integral or string types",
3930
self.src_ref
4031
)
32+
33+
# All remaining elements shall be castable to the concatenation type
34+
for element in element_iter:
35+
if not is_castable(element.predict_type(), self.type):
36+
self.msg.fatal(
37+
"Elements of a concatenation shall be the same type",
38+
self.src_ref
39+
)
4140
return self.type
4241

4342
def get_min_eval_width(self) -> int:
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
property int_prop {
2+
type = longint;
3+
component = all;
4+
};
5+
6+
addrmap enum_expr_test {
7+
enum my_enum1 {
8+
zero;
9+
one;
10+
two;
11+
three;
12+
};
13+
14+
enum my_enum2 {
15+
ten = 10;
16+
eleven = 11;
17+
twelve = 12;
18+
thirteen = 13;
19+
};
20+
21+
reg myreg {
22+
field {} f;
23+
};
24+
25+
// convenience macro that instantiates the reg, and assigns the UDP with an expression
26+
`define EXPR(name, expr) myreg name; name->int_prop = expr
27+
28+
`EXPR(concat1, {my_enum2::twelve, 8'h10});
29+
`EXPR(concat2, {8'h22, my_enum2::thirteen, 8'h10});
30+
`EXPR(concat3, {8'h22, (8)'(my_enum2::thirteen), 8'h10});
31+
`EXPR(repl, {3{my_enum1::three}});
32+
`EXPR(add, my_enum1::three + 5);
33+
`EXPR(sub, my_enum1::three - 1);
34+
`EXPR(mul, my_enum1::three * 2);
35+
`EXPR(div, my_enum2::twelve / 2);
36+
`EXPR(mod, my_enum2::twelve % 5);
37+
`EXPR(and, my_enum2::twelve & 9);
38+
`EXPR(or, my_enum2::twelve | 9);
39+
`EXPR(xor, my_enum2::twelve ^ 9);
40+
`EXPR(inv, ~my_enum2::twelve);
41+
};

test/test_enums.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,26 @@ def test_enums_pickleable(self):
8181
self.assertEqual(m.rdl_desc, m2.rdl_desc)
8282
self.assertIs(type(e).__class__, type(e2).__class__)
8383
self.assertIs(type(e).__module__, type(e2).__module__)
84+
85+
def test_enums_in_expressions(self):
86+
root = self.compile(
87+
["rdl_src/enums_in_expressions.rdl"],
88+
"enum_expr_test"
89+
)
90+
def check_result(name: str, value: int):
91+
reg = root.top.get_child_by_name(name)
92+
self.assertEqual(reg.get_property("int_prop"), value)
93+
94+
check_result("concat1", 0xC10)
95+
check_result("concat2", 0x22000000000000000D10)
96+
check_result("concat3", 0x220D10)
97+
check_result("repl", 0x000000000000000300000000000000030000000000000003)
98+
check_result("add", 8)
99+
check_result("sub", 2)
100+
check_result("mul", 6)
101+
check_result("div", 6)
102+
check_result("mod", 2)
103+
check_result("and", 8)
104+
check_result("or", 13)
105+
check_result("xor", 5)
106+
check_result("inv", 0xFFFFFFFF_FFFFFFF3)

0 commit comments

Comments
 (0)