public List <Instance> TryTransform(Instance instance, TransformationContext context) { if (!instance.ModuleIdentifier.Contains("io_ibuf") && !instance.ModuleIdentifier.Contains("io_obuf")) { return(null); } var input = instance.Ports.First(p => p.Identifier == "i").ConnectedNet; var output = instance.Ports.First(p => p.Identifier == "o").ConnectedNet; var result = new List <Instance>(); var bufferInput = input; if (instance.Ports.First(p => p.Identifier == "i").IsConnectedNetNegated) { var inverter = new Instance("INV", "inv_" + context.GetNextInstanceNumber(this)); inverter.Ports.Add(new Net("I", NetType.Input, new Net(input.Identifier, NetType.Wire))); var inverterOutput = new Net("n_" + context.GetNextNetNumber(), NetType.Wire); inverter.Ports.Add(new Net("O", NetType.Input, inverterOutput)); bufferInput = inverterOutput; result.Add(inverter); } var buffer = new Instance("BUF", "buf_" + context.GetNextInstanceNumber(this)); buffer.Ports.Add(new Net("I", NetType.Input, bufferInput)); buffer.Ports.Add(new Net("O", NetType.Output, new Net(output.Identifier, NetType.Wire))); result.Add(buffer); return(result); }
public List <Instance> TryTransform(Instance instance, TransformationContext context) { if (!instance.ModuleIdentifier.Contains("dffeas")) { return(null); } var fdc = new Instance("FDC", "fdc_" + context.GetNextInstanceNumber(this)); var clock = instance.Ports.First(p => p.Identifier == "clk").ConnectedNet.Identifier; var clr = instance.Ports.First(p => p.Identifier == "clrn").ConnectedNet.Identifier; var dataInput = instance.Ports.First(p => p.Identifier == "d").ConnectedNet.Identifier; var dataOutput = instance.Ports.First(p => p.Identifier == "q").ConnectedNet.Identifier; fdc.Ports.Add(new Net("C", NetType.Input, new Net("clock", NetType.Wire))); fdc.Ports.Add(new Net("CLR", NetType.Input, new Net(clr, NetType.Wire))); fdc.Ports.Add(new Net("D", NetType.Input, new Net(dataInput, NetType.Wire))); fdc.Ports.Add(new Net("Q", NetType.Output, new Net(dataOutput, NetType.Wire))); return(new List <Instance> { fdc }); }
public List <Instance> TryTransform(Instance instance, TransformationContext context) { if (!instance.ModuleIdentifier.Contains("lcell_comb")) { return(null); } var lutMaskAsString = instance.Parameters.First(p => p.Identifier == "lut_mask").Value; var lutMask = Tools.ParseVerilogNumber(lutMaskAsString); var lutMaskAsBoolArray = Convert.ToString(lutMask, 2) .Select(c => c == '1') .Reverse() .ToArray(); var function = new bool[16]; for (var i = 0; i < lutMaskAsBoolArray.Length; i++) { function[i] = lutMaskAsBoolArray[i]; } function = function.Reverse().ToArray(); var isConjunctive = function.Count(v => v == false) < function.Count(v => v == true); var normalForm = GetNormalFormVariableRows(function, isConjunctive) .Select(r => r.Reverse().ToArray()).ToArray(); var inversionNeeded = new bool[4]; foreach (var row in normalForm) { for (var j = 0; j < row.Length; j++) { inversionNeeded[j] = !(isConjunctive && row[j] || !isConjunctive && !row[j]) || inversionNeeded[j]; } } var result = new List <Instance>(); //var netIdenifiers = new[] {"datad", "datac", "datab", "dataa"}; var netIdenifiers = new[] { "dataa", "datab", "datac", "datad" }; for (var i = 0; i < inversionNeeded.Length; i++) { if (inversionNeeded[i]) { var input = instance.Ports.First(x => x.Identifier == netIdenifiers[i]).ConnectedNet .Identifier; var element = new Instance("INV", "inv_" + input + context.GetNextInstanceNumber(this)); element.Ports.Add(new Net("I", NetType.Input, new Net(input, NetType.Wire))); element.Ports.Add(new Net("O", NetType.Output, new Net("n_" + context.GetNextNetNumber(), NetType.Wire))); result.Add(element); } } var currentLevelElements = new List <Instance>(); for (var i = 0; i < normalForm.Length; i++) { var instancePorts = new string[4]; for (var j = 0; j < 4; j++) { instancePorts[j] = instance.Ports.First(x => x.Identifier == netIdenifiers[j]).ConnectedNet.Identifier; } var element = isConjunctive ? new Instance("OR4", "or4_" + context.GetNextInstanceNumber(this)) : new Instance("AND4", "and4_" + context.GetNextInstanceNumber(this)); for (var j = 0; j < 4; j++) { if (!(normalForm[i][j] && isConjunctive || !normalForm[i][j] && !isConjunctive)) { element.Ports.Add(new Net($"I{j}", NetType.Input, result.First(e => e.Identifier.Contains(instancePorts[j])) .Ports .First(p => p.NetType == NetType.Output).ConnectedNet)); } else { element.Ports.Add(new Net($"I{j}", NetType.Input, new Net(instancePorts[j], NetType.Wire))); } } element.Ports.Add(new Net("O", NetType.Output, new Net(element.Identifier + "_" + context.GetNextNetNumber(), NetType.Wire))); currentLevelElements.Add(element); } if (currentLevelElements.Count == 1) { result.AddRange(currentLevelElements); } while (currentLevelElements.Count != 1) { var nextLevelElements = new List <Instance>(); if (currentLevelElements.Count % 2 == 1) { nextLevelElements.Add(currentLevelElements.Last()); currentLevelElements.RemoveAt(currentLevelElements.Count - 1); } for (var i = 0; i < currentLevelElements.Count; i += 2) { var element = isConjunctive ? new Instance("AND2", "and2_" + context.GetNextInstanceNumber(this)) : new Instance("OR2", "or2_" + context.GetNextInstanceNumber(this)); element.Ports.Add(new Net("I0", NetType.Input, currentLevelElements[i].Ports.First(p => p.NetType == NetType.Output).ConnectedNet)); element.Ports.Add(new Net("I1", NetType.Input, currentLevelElements[i + 1].Ports.First(p => p.NetType == NetType.Output).ConnectedNet)); element.Ports.Add(new Net("O", NetType.Output, new Net("n_" + context.GetNextNetNumber(), NetType.Wire))); nextLevelElements.Add(element); } result.AddRange(currentLevelElements); //if (currentLevelElements.Count == 0) break; currentLevelElements = new List <Instance>(nextLevelElements); } result.AddRange(currentLevelElements); result.Last().Ports.First(p => p.Identifier == "O").ConnectedNet = new Net(instance.Ports.First(p => p.Identifier == "combout").ConnectedNet.Identifier, NetType.Wire); return(result); }