Beispiel #1
0
        /// <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]);
        }
Beispiel #2
0
        /// <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));
        }
Beispiel #3
0
        /// <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]);
        }
    }
Beispiel #4
0
        /// <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));
            }
        }
Beispiel #5
0
        /// <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]);
        }
Beispiel #6
0
        /// <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]);
        }
Beispiel #7
0
        /// <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);
                }
            }
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        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));
            }
        }
Beispiel #10
0
        /// <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());
        }
Beispiel #11
0
 /// <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));
 }
Beispiel #12
0
        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);
        }