/// <summary> /// Updates the modules instantiated within vMod by inserting shadow clock in and chain out ports. /// </summary> /// <param name="vMod"></param> /// <param name="changeLog"></param> private void UpdateInstantiations(InserterMode mode, VerilogModule vMod, FileChangeLog changeLog) { //Propose changes in order to generate finalized change list int chainOutBit = 0; foreach (VerilogModuleInstance vmi in vMod.InstantiatedModules) { StringBuilder update = new StringBuilder();//"," + Environment.NewLine); if (mode == InserterMode.Error || mode == InserterMode.Both) { if (vmi.Type.ErrorControlWidth > 0) { String paramChange = String.Empty; if (vmi.Parameterized) { if (vmi.ParametersNamed) { paramChange = " ." + ERROR_PARAMETER + "(" + ERROR_PARAMETER + "),"; } else { paramChange = " " + ERROR_PARAMETER + ", "; } } else { paramChange = " #(." + ERROR_PARAMETER + "(" + ERROR_PARAMETER + ")) "; } changeLog.ProposeChange(vmi.ParameterList.Pos, paramChange.ToString()); update.AppendLine("\t\t." + ERROR_ENABLE + "(" + vmi.InstanceName + "_" + ERROR_ENABLE + "), // [ERROR]"); update.AppendLine("\t\t." + ERROR_CONTROL + "(" + vmi.InstanceName + "_" + ERROR_CONTROL + ") // [ERROR]"); } } if (mode == InserterMode.Shadow || mode == InserterMode.Both) { if (vmi.Type.NumChainsOut > 0) { int chainOutBitUpperLimit = (chainOutBit + vmi.Type.NumChainsOut - 1); string bitLimits = (chainOutBit == chainOutBitUpperLimit) ? ((vMod.NumChainsIn == 1) ? string.Empty : "[" + chainOutBit.ToString() + "]") : "[" + (chainOutBitUpperLimit + ":" + chainOutBit) + "]"; update.AppendLine(","); update.AppendLine("\t\t." + SHADOW_CLOCK + "(" + SHADOW_CLOCK + "), // [SHADOW]"); update.AppendLine("\t\t." + SHADOW_RESET + "(" + SHADOW_RESET + "), // [SHADOW]"); update.AppendLine("\t\t." + CAPTURE_ENABLE + "(" + CAPTURE_ENABLE + "), // [SHADOW]"); update.AppendLine("\t\t." + DUMP_ENABLE + "(" + CHAINS_DUMP_ENABLE + bitLimits + "), // [SHADOW]"); update.AppendLine("\t\t." + CHAINS_OUT + "(" + INST_CHAINS_OUT + bitLimits + "), // [SHADOW]"); update.AppendLine("\t\t." + CHAINS_OUT_DONE + "(" + INST_CHAINS_OUT_DONE + bitLimits + "), // [SHADOW]"); update.AppendLine("\t\t." + CHAINS_OUT_VALID + "(" + INST_CHAINS_OUT_VALID + bitLimits + ") // [SHADOW]"); chainOutBit += vmi.Type.NumChainsOut; } } if (update.ToString() == ("," + Environment.NewLine)) { continue; } changeLog.ProposeChange(vmi.InOutListEnd.Pos, update.ToString()); } }
/// <summary> /// Inserts all the inputs and outputs into the module being shadowed that are required by the shadow capture module /// </summary> /// <param name="vMod"></param> /// <param name="changeLog"></param> private void InsertLocalPorts(InserterMode mode, VerilogModule vMod, FileChangeLog changeLog) { StringBuilder inouts = new StringBuilder(Environment.NewLine); if (mode == InserterMode.Error || mode == InserterMode.Both) { inouts.AppendLine("," + Environment.NewLine + "//*****[ERROR CAPTURE MODULE INOUTS]*****"); inouts.AppendLine("\t" + ERROR_ENABLE + ", // Error injection enable"); inouts.AppendLine("\t" + ERROR_CONTROL + " // Error injection control"); } if (mode == InserterMode.Shadow || mode == InserterMode.Both) { inouts.AppendLine("," + Environment.NewLine + "//*****[SHADOW CAPTURE MODULE INOUTS]*****"); inouts.AppendLine("\t" + SHADOW_CLOCK + ", // Shadow/data clock"); inouts.AppendLine("\t" + SHADOW_RESET + ", // Shadow/data reset"); inouts.AppendLine("\t" + CAPTURE_ENABLE + ", // Capture enable"); inouts.AppendLine("\t" + DUMP_ENABLE + ", // Dump enable"); inouts.AppendLine("\t" + CHAINS_OUT + ", // Chains out"); inouts.AppendLine("\t" + CHAINS_OUT_VALID + ", // Chains out valid"); inouts.AppendLine("\t" + CHAINS_OUT_DONE + " // Chains done"); } changeLog.ProposeChange(vMod.InOutListEnd.Pos, inouts.ToString()); StringBuilder inoutDeclarations = new StringBuilder(Environment.NewLine); if ((mode == InserterMode.Error || mode == InserterMode.Both) && vMod.ErrorControlWidth > 0) { inoutDeclarations.AppendLine("parameter " + ERROR_PARAMETER + " = 1;" + Environment.NewLine); inoutDeclarations.AppendLine("\t//*****[ERROR CAPTURE MODULE INOUTS INSTANTIATIONS]*****"); inoutDeclarations.AppendLine("\tinput\t" + ERROR_ENABLE + "; // Error injection enable"); inoutDeclarations.AppendLine("\tinput\t" + ((vMod.ErrorControlWidth == 1) ? string.Empty : "[" + (vMod.ErrorControlWidth - 1) + ":0] ") + ERROR_CONTROL + "; // Error injection control"); inoutDeclarations.AppendLine(""); } if (mode == InserterMode.Shadow || mode == InserterMode.Both) { string chainsOutLimits = "[" + (vMod.NumChainsOut - 1) + ":0]"; inoutDeclarations.AppendLine("\t//*****[SHADOW CAPTURE MODULE INOUT INSTANTIATIONS]*****"); inoutDeclarations.AppendLine("\tinput\t" + SHADOW_CLOCK + "; // Shadow/data clock"); inoutDeclarations.AppendLine("\tinput\t" + SHADOW_RESET + "; // Shadow/data reset"); inoutDeclarations.AppendLine("\tinput\t" + CAPTURE_ENABLE + "; // Capture enable"); inoutDeclarations.AppendLine("\tinput\t" + chainsOutLimits + "\t" + DUMP_ENABLE + "; // Dump enable"); inoutDeclarations.AppendLine("\toutput\t" + chainsOutLimits + "\t" + CHAINS_OUT + "; // Chains out"); inoutDeclarations.AppendLine("\toutput\t" + chainsOutLimits + "\t" + CHAINS_OUT_VALID + "; // Chains out Valid"); inoutDeclarations.AppendLine("\toutput\t" + chainsOutLimits + "\t" + CHAINS_OUT_DONE + "; // Chains done"); } changeLog.ProposeChange(vMod.PostHeader.Pos, inoutDeclarations.ToString()); }
/// <summary> /// Insert actual instantiation of shadow capture module /// </summary> /// <param name="vMod"></param> /// <param name="changeLog"></param> private void InstantiateShadowCapture(VerilogModule vMod, FileChangeLog changeLog) { StringBuilder shadowCapture = new StringBuilder(Environment.NewLine); shadowCapture.AppendLine("\t//[Shadow Module Instantiation here]"); string discreteDffs, dffWidths, dclks; DffWidthParameters(vMod, out discreteDffs, out dffWidths, out dclks); shadowCapture.AppendLine("\tshadow_capture #(.DFF_BITS(" + vMod.NumLocalDffBits + "), .USE_DCLK(" + ((vMod.LocalDffs.Count > 0) ? "1" : "0") + "), .CHAINS_IN(" + vMod.NumChainsIn + "), .CHAINS_OUT(" + vMod.NumChainsOut + "), .DISCRETE_DFFS(" + discreteDffs + "), .DFF_WIDTHS(" + dffWidths + ")) " + SHADOW_MOD_NAME + "_" + vMod.Name + " ("); shadowCapture.AppendLine("\t\t.clk(" + SHADOW_CLOCK + "), "); shadowCapture.AppendLine("\t\t.rst(" + SHADOW_RESET + "), "); shadowCapture.AppendLine("\t\t.capture_en(" + CAPTURE_ENABLE + "), "); shadowCapture.AppendLine("\t\t.dclk(" + dclks + "), "); shadowCapture.AppendLine("\t\t.din(" + RouteLocalDffs(vMod) + "),"); shadowCapture.AppendLine("\t\t.dump_en(" + DUMP_ENABLE + "), "); shadowCapture.AppendLine("\t\t.chains_in(" + RouteInstanceShadowChains(vMod) + "), "); shadowCapture.AppendLine("\t\t.chains_in_vld(" + ((vMod.NumChainsIn > 0) ? INST_CHAINS_OUT_VALID : "") + "), "); shadowCapture.AppendLine("\t\t.chains_in_done(" + ((vMod.NumChainsIn == 0) ? "" : INST_CHAINS_OUT_DONE) + "), "); shadowCapture.AppendLine("\t\t.chain_dump_en(" + ((vMod.NumChainsIn == 0) ? "" : CHAINS_DUMP_ENABLE) + "), "); shadowCapture.AppendLine("\t\t.chains_out(" + CHAINS_OUT + "), "); shadowCapture.AppendLine("\t\t.chains_out_vld(" + CHAINS_OUT_VALID + "), "); shadowCapture.AppendLine("\t\t.chains_out_done(" + CHAINS_OUT_DONE + ")"); shadowCapture.AppendLine("\t);"); changeLog.ProposeChange(vMod.PrevEndModule.Pos, shadowCapture.ToString()); string[] args = new string[] { vMod.Name, vMod.NumLocalDffBits.ToString(), vMod.NumChainsIn.ToString(), vMod.NumChainsOut.ToString(), discreteDffs.ToString() }; snapArgLog.AppendLine(string.Join(",", args)); }
private void InstantiateSubErrorSplitters(VerilogModule vMod, FileChangeLog changeLog) { if (vMod.InstantiatedModules.Count < 1) { return; } StringBuilder sesSB = new StringBuilder(Environment.NewLine); sesSB.AppendLine("\t//[Sub Error Control Splitter Instantiations here]"); foreach (VerilogModuleInstance vmi in vMod.InstantiatedModules) { if (vmi.Type.ErrorControlWidth <= 0) { continue; } sesSB.AppendLine("\tsubErrCtrlSplitter #(" + ".INW(" + vMod.ErrorControlWidth + "), " + ".OUTW(" + vmi.Type.ErrorControlWidth + "), " + ".LOW(" + vmi.LowerLocalErrorId + "), " + ".HIGH(" + vmi.UpperLocalErrorId + ")) " + ERROR_SUB_MOD_NAME + "_" + vmi.InstanceName + "("); sesSB.AppendLine("\t\t.err_en(err_en),"); sesSB.AppendLine("\t\t.err_ctrl(err_ctrl),"); sesSB.AppendLine("\t\t.sub_err_en(" + vmi.InstanceName + "_" + ERROR_ENABLE + "),"); sesSB.AppendLine("\t\t.sub_err_ctrl(" + vmi.InstanceName + "_" + ERROR_CONTROL + ")"); sesSB.AppendLine("\t);"); sesSB.AppendLine(Environment.NewLine); } changeLog.ProposeChange(vMod.PrevEndModule.Pos, sesSB.ToString()); }
/// <summary> /// Updates DFFs to support error injections /// </summary> /// <param name="vMod"></param> /// <param name="changeLog"></param> private void UpdateDffs(InserterMode mode, VerilogModule vMod, FileChangeLog changeLog) { int i = 0; foreach (DffInstance dff in vMod.LocalDffs) { if (dff.ParametersExist) { if (dff.ParametersNamed) { changeLog.ProposeChange(dff.ParameterBegin.Pos, " ." + ERROR_PARAMETER + "(" + ERROR_PARAMETER + "), "); } else { if (dff.ParamsInParens) { changeLog.ProposeChange(dff.ParameterBegin.Pos, " ." + ERROR_PARAMETER + "(" + ERROR_PARAMETER + "), .SIZE("); changeLog.ProposeChange(dff.ParameterEnd.Pos, ") "); } else { changeLog.ProposeChange(dff.ParameterBegin.Pos, "( ." + ERROR_PARAMETER + "(" + ERROR_PARAMETER + "), .SIZE("); changeLog.ProposeChange(dff.ParameterEnd.Pos, ")) "); } } } else { changeLog.ProposeChange(dff.ParameterBegin.Pos, " #( ." + ERROR_PARAMETER + "(" + ERROR_PARAMETER + ")) "); } changeLog.ProposeChange(dff.PortList.Pos, Environment.NewLine + ".err_en(lcl_err" + ((vMod.ErrorControlWidth > 1)? "[" + i + "]" : string.Empty) + "),"); i++; } }
/// <summary> /// Instantiates all wires required for routing signals to/from the shadow capture module /// </summary> /// <param name="vMod"></param> /// <param name="changeLog"></param> private void InstantiateWires(InserterMode mode, VerilogModule vMod, FileChangeLog changeLog) { StringBuilder wireInst = new StringBuilder(Environment.NewLine); if (mode == InserterMode.Error || mode == InserterMode.Both) { wireInst.AppendLine("\t//*****[ERROR WIRE INSTANTIATIONS]******"); if (vMod.NumLocalDffs > 0) { wireInst.AppendLine("\twire [" + (vMod.NumLocalDffs - 1) + ":0] " + ERROR_LOCAL_CONTROL + ";"); } foreach (VerilogModuleInstance vmi in vMod.InstantiatedModules) { if (vmi.Type.ErrorControlWidth <= 0) { continue; } wireInst.AppendLine("\twire " + vmi.InstanceName + "_" + ERROR_ENABLE + ";"); wireInst.AppendLine("\twire " + ((vmi.Type.ErrorControlWidth == 0)? string.Empty : "[" + (vmi.Type.ErrorControlWidth - 1) + ":0] ") + vmi.InstanceName + "_" + ERROR_CONTROL + ";"); } changeLog.ProposeChange(vMod.PostHeader.Pos, wireInst.ToString()); wireInst.Clear(); } if (mode == InserterMode.Shadow || mode == InserterMode.Both) { if (vMod.NumChainsIn == 0) { return; } string bitLimits = (vMod.NumChainsIn == 1) ? string.Empty : "[" + (vMod.NumChainsIn - 1).ToString() + ":0] "; wireInst.AppendLine(Environment.NewLine + "//*****[SHADOW WIRE INSTANTIATIONS]*****"); wireInst.AppendLine("\twire " + bitLimits + INST_CHAINS_OUT + ";"); wireInst.AppendLine("\twire " + bitLimits + INST_CHAINS_OUT_VALID + ";"); wireInst.AppendLine("\twire " + bitLimits + INST_CHAINS_OUT_DONE + ";"); wireInst.AppendLine("\twire " + bitLimits + CHAINS_DUMP_ENABLE + ";"); wireInst.AppendLine(""); changeLog.ProposeChange(vMod.PostHeader.Pos, wireInst.ToString()); } }
private void InstantiateLocalErrorSplitter(VerilogModule vMod, FileChangeLog changeLog) { if (vMod.NumLocalDffs == 0) { return; } StringBuilder lesSB = new StringBuilder(Environment.NewLine); lesSB.AppendLine("\t//[Local Error Control Splitter Instantiation here]"); lesSB.AppendLine("\tlclErrCtrlSplitter #(.INW(" + vMod.ErrorControlWidth + "), .LCL(" + vMod.NumLocalDffs + ")) " + ERROR_LCL_MOD_NAME + "_" + vMod.Name + "("); lesSB.AppendLine("\t\t.err_en(err_en),"); lesSB.AppendLine("\t\t.err_ctrl(err_ctrl),"); lesSB.AppendLine("\t\t.lcl_err(lcl_err)"); lesSB.AppendLine("\t);"); lesSB.AppendLine(Environment.NewLine); changeLog.ProposeChange(vMod.PrevEndModule.Pos, lesSB.ToString()); }