private Bitfield ConcatenateContextRegionBitfields(Instruction_ContextRegion contextRegion) { var aggBitfield = contextRegion.BitfieldWrapper.ToAggregatedBitfield(); return(aggBitfield); }
private Instruction_ContextRegion BuildContextRegionBitfields(List <List <Instruction> > instrSets, out uint contextRegionByteSize, out uint maxInstrPathByteSize) { var contextRegion = new Instruction_ContextRegion(); contextRegion.ToBitfieldWrapper(); // Build common context-region: var contextRegionByteLenBitfield = new Bitfield(width: 16, name: "contx-reg byte len"); var instrRegionByteLenBitfield = new Bitfield(width: 32, name: "instr-reg byte len"); var ledCountBitfield = new Bitfield(width: 16, value: DeviceTable.Dev.LedCount, name: "total led len"); var timerIntervalMs = new Bitfield(width: 16, value: DeviceTable.Dev.TickIntervalMs, name: "tick interval ms"); var simBrightCoeffBitfield = new Bitfield(width: 16, value: DeviceTable.Dev.SimulatorBrightnessCoeff, name: "sim bright coeff"); var totalPathsBitfield = new Bitfield(width: 8, value: (uint)instrSets.Count, name: "total paths"); var pathEndedBitmap = new Bitfield(width: (uint)instrSets.Count, name: "path end bitmap"); contextRegion.BitfieldWrapper.AddBitfield(contextRegionByteLenBitfield); contextRegion.BitfieldWrapper.AddBitfield(instrRegionByteLenBitfield); contextRegion.BitfieldWrapper.AddBitfield(ledCountBitfield); contextRegion.BitfieldWrapper.AddBitfield(timerIntervalMs); contextRegion.BitfieldWrapper.AddBitfield(simBrightCoeffBitfield); contextRegion.BitfieldWrapper.AddBitfield(totalPathsBitfield); contextRegion.BitfieldWrapper.AddBitfield(pathEndedBitmap); uint totalInstrRegionByteLen = 0; maxInstrPathByteSize = 0; // Build a context-region block for each path: for (var i = 0; i < instrSets.Count; i++) { // Mark current path as ended (except path 0): if (i > 0) { pathEndedBitmap.SetFlag((uint)(instrSets.Count - i - 1)); } // Add start of current path byte-address bitfield: if ((instrSets[i].First().BitAddress - instrSets[0].First().BitAddress) % BitsPerByte > 0) { Console.WriteLine("Byte alignment error"); throw new Exception(); } var pathStartByteAddr = (instrSets[i].First().BitAddress - instrSets[0].First().BitAddress) >> BitByteShift; var opcode2Bit = MiscOps.GetOpcode2Bit(pathStartByteAddr, out var valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 2, value: opcode2Bit, name: "byte width opcode")); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: pathStartByteAddr, name: $"path={i} byte addr")); // Add current path byte-length bitfield: var instrPathByteLen = (instrSets[i].Last().BitAddress + instrSets[i].Last().BitfieldWrapper.BitWidth - instrSets[i].First().BitAddress) >> BitByteShift; opcode2Bit = MiscOps.GetOpcode2Bit(instrPathByteLen, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 2, value: opcode2Bit, name: "byte width opcode")); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: instrPathByteLen, name: $"path={i} byte len")); // Keep running total of paths length: totalInstrRegionByteLen += instrPathByteLen; maxInstrPathByteSize = Math.Max(maxInstrPathByteSize, instrPathByteLen); // Add current path instruction bit address bitfield: var instrBitAddr = instrPathByteLen << BitByteShift; // max possible value is number of bits in path. opcode2Bit = MiscOps.GetOpcode2Bit(instrBitAddr, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 2, value: opcode2Bit, name: "byte width opcode")); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: 0, name: $"path={i} instr bit addr")); // Add current path extra-value bitfield: uint maxValue = 0; var rampInstrs = instrSets[i].Where(x => x.Type == Instruction.InstrType.GlowRamp); if (rampInstrs.Count() > 0) { maxValue = rampInstrs.Max(x => ((GlowRampInstruction)x).RampTicks); } var opcode3Bit = MiscOps.GetOpcode3Bit(maxValue, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 3, value: opcode3Bit, name: "byte width opcode")); if (valueBitWidth > 0) { contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: 0, name: $"path={i} extra value")); } // Add current path pause-ticks bitfield: maxValue = 0; var pauseInstrs = instrSets[i].Where(x => x.Type == Instruction.InstrType.Pause); if (pauseInstrs.Count() > 0) { maxValue = pauseInstrs.Max(x => ((PauseInstruction)x).Ticks); } else if (rampInstrs.Count() > 0) { maxValue = 1; } opcode3Bit = MiscOps.GetOpcode3Bit(maxValue, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 3, value: opcode3Bit, name: "byte width opcode")); if (valueBitWidth > 0) { contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: 0, name: $"path={i} pause ticks")); } } // Set total instruction region byte length: instrRegionByteLenBitfield.SetValue(totalInstrRegionByteLen); // Add padding to context-region so following instruction path memory is byte-aligned: var paddingWidth = BitsPerByte - (contextRegion.BitfieldWrapper.BitWidth % BitsPerByte); if (paddingWidth < 8) { contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(paddingWidth, "byte-align padding")); } // Set total context-region byte length (convert from bits): contextRegionByteSize = contextRegion.BitfieldWrapper.BitWidth >> BitByteShift; contextRegionByteLenBitfield.SetValue(contextRegionByteSize); return(contextRegion); }