def dip_chk_module(self): # create dip_checker module portslist = [] portslist.append(vast.Ioport(vast.Input('clk'))) portslist.append(vast.Ioport(vast.Input('iv', width=self.inp_width))) portslist.append(vast.Ioport(vast.Input('k1', width=self.key_width))) portslist.append(vast.Ioport(vast.Input('k2', width=self.key_width))) portslist = vast.Portlist(portslist) inst_list = [] inst_list.append(vast.Wire('ov0', width=self.out_width)) inst_list.append(vast.Wire('ov1', width=self.out_width)) inst_list.append(vast.Wire('ov2', width=self.out_width)) inst_list.extend([self.org0, self.obf1, self.obf2]) # add always block sens = vast.Sens(vast.Identifier('clk'), type='posedge') senslist = vast.SensList([sens]) blocks = [] blocks.append(vast.Identifier('assume (ov0 == ov1);')) blocks.append(vast.Identifier('assume (ov0 == ov2);')) statement = vast.Block(blocks) inst_list.append(vast.Always(senslist, statement)) self.dip_chk = vast.ModuleDef("dip_checker", None, portslist, inst_list)
def dip_gen_module_uc(self): # create dip_generator module # this is the assume based version # slower than dip_gen_module() due to the assume portslist = [] portslist.append(vast.Ioport(vast.Input('clk'))) portslist.append(vast.Ioport(vast.Input('iv', width=self.inp_width))) portslist.append(vast.Ioport(vast.Input('k1', width=self.key_width))) portslist.append(vast.Ioport(vast.Input('k2', width=self.key_width))) portslist = vast.Portlist(portslist) inst_list = [] inst_list.append(vast.Wire('ov1', width=self.out_width)) inst_list.append(vast.Wire('ov2', width=self.out_width)) inst_list.extend([self.obf1, self.obf2]) # add always* block blocks = [] blocks.append(vast.Identifier('assume (k1 != k2);')) blocks.append(vast.Identifier('assert (ov1 == ov2);')) statement = vast.Block(blocks) # sens = vast.Sens(None, type='all') sens = vast.Sens(vast.Identifier('clk'), type='posedge') inst_list.append(vast.Always(vast.SensList([sens]), statement)) self.dip_gen = vast.ModuleDef("dip_generator", None, portslist, inst_list)
def visit_Wire(self, node): name = node.name width = (None if node.width is None else self.make_width_msb_lsb(node.width_msb, node.width_lsb) if node.width_msb is not None and node.width_lsb is not None else self.make_width(node.width)) length = (None if node.length is None else self.make_length_msb_lsb(node.length_msb, node.length_lsb) if node.length_msb is not None and node.length_lsb is not None else self.make_length(node.length)) signed = node.signed if length is not None: return vast.WireArray(name, width, length, signed) return vast.Wire(name, width, signed)
def dip_gen_module(self): # creates dip_generator module # a more complicated version of dip_gen_module_uc # uses if in place of assume, it is faster but couldn't be used for uc termination portslist = [] portslist.append(vast.Ioport(vast.Input('clk'))) portslist.append(vast.Ioport(vast.Input('iv', width=self.inp_width))) portslist.append(vast.Ioport(vast.Input('k1', width=self.key_width))) portslist.append(vast.Ioport(vast.Input('k2', width=self.key_width))) portslist = vast.Portlist(portslist) inst_list = [] inst_list.append(vast.Wire('ov1', width=self.out_width)) inst_list.append(vast.Wire('ov2', width=self.out_width)) inst_list.extend([self.obf1, self.obf2]) # add always* block blocks = [] # blocks.append(vast.IfStatement(vast.Identifier('k1 != k2'), # vast.IfStatement(vast.Identifier('ov1 != ov2'), # vast.Identifier('assert (ov1 == ov2);'), None), # None)) # TODO: changed for latch locking blocks.append(vast.Identifier('assume (k1 != k2);')) blocks.append(vast.Identifier('assert (ov1 == ov2);')) statement = vast.Block(blocks) # TODO: posedge in case of latch # sens = vast.Sens(None, type='all') sens = vast.Sens(vast.Identifier('clk'), type='posedge') inst_list.append(vast.Always(vast.SensList([sens]), statement)) self.dip_gen = vast.ModuleDef("dip_generator", None, portslist, inst_list)
def build_package_avalon(self, configs, synthesized_code, common_code, threads, top_parameters, top_ioports, userlogic_topmodule, userlogic_include, userlogic_define, memimg, usertest): # default values ext_burstlength = 256 # write to files, with AXI interface def_top_parameters = [] def_top_localparams = [] def_top_ioports = [] name_top_ioports = [] tcl_parameters = [] tcl_ports = [] asttocode = ASTCodeGenerator() for pk, pv in top_parameters.items(): r = asttocode.visit(pv) def_top_parameters.append(r) if r.count('localparam'): def_top_localparams.append(r) continue _name = pv.name _value = asttocode.visit(pv.value) _dt = ('STRING' if r.count('"') else 'INTEGER' if r.count('integer') else 'STD_LOGIC_VECTOR') tcl_parameters.append((_name, _value, _dt)) for pk, (pv, pwidth) in top_ioports.items(): name_top_ioports.append(pk) new_pv = vast.Wire(pv.name, pv.width, pv.signed) def_top_ioports.append(asttocode.visit(new_pv)) _name = pv.name _dir = ('Input' if isinstance(pv, vast.Input) else 'Output' if isinstance(pv, vast.Output) else 'Inout') _vec = str(pwidth) tcl_ports.append((_name, _dir, _vec)) for thread in threads: _name = ''.join(('coe_', thread.name, '_finish')) _dir = 'Output' _vec = '1' tcl_ports.append((_name, _dir, _vec)) # write to files ipcore_version = '_v1_00_a' dirname = 'pycoram_' + userlogic_topmodule + ipcore_version + '/' tclname = 'pycoram_' + userlogic_topmodule + '.tcl' hdlname = 'pycoram_' + userlogic_topmodule + '.v' common_hdlname = 'pycoram_common.v' testname = 'test_pycoram_' + userlogic_topmodule + '.v' memname = 'mem.img' makefilename = 'Makefile' copied_memimg = memname if memimg is not None else None binfile = (True if memimg is not None and memimg.endswith('.bin') else False) hdlpath = dirname + 'hdl/' verilogpath = dirname + 'hdl/verilog/' tclpath = dirname + 'hdl/verilog/' testpath = dirname + 'test/' makefilepath = dirname + 'test/' if not os.path.exists(dirname): os.mkdir(dirname) if not os.path.exists(dirname + '/' + 'hdl'): os.mkdir(dirname + '/' + 'hdl') if not os.path.exists(dirname + '/' + 'hdl/verilog'): os.mkdir(dirname + '/' + 'hdl/verilog') if not os.path.exists(dirname + '/' + 'test'): os.mkdir(dirname + '/' + 'test') # tcl file tcl_template_file = 'qsys_tcl.txt' tcl_code = self.render(tcl_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], hdlname=hdlname, common_hdlname=common_hdlname, tcl_ports=tcl_ports, tcl_parameters=tcl_parameters) f = open(tclpath + tclname, 'w') f.write(tcl_code) f.close() # hdl file f = open(verilogpath + hdlname, 'w') f.write(synthesized_code) f.close() # common hdl file f = open(verilogpath + common_hdlname, 'w') f.write(common_code) f.close() # user test code usertestcode = None if usertest is not None: usertestcode = open(usertest, 'r').read() # test file test_template_file = 'test_coram_avalon.txt' test_code = self.render( test_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], hdlname=hdlname, common_hdlname=common_hdlname, memimg=copied_memimg, binfile=binfile, usertestcode=usertestcode, simaddrwidth=configs['sim_addrwidth'], clock_hperiod_userlogic=configs['hperiod_ulogic'], clock_hperiod_controlthread=configs['hperiod_cthread'], clock_hperiod_bus=configs['hperiod_bus']) f = open(testpath + testname, 'w') f.write(test_code) f.write(open(TEMPLATE_DIR + 'avalon_master_fifo.v', 'r').read()) f.close() # memory image for test if memimg is not None: shutil.copy(memimg, testpath + memname) # makefile file makefile_template_file = 'Makefile.txt' makefile_code = self.render(makefile_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], testname=testname) f = open(makefilepath + makefilename, 'w') f.write(makefile_code) f.close()
def build_package_axi(self, configs, synthesized_code, common_code, threads, top_parameters, top_ioports, userlogic_topmodule, userlogic_include, userlogic_define, memimg, usertest): code = synthesized_code + common_code # default values ext_burstlength = 256 # write to files, with AXI interface def_top_parameters = [] def_top_localparams = [] def_top_ioports = [] name_top_ioports = [] mpd_parameters = [] mpd_ports = [] ext_params = [] ext_ports = [] asttocode = ASTCodeGenerator() for pk, pv in top_parameters.items(): r = asttocode.visit(pv) def_top_parameters.append(r) if r.count('localparam'): def_top_localparams.append(r) continue _name = pv.name _value = asttocode.visit(pv.value) _dt = 'string' if r.count('"') else 'integer' mpd_parameters.append((_name, _value, _dt)) for pk, (pv, pwidth) in top_ioports.items(): name_top_ioports.append(pk) new_pv = vast.Wire(pv.name, pv.width, pv.signed) def_top_ioports.append(asttocode.visit(new_pv)) _name = pv.name _dir = ('I' if isinstance(pv, vast.Input) else 'O' if isinstance(pv, vast.Output) else 'IO') _vec = '' if pv.width is None else asttocode.visit(pv.width) mpd_ports.append((_name, _dir, _vec)) for pk, (pv, pwidth) in top_ioports.items(): new_pv = vast.Wire(pv.name, pv.width, pv.signed) _name = pv.name _dir = ('in' if isinstance(pv, vast.Input) else 'out' if isinstance(pv, vast.Output) else 'inout') _vec = None if pv.width is None else asttocode.visit(pv.width.msb) ext_ports.append((_name, _dir, _vec)) for pk, pv in top_parameters.items(): r = asttocode.visit(pv) if r.count('localparam'): def_top_localparams.append(r) continue _name = pv.name _value = asttocode.visit(pv.value) _dt = 'string' if r.count('"') else 'integer' ext_params.append((_name, _value, _dt)) # write to files # with AXI interface, create IPcore dir ipcore_version = '_v1_00_a' mpd_version = '_v2_1_0' dirname = 'pycoram_' + userlogic_topmodule + ipcore_version + '/' # pcore mpdname = 'pycoram_' + userlogic_topmodule + mpd_version + '.mpd' #muiname = 'pycoram_' + userlogic_topmodule + mpd_version + '.mui' paoname = 'pycoram_' + userlogic_topmodule + mpd_version + '.pao' tclname = 'pycoram_' + userlogic_topmodule + mpd_version + '.tcl' # IP-XACT xmlname = 'component.xml' xdcname = 'pycoram_' + userlogic_topmodule + '.xdc' bdname = 'bd.tcl' xguiname = 'xgui.tcl' # source hdlname = 'pycoram_' + userlogic_topmodule + '.v' testname = 'test_pycoram_' + userlogic_topmodule + '.v' memname = 'mem.img' makefilename = 'Makefile' copied_memimg = memname if memimg is not None else None binfile = (True if memimg is not None and memimg.endswith('.bin') else False) # pcore mpdpath = dirname + 'data/' #muipath = dirname + 'data/' paopath = dirname + 'data/' tclpath = dirname + 'data/' # IP-XACT xmlpath = dirname xdcpath = dirname + 'data/' bdpath = dirname + 'bd/' xguipath = dirname + 'xgui/' # source hdlpath = dirname + 'hdl/' verilogpath = dirname + 'hdl/verilog/' testpath = dirname + 'test/' makefilepath = dirname + 'test/' if not os.path.exists(dirname): os.mkdir(dirname) if not os.path.exists(dirname + '/' + 'data'): os.mkdir(dirname + '/' + 'data') if not os.path.exists(dirname + '/' + 'doc'): os.mkdir(dirname + '/' + 'doc') if not os.path.exists(dirname + '/' + 'bd'): os.mkdir(dirname + '/' + 'bd') if not os.path.exists(dirname + '/' + 'xgui'): os.mkdir(dirname + '/' + 'xgui') if not os.path.exists(dirname + '/' + 'hdl'): os.mkdir(dirname + '/' + 'hdl') if not os.path.exists(dirname + '/' + 'hdl/verilog'): os.mkdir(dirname + '/' + 'hdl/verilog') if not os.path.exists(dirname + '/' + 'test'): os.mkdir(dirname + '/' + 'test') # mpd file mpd_template_file = 'mpd.txt' mpd_code = self.render(mpd_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], hdlname=hdlname, ipcore_version=ipcore_version, mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) f = open(mpdpath + mpdname, 'w') f.write(mpd_code) f.close() # mui file #mui_template_file = 'mui.txt' #mui_code = self.render(mui_template_file, # userlogic_topmodule, threads, # def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, # ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, # single_clock=configs['single_clock'], lite=configs['io_lite'], # hdlname=hdlname, # ipcore_version=ipcore_version, # mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) #f = open(muipath+muiname, 'w') #f.write(mui_code) #f.close() # pao file pao_template_file = 'pao.txt' pao_code = self.render(pao_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], hdlname=hdlname, ipcore_version=ipcore_version, mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) f = open(paopath + paoname, 'w') f.write(pao_code) f.close() # tcl file tcl_code = '' if not configs['single_clock']: tcl_code = open(TEMPLATE_DIR + 'pcore_tcl.tcl', 'r').read() f = open(tclpath + tclname, 'w') f.write(tcl_code) f.close() # component.xml gen = utils.componentgen.ComponentGen() xml_code = gen.generate(userlogic_topmodule, threads, lite=configs['io_lite'], ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, ext_ports=ext_ports, ext_params=ext_params) f = open(xmlpath + xmlname, 'w') f.write(xml_code) f.close() # xdc xdc_code = '' if not configs['single_clock']: xdc_code = open(TEMPLATE_DIR + 'ipxact.xdc', 'r').read() f = open(xdcpath + xdcname, 'w') f.write(xdc_code) f.close() # bd bd_code = '' bd_code = open(TEMPLATE_DIR + 'bd.tcl', 'r').read() f = open(bdpath + bdname, 'w') f.write(bd_code) f.close() # xgui file xgui_template_file = 'xgui_tcl.txt' xgui_code = self.render(xgui_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], hdlname=hdlname, ipcore_version=ipcore_version, mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) f = open(xguipath + xguiname, 'w') f.write(xgui_code) f.close() # hdl file f = open(verilogpath + hdlname, 'w') f.write(code) f.close() # user test code usertestcode = None if usertest is not None: usertestcode = open(usertest, 'r').read() # test file test_template_file = 'test_coram_axi.txt' test_code = self.render( test_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], hdlname=hdlname, memimg=copied_memimg, binfile=binfile, usertestcode=usertestcode, simaddrwidth=configs['sim_addrwidth'], clock_hperiod_userlogic=configs['hperiod_ulogic'], clock_hperiod_controlthread=configs['hperiod_cthread'], clock_hperiod_bus=configs['hperiod_bus']) f = open(testpath + testname, 'w') f.write(test_code) f.write(open(TEMPLATE_DIR + 'axi_master_fifo.v', 'r').read()) f.close() # memory image for test if memimg is not None: shutil.copyfile(os.path.expanduser(memimg), testpath + memname) # makefile file makefile_template_file = 'Makefile.txt' makefile_code = self.render(makefile_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite'], testname=testname) f = open(makefilepath + makefilename, 'w') f.write(makefile_code) f.close()
def build(self, configs, userlogic_topmodule, userlogic_filelist, controlthread_filelist=None, controlthread_funcs=None, function_lib=None, userlogic_include=None, userlogic_define=None, memimg=None, usertest=None): # default values ext_burstlength = 256 if (configs['single_clock'] and ((configs['hperiod_ulogic'] != configs['hperiod_cthread']) or (configs['hperiod_ulogic'] != configs['hperiod_bus']) or (configs['hperiod_cthread'] != configs['hperiod_bus']))): raise ValueError( "All clock periods should be same in single clock mode.") # User RTL Conversion converter = RtlConverter(userlogic_filelist, userlogic_topmodule, include=userlogic_include, define=userlogic_define, single_clock=configs['single_clock']) userlogic_ast = converter.generate() top_parameters = converter.getTopParameters() top_ioports = converter.getTopIOPorts() # dump converter.dumpCoramObject() # Code Generator asttocode = ASTCodeGenerator() userlogic_code = asttocode.visit(userlogic_ast) # Control Thread controlthread_codes = [] generator = ControlThreadGenerator() thread_status = {} # from files if controlthread_filelist is not None: for f in controlthread_filelist: (thread_name, ext) = os.path.splitext(os.path.basename(f)) controlthread_codes.append( generator.compile( thread_name, filename=f, signalwidth=configs['signal_width'], ext_addrwidth=configs['ext_addrwidth'], ext_max_datawidth=configs['ext_datawidth'], dump=True)) thread_status.update(generator.getStatus()) # from func objects if controlthread_funcs is not None: for func_name, func in controlthread_funcs.items(): controlthread_codes.append( generator.compile( func_name, func=func, function_lib=function_lib, signalwidth=configs['signal_width'], ext_addrwidth=configs['ext_addrwidth'], ext_max_datawidth=configs['ext_datawidth'], dump=True)) thread_status.update(generator.getStatus()) # Template Render threads = [] for tname, (tmemories, tinstreams, toutstreams, tchannels, tregisters, tiochannels, tioregisters) in sorted(thread_status.items(), key=lambda x: x[0]): threads.append( ControlThread(tname, tmemories, tinstreams, toutstreams, tchannels, tregisters, tiochannels, tioregisters)) asttocode = ASTCodeGenerator() def_top_parameters = [] def_top_localparams = [] def_top_ioports = [] name_top_ioports = [] for p in top_parameters.values(): r = asttocode.visit(p) if r.count('localparam'): def_top_localparams.append(r) else: def_top_parameters.append(r.replace(';', ',')) for pk, (pv, pwidth) in top_ioports.items(): if configs['if_type'] == 'avalon': new_pv = copy.deepcopy(pv) new_pv.name = 'coe_' + new_pv.name new_pv = vast.Ioport( new_pv, vast.Wire(new_pv.name, new_pv.width, new_pv.signed)) def_top_ioports.append(asttocode.visit(new_pv)) else: new_pv = vast.Ioport(pv, vast.Wire(pv.name, pv.width, pv.signed)) def_top_ioports.append(asttocode.visit(new_pv)) name_top_ioports.append(pk) node_template_file = ( 'node_axi.txt' if configs['if_type'] == 'axi' else 'node_avalon.txt' if configs['if_type'] == 'avalon' else #'node_wishborn.txt' if configs['if_type'] == 'wishborn' else 'node_general.txt') node_code = self.render(node_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite']) dmac_memory_template_file = 'dmac_memory.txt' dmac_memory_code = self.render(dmac_memory_template_file, userlogic_topmodule, threads, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], lite=configs['io_lite']) # finalize of code generation synthesized_code_list = [] synthesized_code_list.append(node_code) synthesized_code_list.append(userlogic_code) synthesized_code_list.extend(controlthread_codes) synthesized_code_list.append(dmac_memory_code) common_code_list = [] pycoram_object = open(TEMPLATE_DIR + 'pycoram_object.v', 'r').read() dmac_memory_common = open(TEMPLATE_DIR + 'dmac_memory_common.v', 'r').read() dmac_stream = open(TEMPLATE_DIR + 'dmac_stream.v', 'r').read() dmac_iochannel = open(TEMPLATE_DIR + 'dmac_iochannel.v', 'r').read() dmac_ioregister = open(TEMPLATE_DIR + 'dmac_ioregister.v', 'r').read() common_code_list.append(pycoram_object) common_code_list.append(dmac_memory_common) common_code_list.append(dmac_stream) common_code_list.append(dmac_iochannel) common_code_list.append(dmac_ioregister) if configs['if_type'] == 'axi': common_code_list.append( open(TEMPLATE_DIR + 'axi_master_interface.v', 'r').read()) if configs['io_lite']: common_code_list.append( open(TEMPLATE_DIR + 'axi_lite_slave_interface.v', 'r').read()) else: common_code_list.append( open(TEMPLATE_DIR + 'axi_slave_interface.v', 'r').read()) if configs['if_type'] == 'avalon': common_code_list.append( open(TEMPLATE_DIR + 'avalon_master_interface.v', 'r').read()) if configs['io_lite']: common_code_list.append( open(TEMPLATE_DIR + 'avalon_lite_slave_interface.v', 'r').read()) else: common_code_list.append( open(TEMPLATE_DIR + 'avalon_slave_interface.v', 'r').read()) synthesized_code = ''.join(synthesized_code_list) common_code = ''.join(common_code_list) # Print settings print("Synthesis Setting") for k, v in sorted(configs.items(), key=lambda x: x[0]): print(" %s : %s" % (str(k), str(v))) # write to file, without AXI interfaces if configs['if_type'] == 'general': self.build_package_general(configs, synthesized_code, common_code) return if configs['if_type'] == 'axi': self.build_package_axi(configs, synthesized_code, common_code, threads, top_parameters, top_ioports, userlogic_topmodule, userlogic_include, userlogic_define, memimg, usertest) return if configs['if_type'] == 'avalon': self.build_package_avalon(configs, synthesized_code, common_code, threads, top_parameters, top_ioports, userlogic_topmodule, userlogic_include, userlogic_define, memimg, usertest) return raise ValueError("Interface type '%s' is not supported." % configs['if_type'])
def build(self, configs, userlogic_topmodule, userlogic_filelist, include=None, define=None, memimg=None, usertest=None, skip_not_found=False, ignore_protocol_error=False): # default values ext_burstlength = 256 if configs['single_clock'] and (configs['hperiod_ulogic'] != configs['hperiod_bus']): raise ValueError( "All clock periods should be same in single clock mode.") # User RTL Conversion converter = RtlConverter(userlogic_filelist, userlogic_topmodule, include=include, define=define) userlogic_ast = converter.generate(skip_not_found) (masterlist, slavelist) = converter.getResourceDefinitions() top_parameters = converter.getTopParameters() top_ioports = converter.getTopIOPorts() not_found_modules = converter.getNotFoundModules() # dump converter.dumpTargetObject() # Code Generator asttocode = ASTCodeGenerator() userlogic_code = asttocode.visit(userlogic_ast) asttocode = ASTCodeGenerator() def_top_parameters = [] def_top_localparams = [] def_top_ioports = [] name_top_ioports = [] for p in top_parameters.values(): r = asttocode.visit(p) if r.count('localparam'): def_top_localparams.append(r) else: def_top_parameters.append(r.replace(';', ',')) for pk, (pv, pwidth) in top_ioports.items(): if configs['if_type'] == 'avalon': new_pv = copy.deepcopy(pv) new_pv.name = 'coe_' + new_pv.name new_pv = vast.Ioport( new_pv, vast.Wire(new_pv.name, new_pv.width, new_pv.signed)) def_top_ioports.append(asttocode.visit(new_pv)) else: new_pv = vast.Ioport(pv, vast.Wire(pv.name, pv.width, pv.signed)) def_top_ioports.append(asttocode.visit(new_pv)) name_top_ioports.append(pk) node_template_file = ( 'node_axi.txt' if configs['if_type'] == 'axi' else 'node_avalon.txt' if configs['if_type'] == 'avalon' else #'node_wishborn.txt' if configs['if_type'] == 'wishborn' else 'node_general.txt') node_code = self.render(node_template_file, userlogic_topmodule, masterlist, slavelist, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=ext_burstlength, single_clock=configs['single_clock']) # finalize of code generation synthesized_code_list = [] synthesized_code_list.append(node_code) synthesized_code_list.append(userlogic_code) common_code_list = [] if configs['if_type'] == 'axi': common_code_list.append( open(TEMPLATE_DIR + 'axi_master_interface.v', 'r').read()) common_code_list.append( open(TEMPLATE_DIR + 'axi_lite_master_interface.v', 'r').read()) common_code_list.append( open(TEMPLATE_DIR + 'axi_slave_interface.v', 'r').read()) common_code_list.append( open(TEMPLATE_DIR + 'axi_lite_slave_interface.v', 'r').read()) if configs['if_type'] == 'avalon': common_code_list.append( open(TEMPLATE_DIR + 'avalon_master_interface.v', 'r').read()) common_code_list.append( open(TEMPLATE_DIR + 'avalon_lite_master_interface.v', 'r').read()) common_code_list.append( open(TEMPLATE_DIR + 'avalon_slave_interface.v', 'r').read()) common_code_list.append( open(TEMPLATE_DIR + 'avalon_lite_slave_interface.v', 'r').read()) synthesized_code = ''.join(synthesized_code_list) common_code = ''.join(common_code_list) # Print settings print("----------------------------------------") print("Synthesis Setting") for k, v in sorted(configs.items(), key=lambda x: x[0]): print(" %s : %s" % (str(k), str(v))) # write to file, without AXI interfaces if configs['if_type'] == 'general': self.build_package_general(configs, synthesized_code, common_code) return if configs['if_type'] == 'axi': self.build_package_axi(configs, synthesized_code, common_code, masterlist, slavelist, top_parameters, top_ioports, userlogic_topmodule, memimg, usertest, ignore_protocol_error) return if configs['if_type'] == 'avalon': self.build_package_avalon(configs, synthesized_code, common_code, masterlist, slavelist, top_parameters, top_ioports, userlogic_topmodule, memimg, usertest, ignore_protocol_error) return raise ValueError("Interface type '%s' is not supported." % configs['if_type'])
def build(self, configs, memory_configs, filelist, topmodule, include=None, define=None, memimg=None, usertest=None): if configs['single_clock'] and (configs['hperiod_ulogic'] != configs['hperiod_axi']): raise ValueError( "All clock periods should be same in single clock mode.") # default values ext_burstlength = 256 if configs['if_type'] == 'axi' else 256 converter = RtlConverter(filelist, topmodule=topmodule, include=include, define=define) ast = converter.generate() top_parameters = converter.getTopParameters() top_ioports = converter.getTopIOPorts() memoryspacelist, interfacelist, outchannellist, inchannellist = converter.getResourceDefinitions( ) domains = configuration_reader.domain_generator.get_domains( interfacelist, outchannellist, inchannellist) if len(domains) > 1: raise ValueError( "Using multiple domains is not supported currently.") # Drive Signal Insertion inserter = DriveInserter(configs['drive']) drive_ast = inserter.generate(ast) asttocode = ASTCodeGenerator() userlogic_code = asttocode.visit(drive_ast) # Syrup memory resourcelist = configuration_reader.configuration_reader.readResourceDefinitions( memory_configs) onchipmemorylist = [] offchipmemorylist = [] for resource in resourcelist: if isinstance(resource, OnchipMemoryDefinition): onchipmemorylist.append(resource) elif isinstance(resource, OffchipMemoryDefinition): offchipmemorylist.append(resource) elif isinstance(resource, MemorySpaceDefinition): raise TypeError( "Can not accept External Memory Space Definitions.") elif isinstance(resource, InterfaceDefinition): raise TypeError( "Can not accept External Interface Definitions.") else: raise NameError('Wrong Definition Format') if not offchipmemorylist: raise ValueError("Off-chip Memory Definition not found") if not onchipmemorylist: raise ValueError("On-chip Memory Definition not found") ext_addrwidth = offchipmemorylist[0].addrlen ext_datawidth = offchipmemorylist[0].datawidth memorygen = AbstractMemoryGenerator(onchipmemorylist, offchipmemorylist, memoryspacelist, interfacelist, domains) memory_code = memorygen.create() channelgen = AbstractChannelGenerator() channel_code = channelgen.create(domains) # top module asttocode = ASTCodeGenerator() def_top_parameters = [] def_top_localparams = [] def_top_ioports = [] name_top_ioports = [] for p in top_parameters.values(): r = asttocode.visit(p) if r.count('localparam'): def_top_localparams.append(r) else: def_top_parameters.append(r.replace(';', ',')) for pk, pv in top_ioports.items(): new_pv = vast.Ioport(pv, vast.Wire(pv.name, pv.width, pv.signed)) def_top_ioports.append(asttocode.visit(new_pv)) name_top_ioports.append(pk) node_template_file = ( 'node_axi.txt' if configs['if_type'] == 'axi' else #'node_avalon.txt' if configs['if_type'] == 'avalon' else #'node_wishborn.txt' if configs['if_type'] == 'wishborn' else 'node_general.txt') node_code = self.render(node_template_file, topmodule, domains, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=ext_addrwidth, ext_datawidth=ext_datawidth, ext_burstlength=ext_burstlength, drive_name=configs['drive'], single_clock=configs['single_clock']) # finalize entire_code = [] entire_code.append(node_code) entire_code.append(userlogic_code) entire_code.append(memory_code) entire_code.append(channel_code) if configs['if_type'] == 'axi': entire_code.append( open(TEMPLATE_DIR + 'axi_master_interface.v', 'r').read()) code = ''.join(entire_code) # write to file, without AXI interfaces if configs['if_type'] == 'general': f = open(configs['output'], 'w') f.write(code) f.close() return if configs['if_type'] != 'axi': raise ValueError("Interface type '%s' is not supported." % configs['if_type']) # write to files, with AXI interface def_top_parameters = [] def_top_ioports = [] mpd_parameters = [] mpd_ports = [] for pk, pv in top_parameters.items(): r = asttocode.visit(pv) def_top_parameters.append(r) if r.count('localparam'): continue _name = pv.name _value = asttocode.visit(pv.value) _dt = 'string' if r.count('"') else 'integer' mpd_parameters.append((_name, _value, _dt)) for pk, pv in top_ioports.items(): new_pv = vast.Wire(pv.name, pv.width, pv.signed) def_top_ioports.append(asttocode.visit(new_pv)) _name = pv.name _dir = ('I' if isinstance(pv, vast.Input) else 'O' if isinstance(pv, vast.Output) else 'IO') _vec = '' if pv.width is None else asttocode.visit(pv.width) mpd_ports.append((_name, _dir, _vec)) # write to files # with AXI interface, create IPcore dir ipcore_version = '_v1_00_a' mpd_version = '_v2_1_0' dirname = 'syrup_' + topmodule + ipcore_version + '/' mpdname = 'syrup_' + topmodule + mpd_version + '.mpd' #muiname = 'syrup_' + topmodule + mpd_version + '.mui' paoname = 'syrup_' + topmodule + mpd_version + '.pao' tclname = 'syrup_' + topmodule + mpd_version + '.tcl' hdlname = 'syrup_' + topmodule + '.v' testname = 'testbench_' + topmodule + '.v' memname = 'mem.img' makefilename = 'Makefile' copied_memimg = memname if memimg is not None else None binfile = (True if memimg is not None and memimg.endswith('.bin') else False) hdlpath = dirname + 'hdl/' verilogpath = dirname + 'hdl/verilog/' mpdpath = dirname + 'data/' #muipath = dirname + 'data/' paopath = dirname + 'data/' tclpath = dirname + 'data/' testpath = dirname + 'test/' makefilepath = dirname + 'test/' if not os.path.exists(dirname): os.mkdir(dirname) if not os.path.exists(dirname + '/' + 'data'): os.mkdir(dirname + '/' + 'data') if not os.path.exists(dirname + '/' + 'doc'): os.mkdir(dirname + '/' + 'doc') if not os.path.exists(dirname + '/' + 'hdl'): os.mkdir(dirname + '/' + 'hdl') if not os.path.exists(dirname + '/' + 'hdl/verilog'): os.mkdir(dirname + '/' + 'hdl/verilog') if not os.path.exists(dirname + '/' + 'test'): os.mkdir(dirname + '/' + 'test') # hdl file f = open(verilogpath + hdlname, 'w') f.write(code) f.close() # mpd file mpd_template_file = 'mpd.txt' mpd_code = self.render(mpd_template_file, topmodule, domains, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=ext_addrwidth, ext_datawidth=ext_datawidth, ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], ipcore_version=ipcore_version, mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) f = open(mpdpath + mpdname, 'w') f.write(mpd_code) f.close() # mui file #mui_template_file = 'mui.txt' #mui_code = self.render(mui_template_file, # topmodule, domains, # def_top_parameters, def_top_localparams, # def_top_ioports, name_top_ioports, # ext_addrwidth=ext_addrwidth, # ext_datawidth=ext_datawidth, # ext_burstlength=ext_burstlength, # single_clock=configs['single_clock'], # mpd_parameters=mpd_parameters) #f = open(muipath+muiname, 'w') #f.write(mui_code) #f.close() # pao file pao_template_file = 'pao.txt' pao_code = self.render(pao_template_file, topmodule, domains, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=ext_addrwidth, ext_datawidth=ext_datawidth, ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], hdlname=hdlname, ipcore_version=ipcore_version) f = open(paopath + paoname, 'w') f.write(pao_code) f.close() # tcl file tcl_code = '' if not configs['single_clock'] and inchannellist: tcl_code = open(TEMPLATE_DIR + 'tcl.tcl', 'r').read() f = open(tclpath + tclname, 'w') f.write(tcl_code) f.close() # user test code usertestcode = None if usertest is not None: usertestcode = open(usertest, 'r').read() # test file test_template_file = 'testbench.txt' test_code = self.render( test_template_file, topmodule, domains, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=ext_addrwidth, ext_datawidth=ext_datawidth, ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], hdlname=hdlname, memimg=copied_memimg, binfile=binfile, usertestcode=usertestcode, simaddrwidth=configs['sim_addrwidth'], clock_hperiod_userlogic=configs['hperiod_ulogic'], clock_hperiod_axi=configs['hperiod_axi']) f = open(testpath + testname, 'w') f.write(test_code) f.close() # memory image for test if memimg is not None: f = open(testpath + memname, 'w') f.write(open(memimg, 'r').read()) f.close() # makefile file makefile_template_file = 'Makefile.txt' makefile_code = self.render(makefile_template_file, topmodule, domains, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=ext_addrwidth, ext_datawidth=ext_datawidth, ext_burstlength=ext_burstlength, single_clock=configs['single_clock'], testname=testname) f = open(makefilepath + makefilename, 'w') f.write(makefile_code) f.close()
def build_package_axi(self, configs, synthesized_code, common_code, masterlist, slavelist, top_parameters, top_ioports, topmodule, ipname, memimg, usertest, ignore_protocol_error): code = '\n'.join([synthesized_code, common_code]) # write to files def_top_parameters = [] def_top_localparams = [] def_top_ioports = [] name_top_ioports = [] mpd_parameters = [] mpd_ports = [] ext_params = [] ext_ports = [] asttocode = ASTCodeGenerator() for pk, pv in top_parameters.items(): r = asttocode.visit(pv) def_top_parameters.append(r) if r.count('localparam'): def_top_localparams.append(r) continue _name = pv.name _value = asttocode.visit(pv.value) _dt = 'string' if r.count('"') else 'integer' mpd_parameters.append((_name, _value, _dt)) for pk, (pv, pwidth) in top_ioports.items(): name_top_ioports.append(pk) new_pv = vast.Wire(pv.name, pv.width, pv.signed) def_top_ioports.append(asttocode.visit(new_pv)) _name = pv.name _dir = ('I' if isinstance(pv, vast.Input) else 'O' if isinstance(pv, vast.Output) else 'IO') _vec = '' if pv.width is None else asttocode.visit(pv.width) mpd_ports.append((_name, _dir, _vec)) for pk, (pv, pwidth) in top_ioports.items(): new_pv = vast.Wire(pv.name, pv.width, pv.signed) _name = pv.name _dir = ('in' if isinstance(pv, vast.Input) else 'out' if isinstance(pv, vast.Output) else 'inout') _vec = None if pv.width is None else pwidth - 1 _ids = None if pv.width is None else iv.getIdentifiers( pv.width.msb) _d = {} if _ids is not None: for i in _ids: _d[i] = "(spirit:decode(id('MODELPARAM_VALUE." + i + "')))" _msb = (None if _ids is None else asttocode.visit( ir.replaceIdentifiers(pv.width.msb, _d))) ext_ports.append((_name, _dir, _vec, _msb)) for pk, pv in top_parameters.items(): r = asttocode.visit(pv) if r.count('localparam'): def_top_localparams.append(r) continue _name = pv.name _value = asttocode.visit(pv.value) _dt = 'string' if r.count('"') else 'integer' ext_params.append((_name, _value, _dt)) # names ipcore_version = '_v1_00_a' mpd_version = '_v2_1_0' dirname = ipname + ipcore_version + '/' # pcore mpdname = ipname + mpd_version + '.mpd' #muiname = ipname + mpd_version + '.mui' paoname = ipname + mpd_version + '.pao' tclname = ipname + mpd_version + '.tcl' # IP-XACT xmlname = 'component.xml' xdcname = ipname + '.xdc' bdname = 'bd.tcl' xguiname = 'xgui.tcl' # source hdlname = ipname + '.v' testname = 'test_' + ipname + '.v' memname = 'mem.img' makefilename = 'Makefile' copied_memimg = memname if memimg is not None else None binfile = (True if memimg is not None and memimg.endswith('.bin') else False) # pcore mpdpath = dirname + 'data/' #muipath = dirname + 'data/' paopath = dirname + 'data/' tclpath = dirname + 'data/' # IP-XACT xmlpath = dirname xdcpath = dirname + 'data/' bdpath = dirname + 'bd/' xguipath = dirname + 'xgui/' # source hdlpath = dirname + 'hdl/' verilogpath = dirname + 'hdl/verilog/' testpath = dirname + 'test/' makefilepath = dirname + 'test/' if not os.path.exists(dirname): os.mkdir(dirname) if not os.path.exists(dirname + '/' + 'data'): os.mkdir(dirname + '/' + 'data') if not os.path.exists(dirname + '/' + 'doc'): os.mkdir(dirname + '/' + 'doc') if not os.path.exists(dirname + '/' + 'bd'): os.mkdir(dirname + '/' + 'bd') if not os.path.exists(dirname + '/' + 'xgui'): os.mkdir(dirname + '/' + 'xgui') if not os.path.exists(dirname + '/' + 'hdl'): os.mkdir(dirname + '/' + 'hdl') if not os.path.exists(dirname + '/' + 'hdl/verilog'): os.mkdir(dirname + '/' + 'hdl/verilog') if not os.path.exists(dirname + '/' + 'test'): os.mkdir(dirname + '/' + 'test') # mpd file mpd_template_file = 'mpd.txt' mpd_code = self.render(mpd_template_file, topmodule, ipname, masterlist, slavelist, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=default_ext_burstlength, single_clock=configs['single_clock'], hdlname=hdlname, ipcore_version=ipcore_version, mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) f = open(mpdpath + mpdname, 'w') f.write(mpd_code) f.close() # mui file #mui_template_file = 'mui.txt' # mui_code = self.render(mui_template_file, # topmodule, ipname, # masterlist, slavelist, # def_top_parameters, def_top_localparams, # def_top_ioports, name_top_ioports, # # ext_addrwidth=configs['ext_addrwidth'], # ext_burstlength=default_ext_burstlength, # single_clock=configs['single_clock'], # hdlname=hdlname, # ipcore_version=ipcore_version, # mpd_ports=mpd_ports, # mpd_parameters=mpd_parameters) # #f = open(muipath+muiname, 'w') # f.write(mui_code) # f.close() # pao file pao_template_file = 'pao.txt' pao_code = self.render(pao_template_file, topmodule, ipname, masterlist, slavelist, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=default_ext_burstlength, single_clock=configs['single_clock'], hdlname=hdlname, ipcore_version=ipcore_version, mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) f = open(paopath + paoname, 'w') f.write(pao_code) f.close() # tcl file tcl_code = '' if not configs['single_clock']: tcl_code = open(TEMPLATE_DIR + 'pcore_tcl.tcl', 'r').read() f = open(tclpath + tclname, 'w') f.write(tcl_code) f.close() memorylist = [] for m in masterlist: memorylist.append( ipgen.utils.componentgen.AxiDefinition(m.name + '_AXI', m.datawidth, True, m.lite)) for s in slavelist: memorylist.append( ipgen.utils.componentgen.AxiDefinition(s.name + '_AXI', s.datawidth, False, s.lite)) # component.xml gen = ipgen.utils.componentgen.ComponentGen() xml_code = gen.generate(ipname, memorylist, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=default_ext_burstlength, ext_ports=ext_ports, ext_params=ext_params) f = open(xmlpath + xmlname, 'w') f.write(xml_code) f.close() # xdc xdc_code = '' if not configs['single_clock']: xdc_code = open(TEMPLATE_DIR + 'ipxact.xdc', 'r').read() f = open(xdcpath + xdcname, 'w') f.write(xdc_code) f.close() # bd bd_code = '' bd_code = open(TEMPLATE_DIR + 'bd.tcl', 'r').read() f = open(bdpath + bdname, 'w') f.write(bd_code) f.close() # xgui file xgui_template_file = 'xgui_tcl.txt' xgui_code = self.render(xgui_template_file, topmodule, ipname, masterlist, slavelist, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=default_ext_burstlength, single_clock=configs['single_clock'], hdlname=hdlname, ipcore_version=ipcore_version, mpd_ports=mpd_ports, mpd_parameters=mpd_parameters) f = open(xguipath + xguiname, 'w') f.write(xgui_code) f.close() # hdl file f = open(verilogpath + hdlname, 'w') f.write(code) f.close() # user test code usertestcode = None if usertest is not None: usertestcode = open(usertest, 'r').read() # test file test_template_file = 'test_ipgen_axi.txt' test_code = self.render( test_template_file, topmodule, ipname, masterlist, slavelist, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=default_ext_burstlength, single_clock=configs['single_clock'], use_acp=configs['use_acp'], hdlname=hdlname, memimg=copied_memimg, binfile=binfile, usertestcode=usertestcode, simaddrwidth=configs['sim_addrwidth'], clock_hperiod_userlogic=configs['hperiod_ulogic'], clock_hperiod_bus=configs['hperiod_bus'], ignore_protocol_error=ignore_protocol_error) f = open(testpath + testname, 'w') f.write(test_code) f.write(open(TEMPLATE_DIR + 'axi_master_fifo.v', 'r').read()) f.close() # memory image for test if memimg is not None: shutil.copyfile(os.path.expanduser(memimg), testpath + memname) # makefile file makefile_template_file = 'Makefile.txt' makefile_code = self.render(makefile_template_file, topmodule, ipname, masterlist, slavelist, def_top_parameters, def_top_localparams, def_top_ioports, name_top_ioports, ext_addrwidth=configs['ext_addrwidth'], ext_burstlength=default_ext_burstlength, single_clock=configs['single_clock'], testname=testname) f = open(makefilepath + makefilename, 'w') f.write(makefile_code) f.close()
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
# get the portlist # loop over all items with type InstanceList # print the cell ports and their corresponding arguments newrtl = [] inputlist = [] outputlist = [] clkgateArgs = [ vast.PortArg("GCLK", vast.Identifier("__clockgate_output_gclk_")), vast.PortArg("GATE", vast.Identifier("EN")), vast.PortArg("CLK", vast.Identifier("CLK")) ] clkgate_cell = vast.Instance("sky130_fd_sc_hd__dlclkp", "__clockgate_cell__", tuple(clkgateArgs), tuple()) clockgate_output_gclk = vast.Wire('__clockgate_output_gclk_') k = 0 insertedbefore = 0 newrtl.append(clockgate_output_gclk) for itemDeclaration in definition.items: item_type = type(itemDeclaration).__name__ if item_type == "InstanceList": instance = itemDeclaration.instances[0] if (instance.module == "sky130_fd_sc_hd__mux2_1"): if insertedbefore == 0: newrtl.append( vast.InstanceList("sky130_fd_sc_hd__dlclkp", tuple(), tuple([clkgate_cell]))) insertedbefore = 1 for hook in instance.portlist:
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)
def visit_Wire(self, node): name = node.name width = self.make_width(node) dims = self.make_dims(node) signed = node.signed return vast.Wire(name, width, signed, dims)