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 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 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 gen_lat(path): clk = vast.Ioport(vast.Input('en')) q = vast.Ioport(vast.Output('Q')) d = vast.Ioport(vast.Input('D')) r = vast.Ioport(vast.Input('rst')) ports = vast.Portlist([clk, q, d, r]) q_reg = vast.Identifier('reg Q = 0;') sens = [] sens.append(vast.Sens(vast.Identifier('en'), type='level')) sens.append(vast.Sens(vast.Identifier('rst'), type='level')) sens.append(vast.Sens(vast.Identifier('D'), type='level')) senslist = vast.SensList(sens) assign_q = vast.NonblockingSubstitution(vast.Lvalue(vast.Identifier('Q')), vast.Rvalue(vast.Identifier('D'))) blocks = [] blocks.append( vast.IfStatement( vast.Identifier('rst'), vast.Identifier('Q <= 0;'), vast.IfStatement(vast.Identifier('en'), assign_q, None), None)) statement = vast.Block(blocks) always = vast.Always(senslist, statement) items = [] items.append(q_reg) items.append(always) ast = vast.ModuleDef("lat", None, ports, items) write_verilog(ast, 'lat.v', path)
def ce_module_ext_formal(self): self.ce.portlist.ports.append( vast.Ioport(vast.Input('k1', width=self.key_width))) self.ce.portlist.ports.append( vast.Ioport(vast.Input('k2', width=self.key_width))) self.ce.items.append( vast.Identifier('assume property (@(clk) $stable(k1));')) self.ce.items.append( vast.Identifier('assume property (@(clk) $stable(k2));')) self.ce.items.append(vast.Identifier('reg [10:0] cycle;'))
def test(): 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) * 2 count_plus_1 = vast.Plus(vast.Identifier('count'), vast.IntConst('1')) cp1_times_2 = vast.Times(count_plus_1, vast.IntConst('2')) cp1t2_plus_1 = vast.Plus(cp1_times_2, vast.IntConst('1')) assign_count_false = vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier('count')), vast.Rvalue(cp1t2_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) assert(expected == rslt)
def umc_module(self, dip_list): # create umc module portslist = [] portslist.append(vast.Ioport(vast.Input('clk'))) portslist.append(vast.Ioport(vast.Input('iv', width=self.inp_width))) portslist = vast.Portlist(portslist) inst_list = [] # add instance for dip_generator dip_ports = [vast.PortArg("", vast.Identifier('clk'))] dip_ports.append(vast.PortArg("", vast.Identifier('iv'))) dip_ports.append(vast.PortArg("", vast.Identifier('k1'))) dip_ports.append(vast.PortArg("", vast.Identifier('k2'))) inst = vast.Instance('dip_generator', 'dg', dip_ports, "") inst_list.append(vast.InstanceList('dip_generator', "", [inst])) 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))) blocks = [] # 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)) statement = vast.Block([vast.Identifier(self.key_constraints)]) sens = vast.Sens(None, type='all') 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 initial 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) sens = vast.Sens(vast.Identifier('clk'), type='posedge') inst_list.append(vast.Always(vast.SensList([sens]), statement)) self.umc = vast.ModuleDef("umc", None, portslist, inst_list)
def uc_module_ext_formal(self, ): # create additional blocks for jaspergold self.uc.portlist.ports.append(vast.Ioport(vast.Input('clk'))) self.uc.portlist.ports.append( vast.Ioport(vast.Input('k1', width=self.key_width))) self.uc.portlist.ports.append( vast.Ioport(vast.Input('k2', width=self.key_width))) self.uc.items.append(vast.Identifier('reg [10:0] cycle;')) self.uc.items.append( vast.Identifier('assume property (@(clk) $stable(k1));')) self.uc.items.append( vast.Identifier('assume property (@(clk) $stable(k2));'))
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 visit_Inout(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)) signed = node.signed return vast.Ioport(vast.Inout(name, width, signed))
def visit_Output(self, node): name = node.name width = self.make_width(node) dims = self.make_dims(node) signed = node.signed first = vast.Output(name, width, signed, dims) second = vast.Reg(name, width, signed, dims) if self.module.is_reg(name) else None return vast.Ioport(first, second)
def visit_Output(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)) signed = node.signed first = vast.Output(name, width, signed) second = vast.Reg(name, width, signed) if self.module.is_reg(name) else None return vast.Ioport(first, second)
def gen_dff(path): clk = vast.Ioport(vast.Input('clk')) q = vast.Ioport(vast.Output('Q')) d = vast.Ioport(vast.Input('D')) ports = vast.Portlist([clk, q, d]) q_reg = vast.Identifier('reg Q = 0;') sens = vast.Sens(vast.Identifier('clk'), type='posedge') senslist = vast.SensList([sens]) assign_q = vast.NonblockingSubstitution(vast.Lvalue(vast.Identifier('Q')), vast.Rvalue(vast.Identifier('D'))) statement = vast.Block([assign_q]) always = vast.Always(senslist, statement) items = [] items.append(q_reg) items.append(always) ast = vast.ModuleDef("dff", None, ports, items) write_verilog(ast, 'dff.v', path)
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 fk_module_ext_sby(self): if self.enable_async: self.ce.items.append(vast.Identifier('reg clk = 0;')) self.ce.items.append(vast.Identifier('(* gclk *) reg gbl_clk;')) self.ce.items.append(vast.Identifier('always @(posedge gbl_clk)')) self.ce.items.append(vast.Identifier('clk =! clk;')) else: self.ce.portlist.ports.append(vast.Ioport(vast.Input('clk'))) self.ce.items.append(vast.Identifier('reg [10:0] cycle = 0;')) self.ce.items.append( vast.Identifier('(* anyconst *) wire [' + str(self.key_size_msb) + ':0] k1;')) self.ce.items.append( vast.Identifier('(* anyconst *) wire [' + str(self.key_size_msb) + ':0] k2;'))
def uc_module_ext_sby(self): # create additional blocks for symbiyosys if not self.enable_async: self.uc.portlist.ports.append(vast.Ioport(vast.Input('clk = 0'))) else: self.uc.items.append(vast.Identifier('reg clk = 0;')) self.uc.items.append(vast.Identifier('reg [10:0] cycle = 0;')) self.uc.items.append( vast.Identifier('(* anyconst *) wire [{}:0] k1;'.format( self.key_size_msb))) self.uc.items.append( vast.Identifier('(* anyconst *) wire [{}:0] k2;'.format( self.key_size_msb))) if self.enable_async: self.uc.items.append(vast.Identifier('(* gclk *) reg gbl_clk;')) self.uc.items.append(vast.Identifier('always @(posedge gbl_clk)')) self.uc.items.append(vast.Identifier('clk = !clk;')) self.uc.items.append(vast.Identifier('always @(posedge gbl_clk)')) self.uc.items.append(vast.Identifier('if (!$rose(clk))')) self.uc.items.append(vast.Identifier('assume($stable(iv));'))
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()
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)
def visit_Inout(self, node): name = node.name width = self.make_width(node) dims = self.make_dims(node) signed = node.signed return vast.Ioport(vast.Inout(name, width, signed, dims))
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 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 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 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])