Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ImportVerilog] add stream concat operation #7784

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
83 changes: 83 additions & 0 deletions lib/Conversion/ImportVerilog/Expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,49 @@ struct RvalueExprVisitor {
return visitAssignmentPattern(expr, *count);
}

Value visit(const slang::ast::StreamingConcatenationExpression &expr) {
SmallVector<Value> operands;
for (auto stream: expr.streams()) {
auto value = context.convertRvalueExpression(*stream.operand);
if (!value)
continue;
chenbo-again marked this conversation as resolved.
Show resolved Hide resolved
value = context.convertToSimpleBitVector(value);
if(!value) {
mlir::emitError(loc) << "Streaming concatentation do only support SimpleBitVector for now";
// return {};
chenbo-again marked this conversation as resolved.
Show resolved Hide resolved
}
operands.push_back(value);
}
auto value = builder.create<moore::ConcatOp>(loc, operands).getResult();

if(expr.sliceSize == 0) {
return value;
}

SmallVector<Value> slicedOperands;
auto iterMax = value.getType().getWidth()/expr.sliceSize;
auto remainSize = value.getType().getWidth() % expr.sliceSize;

for (size_t i=0; i<iterMax; i++) {
auto extractResultType = moore::IntType::get(context.getContext(),
expr.sliceSize, value.getType().getDomain());

auto extracted = builder.create<moore::ExtractOp>(loc, extractResultType, value, i*expr.sliceSize);
slicedOperands.push_back(extracted);
}
// handle other wire
if(remainSize) {
auto extractResultType = moore::IntType::get(context.getContext(),
remainSize, value.getType().getDomain());

auto extracted = builder.create<moore::ExtractOp>(loc, extractResultType, value, iterMax*expr.sliceSize);
slicedOperands.push_back(extracted);
}

std::reverse(slicedOperands.begin(), slicedOperands.end());
chenbo-again marked this conversation as resolved.
Show resolved Hide resolved
return builder.create<moore::ConcatOp>(loc, slicedOperands);
}

/// Emit an error for all other expressions.
template <typename T>
Value visit(T &&node) {
Expand Down Expand Up @@ -929,6 +972,46 @@ struct LvalueExprVisitor {
dynLowBit);
}

Value visit(const slang::ast::StreamingConcatenationExpression &expr) {
SmallVector<Value> operands;
for (auto stream: expr.streams()) {
auto value = context.convertLvalueExpression(*stream.operand);
if (!value)
continue;
operands.push_back(value);
}
auto value = builder.create<moore::ConcatRefOp>(loc, operands).getResult();

if(expr.sliceSize == 0) {
return value;
}

SmallVector<Value> slicedOperands;
auto widthSum = cast<moore::IntType>(value.getType().getNestedType()).getWidth();
auto domain = cast<moore::IntType>(value.getType().getNestedType()).getDomain();
auto iterMax = widthSum/expr.sliceSize;
auto remainSize = widthSum % expr.sliceSize;

for (size_t i=0; i<iterMax; i++) {
auto extractResultType = moore::RefType::get(moore::IntType::get(context.getContext(),
expr.sliceSize, domain));

auto extracted = builder.create<moore::ExtractRefOp>(loc, extractResultType, value, i*expr.sliceSize);
slicedOperands.push_back(extracted);
}
// handle other wire
if(remainSize) {
auto extractResultType = moore::RefType::get(moore::IntType::get(context.getContext(),
remainSize, domain));

auto extracted = builder.create<moore::ExtractRefOp>(loc, extractResultType, value, iterMax*expr.sliceSize);
slicedOperands.push_back(extracted);
}

std::reverse(slicedOperands.begin(), slicedOperands.end());
return builder.create<moore::ConcatRefOp>(loc, slicedOperands);
}

Value visit(const slang::ast::MemberAccessExpression &expr) {
auto type = context.convertType(*expr.type);
auto valueType = expr.value().type;
Expand Down
9 changes: 9 additions & 0 deletions lib/Conversion/ImportVerilog/FormatStrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ struct FormatStringParser {
emitLiteral(lit->getValue());
return success();
}

if (slang::ast::NamedValueExpression::isKind(arg.kind)) {
if(options.width)
return mlir::emitError(loc)
<< "string format specifier with width not supported";

fragments.push_back(context.convertRvalueExpression(arg));
return success();
}
chenbo-again marked this conversation as resolved.
Show resolved Hide resolved
return mlir::emitError(argLoc)
<< "expression cannot be formatted as string";

Expand Down
24 changes: 24 additions & 0 deletions test/Conversion/ImportVerilog/basic.sv
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,8 @@ module Expressions;
logic [31:0] vec_1;
// CHECK: %vec_2 = moore.variable : <l32>
logic [0:31] vec_2;
// CHECK: %vec_3 = moore.variable : <l64>
logic [63:0] vec_3;
// CHECK: %arr = moore.variable : <uarray<3 x uarray<6 x i4>>>
bit [4:1] arr [1:3][2:7];
// CHECK: %struct0 = moore.variable : <struct<{a: i32, b: i32}>>
Expand Down Expand Up @@ -690,6 +692,28 @@ module Expressions;
{a, b, c} = a;
// CHECK: moore.concat_ref %d, %e : (!moore.ref<l32>, !moore.ref<l32>) -> <l64>
{d, e} = d;
// CHECK: [[CONCAT1:%.+]] = moore.concat [[SOURCE0:%.+]], [[SOURCE1:%.+]] : (!moore.l32, !moore.l32) -> l64
// CHECK: [[EXTRACT1:%.+]] = moore.extract [[CONCAT1]] from 0 : l64 -> l8
// CHECK: [[EXTRACT2:%.+]] = moore.extract [[CONCAT1]] from 8 : l64 -> l8
// CHECK: [[EXTRACT3:%.+]] = moore.extract [[CONCAT1]] from 16 : l64 -> l8
// CHECK: [[EXTRACT4:%.+]] = moore.extract [[CONCAT1]] from 24 : l64 -> l8
// CHECK: [[EXTRACT5:%.+]] = moore.extract [[CONCAT1]] from 32 : l64 -> l8
// CHECK: [[EXTRACT6:%.+]] = moore.extract [[CONCAT1]] from 40 : l64 -> l8
// CHECK: [[EXTRACT7:%.+]] = moore.extract [[CONCAT1]] from 48 : l64 -> l8
// CHECK: [[EXTRACT8:%.+]] = moore.extract [[CONCAT1]] from 56 : l64 -> l8
// CHECK: [[RESULT:%.+]] = moore.concat [[EXTRACT8]], [[EXTRACT7]], [[EXTRACT6]], [[EXTRACT5]], [[EXTRACT4]], [[EXTRACT3]], [[EXTRACT2]], [[EXTRACT1]] : (!moore.l8, !moore.l8, !moore.l8, !moore.l8, !moore.l8, !moore.l8, !moore.l8, !moore.l8) -> l64
vec_3 = {<<byte{vec_1, vec_1}};
chenbo-again marked this conversation as resolved.
Show resolved Hide resolved
// CHECK: [[CONCAT1:%.+]] = moore.concat_ref [[SOURCE0:%.+]], [[SOURCE1:%.+]] : (!moore.ref<l32>, !moore.ref<l32>) -> <l64>
// CHECK: [[EXTRACT1:%.+]] = moore.extract_ref [[CONCAT1]] from 0 : <l64> -> <l8>
// CHECK: [[EXTRACT2:%.+]] = moore.extract_ref [[CONCAT1]] from 8 : <l64> -> <l8>
// CHECK: [[EXTRACT3:%.+]] = moore.extract_ref [[CONCAT1]] from 16 : <l64> -> <l8>
// CHECK: [[EXTRACT4:%.+]] = moore.extract_ref [[CONCAT1]] from 24 : <l64> -> <l8>
// CHECK: [[EXTRACT5:%.+]] = moore.extract_ref [[CONCAT1]] from 32 : <l64> -> <l8>
// CHECK: [[EXTRACT6:%.+]] = moore.extract_ref [[CONCAT1]] from 40 : <l64> -> <l8>
// CHECK: [[EXTRACT7:%.+]] = moore.extract_ref [[CONCAT1]] from 48 : <l64> -> <l8>
// CHECK: [[EXTRACT8:%.+]] = moore.extract_ref [[CONCAT1]] from 56 : <l64> -> <l8>
// CHECK: [[RESULT:%.+]] = moore.concat_ref [[EXTRACT8]], [[EXTRACT7]], [[EXTRACT6]], [[EXTRACT5]], [[EXTRACT4]], [[EXTRACT3]], [[EXTRACT2]], [[EXTRACT1]] : (!moore.ref<l8>, !moore.ref<l8>, !moore.ref<l8>, !moore.ref<l8>, !moore.ref<l8>, !moore.ref<l8>, !moore.ref<l8>, !moore.ref<l8>) -> <l64>
{<<byte{vec_1, vec_1}} = vec_3;
// CHECK: [[TMP1:%.+]] = moore.constant 0 : i1
// CHECK: [[TMP2:%.+]] = moore.concat [[TMP1]] : (!moore.i1) -> i1
// CHECK: moore.replicate [[TMP2]] : i1 -> i32
Expand Down
Loading