public static IEnumerable <Dictionary <string, string> > GetTestCases(DataPathGenerator dataPathGenerator)
        {
            while (true)
            {
                if (!agreeToCreateTestCase())
                {
                    yield break;
                }

                var returnValue = new Dictionary <string, string>();

                var file = dataPathGenerator.AifFile;

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Enter the values for the inputs:");
                foreach (var reg in file.Registers.Values.OfType <InputRegister>())
                {
                    returnValue[reg.Name] = GetInputForReg(reg);
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Enter the expected values for the outputs:");
                foreach (var reg in file.Registers.Values.OfType <OutputRegister>())
                {
                    returnValue[reg.Name] = GetInputForReg(reg);
                }

                yield return(returnValue);
            }
        }
        private void test(Func <AifFile> getFile, params Dictionary <string, string>[] testCases)
        {
            TestLogger.Setup();

            var log  = LogManager.GetLogger(nameof(DataPathGeneratorTests));
            var file = getFile();

            var schedule = new IlpScheduler(file, file.MinCycles.Values.Max());

            schedule.BuildSchedule();

            var dataPathGenerator = new DataPathGenerator(new MultiplexerGenerator(new RegisterAllocator(new FunctionalUnitAllocator(schedule))));

            using (var stream = new MemoryStream())
                using (var writeStream = new StreamWriter(stream))
                {
                    if (testCases.Length > 0)
                    {
                        Debug.WriteLine(nameof(dataPathGenerator.SaveTestBench));
                        dataPathGenerator.SaveTestBench(writeStream, testCases);
                    }

                    Debug.WriteLine(nameof(dataPathGenerator.SaveController));
                    dataPathGenerator.SaveController(writeStream);

                    Debug.WriteLine(nameof(dataPathGenerator.SaveDataPath));
                    dataPathGenerator.SaveDataPath(writeStream, true);

                    Debug.WriteLine(nameof(dataPathGenerator.SaveDesign));
                    dataPathGenerator.SaveDesign(writeStream);

                    writeStream.Flush();
                    log.Info(Encoding.UTF8.GetString(stream.ToArray()));
                }
        }
        public static void Main(string[] args)
        {
            StreamWriter controller = null, dataPath = null, design = null, testBench = null;

            try
            {
                string fileName;
                var    file = GetAifFile(out fileName);
                if (file == null)
                {
                    return;
                }

                //1. Operation Scheduling:
                var schedule = GetSchedule(file);
                if (schedule == null)
                {
                    return;
                }

                //2. Functional Unit Allocation and Binding:
                var functionalUnits = new FunctionalUnitAllocator(schedule);

                //3. Register Allocation and Binding
                var registers = new RegisterAllocator(functionalUnits);

                //4. Multiplexer Generation:
                var multiplexorGenerator = new MultiplexerGenerator(registers);

                //5. Datapath Generation in VHDL:
                var dataPathGenerator = new DataPathGenerator(multiplexorGenerator);

                //6. Get test cases
                Console.ForegroundColor = ConsoleColor.Green;
                foreach (var expression in file.AsExpressions)
                {
                    Console.WriteLine(expression);
                }
                var testCases = GetTestCases(dataPathGenerator).ToArray();

                var saveFolder = GetSaveTo();
                if (saveFolder == null)
                {
                    return;
                }

                //save generation
                dataPath = GetSaveStream(Path.Combine(saveFolder, fileName + "_dp.vhd"));
                if (dataPath == null)
                {
                    return;
                }
                controller = GetSaveStream(Path.Combine(saveFolder, fileName + "_con.vhd"));
                if (controller == null)
                {
                    return;
                }
                design = GetSaveStream(Path.Combine(saveFolder, fileName + "_des.vhd"));
                if (design == null)
                {
                    return;
                }
                if (testCases.Length > 0)
                {
                    testBench = GetSaveStream(Path.Combine(saveFolder, fileName + "_tb.vhd"));
                    if (testBench == null)
                    {
                        return;
                    }
                }

                using (controller)
                {
                    dataPathGenerator.SaveController(controller);
                }

                foreach (var codeFile in functionalUnits.Units
                         .Select(unit => unit.VhdlCodeFile)
                         .Concat(new []
                {
                    "c_multiplexer",
                    "c_register"
                })
                         .Distinct(StringComparer.OrdinalIgnoreCase))
                {
                    var savePath = Path.Combine(saveFolder, codeFile + ".vhd");
                    if (!File.Exists(savePath))
                    {
                        using (var stream = File.CreateText(savePath))
                        {
                            stream.WriteVhdlFile(codeFile);
                        }
                    }
                }
                using (dataPath)
                {
                    dataPathGenerator.SaveDataPath(dataPath);
                }
                using (design)
                {
                    dataPathGenerator.SaveDesign(design);
                }
                if (testCases.Length > 0)
                {
                    using (testBench)
                    {
                        dataPathGenerator.SaveTestBench(testBench, testCases);
                    }
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Press enter to exit.");
                Console.ReadLine();
            }
            catch (Exception error)
            {
                Log.Error(error);

                dataPath?.Dispose();
                design?.Dispose();
                controller?.Dispose();
                testBench?.Dispose();
            }
        }