Exemplo n.º 1
0
        private static GraphFIR.IO.FIRIO VisitExp(VisitHelper helper, FIRRTL.Expression exp, GraphFIR.IO.IOGender gender)
        {
            if (exp is FIRRTL.RefLikeExpression)
            {
                return((GraphFIR.IO.FIRIO)VisitRef(helper, exp, helper.Mod, gender));
            }

            if (exp is FIRRTL.Literal lit)
            {
                GraphFIR.ConstValue value = new GraphFIR.ConstValue(lit);

                helper.AddNodeToModule(value);
                return(value.Result);
            }
            else if (exp is FIRRTL.DoPrim prim)
            {
                var args = prim.Args.Select(x => VisitExp(helper, x, GraphFIR.IO.IOGender.Male)).Cast <GraphFIR.IO.Output>().ToArray();
                GraphFIR.FIRRTLPrimOP nodePrim;
                if (prim.Op is FIRRTL.Add)
                {
                    nodePrim = new GraphFIR.FIRAdd(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Sub)
                {
                    nodePrim = new GraphFIR.FIRSub(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Mul)
                {
                    nodePrim = new GraphFIR.FIRMul(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Div)
                {
                    nodePrim = new GraphFIR.FIRDiv(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Rem)
                {
                    nodePrim = new GraphFIR.FIRRem(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Dshl)
                {
                    nodePrim = new GraphFIR.FIRDshl(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Dshr)
                {
                    nodePrim = new GraphFIR.FIRDshr(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Cat)
                {
                    nodePrim = new GraphFIR.FIRCat(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Eq)
                {
                    nodePrim = new GraphFIR.FIREq(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Neq)
                {
                    nodePrim = new GraphFIR.FIRNeq(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Geq)
                {
                    nodePrim = new GraphFIR.FIRGeq(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Leq)
                {
                    nodePrim = new GraphFIR.FIRLeq(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Gt)
                {
                    nodePrim = new GraphFIR.FIRGt(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Lt)
                {
                    nodePrim = new GraphFIR.FIRLt(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.And)
                {
                    nodePrim = new GraphFIR.FIRAnd(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Or)
                {
                    nodePrim = new GraphFIR.FIROr(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Xor)
                {
                    nodePrim = new GraphFIR.FIRXor(args[0], args[1], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Head)
                {
                    nodePrim = new GraphFIR.Head(args[0], prim.Type, (int)prim.Consts[0], prim);
                }
                else if (prim.Op is FIRRTL.Tail)
                {
                    nodePrim = new GraphFIR.Tail(args[0], prim.Type, (int)prim.Consts[0], prim);
                }
                else if (prim.Op is FIRRTL.Bits)
                {
                    nodePrim = new GraphFIR.BitExtract(args[0], prim.Type, (int)prim.Consts[1], (int)prim.Consts[0], prim);
                }
                else if (prim.Op is FIRRTL.Pad)
                {
                    nodePrim = new GraphFIR.Pad(args[0], prim.Type, (int)prim.Consts[0], prim);
                }
                else if (prim.Op is FIRRTL.AsUInt)
                {
                    nodePrim = new GraphFIR.FIRAsUInt(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.AsSInt)
                {
                    nodePrim = new GraphFIR.FIRAsSInt(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.AsClock)
                {
                    nodePrim = new GraphFIR.FIRAsClock(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Cvt)
                {
                    nodePrim = new GraphFIR.FIRCvt(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Neg)
                {
                    nodePrim = new GraphFIR.FIRNeg(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Not)
                {
                    nodePrim = new GraphFIR.FIRNot(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Andr)
                {
                    nodePrim = new GraphFIR.FIRAndr(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Orr)
                {
                    nodePrim = new GraphFIR.FIROrr(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Xorr)
                {
                    nodePrim = new GraphFIR.FIRXorr(args[0], prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Shl)
                {
                    var constLit    = new FIRRTL.UIntLiteral(prim.Consts[0], (int)prim.Consts[0].GetBitLength());
                    var constOutput = (GraphFIR.IO.Output)VisitExp(helper, constLit, GraphFIR.IO.IOGender.Male);
                    nodePrim = new GraphFIR.FIRShl(args[0], constOutput, prim.Type, prim);
                }
                else if (prim.Op is FIRRTL.Shr)
                {
                    var constLit    = new FIRRTL.UIntLiteral(prim.Consts[0], (int)prim.Consts[0].GetBitLength());
                    var constOutput = (GraphFIR.IO.Output)VisitExp(helper, constLit, GraphFIR.IO.IOGender.Male);
                    nodePrim = new GraphFIR.FIRShr(args[0], constOutput, prim.Type, prim);
                }
                else
                {
                    throw new NotImplementedException();
                }

                helper.AddNodeToModule(nodePrim);
                return(nodePrim.Result);
            }
            else if (exp is FIRRTL.Mux mux)
            {
                var cond    = (GraphFIR.IO.Output)VisitExp(helper, mux.Cond, GraphFIR.IO.IOGender.Male);
                var ifTrue  = VisitExp(helper, mux.TrueValue, GraphFIR.IO.IOGender.Male);
                var ifFalse = VisitExp(helper, mux.FalseValue, GraphFIR.IO.IOGender.Male);

                GraphFIR.Mux node = new GraphFIR.Mux(new List <GraphFIR.IO.FIRIO>()
                {
                    ifTrue, ifFalse
                }, cond, mux);

                helper.AddNodeToModule(node);
                return(node.Result);
            }
            else if (exp is FIRRTL.ValidIf validIf)
            {
                var cond    = (GraphFIR.IO.Output)VisitExp(helper, validIf.Cond, GraphFIR.IO.IOGender.Male);
                var ifValid = VisitExp(helper, validIf.Value, GraphFIR.IO.IOGender.Male);

                GraphFIR.Mux node = new GraphFIR.Mux(new List <GraphFIR.IO.FIRIO>()
                {
                    ifValid
                }, cond, validIf);

                helper.AddNodeToModule(node);
                return(node.Result);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Exemplo n.º 2
0
        private static void VisitConditional(VisitHelper parentHelper, FIRRTL.Conditionally conditional)
        {
            GraphFIR.Conditional cond = new GraphFIR.Conditional(conditional);

            void AddCondModule(GraphFIR.IO.Output ena, FIRRTL.Statement body)
            {
                VisitHelper helper = parentHelper.ForNewCondModule(parentHelper.GetUniqueName(), null);

                var internalEnaDummy = new GraphFIR.DummyPassthrough(ena);
                var internalUseEna   = new GraphFIR.DummySink(internalEnaDummy.Result);

                helper.AddNodeToModule(internalEnaDummy);
                helper.AddNodeToModule(internalUseEna);
                helper.Mod.SetEnableCond(internalEnaDummy.Result);

                //Set signal that enables this scope as things like memory
                //ports need it
                helper.EnterEnabledScope(internalEnaDummy.Result);

                //Fill out module
                VisitStatement(helper, body);

                cond.AddConditionalModule(internalEnaDummy.InIO, helper.Mod);

                helper.ExitEnabledScope();
            }

            GraphFIR.IO.Output enableCond = (GraphFIR.IO.Output)VisitExp(parentHelper, conditional.Pred, GraphFIR.IO.IOGender.Male);

            if (conditional.HasIf())
            {
                GraphFIR.IO.Output ifEnableCond = enableCond;
                if (parentHelper.Mod.IsConditional)
                {
                    GraphFIR.FIRAnd chainConditions = new GraphFIR.FIRAnd(parentHelper.Mod.EnableCon, enableCond, new FIRRTL.UIntType(1), null);
                    parentHelper.AddNodeToModule(chainConditions);

                    ifEnableCond = chainConditions.Result;
                }

                AddCondModule(ifEnableCond, conditional.WhenTrue);
            }
            if (conditional.HasElse())
            {
                GraphFIR.FIRNot notEnableComponent = new GraphFIR.FIRNot(enableCond, new FIRRTL.UIntType(1), null);
                parentHelper.AddNodeToModule(notEnableComponent);

                GraphFIR.IO.Output elseEnableCond = notEnableComponent.Result;
                if (parentHelper.Mod.IsConditional)
                {
                    GraphFIR.FIRAnd chainConditions = new GraphFIR.FIRAnd(parentHelper.Mod.EnableCon, elseEnableCond, new FIRRTL.UIntType(1), null);
                    parentHelper.AddNodeToModule(chainConditions);

                    elseEnableCond = chainConditions.Result;
                }

                AddCondModule(elseEnableCond, conditional.Alt);
            }

            parentHelper.AddNodeToModule(cond);
        }