diff --git a/lib/Conversion/ImportVerilog/Expressions.cpp b/lib/Conversion/ImportVerilog/Expressions.cpp index 92eaa4fdb8b2..3dd3c629ba6c 100644 --- a/lib/Conversion/ImportVerilog/Expressions.cpp +++ b/lib/Conversion/ImportVerilog/Expressions.cpp @@ -798,19 +798,70 @@ struct RvalueExprVisitor { } Value visit(const slang::ast::StreamingConcatenationExpression &expr) { - SmallVector arguments; + SmallVector operands; for (auto stream: expr.streams()) { auto value = context.convertRvalueExpression(*stream.operand); - // mlir::emitError(value.getLoc(), "expression of type ") - // << value.getType(); + if (!value) + continue; + value = context.convertToSimpleBitVector(value); + operands.push_back(value); + } + if(expr.sliceSize == 0) { + return builder.create(loc, operands); + } - if(!value) { - mlir::emitError(loc) << "error occour"; + SmallVector slicedOperands; + SmallVector tempOperands; + size_t currentWidth = 0; + for (auto value : operands) { + auto sliceSize = expr.sliceSize; + tempOperands.push_back(value); + currentWidth += cast(value.getType()).getWidth(); + + while(currentWidth >= sliceSize) { + // mlir::emitError(loc) <(lastValue.getType()); + + if(currentWidth == sliceSize) { + // do not need extract operation + if(tempOperands.empty()) { + slicedOperands.push_back(lastValue); + } else { + tempOperands.push_back(lastValue); + auto concatOp = builder.create(loc, tempOperands); + slicedOperands.push_back(concatOp.getResult()); + } + tempOperands.clear(); + } else { + auto remainWidth = currentWidth - sliceSize; + auto extractWidth = type.getWidth() - remainWidth; + auto extractResultType = moore::IntType::get(context.getContext(), + extractWidth, type.getDomain()); + auto remainExtractResultType = moore::IntType::get(context.getContext(), + remainWidth, type.getDomain()); + + auto extractOp = builder.create(loc, extractResultType, lastValue, 0); + auto remainExtractOp = builder.create(loc, remainExtractResultType, lastValue, extractWidth); + + if(tempOperands.empty()) { + slicedOperands.push_back(extractOp.getResult()); + } else { + tempOperands.push_back(extractOp.getResult()); + auto concatOp = builder.create(loc, tempOperands); + slicedOperands.push_back(concatOp.getResult()); + } + tempOperands.clear(); + tempOperands.push_back(remainExtractOp.getResult()); + } + currentWidth -= sliceSize; + // mlir::emitError(loc) <(loc, arguments, - builder.getUI32IntegerAttr(expr.sliceSize)); + + std::reverse(slicedOperands.begin(), slicedOperands.end()); + return builder.create(loc, slicedOperands); } /// Emit an error for all other expressions. @@ -952,19 +1003,69 @@ struct LvalueExprVisitor { } Value visit(const slang::ast::StreamingConcatenationExpression &expr) { - SmallVector arguments; + SmallVector operands; for (auto stream: expr.streams()) { auto value = context.convertLvalueExpression(*stream.operand); - // mlir::emitError(value.getLoc(), "expression of type ") - // << value.getType(); + if (!value) + continue; + operands.push_back(value); + } + if(expr.sliceSize == 0) { + return builder.create(loc, operands); + } - if(!value) { - mlir::emitError(loc) << "error occour"; + SmallVector slicedOperands; + SmallVector tempOperands; + size_t currentWidth = 0; + for (auto value : operands) { + auto sliceSize = expr.sliceSize; + tempOperands.push_back(value); + currentWidth += cast(cast(value.getType()).getNestedType()).getWidth(); + + while(currentWidth >= sliceSize) { + // mlir::emitError(loc) <(cast(lastValue.getType()).getNestedType()); + + if(currentWidth == sliceSize) { + // do not need extract operation + if(tempOperands.empty()) { + slicedOperands.push_back(lastValue); + } else { + tempOperands.push_back(lastValue); + auto concatOp = builder.create(loc, tempOperands); + slicedOperands.push_back(concatOp.getResult()); + } + tempOperands.clear(); + } else { + auto remainWidth = currentWidth - sliceSize; + auto extractWidth = type.getWidth() - remainWidth; + auto extractResultType = moore::RefType::get(moore::IntType::get(context.getContext(), + extractWidth, type.getDomain())); + auto remainExtractResultType = moore::RefType::get(moore::IntType::get(context.getContext(), + remainWidth, type.getDomain())); + + auto extractOp = builder.create(loc, extractResultType, lastValue, 0); + auto remainExtractOp = builder.create(loc, remainExtractResultType, lastValue, extractWidth); + + if(tempOperands.empty()) { + slicedOperands.push_back(extractOp.getResult()); + } else { + tempOperands.push_back(extractOp.getResult()); + auto concatOp = builder.create(loc, tempOperands); + slicedOperands.push_back(concatOp.getResult()); + } + tempOperands.clear(); + tempOperands.push_back(remainExtractOp.getResult()); + } + currentWidth -= sliceSize; + // mlir::emitError(loc) <(loc, arguments, - builder.getUI32IntegerAttr(expr.sliceSize)); + + std::reverse(slicedOperands.begin(), slicedOperands.end()); + return builder.create(loc, slicedOperands); } Value visit(const slang::ast::MemberAccessExpression &expr) {