[ImportVerilog] Fix empty replications within concatenations

Verilog allows for empty replications like `{0{...}}` to appear within
concatenations. Slang assigns them the `void` type, which we can check
for in the concatenation. This fixes an issue where the replication
lowering would return a null value to indicate an empty replication,
which conflicts with the null value being used as error indicator
everywhere else in the lowering.

Thanks @hailongSun2000 for pointing out the issue!
This commit is contained in:
Fabian Schuiki 2025-04-09 10:23:39 -07:00
parent c9e048c2fc
commit bd6949339c
2 changed files with 13 additions and 3 deletions

View File

@ -409,6 +409,11 @@ struct RvalueExprVisitor {
Value visit(const slang::ast::ConcatenationExpression &expr) {
SmallVector<Value> operands;
for (auto *operand : expr.operands()) {
// Handle empty replications like `{0{...}}` which may occur within
// concatenations. Slang assigns them a `void` type which we can check for
// here.
if (operand->type->isVoid())
continue;
auto value = context.convertRvalueExpression(*operand);
value = context.convertToSimpleBitVector(value);
if (!value)
@ -421,9 +426,6 @@ struct RvalueExprVisitor {
// Handle replications.
Value visit(const slang::ast::ReplicationExpression &expr) {
auto type = context.convertType(*expr.type);
if (isa<moore::VoidType>(type))
return {};
auto value = context.convertRvalueExpression(expr.concat());
if (!value)
return {};

View File

@ -859,6 +859,14 @@ module Expressions;
// CHECK: [[TMP2:%.+]] = moore.concat [[TMP1]] : (!moore.i1) -> i1
// CHECK: moore.replicate [[TMP2]] : i1 -> i32
a = {32{1'b0}};
// CHECK: [[TMP1:%.+]] = moore.read %a : <i32>
// CHECK: [[TMP2:%.+]] = moore.read %c : <i32>
// CHECK: moore.concat [[TMP1]], [[TMP2]] : (!moore.i32, !moore.i32) -> i64
a = {a, {0{b}}, c};
// CHECK: [[TMP1:%.+]] = moore.read %a : <i32>
// CHECK: [[TMP2:%.+]] = moore.read %c : <i32>
// CHECK: moore.concat [[TMP1]], [[TMP2]] : (!moore.i32, !moore.i32) -> i64
a = {a, {0{b}}, {0{a, {0{b}}, c}}, c};
// CHECK: [[TMP1:%.+]] = moore.read %vec_1 : <l32>
// CHECK: moore.extract [[TMP1]] from 1 : l32 -> l3
y = vec_1[3:1];