public static string Generate(string moduleName, string taskName, int registerCount, int latency)
        {
            string waitCases = "";

            if (latency != 0)
            {
                //Console.WriteLine();

                waitCases = Enumerable
                    .Range(1, latency - 1)
                    .Select(x => string.Format(_waitTemplate, moduleName, x, x + 1))
                    .Join("\r\n");

                waitCases += "\r\n" + string.Format(_waitLastTemplate, moduleName, latency, latency + 1);
            }

            var finalStage = latency + 1;

            var tasks = Enumerable
                .Range(0, registerCount)
                .Select(x => new StringTemplate(registerConstantTemplate).PopulateObj(new
                {
                    TaskName = taskName,
                    Module = moduleName,
                    Register = x,
                    FinalStage = finalStage,
                    WaitCases = waitCases,
                    ReadEnable = latency == 0 ? "readInstructionEnable <= 1;" : "",
                }))
                .Join("\r\n");

            var doc = new VerilogDocument();

            var cases = Enumerable
                .Range(0, registerCount)
                .Select(x => string.Format(
                    _opcodeCaseTemplate,
                    taskName.Length > 3 && !taskName.Contains("Shift") ? taskName.Remove(3) : taskName,
                    x,
                    taskName))
                .Join("\r\n");

            VerilogGlobals.Globals.AddDefineString(taskName + "Cases", cases);

            //doc.AddDefineString(taskName + "Cases", cases);

            //return tasks + "\r\n" + doc.ToString();
            return tasks;
        }
        public void AssembleToVerilog(string asm, string verilogFile)
        {
            var bytes = Assemble(asm).SelectMany(x => x).ToArray();
            var padding = 5 - (bytes.Length % 5);

            if (padding == 5)
            {
                padding = 0;
            }

            Array.Resize(ref bytes, bytes.Length + padding);

            if (bytes.Length > 0xffff)
            {
                throw new InvalidOperationException();
            }

            var asmStr = bytes
                .GroupEvery(5)
                .Select((x, i) => string.Format(
                    "{0}: writeInstructionBuffer <= 40'h{1};",
                    i * 5,
                    ByteHelper.ToHex(x.ToArray())))
                .Join("\r\n");

            var doc3 = new VerilogDocument();
            doc3.AddDefineString("Program", asmStr);
            doc3.AddDefine16("ProgramSize", (ushort)bytes.Length);
            File.WriteAllText(verilogFile, doc3.ToString());

            //return null;
            //return
            //    .Select((x, i) => string.Format(
            //        "{0}: writeInstructionBuffer <= 40'h{1};",
            //        i * 5,
            //        ByteHelper.ToHex(x)))
            //    .Join("\r\n");
        }