예제 #1
0
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)
예제 #2
0
    def instantiate(self, instanceName, rank):
        inst = Instance(self.name, instanceName, self.portlist, self.paramlist)

        self.set_core_params(inst.parameterlist)

        for line in inst.portlist:
            if (line.argname.name != "wb_clk") & (line.argname.name != "wb_rst") & line.argname.name.startswith("wb"):
                if rank == "slave":
                    if line.argname.name.endswith("i"):
                        line.argname.name = "wb_m2s_{modul_name}_{port}".format(modul_name=self.name,
                                                                                port=line.argname.name[3:-2])
                    else:
                        line.argname.name = "wb_s2m_{modul_name}_{port}".format(modul_name=self.name,
                                                                                port=line.argname.name[3:-2])
                else:
                    if line.argname.name.endswith("o"):
                        line.argname.name = "wb_m2s_{modul_name}_{port}".format(modul_name=self.name,
                                                                                port=line.argname.name[3:-2])
                    else:
                        line.argname.name = "wb_s2m_{modul_name}_{port}".format(modul_name=self.name,
                                                                                port=line.argname.name[3:-2])
        # Call the code generator
        cg = ASTCodeGenerator()
        val = cg.visit(inst)
        val += "\n\n"
        print(rank)
        print(val)
        return val
예제 #3
0
파일: esta_flow.py 프로젝트: kmurray/esta
def fix_modelsim_altera_sdf_annotation(top_verilog):
    base, ext = os.path.splitext(top_verilog)
    new_file = '.'.join([base, "fixed"]) + ext;

    #
    #Load the original verilog
    #
    ast, directives = verilog_parser.parse([top_verilog])

    #
    #Add an unused stratixiv cell
    #
    mod_def = ast.description.definitions[0] #Definition of top

    new_inst = vast.Instance('stratixiv_io_ibuf', 'fix_modelsim_altera_sdf_annotation', [], []);
    new_inst_list = vast.InstanceList('stratixiv_io_ibuf', [], [new_inst])

    items = list(mod_def.items) + [new_inst_list]

    new_mod_def = vast.ModuleDef(mod_def.name, mod_def.paramlist, mod_def.portlist, items)

    #
    #Write out the new verilog
    #
    codegen = ASTCodeGenerator()
    with open(new_file, "w") as f:
        print >>f, codegen.visit(new_mod_def)

    return new_file
예제 #4
0
def read_verilog_stubmodule(*filelist, **opt):
    module_dict = to_module_dict(*filelist, **opt)
    codegen = ASTCodeGenerator()
    stubs = collections.OrderedDict()
    for name, m in module_dict.items():
        description = vast.Description((m,))
        source = vast.Source('', description)
        code = codegen.visit(source)
        stubs[name] = module.StubModule(name, code=code)
    return stubs
예제 #5
0
    def findParameters(self, node, lst):
        if isinstance(node, Parameter):
            var = node.value.var
            cg = ASTCodeGenerator()
            val = cg.visit(var)
            self.paramlist.append(ParamArg(Identifier(node.name), var))
            lst.append((node.name, val))
        for child in node.children():
            self.findParameters(child, lst)

        return lst
예제 #6
0
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)
예제 #7
0
def test_led():
    test_module = instance_noname_args.mkTop()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
예제 #8
0
def test_led():
    modules = led.mkThread()
    code = ''.join([ m.to_verilog() for m in modules.values() ])

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    test_module = submodule_read_verilog_nested.mkTop()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
예제 #10
0
def test_bram():
    bram_module = bram.mkTop()
    bram_code = bram_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == bram_code)
예제 #11
0
def test_led():
    led_module = led.mkLed()
    led_code = led_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == led_code)
def test():
    veriloggen.reset()
    test_module = from_verilog_module_oldstylecode.mkTop()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    veriloggen.reset()
    test_module = thread_call_from_different_point.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    veriloggen.reset()
    test_module = thread_intrinsic_method_prefix.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    veriloggen.reset()
    test_module = seq_delayed_eager_val_lazy_cond.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
예제 #16
0
def test():
    veriloggen.reset()
    test_module = regchain.mkRegChain(length=120)
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    veriloggen.reset()
    modules = from_verilog_pycoram_object.mkUserlogic()
    code = ''.join([ m.to_verilog() for m in modules.values() if not m.used ])

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    veriloggen.reset()
    test_module = pipeline_acc_add_valid.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
예제 #19
0
def test():
    veriloggen.reset()
    test_module = primitive_mux.mkLed()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    veriloggen.reset()
    test_module = dataflow_two_outputs_mul.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
예제 #21
0
def test_sort():
    sort_module = sort.mkSimSort()
    sort_code = sort_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator

    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert expected_code == sort_code
예제 #22
0
def test():
    veriloggen.reset()
    test_module = types_axi_read_lite.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
def test():
    veriloggen.reset()
    test_module = thread_multibank_ram_rtl_connect.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)
예제 #24
0
def write_verilog(node, filename=None):
    visitor = VerilogModuleVisitor()
    modules = tuple(get_modules(node).values())

    module_ast_list = [visitor.visit(module) for module in modules]
    description = vast.Description(module_ast_list)
    source = vast.Source(filename, description)

    codegen = ASTCodeGenerator()
    code = codegen.visit(source)
    if filename:
        with open(filename, "w") as f:
            f.write(code)
    return code
예제 #25
0
def main():
    from optparse import OptionParser
    INFO = "PyCoRAM RTL Converter"
    VERSION = utils.version.VERSION
    USAGE = "Usage: python rtlconverter.py -t TOPMODULE file ..."

    def showVersion():
        print(INFO)
        print(VERSION)
        print(USAGE)
        sys.exit()
    
    optparser = OptionParser()
    optparser.add_option("-v","--version",action="store_true",dest="showversion",
                         default=False,help="Show the version")
    optparser.add_option("-t","--top",dest="topmodule",
                         default="userlogic",help="Top module, Default=userlogic")
    optparser.add_option("-o","--output",dest="outputfile",
                         default="out.v",help="Output file name, Default=out.v")
    optparser.add_option("-I","--include",dest="include",action="append",
                         default=[],help="Include path")
    optparser.add_option("-D",dest="define",action="append",
                         default=[],help="Macro Definition")
    optparser.add_option("--singleclock",action="store_true",dest="single_clock",
                         default=False,help="Use single clock mode")
    (options, args) = optparser.parse_args()

    filelist = args
    if options.showversion:
        showVersion()

    for f in filelist:
        if not os.path.exists(f): raise IOError("file not found: " + f)

    if len(filelist) == 0:
        showVersion()

    converter = RtlConverter(filelist, options.topmodule,
                             include=options.include, 
                             define=options.define,
                             single_clock=options.single_clock)
    ast = converter.generate()
    converter.dumpCoramObject()
    
    asttocode = ASTCodeGenerator()
    code = asttocode.visit(ast)

    f = open(options.outputfile, 'w')
    f.write(code)
    f.close()
예제 #26
0
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.Lvalue(vast.Identifier('led')),
                           vast.Rvalue(vast.IntConst('8'))) ]
    ast = vast.ModuleDef("top", params, ports, items)
    
    codegen = ASTCodeGenerator()
    rslt = codegen.visit(ast)
    
    print(rslt)
    assert(expected == rslt)
def test():
    veriloggen.reset()
    test_module = simulation_simulator_iverilog.mkTest()
    code = test_module.to_verilog()

    from pyverilog.vparser.parser import VerilogParser
    from pyverilog.ast_code_generator.codegen import ASTCodeGenerator
    parser = VerilogParser()
    expected_ast = parser.parse(expected_verilog)
    codegen = ASTCodeGenerator()
    expected_code = codegen.visit(expected_ast)

    assert(expected_code == code)

    sim = simulation.Simulator(test_module, sim='iverilog')
    rslt = sim.run()
    
    assert(expected_rslt == rslt)
예제 #28
0
def main():
    INFO = "Verilog ast modificator parser"
    VERSION = version.VERSION
    USAGE = "Usage: python parser.py file ..."

    def showVersion():
        print(INFO)
        print(VERSION)
        print(USAGE)
        sys.exit()

    optparser = OptionParser()
    optparser.add_option(
        "-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version"
    )
    optparser.add_option("-o", "--output", dest="outputfile", default="out.v", help="Output File name, Default=out.v")
    optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path")
    (options, args) = optparser.parse_args()

    filelist = args
    if options.showversion:
        showVersion()

    for f in filelist:
        if not os.path.exists(f):
            raise IOError("file not found: " + f)

    if len(filelist) == 0:
        showVersion()

    codeparser = VerilogCodeParser(filelist, preprocess_include=options.include)
    ast = codeparser.parse()
    directives = codeparser.get_directives()

    inserter = DriveInserter("DRIVE")

    rslt = inserter.generate(ast)

    asttocode = ASTCodeGenerator()
    code = asttocode.visit(rslt)

    f = open(options.outputfile, "w")
    f.write(code)
    f.close()
예제 #29
0
def write_verilog(node, filename=None, for_verilator=False):
    visitor = VerilogModuleVisitor(for_verilator)
    modules = tuple(node.get_modules().values())

    module_ast_list = [visitor.visit(mod) for mod in modules
                       if not isinstance(mod, module.StubModule)]
    description = vast.Description(module_ast_list)
    source = vast.Source(filename, description)

    codegen = ASTCodeGenerator()
    main = codegen.visit(source)

    stub = [mod.get_code()
            for mod in modules if isinstance(mod, module.StubModule)]

    code = ''.join([main] + stub)

    if filename:
        with open(filename, 'w') as f:
            f.write(code)
    return code
예제 #30
0
def main():
    INFO = "Code converter from AST"
    VERSION = pyverilog.utils.version.VERSION
    USAGE = "Usage: python example_codegen.py file ..."

    def showVersion():
        print(INFO)
        print(VERSION)
        print(USAGE)
        sys.exit()
    
    optparser = OptionParser()
    optparser.add_option("-v","--version",action="store_true",dest="showversion",
                         default=False,help="Show the version")
    optparser.add_option("-I","--include",dest="include",action="append",
                         default=[],help="Include path")
    optparser.add_option("-D",dest="define",action="append",
                         default=[],help="Macro Definition")
    (options, args) = optparser.parse_args()

    filelist = args
    if options.showversion:
        showVersion()

    for f in filelist:
        if not os.path.exists(f): raise IOError("file not found: " + f)

    if len(filelist) == 0:
        showVersion()

    codeparser = VerilogCodeParser(filelist,
                                   preprocess_include=options.include,
                                   preprocess_define=options.define)

    ast = codeparser.parse()
    directives = codeparser.get_directives()

    codegen = ASTCodeGenerator()
    rslt = codegen.visit(ast)
    print(rslt)
예제 #31
0
                newrtl.append(
                    vast.InstanceList("sky130_fd_sc_hd__dlclkp", tuple(),
                                      tuple([clkgate_cell])))
                insertedbefore = 1
            for hook in instance.portlist:
                if hook.portname == "A1":  #input
                    inputlist.append(hook.argname)
                if hook.portname == "A0":  #output
                    outputlist.append(hook.argname)
            continue
        print("cell-name: ", instance.module, "instance-name: ", instance.name)
        for hook in instance.portlist:
            if hook.portname == "CLK":
                print("change to clk input which is __clockgate_output_gclk_",
                      hook.argname)
                hook.argname = vast.Identifier('__clockgate_output_gclk_')
            if hook.portname == "D":
                hook.argname = inputlist[k]
            if hook.portname == "Q":
                hook.argname = outputlist[k]
        k = k + 1
        print("portname: ", hook.portname, "argname: ", hook.portname)
    newrtl.append(itemDeclaration)

definition.items = tuple(newrtl)
codegen = ASTCodeGenerator()
rslt = codegen.visit(ast)
f = open("testUpdated.v", "w+")
f.write(rslt)
f.close()
예제 #32
0
    def build_package_axi(self, configs, synthesized_code, common_code,
                          threads, top_parameters, top_ioports,
                          userlogic_topmodule, 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 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))

        # 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 = pycoram.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()
예제 #33
0
    def build_package_avalon(self, configs, synthesized_code, common_code,
                             threads, top_parameters, top_ioports,
                             userlogic_topmodule, 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()
예제 #34
0
def main():
    INFO = "Verilog identifier renamer"
    USAGE = "Usage: python3 amnesia.py file ..."

    keeplist = ["clk", "reset", "inData", "outData"]

    def showUsage():
        print(INFO)
        print(USAGE)
        sys.exit()

    optparser = OptionParser()
    optparser.add_option("-I",
                         "--include",
                         dest="include",
                         action="append",
                         default=[],
                         help="Include path")
    optparser.add_option("-D",
                         dest="define",
                         action="append",
                         default=[],
                         help="Macro Definition")
    optparser.add_option("-x",
                         dest="exclude",
                         action="append",
                         default=keeplist,
                         help="Identifiers to exclude from obfuscation")
    (options, args) = optparser.parse_args()

    filelist = args

    for f in filelist:
        if not os.path.exists(f): raise IOError("file not found: " + f)

    if len(filelist) == 0:
        showUsage()

    ast, directives = parse(filelist,
                            preprocess_include=options.include,
                            preprocess_define=options.define)

    #ast.show()
    # getIdentifiers is a list of all identifiers, including repeats.
    # ths i:i thing changes it on the fly into a dictionary,
    # as a way of doing "sort | uniq," basically.
    ids = {i: i for i in getIdentifiers(ast)}

    # now build our from:to mapping for all of those identifiers.
    for orig_id in ids:
        if orig_id in options.exclude:
            ids[orig_id] = orig_id
        else:
            ids[orig_id] = stringGarbage(32)

    ## PyVerilog comes with a function called "replaceIdentifiers" that should
    ## do this, but it doesn't get everything.  Ours will chomp on anything
    ## what has a name.
    AST_traverse_rename_identifiers(ast, ids)

    codegen = ASTCodeGenerator()
    rslt = codegen.visit(ast)  ## AST back to Verilog
    print(rslt)
예제 #35
0
class TopRTLParser:

    fifo_dout_format = '([^ ]*[^_])_+dout'
    fifo_din_format = '([^ ]*[^_])_+din'

    def __init__(self, top_rtl_path):
        self.top_rtl_path = top_rtl_path
        self.top_module_ast, directives = rtl_parse([top_rtl_path])
        self.__checker()

        self.mod_to_fifo_in = defaultdict(list)
        self.mod_to_fifo_out = defaultdict(list)

        self.wire_to_fifo_name = {}  # str -> str
        self.fifo_name_to_wires = defaultdict(list)  # fifo -> interface wires
        self.fifo_name_to_outbound_wires = defaultdict(list)
        self.fifo_name_to_inbound_wires = defaultdict(list)
        self.wire_to_v_name = {}  # str -> str
        self.v_name_to_wires = defaultdict(list)  # vertex -> interface wires
        self.inst_name_to_rtl = {}
        self.reg_wire_name_to_width = {
        }  # from name to full declaration (with width, etc)
        self.io_name_to_width = {}
        self.io_name_to_dir = {}
        self.all_decl_except_io = []
        self.codegen = ASTCodeGenerator()
        self.ap_done_v_name_to_wire = {}  # ap_done module name -> wire name
        self.ap_ready_v_name_to_wire = {}
        self.param_to_value_str = {}
        self.e_name_to_ast_node = {}

        self.__initWireToFIFOMapping()
        self.__initWireToVertexMapping()
        self.__initFIFOListOfModuleInst()
        self.__initRTLOfAllInsts()
        self.__initParamToValueStr()
        self.__initDeclList()
        self.__initApDoneSources()
        self.__initApReadySources()

        # for mod, ap_done in self.ap_done_v_name_to_wire.items():
        #   print(f'{ap_done} -> {mod}')

    # 1. no start_for FIFOs
    # 2. each inst has different name
    def __checker(self):
        for node in self.__DFS(self.top_module_ast,
                               lambda node: isinstance(node, ast.Instance)):
            assert 'start_for' not in node.name, f'Found start FIFOs: {self.top_rtl_path} : {node.name}'

        names = set()
        for node in self.__DFS(self.top_module_ast,
                               lambda node: isinstance(node, ast.Instance)):
            if node.name not in names:
                names.add(node.name)
            else:
                assert False, f'Found duplicated name for instance {node.name}'

    def __DFS(self, node, filter_func):
        if filter_func(node):
            try:
                logging.debug(f'visit node {node.name}')
            except:
                pass
                # logging.debug(f'node in line {node.lineno} has no name')
            yield node
        for c in node.children():
            yield from self.__DFS(c, filter_func)

    def __initRTLOfAllInsts(self):
        for v_inst_list in self.__DFS(self.top_module_ast,
                                      self.__isVertexInstanceList):
            assert len(
                v_inst_list.instances
            ) == 1, f'unsupported RTL coding style at line {v_inst_list.lineno}'
            v_node = v_inst_list.instances[0]
            self.inst_name_to_rtl[v_node.name] = self.codegen.visit(
                v_inst_list)

        for e_inst_list in self.__DFS(self.top_module_ast,
                                      self.__isEdgeInstanceList):
            assert len(
                e_inst_list.instances
            ) == 1, f'unsupported RTL coding style at line {e_inst_list.lineno}'
            e_node = e_inst_list.instances[0]
            self.inst_name_to_rtl[e_node.name] = self.codegen.visit(
                e_inst_list)
            self.e_name_to_ast_node[e_node.name] = e_inst_list

    # get mapping from reg/wire/io name to width/direction
    def __initDeclList(self):
        # replace the parameters in
        def replaceParamByValue(width: str):
            tokens = re.findall(r'[A-Za-z0-9_]+', width)
            while any(t in self.param_to_value_str for t in tokens):
                for t in tokens:
                    if t in self.param_to_value_str:
                        width = width.replace(t, self.param_to_value_str[t])
                        logging.debug(
                            f'replace {t} by {self.param_to_value_str[t]}')
                tokens = re.findall(r'[A-Za-z0-9_]+', width)
            return width.replace(
                ' ', ''
            )  # must remove the spaces because later steps will partition expressions based on space

        # get a copy of all delcaration
        for decl_node in self.__DFS(self.top_module_ast,
                                    lambda node: isinstance(node, ast.Decl)):
            assert len(decl_node.children()) == 1
            content = decl_node.children()[0]
            name = content.name

            if not isinstance(content, ast.Input) and not isinstance(
                    content, ast.Output):
                self.all_decl_except_io.append(self.codegen.visit(decl_node))

        # initialize various mappings
        for decl_node in self.__DFS(self.top_module_ast,
                                    lambda node: isinstance(node, ast.Decl)):
            assert len(decl_node.children()) == 1
            content = decl_node.children()[0]
            name = content.name

            # filter out ast.Parameter
            if isinstance(content, ast.Parameter):
                continue

            width_node = content.width
            if width_node:
                width = self.codegen.visit(width_node)
                width = replaceParamByValue(width)
            else:
                width = ''

            if isinstance(content, ast.Input):
                self.io_name_to_dir[name] = 'input'
                self.io_name_to_width[name] = width

            elif isinstance(content, ast.Output):
                self.io_name_to_dir[name] = 'output'
                self.io_name_to_width[name] = width

            elif isinstance(content, ast.Wire) or isinstance(content, ast.Reg):
                self.reg_wire_name_to_width[name] = width

            else:
                logging.debug(
                    f'unrecorded Decl statement: {name} @ line {decl_node.lineno}'
                )

    def __initParamToValueStr(self):
        for decl_node in self.__DFS(self.top_module_ast,
                                    lambda node: isinstance(node, ast.Decl)):
            assert len(decl_node.children()) == 1
            content = decl_node.children()[0]

            if isinstance(content, ast.Parameter):
                self.param_to_value_str[content.name] = self.codegen.visit(
                    content.value)

    def __initFIFOListOfModuleInst(self):
        for v_node in self.traverseVertexInAST():
            for portarg in v_node.portlist:
                # filter out constant ports
                if (not isinstance(portarg.argname, ast.Identifier)):
                    continue

                port_name = portarg.portname
                wire_name = portarg.argname.name

                # each fifo xxx -> xxx_din & xxx_dout, each maps to a vertex
                # note that 'dout' is the output side of FIFO, thus the input side for the vertex
                if '_dout' in port_name:
                    assert '_dout' in wire_name
                    fifo_name = self.wire_to_fifo_name[wire_name]
                    self.mod_to_fifo_in[v_node.name].append(fifo_name)

                elif '_din' in port_name:
                    assert '_din' in wire_name
                    fifo_name = self.wire_to_fifo_name[wire_name]
                    self.mod_to_fifo_out[v_node.name].append(fifo_name)

                else:
                    continue

    def __initWireToFIFOMapping(self):
        outbound_tags = ['_read', '_dout', '_empty_n']
        inbound_tags = ['_write', '_din', '_full_n']
        ctrl_tags = ['clk', 'rst', 'reset']

        for e_node in self.traverseEdgeInAST():
            for portarg in e_node.portlist:
                # filter constant ports
                if (not isinstance(portarg.argname, ast.Identifier)):
                    continue

                port_name = portarg.portname
                wire_name = portarg.argname.name
                self.wire_to_fifo_name[wire_name] = e_node.name
                self.fifo_name_to_wires[e_node.name].append(
                    (port_name, wire_name))

                if any(o_tag in port_name for o_tag in outbound_tags):
                    self.fifo_name_to_outbound_wires[e_node.name].append(
                        wire_name)
                elif any(i_tag in port_name for i_tag in inbound_tags):
                    self.fifo_name_to_inbound_wires[e_node.name].append(
                        wire_name)
                else:
                    assert any(c_tag in port_name for c_tag in ctrl_tags)

    def __initWireToVertexMapping(self):
        for v_node in self.traverseVertexInAST():
            for portarg in v_node.portlist:
                # filter constant ports
                if (not isinstance(portarg.argname, ast.Identifier)):
                    continue

                wire_name = portarg.argname.name
                self.wire_to_v_name[wire_name] = v_node.name
                self.v_name_to_wires[v_node.name].append(wire_name)

    # only some modules will be used to check if the whole design has finished
    # we only collect the ap_done names of those modules
    def __initApDoneSources(self):
        f = open(self.top_rtl_path, 'r')
        for line in f:
            if re.search(r'assign[ ]*ap_sync_done', line):
                line = re.sub(r'assign[ ]*ap_sync_done[ ]*=[ ]*', '', line)
                line = re.sub(r'[() ;\n]', '', line)
                ap_dones = line.split('&')
                assert len(ap_dones)
                self.ap_done_v_name_to_wire = {
                    self.wire_to_v_name[ap_done]: ap_done
                    for ap_done in ap_dones
                }
                return
        assert False, 'ap_done signal in unexpected format'

    # extract which ap_ready signals will be used for the final ap_ready signal
    # [FIXME] some situations cannot be handled yet (multiple levels of intermediate wires)
    def __initApReadySources(self):
        f = open(self.top_rtl_path, 'r')

        # case 1: assign ap_ready = xxx & xxx ...
        for line in f:
            if re.search(r'assign[ ]*ap_ready', line):
                line = re.sub(r'assign[ ]*ap_ready[ ]*=[ ]*', '', line)
                line = re.sub(r'[() ;\n]', '', line)
                ap_readies = line.split('&')
                assert len(ap_readies)

                if len(ap_readies) == 1 and ap_readies[0] == 'ap_sync_ready':
                    break

                self.ap_ready_v_name_to_wire = {
                    self.wire_to_v_name[ap_ready]: ap_ready
                    for ap_ready in ap_readies
                }
                return

        # case 2: assign ap_ready = ap_sync_ready;
        f.seek(0)
        for line in f:
            if re.search(r'assign[ ]*ap_sync_ready', line):
                line = re.sub(r'assign[ ]*ap_sync_ready[ ]*=[ ]*', '', line)
                line = re.sub(r'[() ;\n]', '', line)
                ap_readies = line.split('&')
                assert len(ap_readies)

                try:
                    self.ap_ready_v_name_to_wire = {
                        self.wire_to_v_name[ap_ready]: ap_ready
                        for ap_ready in ap_readies
                    }
                except:
                    logging.critical('failed in parsing ap_ready signals')
                return

        assert False, 'ap_ready signal in unexpected format'

    def __isVertexNode(self, node):
        return isinstance(node, ast.Instance) and 'fifo' not in node.module

    def __isEdgeNode(self, node):
        return isinstance(node, ast.Instance) and 'fifo' in node.module

    def __isVertexInstanceList(self, node):
        return isinstance(node, ast.InstanceList) and 'fifo' not in node.module

    def __isEdgeInstanceList(self, node):
        return isinstance(node, ast.InstanceList) and 'fifo' in node.module

    #                                                 #
    # ---------------- Public Methods --------------- #
    #                                                 #

    def traverseVertexInAST(self):
        yield from self.__DFS(self.top_module_ast, self.__isVertexNode)

    def traverseEdgeInAST(self):
        yield from self.__DFS(self.top_module_ast, self.__isEdgeNode)

    # get the interface wires of vertex or edges
    def getWiresOfFIFOName(self, inst_name) -> list:
        return self.fifo_name_to_wires[inst_name]

    def getOutboundSideWiresOfFIFOName(self, fifo_name):
        return self.fifo_name_to_outbound_wires[fifo_name]

    def getInboundSideWiresOfFIFOName(self, fifo_name):
        return self.fifo_name_to_inbound_wires[fifo_name]

    def getWiresOfVertexName(self, v_name) -> list:
        return self.v_name_to_wires[v_name]

    def getWidthOfRegOrWire(self, name):
        width = self.reg_wire_name_to_width[name]
        assert ' ' not in width, 'Spaces in width express will result in error in getSlotNameToIOList()'
        return width

    def getIntegerWidthOfRegOrWire(self, name):
        width = self.reg_wire_name_to_width[name]
        if not width:
            return 1
        else:
            match = re.search(r'\[(\d+):', width).group(1)
            assert match
            return int(match) + 1

    def getRTLOfInst(self, inst_name: str):
        return self.inst_name_to_rtl[inst_name]

    # transform the default FIFO used by HLS to our unified template
    def getFIFOInstOfNewTemplate(self, e_name: str, e_width: int, e_depth: int,
                                 pipeline_level: int):
        e_inst_list = self.e_name_to_ast_node[e_name]

        # use our FIFO template
        e_inst_list.module = 'fifo_almost_full'

        param_width = ast.ParamArg('DATA_WIDTH',
                                   ast.Rvalue(ast.IntConst(str(e_width))))
        param_depth = ast.ParamArg('DEPTH',
                                   ast.Rvalue(ast.IntConst(str(e_depth))))

        addr_bitwidth = int(math.log2(e_width) + 1)
        param_addr_width = ast.ParamArg(
            'ADDR_WIDTH', ast.Rvalue(ast.IntConst(str(addr_bitwidth))))

        # pipeline_level equals the required grace period
        param_grace_period = ast.ParamArg(
            'GRACE_PERIOD', ast.Rvalue(ast.IntConst(str(pipeline_level))))

        params = [
            param_width, param_depth, param_addr_width, param_grace_period
        ]
        e_inst_list.parameterlist = params

        for c in e_inst_list.instances:  # should only has 1 instance
            c.module = e_inst_list.module
            c.parameterlist = params

        return self.codegen.visit(e_inst_list)

    def getWidthOfIO(self, io_name):
        return self.io_name_to_width[io_name]

    def getAllDeclExceptIO(self):
        return self.all_decl_except_io

    def isIO(self, io_name):
        return io_name in self.io_name_to_width

    def getDirOfIO(self, io_name):
        return self.io_name_to_dir[io_name]

    def getDirWidthNameOfAllIO(self):
        return [(self.io_name_to_dir[name], width, name)
                for name, width in self.io_name_to_width.items()]

    def getInFIFOsOfModuleInst(self, inst_name):
        return self.mod_to_fifo_in[inst_name]

    def getOutFIFOsOfModuleInst(self, inst_name):
        return self.mod_to_fifo_out[inst_name]

    # fifo_w32_d2_A xxx -> 32
    def getFIFOWidthFromFIFOType(self, fifo_type):
        match = re.search(r'_w(\d+)_d(\d+)_', fifo_type)
        assert match, f'wrong FIFO instance name: {fifo_type}'
        return int(match.group(1))  # group 111111

    # fifo_w32_d2_A xxx -> 2
    def getFIFODepthFromFIFOType(self, fifo_type):
        match = re.search(r'_w(\d+)_d(\d+)_', fifo_type)
        assert match, f'wrong FIFO instance name: {fifo_type}'
        return int(match.group(2))  # group 222222

    def getFIFONameFromInstanceList(self, node):
        assert (len(node.instances) == 1)
        return node.instances[0].name

    # only contains the ap_done signals that are part of the final ap_done
    def getApDoneVNameToWire(self):
        return self.ap_done_v_name_to_wire

    # only contains the ap_ready signals that are part of the final ap_ready
    def getApReadyVNameToWire(self):
        return self.ap_ready_v_name_to_wire

    def getParamValueStr(self, param_name):
        return self.param_to_value_str[param_name]

    def getParamToValueStr(self):
        return self.param_to_value_str

    def getFIFONameFromWire(self, wire):
        return self.wire_to_fifo_name[wire]
예제 #36
0
    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("----------------------------------------")
        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, memimg, usertest)
            return

        if configs['if_type'] == 'avalon':
            self.build_package_avalon(configs, synthesized_code, common_code,
                                      threads, top_parameters, top_ioports,
                                      userlogic_topmodule, memimg, usertest)
            return

        raise ValueError("Interface type '%s' is not supported." %
                         configs['if_type'])
예제 #37
0
def save_ast(ast, filename):
    cg = ASTCodeGenerator()
    with open(filename, "w") as f:
        f.write(cg.visit(ast))
예제 #38
0
def main():
    from optparse import OptionParser
    INFO = "RTL Converter with Pyverilog"
    VERSION = utils.version.VERSION
    USAGE = "Usage: python rtlconverter.py -t TOPMODULE file ..."

    def showVersion():
        print(INFO)
        print(VERSION)
        print(USAGE)
        sys.exit()

    optparser = OptionParser()
    optparser.add_option("-v",
                         "--version",
                         action="store_true",
                         dest="showversion",
                         default=False,
                         help="Show the version")
    optparser.add_option("-t",
                         "--top",
                         dest="topmodule",
                         default="userlogic",
                         help="Top module, Default=userlogic")
    optparser.add_option("-o",
                         "--output",
                         dest="outputfile",
                         default="out.v",
                         help="Output file name, Default=out.v")
    optparser.add_option("-I",
                         "--include",
                         dest="include",
                         action="append",
                         default=[],
                         help="Include path")
    optparser.add_option("-D",
                         dest="define",
                         action="append",
                         default=[],
                         help="Macro Definition")
    (options, args) = optparser.parse_args()

    filelist = args
    if options.showversion:
        showVersion()

    for f in filelist:
        if not os.path.exists(f): raise IOError("file not found: " + f)

    if len(filelist) == 0:
        showVersion()

    converter = RtlConverter(filelist,
                             options.topmodule,
                             include=options.include,
                             define=options.define)
    ast = converter.generate()
    converter.dumpTargetObject()

    asttocode = ASTCodeGenerator()
    code = asttocode.visit(ast)

    f = open(options.outputfile, 'w')
    f.write(code)
    f.close()