public static ComponentChipDefinition ImportFromFile(string fileName)
        {
            var portNameMappings   = new List <Dictionary <ISignal, ISignal> >();
            var constAssignMapping = new Dictionary <ISignal, SignalName>();

            var objects = (new Parser.MyParser()).Parse(fileName);

            if (objects.components.Count == 0 ||
                objects.componentDeclarations.Count == 1 ||
                objects.logicGates.Count > 0)
            {
                return(null);
            }

            string chipName = objects.entityPrototype.name;

            // チップの入出力信号
            var portSet = new HashSet <ISignal>(objects.signalTable.Values.Where(
                                                    x => (x.mode == SignalMode.IN || x.mode == SignalMode.OUT || x.mode == SignalMode.INOUT) &&
                                                    x.GetType() == typeof(StdLogic)));

            // ポートの対応関係を作成
            ComponentPrototype componentPrototype = objects.components[0].prototype;

            foreach (var component in objects.components)
            {
                if (component.prototype != componentPrototype)
                {
                    throw new ChipDefinitionException(fileName,
                                                      string.Format(@"Component chip ""{0}"" has another component ""{1}""",
                                                                    componentPrototype.name, component.prototype.name));
                }

                var portNameMap = new Dictionary <ISignal, ISignal>();

                foreach (var componentSignal in component.portMap.Keys)
                {
                    if (componentSignal.mode == SignalMode.IN ||
                        componentSignal.mode == SignalMode.OUT ||
                        componentSignal.mode == SignalMode.INOUT)
                    {
                        if (!portSet.Contains(component.portMap[componentSignal]))
                        {
                            throw new ChipDefinitionException(fileName,
                                                              string.Format("The port signal of the component must be connected directly to the port of the component"));
                        }

                        portSet.Remove(component.portMap[componentSignal]);
                        portNameMap.Add(componentSignal, component.portMap[componentSignal]);
                    }
                }

                portNameMappings.Add(portNameMap);
            }

            // チップの入力でコンポネントの入出力以外に接続するもの
            foreach (var port in objects.signalTable.Values)
            {
                if ((port.mode == SignalMode.IN || port.mode == SignalMode.INOUT) &&
                    portSet.Contains(port) && /* まだ接続されていない */
                    port.attribute.ContainsKey("const_assign"))
                {
                    var constValue = port.attribute["const_assign"];
                    if (constValue is string)
                    {
                        constAssignMapping[port] = SignalName.Parse((string)constValue);
                    }
                }
            }

            return(new ComponentChipDefinition(chipName, componentPrototype, portNameMappings.ToArray(), constAssignMapping, objects.entityAttribute));
        }
示例#2
0
        public static GateChipDefinition ImportFromFile(string fileName)
        {
            var portNameMappings   = new List <Dictionary <ISignal, ISignal> >();
            var constAssignMapping = new Dictionary <ISignal, SignalName>();

            var objects = (new Parser.MyParser()).Parse(fileName);

            if (objects.components.Count > 0 ||
                objects.componentDeclarations.Count > 1 ||
                objects.logicGates.Count == 0)
            {
                return(null);
            }

            string chipName = objects.entityPrototype.name;

            // チップの入力信号
            var inPortSet = new HashSet <ISignal>(objects.signalTable.Values.Where(
                                                      x => x.mode == SignalMode.IN && x.GetType() == typeof(StdLogic)));

            // チップの出力信号
            var outPortSet = new HashSet <ISignal>(objects.signalTable.Values.Where(
                                                       x => x.mode == SignalMode.OUT && x.GetType() == typeof(StdLogic)));

            // チップの出力信号に直結した信号
            var outPortAssignment = new Dictionary <ISignal, ISignal>();

            foreach (var pair in objects.assignments.Where(
                         x => x.Key.mode == SignalMode.OUT && x.Key.GetType() == typeof(StdLogic)))
            {
                outPortAssignment.Add(pair.Value, pair.Key);
            }

            // ポートの対応関係を作成
            GateType gateType  = objects.logicGates[0].gateType;
            int      gateWidth = objects.logicGates[0].inputSignals.Count;

            foreach (var logicGate in objects.logicGates)
            {
                if (logicGate.gateType != gateType || logicGate.inputSignals.Count != gateWidth)
                {
                    throw new ChipDefinitionException(fileName,
                                                      string.Format(@"Gate chip ""{0}{1}"" has another gate ""{2}{3}""",
                                                                    gateType, gateWidth, logicGate.gateType, logicGate.inputSignals.Count));
                }

                var portNameMap = new Dictionary <ISignal, ISignal>();

                for (int i = 0; i < logicGate.inputSignals.Count; ++i)
                {
                    if (!inPortSet.Contains(logicGate.inputSignals[i]))
                    {
                        throw new ChipDefinitionException(fileName,
                                                          string.Format("The input signal of the gate must be connected directly to the input port of the chip"));
                    }

                    inPortSet.Remove(logicGate.inputSignals[i]);
                    portNameMap.Add(new StdLogic(new SignalName(".in" + i)), logicGate.inputSignals[i]);
                }

                if (!outPortAssignment.ContainsKey(logicGate.outputSignal) ||
                    !outPortSet.Contains(outPortAssignment[logicGate.outputSignal]))
                {
                    throw new ChipDefinitionException(fileName,
                                                      string.Format("The output signal of the gate must be connected directly to the output port of the chip"));
                }

                var outPort = outPortAssignment[logicGate.outputSignal];
                outPortSet.Remove(outPort);
                portNameMap.Add(new StdLogic(new SignalName(".out")), outPort);

                portNameMappings.Add(portNameMap);
            }

            // チップの入力でゲートの入力以外に接続するもの
            foreach (var inPort in inPortSet)
            {
                if (inPort.attribute.ContainsKey("const_assign"))
                {
                    var constValue = inPort.attribute["const_assign"];
                    if (constValue is string)
                    {
                        constAssignMapping[inPort] = SignalName.Parse((string)constValue);
                    }
                }
            }

            return(new GateChipDefinition(chipName, gateType, gateWidth, portNameMappings.ToArray(), constAssignMapping, objects.entityAttribute));
        }