/// <summary> /// Gets the VHDL type for a parameter. /// </summary> /// <returns>The VHDL type.</returns> /// <param name="type">The parameter definition.</param> public VHDLType GetVHDLType(ParameterDefinition type) { var tr = type.ParameterType; if (!tr.IsArrayType()) { return(GetVHDLType(tr)); } var eltype = GetVHDLType(tr.GetArrayElementType()); var name = string.IsNullOrWhiteSpace(eltype.Alias) ? ((MethodDefinition)type.Method).Name + "_" + type.Name + "_ARRAY" : eltype.ToString() + "_ARRAY"; if (!m_arrays.ContainsKey(name)) { m_arrays[name] = new VHDLType() { IsArray = true, Name = name, ElementName = eltype.ToString() }; } return(m_arrays[name]); }
/// <summary> /// Gets a STD_LOGIC_VECTOR of a size matching the given type /// </summary> /// <returns>The std_logic_vector equivalent.</returns> /// <param name="type">The type to get an equivalent for.</param> public VHDLType StdLogicVectorEquivalent(VHDLType type) { if (!type.IsStdLogicVector && !type.IsSystemSigned && !type.IsSystemUnsigned && !type.IsVHDLSigned && !type.IsVHDLUnsigned) { throw new Exception(string.Format("Unable to find suitable std_logic_vector type for {0}", type.Alias ?? type.Name)); } return(GetStdLogicVector(type.Length)); }
/// <summary> /// Gets a std_logic_vector of the given length /// </summary> /// <returns>The std_logic_vector type.</returns> /// <param name="length">The length of the vector.</param> public VHDLType GetStdLogicVector(int length) { if (!m_vectorTypes.ContainsKey(length)) { m_vectorTypes[length] = new VHDLType() { Name = string.Format("STD_LOGIC_VECTOR({0} downto 0)", length - 1), IsArray = true, ElementName = "STD_LOGIC", LowerBound = 0, UpperBound = length - 1, } } ; return(m_vectorTypes[length]); } }
/// <summary> /// Gets a system equivalent type for the given VHDL type /// </summary> /// <returns>The system type equivalent.</returns> /// <param name="type">The VHDL type to get a system equivalent.</param> public VHDLType SystemEquivalent(VHDLType type) { if (type.IsSystemType) { return(type); } if (type == VHDLTypes.NUMERIC_UINT8 || type.IsStdLogicVector && type.Length == 8) { return(VHDLTypes.SYSTEM_UINT8); } else if (type == VHDLTypes.NUMERIC_UINT16 || type.IsStdLogicVector && type.Length == 16) { return(VHDLTypes.SYSTEM_UINT16); } else if (type == VHDLTypes.NUMERIC_UINT32 || type.IsStdLogicVector && type.Length == 32) { return(VHDLTypes.SYSTEM_UINT32); } else if (type == VHDLTypes.NUMERIC_UINT64 || type.IsStdLogicVector && type.Length == 64) { return(VHDLTypes.SYSTEM_UINT64); } else if (type == VHDLTypes.NUMERIC_INT8 || type.IsStdLogicVector && type.Length == 8) { return(VHDLTypes.SYSTEM_INT8); } else if (type == VHDLTypes.NUMERIC_INT16 || type.IsStdLogicVector && type.Length == 16) { return(VHDLTypes.SYSTEM_INT16); } else if (type == VHDLTypes.NUMERIC_INT32 || type.IsStdLogicVector && type.Length == 32) { return(VHDLTypes.SYSTEM_INT32); } else if (type == VHDLTypes.NUMERIC_INT64 || type.IsStdLogicVector && type.Length == 64) { return(VHDLTypes.SYSTEM_INT64); } else { throw new Exception(string.Format("Unable to find suitable system type for {0}", type.Alias ?? type.Name)); } }
/// <summary> /// Gets the VHDL type for a property. /// </summary> /// <returns>The VHDL type.</returns> /// <param name="pi">The property definition.</param> public VHDLType GetVHDLType(System.Reflection.PropertyInfo pi) { var customtype = pi.GetCustomAttributes(typeof(VHDLTypeAttribute), true).FirstOrDefault() as VHDLTypeAttribute; if (customtype != null) { return(GetVHDLType(customtype, m_resolveModule.ImportReference(pi.PropertyType))); } // Try on-type declaration customtype = pi.PropertyType.GetCustomAttributes(typeof(VHDLTypeAttribute), true).FirstOrDefault() as VHDLTypeAttribute; if (customtype != null) { return(GetVHDLType(customtype, m_resolveModule.ImportReference(pi.PropertyType))); } if (!pi.PropertyType.IsArrayType()) { return(GetVHDLType(pi.PropertyType)); } var eltype = GetVHDLType(pi.PropertyType.GetArrayElementType()); var name = string.IsNullOrWhiteSpace(eltype.Alias) ? pi.Name + "_ARRAY" : eltype.ToString() + "_ARRAY"; if (!m_arrays.ContainsKey(name)) { m_arrays[name] = new VHDLType() { IsArray = true, Name = name, ElementName = eltype.ToString() }; } return(m_arrays[name]); }
/// <summary> /// Gets the vhdl type from a member definition /// </summary> /// <returns>The VHDL type.</returns> /// <param name="type">The member definition.</param> /// <param name="membertype">The forced type.</param> public VHDLType GetVHDLType(IMemberDefinition type, TypeReference membertype = null) { TypeReference tr = membertype; var customtype = type.GetAttribute <VHDLTypeAttribute>(); if (tr == null) { if (type is FieldDefinition) { tr = (type as FieldDefinition).FieldType; } else if (type is PropertyDefinition) { tr = (type as PropertyDefinition).PropertyType; } else if (type is MethodDefinition) { tr = (type as MethodDefinition).ReturnType; } else { throw new Exception(string.Format("Not supported member type: {0}", type.GetType().FullName)); } } if (customtype == null) { customtype = tr.GetAttribute <VHDLTypeAttribute>(); } VHDLType customvhdl = null; if (customtype != null) { var argname = customtype.ConstructorArguments.First().Value as string; var argalias = customtype.ConstructorArguments.Count > 1 ? customtype.ConstructorArguments.Last().Value as string : null; customvhdl = GetVHDLType(new VHDLTypeAttribute(argname, argalias), tr); } if (!tr.IsArrayType()) { if (tr.IsSameTypeReference(typeof(IntPtr))) { if (IntPtr.Size == 4) { return(VHDLTypes.SYSTEM_INT32); } else if (IntPtr.Size == 8) { return(VHDLTypes.SYSTEM_INT64); } } else if (tr.IsSameTypeReference(typeof(UIntPtr))) { if (IntPtr.Size == 4) { return(VHDLTypes.SYSTEM_UINT32); } else if (IntPtr.Size == 8) { return(VHDLTypes.SYSTEM_UINT64); } } return(customvhdl == null?GetVHDLType(tr) : customvhdl); } var eltype = GetVHDLType(tr.GetArrayElementType()); var name = string.IsNullOrWhiteSpace(eltype.Alias) ? type.Name + "_ARRAY" : eltype.ToString() + "_ARRAY"; if (!m_arrays.ContainsKey(name)) { var rt = customvhdl == null ? eltype : customvhdl; m_arrays[name] = new VHDLType() { IsArray = true, Name = name, ElementName = rt.ToString() }; } return(m_arrays[name]); }
/// <summary> /// Gets a numeric equivalent type for a VHDL type /// </summary> /// <returns>The equivalent VHDL type.</returns> /// <param name="type">The type to find a numeric equivalent for.</param> /// <param name="throwIfNotFound">If set to <c>true</c> throws and exception if not found.</param> public VHDLType NumericEquivalent(VHDLType type, bool throwIfNotFound = true) { if (type.IsNumeric) { return(type); } if (type == VHDLTypes.SYSTEM_UINT8) { return(VHDLTypes.NUMERIC_UINT8); } else if (type == VHDLTypes.SYSTEM_UINT16) { return(VHDLTypes.NUMERIC_UINT16); } else if (type == VHDLTypes.SYSTEM_UINT32) { return(VHDLTypes.NUMERIC_UINT32); } else if (type == VHDLTypes.SYSTEM_UINT64) { return(VHDLTypes.NUMERIC_UINT64); } else if (type == VHDLTypes.SYSTEM_INT8) { return(VHDLTypes.NUMERIC_INT8); } else if (type == VHDLTypes.SYSTEM_INT16) { return(VHDLTypes.NUMERIC_INT16); } else if (type == VHDLTypes.SYSTEM_INT32) { return(VHDLTypes.NUMERIC_INT32); } else if (type == VHDLTypes.SYSTEM_INT64) { return(VHDLTypes.NUMERIC_INT64); } else if (type.IsStdLogicVector && type.Length == 8) { return(VHDLTypes.NUMERIC_UINT8); } else if (type.IsStdLogicVector && type.Length == 16) { return(VHDLTypes.NUMERIC_UINT16); } else if (type.IsStdLogicVector && type.Length == 32) { return(VHDLTypes.NUMERIC_UINT32); } else if (type.IsStdLogicVector && type.Length == 64) { return(VHDLTypes.NUMERIC_UINT64); } else if (type.SourceType != null && type.IsStdLogicVector) { /*foreach (var n in type.SourceType.Resolve().Methods) * { * if (n.IsSpecialName && n.IsStatic && n.Name == "op_Implicit") * Console.WriteLine(); * if (n.MethodReturnType.ReturnType.IsPrimitive) * Console.WriteLine(); * }*/ var targets = type.SourceType.Resolve().Methods.Where(x => x.IsSpecialName && x.IsStatic && x.Name == "op_Implicit" && x.MethodReturnType.ReturnType.IsPrimitive && m_resolvedNumericTypes.Where(y => x.MethodReturnType.ReturnType.IsSameTypeReference(y)).Any()).Select(y => y.MethodReturnType.ReturnType).ToArray(); if (targets.Count() == 0) { throw new Exception(string.Format("Unable to get numeric equivalent for {0}", type.SourceType.FullName)); } else if (targets.Count() == 1) { var t = targets.First(); var vt = GetVHDLType(t); if (vt.IsStdLogicVector && vt.Length == type.Length) { return(NumericEquivalent(vt)); } if (m_signedNumericTypes.Any(x => x.IsSameTypeReference(t))) { var name = string.Format("SIGNED({0} downto {1})", type.UpperBound, type.LowerBound); if (m_stringTypes.ContainsKey(name)) { return(m_stringTypes[name]); } return(m_stringTypes[name] = new VHDLType() { Name = name, IsArray = true, ElementName = "STD_LOGIC", UpperBound = type.UpperBound, LowerBound = type.LowerBound }); } else if (m_unsignedNumericTypes.Where(x => x.IsSameTypeReference(t)).Any()) { var name = string.Format("UNSIGNED({0} downto {1})", type.UpperBound, type.LowerBound); if (m_stringTypes.ContainsKey(name)) { return(m_stringTypes[name]); } return(m_stringTypes[name] = new VHDLType() { Name = name, IsArray = true, ElementName = "STD_LOGIC", UpperBound = type.UpperBound, LowerBound = type.LowerBound }); } else { throw new Exception("Unexpected case"); } } else { return(type); // Defer decision until later so the typecast can choose the right variant } } else { if (throwIfNotFound) { throw new Exception(string.Format("Unable to find suitable numeric type for {0}", type.Alias ?? type.Name)); } else { return(null); } } }
/// <summary> /// Gets a VHDL type from values /// </summary> /// <returns>The VHDL type.</returns> /// <param name="typename">The name of the type to get.</param> /// <param name="alias">The type alias to use.</param> /// <param name="type">The type in Mono.Cecil.</param> public VHDLType GetVHDLType(string typename, string alias, TypeReference type) { if (!string.IsNullOrWhiteSpace(alias) && m_stringTypes.ContainsKey(alias)) { return(m_stringTypes[alias]); } if (m_stringTypes.ContainsKey(typename) && m_stringTypes[typename].Alias == alias) { return(m_stringTypes[typename]); } var m = VHDLHelper.VHDLRE.Match(typename); VHDLType res; if (m.Success && m.Length == typename.Length) { var fr = int.Parse(m.Groups["lower"].Value); var to = int.Parse(m.Groups["upper"].Value); if (alias == null && string.Equals(m.Groups["direction"].Value, "downto", StringComparison.OrdinalIgnoreCase)) { return(GetStdLogicVector(Math.Max(fr, to) - Math.Min(fr, to) + 1)); } res = new VHDLType() { Name = typename, Alias = alias, IsArray = true, ElementName = "STD_LOGIC", SourceType = type, UpperBound = string.Equals(m.Groups["direction"].Value, "downto", StringComparison.OrdinalIgnoreCase) ? Math.Max(fr, to) : Math.Min(fr, to), LowerBound = string.Equals(m.Groups["direction"].Value, "downto", StringComparison.OrdinalIgnoreCase) ? Math.Min(fr, to) : Math.Max(fr, to), }; } else { var tr = type.Resolve(); res = new VHDLType() { Name = typename, Alias = alias, SourceType = type, IsArray = false, IsEnum = tr.IsEnum, IsIrregularEnum = IsEnumIrregular(tr) }; if (res.IsEnum) { res.ElementName = GetVHDLType(tr.Fields.First(x => x.IsSpecialName && x.Name == "value__")).ToString(); } } if (!m_stringTypes.ContainsKey(res.Name)) { m_stringTypes.Add(res.Name, res); } if (!string.IsNullOrWhiteSpace(res.Alias)) { m_stringTypes.Add(res.Alias, res); } return(res); }
public static Expression ConvertExpression(RenderState render, Method method, Expression s, VHDLType target, Mono.Cecil.TypeReference targetsource, bool fromCast) { var svhdl = render.VHDLType(s); // Deal with pesky integers that overflow the 32bit VHDL specs if (IsTooLargeIntegerLiteral(s, target)) { svhdl = render.TypeScope.StdLogicVectorEquivalent(target); } // Already the real target type, just return it if (svhdl == target) { return(s); } // Stuff we do not care about if (!svhdl.IsStdLogicVector && !svhdl.IsUnsigned && !svhdl.IsSigned && svhdl.IsArray && target.IsArray && render.TypeScope.GetByName(svhdl.ElementName) == render.TypeScope.GetByName(target.ElementName)) { return(s); } // Array lengths var targetlengthstr = string.IsNullOrWhiteSpace(target.Alias) ? target.Length.ToString() : target.Alias + "'length"; if (target == VHDLTypes.SYSTEM_BOOL) { // Boolean to std_logic is fine if (string.Equals("STD_LOGIC", svhdl.Name, StringComparison.OrdinalIgnoreCase)) { return(s); } // Source is numeric, and output is bool if (svhdl.IsNumeric || svhdl.IsStdLogicVector) { var zero = new PrimitiveExpression() { SourceExpression = s.SourceExpression, SourceResultType = s.SourceResultType, Value = 0 }; var eval = new BinaryOperatorExpression() { Parent = s.Parent, Name = s.Name, SourceExpression = s.SourceExpression, SourceResultType = s.SourceResultType.LoadType(typeof(bool)), Left = s, Operator = ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.InEquality, Right = zero }; zero.Parent = eval; s.ReplaceWith(eval); s.Parent = eval; return(eval); } else if (svhdl == VHDLTypes.BOOL) { var truexp = new PrimitiveExpression() { Value = true, SourceExpression = s.SourceExpression, SourceResultType = s.SourceResultType.LoadType(typeof(bool)), }; var falseexp = new PrimitiveExpression() { Value = false, SourceExpression = s.SourceExpression, SourceResultType = s.SourceResultType.LoadType(typeof(bool)), }; var eval = new ConditionalExpression() { ConditionExpression = s, TrueExpression = truexp, FalseExpression = falseexp, SourceExpression = s.SourceExpression, SourceResultType = truexp.SourceResultType }; truexp.Parent = eval; falseexp.Parent = eval; s.ReplaceWith(eval); s.Parent = eval; return(eval); } else { throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl, target)); } } else if (svhdl == VHDLTypes.INTEGER && (target.IsStdLogicVector || target.IsNumeric)) { if (target.IsSigned && target.IsNumeric) { return(WrapExpression(render, s, string.Format("TO_SIGNED({0}, {1})", "{0}", targetlengthstr), target)); } else if (target.IsUnsigned && target.IsNumeric) { return(WrapExpression(render, s, string.Format("TO_UNSIGNED({0}, {1})", "{0}", targetlengthstr), target)); } else if (target.IsStdLogicVector) { return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(TO_UNSIGNED({0}, {1}))", "{0}", targetlengthstr), target)); } else { throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl, target)); } } else if (target.IsNumeric && !svhdl.IsEnum) { if (svhdl.IsStdLogicVector || svhdl.IsSigned || svhdl.IsUnsigned) { var str = "{0}"; var resized = false; Variable tmpvar = null; if (target.Length != svhdl.Length) { if (svhdl.IsVHDLSigned) { // Resizing with signed is bad because we may chop the upper bit resized = true; str = string.Format("SIGNED(resize(UNSIGNED({0}), {1}))", str, targetlengthstr); } else if (svhdl.IsVHDLUnsigned) { resized = true; str = string.Format("resize({0}, {1})", str, targetlengthstr); } else if (svhdl.IsSystemSigned) { // Resizing with signed is bad because we may chop the upper bit str = string.Format("SIGNED(resize(UNSIGNED({0}), {1}))", str, targetlengthstr); svhdl = render.TypeScope.NumericEquivalent(svhdl); resized = true; } else if (svhdl.IsSystemUnsigned) { str = string.Format("resize(UNSIGNED({0}), {1})", str, targetlengthstr); svhdl = render.TypeScope.NumericEquivalent(svhdl); resized = true; } else if (target.Length > svhdl.Length) { // This must be a variable as bit concatenation is only allowed in assignment statements: // http://stackoverflow.com/questions/209458/concatenating-bits-in-vhdl tmpvar = render.RegisterTemporaryVariable(method, targetsource); render.TypeLookup[tmpvar] = target; var iexp = new IdentifierExpression() { Name = tmpvar.Name, Target = tmpvar, SourceExpression = s.SourceExpression, SourceResultType = targetsource }; string wstr; if (render.Config.USE_EXPLICIT_CONCATENATION_OPERATOR) { wstr = string.Format("IEEE.STD_LOGIC_1164.\"&\"(\"{0}\", {1})", new string('0', target.Length - svhdl.Length), "{0}"); } else { wstr = string.Format("\"{0}\" & {1}", new string('0', target.Length - svhdl.Length), "{0}"); } s.ReplaceWith(iexp); var asstm = new ExpressionStatement() { Expression = new AssignmentExpression() { Left = iexp.Clone(), Right = new CustomNodes.ConversionExpression() { Expression = s, SourceExpression = s.SourceExpression, SourceResultType = targetsource, WrappingTemplate = wstr, }, Operator = ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign, SourceExpression = s.SourceExpression, SourceResultType = targetsource }, }; s.PrependStatement(asstm); asstm.UpdateParents(); resized = true; s = iexp; } } if (svhdl.IsVHDLSigned != target.IsSigned || svhdl.IsVHDLUnsigned != target.IsUnsigned) { str = string.Format("{1}({0})", str, target.IsSigned ? "SIGNED" : "UNSIGNED"); } if (target.Length != svhdl.Length && !resized) { str = string.Format("resize({0}, {1})", str, targetlengthstr); } return(WrapExpression(render, s, str, target)); } /*if (svhdl.IsStdLogicVector && target.IsSigned) * return new VHDLConvertedExpression(s, target, "SIGNED({0})"); * else if (svhdl.IsStdLogicVector && target.IsUnsigned) * return new VHDLConvertedExpression(s, target, "UNSIGNED({0})"); * else*/ throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl, target)); } else if (target.IsStdLogicVector) { if (svhdl.IsNumeric) { if (svhdl.Length == target.Length) { return(WrapExpression(render, s, "STD_LOGIC_VECTOR({0})", target)); } else { if (!fromCast) { Console.WriteLine("WARN: Incompatible array lengths, from {0} to {1}", svhdl, target); } //throw new Exception(string.Format("Incompatible array lengths, from {0} to {1}", svhdl, target)); if (target.Length < svhdl.Length && svhdl.IsNumericSigned) { return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize(UNSIGNED({0}), {1}))", "{0}", targetlengthstr), target)); } else { return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize({0}, {1}))", "{0}", targetlengthstr), target)); } } } else if (svhdl.IsStdLogicVector) { if (target.Length == svhdl.Length) { render.TypeLookup[s] = target; return(s); } if (!fromCast) { Console.WriteLine("WARN: Incompatible array lengths, from {0} to {1}", svhdl, target); } //throw new Exception(string.Format("Incompatible array lengths, from {0} to {1}", svhdl, target)); if (target.Length < svhdl.Length) { // If the expression is a simple identifier, we can select bits from it // otherwise we need to inject a variable with the expression // and select the required bits from it if (!(s is IdentifierExpression || s is MemberReferenceExpression || s is IndexerExpression)) { var tmp = render.RegisterTemporaryVariable(method, s.SourceResultType); render.TypeLookup[tmp] = svhdl; var aleft = new IdentifierExpression() { Name = tmp.Name, Target = tmp, SourceExpression = s.SourceExpression, SourceResultType = s.SourceResultType }; var aexp = new AssignmentExpression() { Left = aleft, Right = s, SourceExpression = s.SourceExpression, SourceResultType = s.SourceResultType }; var astm = new ExpressionStatement() { Expression = aexp, Parent = method, }; var iexp = new IdentifierExpression() { SourceExpression = s.SourceExpression, SourceResultType = s.SourceResultType, Target = tmp }; s.ReplaceWith(iexp); s.PrependStatement(astm); astm.UpdateParents(); return(WrapExpression(render, iexp, string.Format("{0}({1} downto 0)", "{0}", target.Length - 1), target)); } return(WrapExpression(render, s, string.Format("{0}({1} downto 0)", "{0}", target.Length - 1), target)); } else if (svhdl.IsSigned) { return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize(SIGNED({0}), {1}))", "{0}", targetlengthstr), target)); } else if (svhdl.IsUnsigned) { return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize(UNSIGNED({0}), {1}))", "{0}", targetlengthstr), target)); } else { var tmp = render.RegisterTemporaryVariable(method, targetsource); render.TypeLookup[tmp] = target; var iexp = new IdentifierExpression() { Name = tmp.Name, Target = tmp, SourceExpression = s.SourceExpression, SourceResultType = targetsource }; render.TypeLookup[iexp] = target; string wexpr; if (render.Config.USE_EXPLICIT_CONCATENATION_OPERATOR) { wexpr = string.Format("IEEE.STD_LOGIC_1164.\"&\"(\"{0}\", {1})", new string('0', target.Length - svhdl.Length), "{0}"); } else { wexpr = string.Format("\"{0}\" & {1}", new string('0', target.Length - svhdl.Length), "{0}"); } s.ReplaceWith(iexp); var asstm = new ExpressionStatement(); s.PrependStatement(asstm); var asexp = new AssignmentExpression() { Left = iexp.Clone(), Operator = ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign, Right = new CustomNodes.ConversionExpression() { Expression = s, SourceExpression = s.SourceExpression, SourceResultType = targetsource, WrappingTemplate = wexpr }, SourceExpression = s.SourceExpression, SourceResultType = targetsource }; render.TypeLookup[asexp.Left] = target; render.TypeLookup[asexp.Right] = target; asexp.Left.SourceResultType = targetsource; asexp.Right.SourceResultType = targetsource; asstm.Expression = asexp; asstm.UpdateParents(); return(iexp); } } else if (svhdl.IsSigned || svhdl.IsUnsigned) { if (target.Length == svhdl.Length) { return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR({0})", "{0}"), target)); } else { return(WrapExpression(render, s, string.Format("STD_LOGIC_VECTOR(resize({0}, {1}))", "{0}", targetlengthstr), target)); } } else { throw new Exception(string.Format("Unexpected conversion from {0} to {1}", svhdl.Name, target.Name)); } } else if (target == VHDLTypes.INTEGER && (svhdl.IsStdLogicVector || svhdl.IsNumeric)) { if (svhdl.IsNumeric) { return(WrapExpression(render, s, "TO_INTEGER({0})", target)); } if (svhdl.IsSigned) { return(WrapExpression(render, s, "TO_INTEGER(SIGNED({0}))", target)); } else { return(WrapExpression(render, s, "TO_INTEGER(UNSIGNED({0}))", target)); } } else if (target == VHDLTypes.INTEGER && (svhdl.IsSystemSigned || svhdl.IsSystemUnsigned)) { return(WrapExpression(render, s, "TO_INTEGER({0})", target)); } else if (target == VHDLTypes.BOOL && svhdl == VHDLTypes.SYSTEM_BOOL) { return(WrapInParenthesis(render, WrapExpression(render, s, "{0} = '1'", target))); } else if ((target.IsSigned || target.IsUnsigned) && svhdl.IsStdLogicVector) { if (target.Length == svhdl.Length) { return(WrapExpression(render, s, string.Format("{1}({0})", "{0}", target.IsSigned ? "SIGNED" : "UNSIGNED"), target)); } else { return(WrapExpression(render, s, string.Format("resize({1}({0}), {2})", "{0}", target.IsSigned ? "SIGNED" : "UNSIGNED", targetlengthstr), target)); } } else if ((target.IsSigned || target.IsUnsigned) && svhdl == VHDLTypes.INTEGER) { if (target.IsSigned) { return(WrapExpression(render, s, string.Format("TO_SIGNED({0}, {1})", "{0}", target.Length), target)); } else if (target.IsUnsigned) { return(WrapExpression(render, s, string.Format("TO_UNSIGNED({0}, {1})", "{0}", target.Length), target)); } else { throw new Exception("Unexpected case"); } } else if ((svhdl.IsSigned || svhdl.IsUnsigned) && (target.IsSigned || target.IsUnsigned)) { if (target.Length == svhdl.Length) { if (svhdl.IsSigned == target.IsSigned) { return(s); } else { return(WrapExpression(render, s, string.Format("{1}({0})", "{0}", target.IsSigned ? "SIGNED" : "UNSIGNED"), target)); } } else { if (svhdl.IsSigned == target.IsSigned) { return(WrapExpression(render, s, string.Format("resize({0}, {1})", "{0}", targetlengthstr), target)); } else if (svhdl.IsSigned && svhdl.Length > target.Length) { return(WrapExpression(render, s, string.Format("resize(UNSIGNED({0}), {1})", "{0}", targetlengthstr), target)); } else { return(WrapExpression(render, s, string.Format("{2}(resize({0}, {1}))", "{0}", targetlengthstr, target.IsSigned ? "SIGNED" : "UNSIGNED"), target)); } } } else if (target.IsEnum && (svhdl.IsSigned || svhdl.IsUnsigned || svhdl == VHDLTypes.INTEGER)) { if (target.IsIrregularEnum) { return(WrapExpression(render, s, string.Format("fromValue_{1}({0})", svhdl == VHDLTypes.INTEGER ? "{0}" : "TO_INTEGER({0})", target.ToSafeVHDLName()), target)); } else { return(WrapExpression(render, s, string.Format("{1}'VAL({0})", svhdl == VHDLTypes.INTEGER ? "{0}" : "TO_INTEGER({0})", target.ToSafeVHDLName()), target)); } } else if (svhdl.IsEnum && (target.IsSigned || target.IsUnsigned || target == VHDLTypes.INTEGER)) { Expression wrapped; if (target.IsIrregularEnum) { wrapped = WrapExpression(render, s, string.Format("toValue_{1}({0})", "{0}", svhdl.ToSafeVHDLName()), target); } else { wrapped = WrapExpression(render, s, string.Format("{1}'POS({0})", "{0}", svhdl.ToSafeVHDLName()), target); } render.TypeLookup[wrapped] = VHDLTypes.INTEGER; if (target != VHDLTypes.INTEGER) { wrapped = ConvertExpression(render, method, wrapped, target, targetsource, false); } return(wrapped); } else { throw new Exception(string.Format("Unexpected target type: {0} for source: {1}", target, svhdl)); } }
/// <summary> /// Gets the VHDL primitive literal representation for the given expression /// </summary> /// <returns>The integer literal expression.</returns> /// <param name="e">The expression to evaluate.</param> /// <param name="tvhdl">The target VHDL type.</param> public static string GetPrimitiveLiteral(object e, VHDLType tvhdl) { if (e is PrimitiveExpression) { e = (e as PrimitiveExpression).Value; } if (e is ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression) { e = (e as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression).Value; } if (e == null) { return(null); } string binstr = null; if (e is ulong) { var uvalue = (ulong)e; if (uvalue > int.MaxValue) { binstr = Convert.ToString((int)((uvalue >> 32) & 0xffffffff), 2).PadLeft(32, '0') + Convert.ToString((int)(uvalue & 0xffffffff), 2).PadLeft(32, '0'); } } else if (e is long) { var lvalue = (long)e; if (lvalue >= int.MaxValue || lvalue <= int.MinValue) { binstr = Convert.ToString((int)((lvalue >> 32) & 0xffffffff), 2).PadLeft(32, '0') + Convert.ToString((int)(lvalue & 0xffffffff), 2).PadLeft(32, '0'); } } else if (e is uint) { var uvalue = (uint)e; if (uvalue >= int.MaxValue) { binstr = Convert.ToString((uint)(uvalue & 0xffffffff), 2).PadLeft(32, '0'); } } else if (e is int) { var ivalue = (int)e; if (tvhdl.IsUnsigned && ivalue < 0 || ivalue <= int.MinValue) { binstr = Convert.ToString((int)(ivalue & 0xffffffff), 2).PadLeft(32, '0'); } } if (!string.IsNullOrWhiteSpace(binstr)) { if (tvhdl.Length > 0) { binstr = binstr.PadLeft(tvhdl.Length, '0'); } return(string.Format("STD_LOGIC_VECTOR'(\"{0}\")", binstr)); } return(e.ToString()); }
/// <summary> /// Evaluates if the given expression is an integer literal that is too large to be represented as a VHDL integer literal /// </summary> /// <returns><c>true</c>, if the expression is an integer that is too larget, <c>false</c> otherwise.</returns> /// <param name="e">The expression to evaluate.</param> /// <param name="tvhdl">The target VHDL type.</param> public static bool IsTooLargeIntegerLiteral(Expression e, VHDLType tvhdl) { return((GetPrimitiveLiteral(e as PrimitiveExpression, tvhdl) ?? string.Empty).StartsWith("STD_LOGIC_VECTOR'(\"", StringComparison.OrdinalIgnoreCase)); }
public static Expression WrapExpression(RenderState render, Expression expression, string template, VHDLType vhdltarget) { var self = expression.ReplaceWith(new CustomNodes.ConversionExpression() { Expression = expression, WrappingTemplate = template, SourceExpression = expression.SourceExpression, SourceResultType = expression.SourceResultType }); expression.Parent = self; render.TypeLookup[self] = vhdltarget; return(self); }