@@ -2619,7 +2619,7 @@ Value Context::convertToSimpleBitVector(Value value) {
26192619// / corresponding simple bit vector `IntType`. This will apply special handling
26202620// / to time values, which requires scaling by the local timescale.
26212621static Value materializePackedToSBVConversion (Context &context, Value value,
2622- Location loc) {
2622+ Location loc, bool fallible ) {
26232623 if (isa<moore::IntType>(value.getType ()))
26242624 return value;
26252625
@@ -2642,9 +2642,10 @@ static Value materializePackedToSBVConversion(Context &context, Value value,
26422642 // `TimeType` fields. These require special conversion to ensure that the
26432643 // local timescale is in effect.
26442644 if (packedType.containsTimeType ()) {
2645- mlir::emitError (loc) << " unsupported conversion: " << packedType
2646- << " cannot be converted to " << intType
2647- << " ; contains a time type" ;
2645+ if (!fallible)
2646+ mlir::emitError (loc) << " unsupported conversion: " << packedType
2647+ << " cannot be converted to " << intType
2648+ << " ; contains a time type" ;
26482649 return {};
26492650 }
26502651
@@ -2657,7 +2658,8 @@ static Value materializePackedToSBVConversion(Context &context, Value value,
26572658// / time values, which requires scaling by the local timescale.
26582659static Value materializeSBVToPackedConversion (Context &context,
26592660 moore::PackedType packedType,
2660- Value value, Location loc) {
2661+ Value value, Location loc,
2662+ bool fallible) {
26612663 if (value.getType () == packedType)
26622664 return value;
26632665
@@ -2679,9 +2681,10 @@ static Value materializeSBVToPackedConversion(Context &context,
26792681 // `TimeType` fields. These require special conversion to ensure that the
26802682 // local timescale is in effect.
26812683 if (packedType.containsTimeType ()) {
2682- mlir::emitError (loc) << " unsupported conversion: " << intType
2683- << " cannot be converted to " << packedType
2684- << " ; contains a time type" ;
2684+ if (!fallible)
2685+ mlir::emitError (loc) << " unsupported conversion: " << intType
2686+ << " cannot be converted to " << packedType
2687+ << " ; contains a time type" ;
26852688 return {};
26862689 }
26872690
@@ -2723,7 +2726,7 @@ static mlir::Value maybeUpcastHandle(Context &context, mlir::Value actualHandle,
27232726}
27242727
27252728Value Context::materializeConversion (Type type, Value value, bool isSigned,
2726- Location loc) {
2729+ Location loc, bool fallible ) {
27272730 // Nothing to do if the types are already equal.
27282731 if (type == value.getType ())
27292732 return value;
@@ -2737,7 +2740,7 @@ Value Context::materializeConversion(Type type, Value value, bool isSigned,
27372740
27382741 if (dstInt && srcInt) {
27392742 // Convert the value to a simple bit vector if it isn't one already.
2740- value = materializePackedToSBVConversion (*this , value, loc);
2743+ value = materializePackedToSBVConversion (*this , value, loc, fallible );
27412744 if (!value)
27422745 return {};
27432746
@@ -2763,7 +2766,8 @@ Value Context::materializeConversion(Type type, Value value, bool isSigned,
27632766 }
27642767
27652768 // Convert the value from a simple bit vector back to the packed type.
2766- value = materializeSBVToPackedConversion (*this , dstPacked, value, loc);
2769+ value = materializeSBVToPackedConversion (*this , dstPacked, value, loc,
2770+ fallible);
27672771 if (!value)
27682772 return {};
27692773
@@ -2804,13 +2808,10 @@ Value Context::materializeConversion(Type type, Value value, bool isSigned,
28042808 }
28052809
28062810 // Handle Real To Int conversion
2807- if (isa<moore::IntType>(type) && isa<moore::RealType>(value.getType ())) {
2811+ if (dstInt && isa<moore::RealType>(value.getType ())) {
28082812 auto twoValInt = builder.createOrFold <moore::RealToIntOp>(
2809- loc, dyn_cast<moore::IntType>(type).getTwoValued (), value);
2810-
2811- if (dyn_cast<moore::IntType>(type).getDomain () == moore::Domain::FourValued)
2812- return materializePackedToSBVConversion (*this , twoValInt, loc);
2813- return twoValInt;
2813+ loc, dstInt.getTwoValued (), value);
2814+ return materializeConversion (type, twoValInt, true , loc, fallible);
28142815 }
28152816
28162817 // Handle Int to Real conversion
@@ -2903,6 +2904,8 @@ Value Context::materializeConversion(Type type, Value value, bool isSigned,
29032904 return maybeUpcastHandle (*this , value, cast<moore::ClassHandleType>(type));
29042905
29052906 // TODO: Handle other conversions with dedicated ops.
2907+ if (fallible && value.getType () != type)
2908+ return {};
29062909 if (value.getType () != type)
29072910 value = moore::ConversionOp::create (builder, loc, type, value);
29082911 return value;
@@ -3054,6 +3057,40 @@ Value Context::convertSystemCall(
30543057 return convertRealMathBI<moore::BitstoshortrealBIOp>(*this , loc, name,
30553058 args);
30563059
3060+ if (nameId == ksn::Cast) {
3061+ assert (numArgs == 2 && " `cast` takes 2 arguments" );
3062+ auto *dstExpr = args[0 ];
3063+ auto dstType = convertType (*dstExpr->type );
3064+ if (!dstType)
3065+ return {};
3066+
3067+ if (auto *assign = dstExpr->as_if <slang::ast::AssignmentExpression>())
3068+ dstExpr = &assign->left ();
3069+ auto dst = convertLvalueExpression (*dstExpr);
3070+ if (!dst)
3071+ return {};
3072+
3073+ auto src = convertRvalueExpression (*args[1 ]);
3074+ if (!src)
3075+ return {};
3076+ // Class-typed $cast (upcast/downcast) is intentionally left for follow-up.
3077+ if (isa<moore::ClassHandleType>(dstType) ||
3078+ isa<moore::ClassHandleType>(src.getType ())) {
3079+ auto i1Ty = moore::IntType::getInt (builder.getContext (), 1 );
3080+ return moore::ConstantOp::create (builder, loc, i1Ty, 0 ,
3081+ /* isSigned=*/ false );
3082+ }
3083+ auto converted = materializeConversion (
3084+ dstType, src, args[1 ]->type ->isSigned (), loc, /* fallible=*/ true );
3085+ auto i1Ty = moore::IntType::getInt (builder.getContext (), 1 );
3086+ if (!converted)
3087+ return moore::ConstantOp::create (builder, loc, i1Ty, 0 ,
3088+ /* isSigned=*/ false );
3089+ moore::BlockingAssignOp::create (builder, loc, dst, converted);
3090+ return moore::ConstantOp::create (builder, loc, i1Ty, 1 ,
3091+ /* isSigned=*/ false );
3092+ }
3093+
30573094 // ===--------------------------------------------------------------------===//
30583095 // String Methods
30593096 // ===--------------------------------------------------------------------===//
0 commit comments