def visit_SystemTask(self, node): cmd = node.cmd if (self.for_verilator and (cmd == 'dumpfile' or cmd == 'dumpvars')): return vast.SystemCall('write', (vast.StringConst(''),)) if (self.for_verilator and self.in_initial and cmd == 'finish'): return vast.SystemCall('write', (vast.StringConst(''),)) args = tuple([self.visit(a) for a in node.args]) return vast.SystemCall(cmd, args)
def visit_Forever(self, node): if self.for_verilator: return vast.SingleStatement( vast.SystemCall('write', (vast.StringConst(''), ))) statement = self._optimize_block( vast.Block(tuple([self.visit(s) for s in node.statement]))) return vast.ForeverStatement(statement)
def visit_str(self, node): return vast.StringConst(node)
def visit_Str(self, node): return vast.StringConst(node.value)
def visit_Delay(self, node): if self.for_verilator: return vast.SingleStatement(vast.SystemCall('write', (vast.StringConst(''),))) delay = self.visit(node.value) return vast.SingleStatement(vast.DelayStatement(delay))
def createFaultyOutputFile(preparedModules, faultModuleFile): # This file creates the faulty output file # If this code is used as reference for pyverilog, be very cautious about # the exact use of it and a good debugger is very useful # Todo I still have struggle with the fault module injection, so if vectors # appear or similar things it could become diffcult -> it fails print("Start creating faulty verilog file!") # Contains all the verilog components of this module portMembers = [] itemMembersPortInput = [] itemMembersPortInputVector = [] itemMembersPortOutput = [] itemMembersPortOutputVector = [] itemMembersWire = [] itemMembersWireVector = [] itemMembersFaultModule = [] itemMembersGate = [] itemMembers = [] emptyList = [] # The following code create transforms all the modifies parts into # pyverilog understandable code for element in range(0, preparedModules.getModuleListLength()): if 'topmodule' in preparedModules.moduleList[element].type[1]: if verbose: print("Found Topmodule!") outputName = preparedModules.moduleList[element].type[0] # Handling the Ports for port in range(0, preparedModules.moduleList[element].ports.__len__()): if "Input" in preparedModules.moduleList[element].ports[port][0]: # print("Input") if 'singular' in preparedModules.moduleList[element].ports[port][3]: itemMembersPortInput.append(vast.Input(name=preparedModules.moduleList[element].ports[port][2], width=None, signed=False)) portMembers.append(vast.Port(name=preparedModules.moduleList[element].ports[port][2], type=None, width=None)) elif 'vector' in preparedModules.moduleList[element].ports[port][3]: # For initialization prepVector = getPreparedVector(preparedModules.moduleList[element].ports[port][2]) width = vast.Width(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2])) itemMembersPortInputVector.append(vast.Decl([vast.Input(name=prepVector[0], width=width)])) # For port definition portMembers.append(vast.Port(name=prepVector[0], type=None, width=None)) else: print("createFaultyOutputFile - topmodule - ports: Unknown port type found!") elif "Output" in preparedModules.moduleList[element].ports[port][0]: # print("Output") if 'singular' in preparedModules.moduleList[element].ports[port][3]: portMembers.append(vast.Port(name=preparedModules.moduleList[element].ports[port][2], type=None, width=None)) itemMembersPortOutput.append(vast.Output(name=preparedModules.moduleList[element].ports[port][2], width=None, signed=False)) elif 'vector' in preparedModules.moduleList[element].ports[port][3]: # For initialization prepVector = getPreparedVector(preparedModules.moduleList[element].ports[port][2]) width = vast.Width(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2])) itemMembersPortOutputVector.append(vast.Decl([vast.Output(name=prepVector[0], width=width)])) # For port definition portMembers.append(vast.Port(name=prepVector[0], type=None, width=None)) else: print("createFaultyOutputFile - topmodule - ports: Unknown port type found!") else: print("createFaultyOutputFile - topmodule - ports: Unknown port found!") sys.exit(8) # Handling the wires for wire in range(0, preparedModules.moduleList[element].wires.__len__()): if 'singular' in preparedModules.moduleList[element].wires[wire][1]: wire = vast.Wire(name=preparedModules.moduleList[element].wires[wire][0]) itemMembersWire.append(wire) # TODO this is kind of dangerous, because it seems that there is pointer, wirearray, wire and the use is always similar elif 'vector' in preparedModules.moduleList[element].wires[wire][1]: prepVector = getPreparedVector(preparedModules.moduleList[element].wires[wire][0]) # length = vast.Length(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2])) # wireArray = vast.WireArray(name=prepVector[0], length=length, width=None) # WireArray can also consume width but this seems distinct from the IO ports not to be used for the vector width width = vast.Width(msb=vast.IntConst(prepVector[1]), lsb=vast.IntConst(prepVector[2])) wire = vast.Wire(name=prepVector[0], width=width) itemMembersWireVector.append(vast.Decl(list=[wire])) else: print("createFaultyOutputFile - topmodule - wires: Unknown wire found!") sys.exit(8) # Relevant for the Gates elif 'gate' in preparedModules.moduleList[element].type[1]: moduleName = preparedModules.moduleList[element].name moduleType = preparedModules.moduleList[element].type[0] modulePortList = [] # Port Handling for port in range(0, preparedModules.moduleList[element].ports.__len__()): if 'singular' in preparedModules.moduleList[element].ports[port][3]: argName = vast.Identifier(name=preparedModules.moduleList[element].ports[port][2]) portArg = vast.PortArg(argname=argName, portname=preparedModules.moduleList[element].ports[port][1]) modulePortList.append(portArg) elif 'pointer' in preparedModules.moduleList[element].ports[port][3]: prepPointer = getPreparedPointer(preparedModules.moduleList[element].ports[port][2]) argName = vast.Pointer(var=vast.Identifier(prepPointer[0]), ptr=vast.IntConst(prepPointer[1])) portArg = vast.PortArg(argname=argName, portname=preparedModules.moduleList[element].ports[port][1]) modulePortList.append(portArg) else: print("createFaultyOutputFile - gates - ports: Unknown port type found!") sys.exit(9) # Instance Handling moduleInstance = vast.Instance(module=moduleType, name=moduleName, portlist=modulePortList, parameterlist=emptyList, array=None) moduleInstanceList = vast.InstanceList(module=moduleType, instances=[moduleInstance], parameterlist=emptyList) itemMembersGate.append(moduleInstanceList) else: print("createFaultyOutputFile: Error unknown module-type appeared") sys.exit(7) # Adding the fault modules # Getting the name from the faultModule File, which is an argument of this script print( "Attention, only the name of the faultModule-file is used, anything else is hardcoded in the script (amount of IOs and so on)") print( "We expect, that you use Questa/Modelsim for simulation, so it makes no difference, if the fault module is a Verilog or Systemverilog file") print( "The inputs of the topmodule won't be connected to fault modules, the necessity of the function needs to be evaluated") faultModuleName = (((faultModuleFile.split('/'))[-1]).split('.'))[0] print('Faultmodule name: %s' % faultModuleName) global MAKE_PORTS_FAULTY if MAKE_PORTS_FAULTY: print("The function to involve the ports of the top module has to be evaluated and if necessary implemented!") # Implementing Fault Modules - this is hardcoded, must be modified if a different kind of fault modules is used # TODO a code block which handles the inport outport so that there is a clean cut between the ports and the wires # Additional values for the module parameters moduleID = ("MODULEID", "") faultParametersByScript = False prob_c2f = ("PROB_C2F", "32'd42949672") prob_f2c = ("PROB_F2C", "32'd3865470565") seed = ("SEED", "32'd1234") random.seed(a=None, version=2) randomSeed = True for i in range(0, preparedModules.moduleList[0].wires.__len__()): # Wire Preperation if 'singular' in preparedModules.moduleList[0].wires[i][1]: wireName = preparedModules.moduleList[0].wires[i][0] if "_a" == wireName[(len(wireName) - 2):]: faultPortList = [] # Module wirePair = ( preparedModules.moduleList[0].wires[i][0], preparedModules.moduleList[0].wires[i + 1][0]) moduleName = wirePair[0][:(len(wirePair[0]) - 2)] + '_faulty' # Clock argName = vast.Identifier(name='faultClock') portArg = vast.PortArg(argname=argName, portname='CLK') faultPortList.append(portArg) # Inport argName = vast.Identifier(name=wirePair[0]) portArg = vast.PortArg(argname=argName, portname='in') faultPortList.append(portArg) # Outport argName = vast.Identifier(name=wirePair[1]) portArg = vast.PortArg(argname=argName, portname='out') faultPortList.append(portArg) # Parameter Handling - If we want to add certain parameters to the file, these lines need to be modified parameterList = [] moduleID = (moduleID[0], wirePair[0][:(len(wirePair[0]) - 2)]) parameterList.append(vast.ParamArg(argname=vast.StringConst(moduleID[1]), paramname=moduleID[0])) # Condition query if the testbench shall set the parameters (so no global defines are used if faultParametersByScript: parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_c2f[1]), paramname=prob_c2f[0])) parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_f2c[1]), paramname=prob_f2c[0])) # Randomizing seed if randomSeed: seed = ("SEED", "32'd" + str(random.randint(a=1, b=10000))) parameterList.append(vast.ParamArg(argname=vast.IntConst(seed[1]), paramname=seed[0])) # Instance Handling moduleInstance = vast.Instance(module=faultModuleName, name=moduleName, portlist=faultPortList, parameterlist=emptyList, array=None) moduleInstanceList = vast.InstanceList(module=faultModuleName, instances=[moduleInstance], parameterlist=parameterList) itemMembersFaultModule.append(moduleInstanceList) # FaultModule initialization elif 'vector' in preparedModules.moduleList[0].wires[i][1]: # Preparing the vector prepVector = getPreparedVector(preparedModules.moduleList[0].wires[i][0]) wireName_a = prepVector[0] vectorMSB = prepVector[1] vectorLSB = prepVector[2] # print(preparedModules.moduleList[0].wires[i][0]) if "_a" == wireName_a[(len(wireName_a) - 2):]: # Must be after if else it would possible take a wrong wire wireName_b = getPreparedVector(preparedModules.moduleList[0].wires[i + 1][0])[0] for j in range(int(vectorLSB), int(vectorMSB) + 1): # +1 that the last bit is also included faultPortList = [] # Module wirePair = (wireName_a , wireName_b) moduleName = wirePair[0][:(len(wireName_a[0]) - 2)] + str(j) + 'b_faulty' # Clock argName = vast.Identifier(name='faultClock') portArg = vast.PortArg(argname=argName, portname='CLK') faultPortList.append(portArg) # Inport argName = vast.Pointer(var=vast.Identifier(wireName_a), ptr=vast.IntConst(j)) portArg = vast.PortArg(argname=argName, portname='in') faultPortList.append(portArg) # Outport argName = vast.Pointer(var=vast.Identifier(wireName_b), ptr=vast.IntConst(j)) portArg = vast.PortArg(argname=argName, portname='out') faultPortList.append(portArg) # Parameter Handling - If we want to add certain parameters to the file, these lines need to be modified parameterList = [] moduleID = (moduleID[0], wirePair[0][:(len(wirePair[0]) - 2)] + '_' + str(j)) parameterList.append(vast.ParamArg(argname=vast.StringConst(moduleID[1]), paramname=moduleID[0])) # Condition query if the testbench shall set the parameters (so no global defines are used) if faultParametersByScript: parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_c2f[1]), paramname=prob_c2f[0])) parameterList.append(vast.ParamArg(argname=vast.IntConst(prob_f2c[1]), paramname=prob_f2c[0])) # Randomizing seed if randomSeed: seed = ("SEED", "32'd" + str(random.randint(a=1, b=10000))) parameterList.append(vast.ParamArg(argname=vast.IntConst(seed[1]), paramname=seed[0])) # Instance Handling moduleInstance = vast.Instance(module=faultModuleName, name=moduleName, portlist=faultPortList, parameterlist=emptyList, array=None) moduleInstanceList = vast.InstanceList(module=faultModuleName, instances=[moduleInstance], parameterlist=parameterList) itemMembersFaultModule.append(moduleInstanceList) # FaultModule initialization else: print("Implement fault modules: Error appeared during instantiation in wire section!") sys.exit(9) # Last preperations steps # Ports itemMembers.extend(itemMembersPortInputVector) # itemMembers.extend(itemMembersPortInput) # In this way for every signal is a new line used itemMembers.append(vast.Decl(list=itemMembersPortInput)) # In this way it is more "bulk" like itemMembers.extend(itemMembersPortOutputVector) # itemMembers.extend(itemMembersPortOutput) itemMembers.append(vast.Decl(list=itemMembersPortOutput)) # Wires itemMembers.extend(itemMembersWireVector) #itemMembers.extend(itemMembersWire) itemMembers.append(vast.Decl(list=itemMembersWire)) # Module Declaration itemMembers.extend(itemMembersGate) itemMembers.extend(itemMembersFaultModule) # Wire Arrays # Actual code generation portList = vast.Portlist(portMembers) ast = vast.ModuleDef(name=outputName, paramlist=None, portlist=portList, items=itemMembers) codegen = ASTCodeGenerator() result = codegen.visit(ast) if(verbose): print(result) # Writing to the code to output file outputFile = open((outputName + ".v"), 'w') outputFile.write(result) outputFile.close() print("Finished writing process!") return 0