diff --git a/lib/Conversion/ImportVerilog/Expressions.cpp b/lib/Conversion/ImportVerilog/Expressions.cpp index 15f1b4e0590e..dcef063eac36 100644 --- a/lib/Conversion/ImportVerilog/Expressions.cpp +++ b/lib/Conversion/ImportVerilog/Expressions.cpp @@ -791,6 +791,49 @@ struct RvalueExprVisitor { return visitAssignmentPattern(expr, *count); } + Value visit(const slang::ast::StreamingConcatenationExpression &expr) { + SmallVector operands; + for (auto stream: expr.streams()) { + auto value = context.convertRvalueExpression(*stream.operand); + if (!value) + continue; + value = context.convertToSimpleBitVector(value); + if(!value) { + mlir::emitError(loc) << "Streaming concatentation do only support SimpleBitVector for now"; + // return {}; + } + operands.push_back(value); + } + auto value = builder.create(loc, operands).getResult(); + + if(expr.sliceSize == 0) { + return value; + } + + SmallVector slicedOperands; + auto iterMax = value.getType().getWidth()/expr.sliceSize; + auto remainSize = value.getType().getWidth() % expr.sliceSize; + + for (size_t i=0; i(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(loc, extractResultType, value, iterMax*expr.sliceSize); + slicedOperands.push_back(extracted); + } + + std::reverse(slicedOperands.begin(), slicedOperands.end()); + return builder.create(loc, slicedOperands); + } + /// Emit an error for all other expressions. template Value visit(T &&node) { @@ -929,6 +972,46 @@ struct LvalueExprVisitor { dynLowBit); } + Value visit(const slang::ast::StreamingConcatenationExpression &expr) { + SmallVector operands; + for (auto stream: expr.streams()) { + auto value = context.convertLvalueExpression(*stream.operand); + if (!value) + continue; + operands.push_back(value); + } + auto value = builder.create(loc, operands).getResult(); + + if(expr.sliceSize == 0) { + return value; + } + + SmallVector slicedOperands; + auto widthSum = cast(value.getType().getNestedType()).getWidth(); + auto domain = cast(value.getType().getNestedType()).getDomain(); + auto iterMax = widthSum/expr.sliceSize; + auto remainSize = widthSum % expr.sliceSize; + + for (size_t i=0; i(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(loc, extractResultType, value, iterMax*expr.sliceSize); + slicedOperands.push_back(extracted); + } + + std::reverse(slicedOperands.begin(), slicedOperands.end()); + return builder.create(loc, slicedOperands); + } + Value visit(const slang::ast::MemberAccessExpression &expr) { auto type = context.convertType(*expr.type); auto valueType = expr.value().type; diff --git a/lib/Conversion/ImportVerilog/FormatStrings.cpp b/lib/Conversion/ImportVerilog/FormatStrings.cpp index 7698ad142b71..439c3e02c321 100644 --- a/lib/Conversion/ImportVerilog/FormatStrings.cpp +++ b/lib/Conversion/ImportVerilog/FormatStrings.cpp @@ -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(); + } return mlir::emitError(argLoc) << "expression cannot be formatted as string"; diff --git a/test/Conversion/ImportVerilog/basic.sv b/test/Conversion/ImportVerilog/basic.sv index d1e87f2ac8a4..31df26a227a7 100644 --- a/test/Conversion/ImportVerilog/basic.sv +++ b/test/Conversion/ImportVerilog/basic.sv @@ -622,6 +622,8 @@ module Expressions; logic [31:0] vec_1; // CHECK: %vec_2 = moore.variable : logic [0:31] vec_2; + // CHECK: %vec_3 = moore.variable : + logic [63:0] vec_3; // CHECK: %arr = moore.variable : >> bit [4:1] arr [1:3][2:7]; // CHECK: %struct0 = moore.variable : > @@ -690,6 +692,28 @@ module Expressions; {a, b, c} = a; // CHECK: moore.concat_ref %d, %e : (!moore.ref, !moore.ref) -> {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 = {<, !moore.ref) -> + // CHECK: [[EXTRACT1:%.+]] = moore.extract_ref [[CONCAT1]] from 0 : -> + // CHECK: [[EXTRACT2:%.+]] = moore.extract_ref [[CONCAT1]] from 8 : -> + // CHECK: [[EXTRACT3:%.+]] = moore.extract_ref [[CONCAT1]] from 16 : -> + // CHECK: [[EXTRACT4:%.+]] = moore.extract_ref [[CONCAT1]] from 24 : -> + // CHECK: [[EXTRACT5:%.+]] = moore.extract_ref [[CONCAT1]] from 32 : -> + // CHECK: [[EXTRACT6:%.+]] = moore.extract_ref [[CONCAT1]] from 40 : -> + // CHECK: [[EXTRACT7:%.+]] = moore.extract_ref [[CONCAT1]] from 48 : -> + // CHECK: [[EXTRACT8:%.+]] = moore.extract_ref [[CONCAT1]] from 56 : -> + // CHECK: [[RESULT:%.+]] = moore.concat_ref [[EXTRACT8]], [[EXTRACT7]], [[EXTRACT6]], [[EXTRACT5]], [[EXTRACT4]], [[EXTRACT3]], [[EXTRACT2]], [[EXTRACT1]] : (!moore.ref, !moore.ref, !moore.ref, !moore.ref, !moore.ref, !moore.ref, !moore.ref, !moore.ref) -> + {< i1 // CHECK: moore.replicate [[TMP2]] : i1 -> i32