def test(): params = vast.Paramlist([]) clk = vast.Ioport(vast.Input('CLK')) rst = vast.Ioport(vast.Input('RST')) width = vast.Width(vast.IntConst('7'), vast.IntConst('0')) led = vast.Ioport(vast.Output('led', width=width), vast.Reg('led', width=width)) ports = vast.Portlist((clk, rst, led)) items = [ vast.EmbeddedCode(""" // Embedded code reg [31:0] count; always @(posedge CLK) begin if(RST) begin count <= 0; led <= 0; end else begin if(count == 1024 - 1) begin count <= 0; led <= led + 1; end else begin count <= count + 1; end end end """) ] ast = vast.ModuleDef("top", params, ports, items) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt) assert (expected == rslt)
def getFIFOInstOfNewTemplate(self, e_name: str, e_width: int, e_depth: int, pipeline_level: int): e_inst_list = self.e_name_to_ast_node[e_name] # use our FIFO template e_inst_list.module = 'fifo_almost_full' param_width = ast.ParamArg('DATA_WIDTH', ast.Rvalue(ast.IntConst(str(e_width)))) param_depth = ast.ParamArg('DEPTH', ast.Rvalue(ast.IntConst(str(e_depth)))) addr_bitwidth = int(math.log2(e_width) + 1) param_addr_width = ast.ParamArg( 'ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(addr_bitwidth)))) # pipeline_level equals the required grace period param_grace_period = ast.ParamArg( 'GRACE_PERIOD', ast.Rvalue(ast.IntConst(str(pipeline_level)))) params = [ param_width, param_depth, param_addr_width, param_grace_period ] e_inst_list.parameterlist = params for c in e_inst_list.instances: # should only has 1 instance c.module = e_inst_list.module c.parameterlist = params return self.codegen.visit(e_inst_list)
def add_decls(self, names, node_type, width=None): '''Adds new signal declarations''' if not issubclass(node_type, ast.Variable): print( 'ERROR: invalid argument for node_type in VerilogMutator.add_decls()' ) # preprocessing inputs if they don't match the expected type if isinstance(names, str): names = [names] if isinstance(width, int): if width == 1: width = None else: width = ast.Width(ast.IntConst(width - 1), ast.IntConst(0)) # msb, lsb # collect all the declared signals new_decls = [] for name in names: new_decls.append(node_type(name, width)) # wrap them in a Decl node decl = ast.Decl(new_decls) # find index to insert at insert_index = 0 for i in range(len(self.module.items)): if isinstance(self.module.items[i], ast.Decl): insert_index = i + 1 # insert the new Decl node self.module.items = self.module.items[:insert_index] + ( decl, ) + self.module.items[insert_index:]
def make_width(self, node): if node.raw_width is not None: msb = self.bind_visitor.visit(node.raw_width[0]) lsb = self.bind_visitor.visit(node.raw_width[1]) return vast.Width(msb, lsb) if node.width is not None: msb = vast.Minus(self.bind_visitor.visit(node.width), vast.IntConst('1')) lsb = vast.IntConst('0') return vast.Width(msb, lsb) return None
def test(): params = vast.Paramlist(()) clk = vast.Ioport(vast.Input('CLK')) rst = vast.Ioport(vast.Input('RST')) width = vast.Width(vast.IntConst('7'), vast.IntConst('0')) led = vast.Ioport(vast.Output('led', width=width)) ports = vast.Portlist((clk, rst, led)) items = (vast.Assign(vast.Identifier('led'), vast.IntConst('8')), ) ast = vast.ModuleDef("top", params, ports, items) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt) assert (expected == rslt)
def print_item(c, defs, type_prefix): zero = vast.IntConst('0') if c.width.msb == zero and c.width.lsb == zero: defs.append((type_prefix, c.name)) else: defs.append((type_prefix, '[%d:%d] %s' % (int(c.width.msb.value), int(c.width.lsb.value), c.name)))
def main(): datawid = vast.Parameter('DATAWID', vast.Rvalue(vast.IntConst('32'))) params = vast.Paramlist([datawid]) clk = vast.Ioport(vast.Input('CLK')) rst = vast.Ioport(vast.Input('RST')) width = vast.Width(vast.IntConst('7'), vast.IntConst('0')) led = vast.Ioport(vast.Output('led', width=width)) ports = vast.Portlist([clk, rst, led]) width = vast.Width( vast.Minus(vast.Identifier('DATAWID'), vast.IntConst('1')), vast.IntConst('0')) count = vast.Reg('count', width=width) assign = vast.Assign( vast.Lvalue(vast.Identifier('led')), vast.Rvalue( vast.Partselect( vast.Identifier('count'), # count vast.Minus(vast.Identifier('DATAWID'), vast.IntConst('1')), # [DATAWID-1: vast.Minus(vast.Identifier('DATAWID'), vast.IntConst('8'))))) # :DATAWID-8] sens = vast.Sens(vast.Identifier('CLK'), type='posedge') senslist = vast.SensList([sens]) assign_count_true = vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier('count')), vast.Rvalue(vast.IntConst('0'))) if0_true = vast.Block([assign_count_true]) # count + 1 count_plus_1 = vast.Plus(vast.Identifier('count'), vast.IntConst('1')) assign_count_false = vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier('count')), vast.Rvalue(count_plus_1)) if0_false = vast.Block([assign_count_false]) if0 = vast.IfStatement(vast.Identifier('RST'), if0_true, if0_false) statement = vast.Block([if0]) always = vast.Always(senslist, statement) items = [] items.append(count) items.append(assign) items.append(always) ast = vast.ModuleDef("top", params, ports, items) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt)
def lower_next(done_stage: vast.IntConst, ns: NextState): """ done_stage is the index of the final stage which just holds the all the values in the register. """ # The computation is finished; transition to the done stage. if isinstance(ns, Done): return vast.Rvalue(done_stage) elif isinstance(ns, DirectNext): return vast.Rvalue(vast.IntConst(ns.state)) elif isinstance(ns, CondNext): return vast.Cond( vast.Rvalue(vast.Identifier(ns.cond.name)), vast.IntConst(ns.on_true), vast.IntConst(ns.on_false), ) else: raise ValueError("Malformed AST, expected next: %s" % ns.pretty())
def _convert_hls_fifo_to_relay_station(node, e: Edge) -> None: node.module = 'relay_station' # pipeline the FIFO width = ast.ParamArg('DATA_WIDTH', ast.Rvalue(ast.IntConst(str(e.width)))) depth = ast.ParamArg( 'DEPTH', ast.Rvalue(ast.IntConst(str(e.depth + e.added_depth_for_rebalance)))) addr_width = ast.ParamArg('ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(e.addr_width)))) level = ast.ParamArg('LEVEL', ast.Rvalue(ast.IntConst(str(e.pipeline_level)))) params = [width, depth, addr_width, level] node.parameterlist = params for c in node.instances: c.module = 'relay_station' c.parameterlist = params
def make_dims(self, node): if node.raw_dims is not None: lengths = [] for raw_dim in node.raw_dims: l = self.bind_visitor.visit(raw_dim[0]) r = self.bind_visitor.visit(raw_dim[1]) lengths.append(vast.Length(l, r)) return vast.Dimensions(lengths) if node.dims is not None: lengths = [] for dim in node.dims: l = vast.IntConst('0') r = vast.Minus(self.bind_visitor.visit(dim), vast.IntConst('1')) lengths.append(vast.Length(l, r)) return vast.Dimensions(lengths) return None
def _convert_hls_fifo_to_autobridge_fifo_template(node, e: Edge) -> None: # TODO: remove the extra grace period from the FIFO template node.module = 'fifo_almost_full' # pipeline the FIFO width = ast.ParamArg('DATA_WIDTH', ast.Rvalue(ast.IntConst(str(e.width)))) depth = ast.ParamArg( 'DEPTH', ast.Rvalue(ast.IntConst(str(e.depth + e.added_depth_for_rebalance)))) addr_width = ast.ParamArg('ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(e.addr_width)))) grace_period = ast.ParamArg('GRACE_PERIOD', ast.Rvalue(ast.IntConst(str("0")))) params = [width, depth, addr_width, grace_period] node.parameterlist = params for c in node.instances: c.module = 'fifo_almost_full' c.parameterlist = params
def lower_expr(expr: SynthExpr): if isinstance(expr, RegRef): return vast.Identifier(expr.name) elif isinstance(expr, Num): return vast.IntConst(expr.val) elif isinstance(expr, Binop): return BINOP_MAP[expr.op]( lower_expr(expr.left), lower_expr(expr.right), ) else: raise ValueError("Malformed AST, expected expr: %s" % expr.pretty())
def addRelayStation(formator, node, edges_dict): # only considers fifo/rs instances if (not formator.isFIFOInstanceList(node)): return edge_name = formator.getFIFONameFromInstanceList(node) e = edges_dict[edge_name] if (e.mark): node.module = 'relay_station' width = ast.ParamArg('DATA_WIDTH', ast.Rvalue(ast.IntConst(str(e.width)))) depth = ast.ParamArg('DEPTH', ast.Rvalue(ast.IntConst(str(e.depth)))) addr_width = ast.ParamArg('ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(e.addr_width)))) level = ast.ParamArg('LEVEL', ast.Rvalue(ast.IntConst(str(e.latency)))) params = [width, depth, addr_width, level] node.parameterlist = params for c in node.instances: c.module = 'relay_station' c.parameterlist = params # print(f'[codegen] update rs to {edge_name} -> {node.module}') # replace the ad-hoc fifos by hls # add the depth used for balancing reconvergent paths else: node.module = 'fifo' new_depth = int(e.depth + e.additional_depth) new_addr_width = int(math.log2(new_depth) + 1) width = ast.ParamArg('DATA_WIDTH', ast.Rvalue(ast.IntConst(str(e.width)))) depth = ast.ParamArg('DEPTH', ast.Rvalue(ast.IntConst(str(new_depth)))) addr_width = ast.ParamArg( 'ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(new_addr_width)))) params = [width, depth, addr_width] node.parameterlist = params for c in node.instances: c.module = 'fifo' c.parameterlist = params
def __init__(self, orcl_cir, obf_cir, enable_async, key_constraints): self.dip_gen = None self.dis_gen = None self.dip_chk = None self.uc = None self.ce = None self.umc = None self.state_size_msb = 0 self.main = None self.enable_async = enable_async self.key_constraints = key_constraints self.orcl_cir = orcl_cir # create common components module if obf_cir: self.key_size_msb = obf_cir.n_keys - 1 self.input_size_msb = orcl_cir.n_inputs - 2 self.output_size_msb = orcl_cir.n_outputs - 1 self.key_width = vast.Width(vast.IntConst(self.key_size_msb), vast.IntConst('0')) self.inp_width = vast.Width(vast.IntConst(str(self.input_size_msb)), vast.IntConst('0')) self.out_width = vast.Width(vast.IntConst(str(self.output_size_msb)), vast.IntConst('0')) # create instances for org0 and obf1 and obf2 ports = create_ports('iv', 'ov0', orcl_cir) inst = vast.Instance(orcl_cir.name, "org0", ports, "") self.org0 = vast.InstanceList(orcl_cir.name, "", [inst]) ports = create_ports('iv', 'ov1', orcl_cir) key_ports = [vast.PortArg("", vast.Identifier('k1'))] inst = vast.Instance(orcl_cir.name + '_obf', "obf1", ports + key_ports, "") self.obf1 = vast.InstanceList(orcl_cir.name + '_obf', "", [inst]) ports = create_ports('iv', 'ov2', orcl_cir) key_ports = [vast.PortArg("", vast.Identifier('k2'))] inst = vast.Instance(orcl_cir.name + '_obf', "obf2", ports + key_ports, "") self.obf2 = vast.InstanceList(orcl_cir.name + '_obf', "", [inst])
def expose_internal_scheduling_signals(self, num_rules_per_module=None, scheduling_order=None, add_force_fire=False): # if schedule isn't provided, assume rules first then modules if scheduling_order is None: scheduling_order = [ 'RL_' + x for x in self.get_rules_in_scheduling_order() ] + ['MODULE_' + x for x, y in self.get_submodules()] instance_to_module = {x: y for x, y in self.get_submodules()} can_fires = [] will_fires = [] # compute total number of bits total_num_bits = 0 for name in scheduling_order: if name.startswith('RL_'): total_num_bits += 1 elif name.startswith('MODULE_'): instance_name = name[len('MODULE_'):] module_name = instance_to_module[instance_name] if num_rules_per_module is None: continue if module_name not in num_rules_per_module: continue num_submodule_rules = num_rules_per_module[module_name] if num_submodule_rules == 0: continue total_num_bits += num_submodule_rules # now add the signals curr_bit_index = 0 for name in scheduling_order: if name.startswith('RL_'): self.add_decls('BLOCK_FIRE_' + name, ast.Wire) if add_force_fire: self.add_decls('FORCE_FIRE_' + name, ast.Wire) # definition of BLOCK_FIRE and FORCE_FILE assign = self.get_assign('WILL_FIRE_' + name) if add_force_fire: new_rhs = ast.Or( ast.Identifier('FORCE_FIRE_' + name), ast.And(ast.Unot(ast.Identifier('BLOCK_FIRE_' + name)), assign.right.var)) else: new_rhs = ast.And( ast.Unot(ast.Identifier('BLOCK_FIRE_' + name)), assign.right.var) assign.right.var = new_rhs # definition of BLOCK_FIRE_* and FORCE_FIRE_* signals from top-level BLOCK_FIRE and FORCE_FIRE if total_num_bits == 1: self.add_assign('BLOCK_FIRE_' + name, ast.Identifier('BLOCK_FIRE')) if add_force_fire: self.add_assign('FORCE_FIRE_' + name, ast.Identifier('FORCE_FIRE')) else: self.add_assign( 'BLOCK_FIRE_' + name, ast.Partselect(ast.Identifier('BLOCK_FIRE'), ast.IntConst(curr_bit_index), ast.IntConst(curr_bit_index))) if add_force_fire: self.add_assign( 'FORCE_FIRE_' + name, ast.Partselect(ast.Identifier('FORCE_FIRE'), ast.IntConst(curr_bit_index), ast.IntConst(curr_bit_index))) curr_bit_index += 1 can_fires.append(ast.Identifier('CAN_FIRE_' + name)) will_fires.append(ast.Identifier('WILL_FIRE_' + name)) elif name.startswith('MODULE_'): instance_name = name[len('MODULE_'):] module_name = instance_to_module[instance_name] if num_rules_per_module is None: continue if module_name not in num_rules_per_module: continue num_submodule_rules = num_rules_per_module[module_name] if num_submodule_rules == 0: continue instance = self.get_instance(instance_name) for signal_type in [ 'CAN_FIRE', 'WILL_FIRE', 'BLOCK_FIRE', 'FORCE_FIRE' ]: if signal_type == 'FORCE_FIRE' and not add_force_fire: continue # declarations of all FIRE signals for the submodule self.add_decls(signal_type + '_' + name, ast.Wire, width=num_submodule_rules) # connection of all FIRE signals to the submodule # this assumes the submodule has ports named CAN_FIRE, WILL_FIRE, BLOCK_FIRE, and if add_force_fire is true, FORCE_FIRE instance.portlist += (ast.PortArg( signal_type, ast.Identifier(signal_type + '_' + name)), ) # assignments of BLOCK_FIRE_* and FORCE_FIRE_* signals from top-level BLOCK_FIRE and FORCE_FIRE lsb = curr_bit_index msb = curr_bit_index + num_submodule_rules - 1 curr_bit_index += num_submodule_rules if total_num_bits == 1: self.add_assign('BLOCK_FIRE_' + name, ast.Identifier('BLOCK_FIRE')) if add_force_fire: self.add_assign('FORCE_FIRE_' + name, ast.Identifier('FORCE_FIRE')) else: self.add_assign( 'BLOCK_FIRE_' + name, ast.Partselect(ast.Identifier('BLOCK_FIRE'), ast.IntConst(msb), ast.IntConst(lsb))) if add_force_fire: self.add_assign( 'FORCE_FIRE_' + name, ast.Partselect(ast.Identifier('FORCE_FIRE'), ast.IntConst(msb), ast.IntConst(lsb))) can_fires.append(ast.Identifier('CAN_FIRE_' + name)) will_fires.append(ast.Identifier('WILL_FIRE_' + name)) elif name.startswith('METH_'): raise ValueError( '"METH_" scheduling signals are not supported yet') else: raise ValueError('unexpected entry "%s" in scheduling_order' % name) if total_num_bits != 0: # new ports self.add_ports(['CAN_FIRE', 'WILL_FIRE', 'BLOCK_FIRE']) if add_force_fire: self.add_ports(['FORCE_FIRE']) self.add_decls('CAN_FIRE', ast.Output, width=total_num_bits) self.add_decls('WILL_FIRE', ast.Output, width=total_num_bits) self.add_decls('BLOCK_FIRE', ast.Input, width=total_num_bits) if add_force_fire: self.add_decls('FORCE_FIRE', ast.Input, width=total_num_bits) self.add_decls('CAN_FIRE', ast.Wire, width=total_num_bits) self.add_decls('WILL_FIRE', ast.Wire, width=total_num_bits) # connect CAN_FIRE and WILL_FIRE can_fires.reverse() will_fires.reverse() self.add_assign('CAN_FIRE', ast.Concat(can_fires)) self.add_assign('WILL_FIRE', ast.Concat(will_fires)) return total_num_bits
def lower_fsm(fsm: FSM): assert fsm.start_state == 0, "Starting state is not 0" zero = vast.IntConst(0) all_registers = [ Register("a", 8), Register("b", 8), Register("tmp", 8), Register("_cond", 1), ] register_defs = [ vast.Reg( reg.name, vast.Width(vast.IntConst(reg.width - 1), zero) if reg.width - 1 != 0 else None) for reg in all_registers ] ports = vast.Portlist([ vast.Ioport(vast.Input('clk')), # XXX(rachit): AST can't represent `output reg done` # so assign to a local register and use a wire. vast.Ioport(vast.Output('done')), ]) done_state = max(fsm.actions.keys()) + 1 done_reg = vast.Reg('done_out') hook_up_done = vast.Assign( vast.Lvalue(vast.Identifier('done')), vast.Rvalue(vast.Identifier('done_out')), ) # Register to store the FSM state. fsm_reg_size = int(math.ceil(math.log2(done_state))) + 1 fsm_reg = vast.Reg(name="fsm_reg", width=vast.Width(vast.IntConst(fsm_reg_size - 1), zero)) # Define all the registers. reg_decl = register_defs + [fsm_reg] # Define the initial process inits = vast.Initial( vast.Block([ vast.BlockingSubstitution( vast.Lvalue(vast.Identifier(reg.name)), vast.Rvalue(vast.IntConst(0)), ) for reg in reg_decl ])) # Default case, assigns to the done register. done = vast.IntConst(done_state) default_case = vast.Case(cond=None, statement=vast.Block([ vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier(reg.name)), vast.Rvalue(vast.Identifier(reg.name)), ) for reg in reg_decl ] + [ vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier('done_out')), vast.Rvalue(vast.IntConst(1))) ])) # Generate Case conditions for each transition. cases = [ vast.Case([vast.IntConst(cond_val)], lower_action(fsm_reg, done, action)) for (cond_val, action) in fsm.actions.items() ] case_statement = vast.CaseStatement(comp=vast.Identifier(fsm_reg.name), caselist=cases + [default_case]) always_ff = vast.Always( vast.SensList([vast.Sens(vast.Identifier('clk'), 'posedge')]), vast.Block([case_statement])) return vast.ModuleDef(name="main", paramlist=vast.Paramlist([]), portlist=ports, items=reg_decl + [done_reg, hook_up_done, inits, always_ff])
def visit_Int(self, node): value_list = [] value = node.value if isinstance(node.value, str) and node.value.find('-') >= 0: pos = node.value.find('-') + 1 value = node.value[pos:] value_list.append('-') if isinstance(node.value, int) and node.value < 0: value = abs(node.value) value_list.append('-') if node.width: value_list.append(str(node.width)) if node.base is None: if node.signed: value_list.append("'sd") elif node.width: value_list.append("'d") if isinstance(value, str): value_list.append(value) else: value_list.append(str(value)) elif node.base == 2: if node.signed: value_list.append("'sb") else: value_list.append("'b") if isinstance(value, str): value_list.append(value) else: value_list.append(bin(value).replace('0b', '')) elif node.base == 8: if node.signed: value_list.append("'so") else: value_list.append("'o") if isinstance(value, str): value_list.append(value) else: value_list.append(oct(value).replace('0o', '')) elif node.base == 10: if node.signed: value_list.append("'sd") else: value_list.append("'d") if isinstance(value, str): value_list.append(value) else: value_list.append(str(value)) elif node.base == 16: if node.signed: value_list.append("'sh") else: value_list.append("'h") if isinstance(value, str): value_list.append(value) else: value_list.append(hex(value).replace('0x', '')) else: raise ValueError("Int.base must be 2, 8, 10, or 16") return vast.IntConst(''.join(value_list))
def make_length(self, node): msb = vast.IntConst('0') lsb = vast.Minus(self.bind_visitor.visit(node), vast.IntConst('1')) return vast.Length(msb, lsb)
def visit_int(self, node): return vast.IntConst(str(node))
def visit_bool(self, node): if node: return vast.IntConst('1') return vast.IntConst('0')
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
def ce_module(self, module_name, dip_list): # module for checking ce state_width = vast.Width(vast.IntConst(self.state_size_msb), vast.IntConst('0')) ce_name = module_name + '_ce' step = 1 # module port list portslist = [] portslist.append(vast.Ioport(vast.Input('clk'))) portslist.append( vast.Ioport(vast.Input('ce_iv_s0', width=self.inp_width))) portslist.append( vast.Ioport(vast.Input('ce_state_s0', width=state_width))) portslist = vast.Portlist(portslist) # create other components for dis_generator inst_list = [] inst_list.append(vast.Wire('ce_state1_s0', width=state_width)) inst_list.append(vast.Wire('ce_state2_s0', width=state_width)) inst_list.append(vast.Wire('ce_state1_s1', width=state_width)) inst_list.append(vast.Wire('ce_state2_s1', width=state_width)) inst_list.append(vast.Wire('ce_ov1_s0', width=self.out_width)) inst_list.append(vast.Wire('ce_ov2_s0', width=self.out_width)) inst_list.append(vast.Identifier('assign ce_state1_s0 = ce_state_s0;')) inst_list.append(vast.Identifier('assign ce_state2_s0 = ce_state_s0;')) for s in range(step): # create instances for obf1_ce, obf2_ce ports = create_ports('ce_iv_s' + str(s), 'ce_ov1_s' + str(s), self.orcl_cir) key_ports = [vast.PortArg("", vast.Identifier('k1'))] state_ports = [ vast.PortArg("", vast.Identifier('ce_state1_s{}'.format(s))) ] nstate_ports = [ vast.PortArg("", vast.Identifier('ce_state1_s{}'.format(s + 1))) ] inst = vast.Instance( ce_name, "obf1_ce_s{}".format(s), ports + key_ports + state_ports + nstate_ports, "") obf1_ce = vast.InstanceList(ce_name, "", [inst]) ports = create_ports('ce_iv_s' + str(s), 'ce_ov2_s' + str(s), self.orcl_cir) state_ports = [ vast.PortArg("", vast.Identifier('ce_state2_s{}'.format(s))) ] key_ports = [vast.PortArg("", vast.Identifier('k2'))] nstate_ports = [ vast.PortArg("", vast.Identifier('ce_state2_s{}'.format(s + 1))) ] inst = vast.Instance( ce_name, 'obf2_ce_s{}'.format(s), ports + key_ports + state_ports + nstate_ports, "") obf2_ce = vast.InstanceList(ce_name, "", [inst]) inst_list.extend([obf1_ce, obf2_ce]) # add always block sens = vast.Sens(vast.Identifier('clk'), type='posedge') senslist = vast.SensList([sens]) blocks = [] for s in range(step): blocks.append( vast.Identifier('assert (ce_ov1_s{} == ce_ov2_s{});'.format( s, s))) blocks.append( vast.Identifier( 'assert (ce_state1_s{} == ce_state2_s{});'.format( s + 1, s + 1))) if len(dip_list) > 0: for i, dip in enumerate(dip_list): inst_list.append( vast.Identifier('reg [{}:0] dip{} [0:{}];'.format( self.input_size_msb, i, len(dip) - 1))) # add always block blocks.append(vast.Identifier('cycle <= cycle + 1;')) statement = vast.Block(blocks) sens = vast.Sens(vast.Identifier('clk'), type='posedge') inst_list.append(vast.Always(vast.SensList([sens]), statement)) if len(dip_list) > 0: for i, dip in enumerate(dip_list): inst_list.append( vast.Identifier( 'dip_checker dc{} (clk, dip{}[cycle], k1, k2);'.format( i, i))) # add always block blocks = [] for i, dip in enumerate(dip_list): for j, inp in enumerate(dip): blocks.append( vast.Identifier('dip{}[{}] = {};'.format(i, j, inp))) statement = vast.Block(blocks) inst_list.append(vast.Always(senslist, statement)) # for s in range(step): # blocks.append(vast.Identifier('assume (ce_state1_s{} != ce_state2_s{});'.format(s+1, s+1))) statement = vast.Block(blocks) inst_list.append(vast.Always(senslist, statement)) self.ce = vast.ModuleDef("ce", None, portslist, inst_list)
from __future__ import absolute_import from __future__ import print_function import sys import os sys.path.insert( 0, os.path.dirname( os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) import pyverilog.vparser.ast as vast from pyverilog.ast_code_generator.codegen import ASTCodeGenerator params = vast.Paramlist(()) clk = vast.Ioport(vast.Input('CLK')) rst = vast.Ioport(vast.Input('RST')) width = vast.Width(vast.IntConst('7'), vast.IntConst('0')) led = vast.Ioport(vast.Output('led', width=width)) ports = vast.Portlist((clk, rst, led)) items = (vast.Assign(vast.Identifier('led'), vast.IntConst('8')), ) ast = vast.ModuleDef("top", params, ports, items) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt)