Skip to content

Commit de56173

Browse files
authored
Merge pull request #1658 from SAY-5/fix-gh1542-wide-enum2
Support 2-state enums wider than 64 bits
2 parents d840335 + 32cb43d commit de56173

5 files changed

Lines changed: 57 additions & 10 deletions

File tree

‎ivtest/ivltests/br_gh1542.v‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Check that a 2-state enum wider than 64 bits is supported.
2+
3+
module test;
4+
typedef enum bit [64:0] {
5+
LOW = 65'h1,
6+
HIGH = 65'h1_0000_0000_0000_0001
7+
} code_t;
8+
9+
code_t value;
10+
bit failed = 1'b0;
11+
12+
initial begin
13+
value = HIGH;
14+
if (value !== 65'h1_0000_0000_0000_0001 || value.name() != "HIGH") begin
15+
$display("FAILED: value=%h name=%s", value, value.name());
16+
failed = 1'b1;
17+
end
18+
if (value.next() !== LOW || value.prev() !== LOW) begin
19+
$display("FAILED: next=%h prev=%h", value.next(), value.prev());
20+
failed = 1'b1;
21+
end
22+
if (!failed) begin
23+
$display("PASSED");
24+
end
25+
end
26+
endmodule

‎ivtest/regress-vvp.list‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ br_gh1385c vvp_tests/br_gh1385c.json
116116
br_gh1407 vvp_tests/br_gh1407.json
117117
br_gh1512 vvp_tests/br_gh1512.json
118118
br_gh1541 vvp_tests/br_gh1541.json
119+
br_gh1542 vvp_tests/br_gh1542.json
119120
br_gh1554a vvp_tests/br_gh1554a.json
120121
br_gh1554b vvp_tests/br_gh1554b.json
121122
br_gh1557 vvp_tests/br_gh1557.json

‎ivtest/vvp_tests/br_gh1542.json‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"type" : "normal",
3+
"source" : "br_gh1542.v",
4+
"iverilog-args" : [ "-g2005-sv" ],
5+
"vlog95" : {
6+
"__comment" : "Enum expressions are not supported",
7+
"type" : "CE",
8+
"iverilog-args" : [ "-pallowsigned=1" ]
9+
}
10+
}

‎tgt-vvp/draw_enum.c‎

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2011 Stephen Williams (steve@icarus.com)
2+
* Copyright (c) 2010-2026 Stephen Williams (steve@icarus.com)
33
*
44
* This source code is free software; you can redistribute it
55
* and/or modify it in source code form under the terms of the GNU
@@ -24,13 +24,16 @@
2424
# include <assert.h>
2525
# include <inttypes.h>
2626

27-
// HERE: This still needs work! Fall back to <width>'b format for
28-
// very large constants. We also should pass the file and
27+
// HERE: This still needs work! We should pass the file and
2928
// line number information for the enum type and the MSB and
3029
// LSB should be used instead of the width.
30+
31+
static void draw_enum4_value(ivl_enumtype_t enumtype, unsigned idx);
32+
3133
/*
3234
* If it fits we always print this as a uint64_t the run time will turn
33-
* it back into a signed value when needed.
35+
* it back into a signed value when needed. Wider values are printed in
36+
* the <width>'b format.
3437
*/
3538
static void draw_enum2_value(ivl_enumtype_t enumtype, unsigned idx)
3639
{
@@ -39,9 +42,11 @@ static void draw_enum2_value(ivl_enumtype_t enumtype, unsigned idx)
3942
const char*bit;
4043
unsigned len = strlen(bits);
4144

42-
// HERE: If this doesn't fit then write it as a enum4 and modify the run
43-
// time to deal with the conversion.
44-
assert(len <= sizeof(uint64_t)*8);
45+
if (len > sizeof(uint64_t)*8) {
46+
draw_enum4_value(enumtype, idx);
47+
return;
48+
}
49+
4550
val = 0;
4651
for (bit = bits, mask = 1 ; *bit != 0 ; bit += 1, mask <<= 1) {
4752
if (*bit == '1')

‎vvp/enum_type.cc‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2025 Stephen Williams (steve@icarus.com)
2+
* Copyright (c) 2010-2026 Stephen Williams (steve@icarus.com)
33
*
44
* This source code is free software; you can redistribute it
55
* and/or modify it in source code form under the terms of the GNU
@@ -147,9 +147,14 @@ void compile_enum2_type(char*label, long width, bool signed_flag,
147147
size_t idx = 0;
148148
for (list<struct enum_name_s>::iterator cur = names->begin()
149149
; cur != names->end() ; ++cur, ++idx) {
150-
assert(cur->val4 == 0);
151150
spec->names[idx].name = cur->text;
152-
spec->names[idx].val2 = vvp_vector2_t(cur->val2, width);
151+
if (cur->val4) {
152+
spec->names[idx].val2 = vvp_vector2_t(vector4_from_text(cur->val4, width));
153+
free(cur->val4);
154+
cur->val4 = 0;
155+
} else {
156+
spec->names[idx].val2 = vvp_vector2_t(cur->val2, width);
157+
}
153158
spec->names[idx].is_signed = signed_flag;
154159
}
155160

0 commit comments

Comments
 (0)