Beispiel #1
0
def default_gen():
    from rtl import config

    try:
        opts, args = getopt.getopt(sys.argv[1:], "n", [
            "hdl=", "name=", "extended", "bram_base=", "path=",
            "bram_adr_width="
        ])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        sys.exit(2)

    name_overide = ""
    hdl = "VHDL"
    extended = False
    bram_base = 0x0
    bram_adr_width = 12
    gen_path = "vhdl_gen"

    for o, a in opts:
        print(o, a)
        if o in ("-n", "--name"):
            name_overide = a

        elif o == "--hdl":
            hdl = a
        elif o == "--bram_base":
            bram_base = int(a, 0)
        elif o == "--bram_adr_width":
            bram_adr_width = int(a, 0)
        elif o == "--extended":
            extended = True
        elif o == "--path":
            gen_path = a

    if not extended:
        config = config.BonfireConfig()
        if name_overide:
            n = name_overide
        else:
            n = "bonfire_core_top"
        gen_core(config, hdl, n, path)
    else:
        config = config.BonfireConfig()
        if name_overide:
            n = name_overide
        else:
            n = "bonfire_core_extended_top"

        gen_extended_core(config,
                          hdl,
                          n,
                          gen_path,
                          bram_adr_base=bram_base,
                          bramAdrWidth=bram_adr_width)
Beispiel #2
0
def tb(config=config.BonfireConfig(), hexFile="", elfFile="", sigFile=""):

    clock = Signal(bool(0))
    reset = ResetSignal(0, active=1, isasync=False)

    dbus = bonfire_interfaces.DbusBundle(config)
    wb_master = bonfire_interfaces.Wishbone_master_bundle()
    wb_bfm = Wishbone_bfm()

    clk_driver = ClkDriver(clock, period=10)

    bram_port_a = ram_dp.RamPort32(readOnly=True)
    bram_port_b = ram_dp.RamPort32()

    soc_i = bonfire_core_ex.bonfireCoreExtendedInterface(wb_master,
                                                         dbus,
                                                         bram_port_a,
                                                         bram_port_b,
                                                         clock,
                                                         reset,
                                                         config=config)

    ram = ram_dp.DualportedRam(hexFile)
    ram_i = ram.ram_instance(bram_port_a, bram_port_b, clock)

    mon_i = monitor_instance(ram.ram,
                             dbus,
                             clock,
                             sigFile=sigFile,
                             elfFile=elfFile)
    bfm_i = wb_bfm.Wishbone_check(wb_master, clock, reset)

    return instances()
Beispiel #3
0
def fusesoc_gen():
    import os
    import yaml
    from rtl import config

    CORE_TEMPLATE = """CAPI=2:
name: {vlnv}

filesets:
    rtl:
        file_type: {filetype}
        files: [ {files} ]
targets:
    default:
        filesets: [ rtl ]

"""

    print(sys.argv[1])
    try:
        with open(sys.argv[1], mode='r') as f:
            p = yaml.load(f, Loader=yaml.Loader)
            print(yaml.dump(p))
            files_root = p["files_root"]
            parameters = p["parameters"]
            print("Generating into: {}".format(os.getcwd()))

            hdl = get(parameters, "language", "VHDL")
            name = get(parameters, "entity_name", "bonfire_core_top")
            vlnv = p["vlnv"]
            os.system("rm -f *.vhd *.v *.core")

            extended = True
            bram_base = get(parameters, "bram_base", 0x0)
            bram_adr_width = get(parameters, "bram_adr_width", 12)
            conversion_warnings = get(parameters, "conversion_warnings",
                                      "default")
            gen_path = os.getcwd()
            config = config.BonfireConfig()
            gen_extended_core(config,
                              hdl,
                              name,
                              gen_path,
                              bram_adr_base=bram_base,
                              bramAdrWidth=bram_adr_width,
                              handleWarnings=conversion_warnings)

            filelist = ["pck_myhdl_011.vhd", name + ".vhd"]
            with open(name + ".core", "w") as corefile:
                corefile.write(
                    CORE_TEMPLATE.format(vlnv=vlnv,
                                         filetype="vhdlSource-2008",
                                         files=",".join(filelist)))

        return True
    except FileNotFoundError as err:
        return False
def pipeline_integration_tests():
    print('Testing SimplePipeline with comb shifter')
    conf=config.BonfireConfig()
    conf.shifter_mode="comb"
    test(tb_simple_pipeline.tb(config=conf),trace=False,filename="tb_simple_pipeline_comb_shift")


    print('Testing SimplePipeline with staged shifter')
    test(tb_simple_pipeline.tb(test_conversion=False),trace=False,filename="tb_simple_pipeline")

    print('Testing Fetch unit')
    test(tb_fetch.tb(test_conversion=False),trace=False,filename="tb_fetch")
def loadstore_unit_tests():    
    print('Testing Loadstore')
    conf=config.BonfireConfig()
    # Waveform tracing test variant
    conf.loadstore_outstanding=1
    conf.registered_read_stage=False
    test(tb_loadstore.tb(config=conf,test_conversion=False),trace=False,filename="tb_loadstore")

    # Other variants
    for i in range(1,3):
        conf.loadstore_outstanding=i
        test(tb_loadstore.tb(config=conf,test_conversion=False),trace=False)

    conf.registered_read_stage=True
    for i in range(1,4):
        conf.loadstore_outstanding=i
        test(tb_loadstore.tb(config=conf,test_conversion=False),trace=False)
def bonfireCoreExtendedInterface(wb_master,db_master,bram_a,bram_b,clock,reset,
                                 config=config.BonfireConfig(),
                                 wb_mask=AdrMask(32,28,0x2),
                                 db_mask=AdrMask(32,28,0x1),
                                 bram_mask=AdrMask(32,28,0)):
    """
    wb_master: Wishbone_master_bundle mapped at address 0x02000000
    db_master: DbusBundle mapped at address 0x100000000
    bram_a: Instruction RamPort32, should be read only, mapped at address 0
    bram_b: Data RamPort32 mapped at address 0
    clock : cpu clock
    reset : reset signal
    wb_mask : Address mask for Wishbone interface 
    db_mask : Address mask for native data bus interface 
    bram_mask : Address mask for Block RAM
    """

    ibus = bonfire_interfaces.DbusBundle(config,readOnly=True)
    dbus = bonfire_interfaces.DbusBundle(config)
    control = bonfire_interfaces.ControlBundle(config)
    debug = bonfire_interfaces.DebugOutputBundle(config)

    db_master_bram = bonfire_interfaces.DbusBundle(config) # Block RAM 
    db_master_wb = bonfire_interfaces.DbusBundle(config) # Wishbone DBUS
    
    ic_class= DbusInterConnects()
    ic = DbusInterConnects.Master3Slaves(dbus,db_master_bram,db_master_wb,db_master,clock,reset,
         bram_mask,wb_mask,db_mask)


    core=bonfire_core_top.BonfireCoreTop(config)
    core_i = core.createInstance(ibus,dbus,control,clock,reset,debug,config)

    wb_i = bonfire_interfaces.DbusToWishbone(db_master_wb,wb_master,clock,reset)

    p_a = dbusToRamPort(ibus,bram_a,clock,readOnly=True)
    p_b = dbusToRamPort(db_master_bram,bram_b,clock,readOnly=False)

    
    return instances()
Beispiel #7
0
def tb(config=config.BonfireConfig(), test_conversion=False):
    clock = Signal(bool(0))
    reset = ResetSignal(0, active=1, isasync=False)
    cmd_index = Signal(intbv(0)[32:])

    debug = DebugOutputBundle(config)
    out = BackendOutputBundle()
    datatbus = loadstore.DbusBundle(config=config)

    backend = SimpleBackend(config=config)
    fetch = FetchInputBundle(config=config)
    frontend = dummy_fetch_unit()
    fu_i = frontend.createInstance(fetch, clock, reset)

    clk_driver = ClkDriver(clock)
    dut = backend.backend(fetch, frontend, datatbus, clock, reset, out, debug)

    if test_conversion:
        dut.convert(hdl='VHDL',
                    std_logic_ports=False,
                    path='vhdl_gen',
                    name="backend")

    # Simulated Data RAM

    mem = sim_ram()
    mem_i = mem.ram_interface(ram, datatbus, clock, reset)

    @always_comb
    def tb_comb():
        result_o.next = debug.result_o
        rd_o.next = debug.rd_adr_o
        we_o.next = debug.reg_we_o
        jump_o.next = backend.execute.jump_o
        jump_dest_o.next = backend.execute.jump_dest_o
        take_branch.next = debug.jump and debug.jump_exec

    def check(cmd):
        t = cmd["t"]
        if type(t) == types.FunctionType:
            if t():
                print("OK")
            else:
                print("FAIL")
                assert StopSimulation
        print("----")

    @always_seq(clock.posedge, reset=reset)
    def commit_check():

        if cmd_index >= len(commands):
            print("Simulation finished")
            raise StopSimulation

        if debug.valid_o:

            cmd = commands[cmd_index]
            if we_o:
                print("at {}ns {}:  commmit to reg {} value {}".format(
                    now(), cmd["source"], abi_name(rd_o), result_o))
            else:
                print("at {}ns {}:  commmit without reg write".format(
                    now(), cmd["source"]))
            check(cmd)

            cmd_index.next = cmd_index + 1

        if debug.jump_exec:
            cmd = commands[cmd_index]
            print("at {}ns: {}, do: {}".format(now(), cmd["source"],
                                               debug.jump))
            check(cmd)
            # In case of a not taken branch increment command counter now, because there will be no jump_o signal
            if not debug.jump:
                cmd_index.next = cmd_index + 1

        if jump_o:
            cmd = commands[cmd_index]
            print("at {}ns: {}, destination: {}".format(
                now(), cmd["source"], jump_dest_o))
            check(cmd)

    return instances()
 def __init__(self, config=config.BonfireConfig()):
     self.config = config
     self.fetch = FetchUnit(config=config)
     self.backend_fetch_input = FetchInputBundle(config=config)
     self.backend_fetch_output = BackendOutputBundle(config=config)
     self.backend = SimpleBackend(config=config)
def tb(config=config.BonfireConfig(),test_conversion=False):
    clock=Signal(bool(0))
    reset = ResetSignal(1, active=1, isasync=False)

   
    ibus = DbusBundle(config=config,readOnly=True) 
    debug=DebugOutputBundle(config)
    out = BackendOutputBundle()
    dbus = DbusBundle(config=config) 
    fetch_bundle = FetchInputBundle(config=config)
   
    fetch_unit = FetchUnit(config=config)
    backend = SimpleBackend(config=config)
    

    clk_driver= ClkDriver(clock)
   
    dut=fetch_unit.SimpleFetchUnit(fetch_bundle,ibus,clock,reset)

    if test_conversion:
        dut.convert(hdl='VHDL',std_logic_ports=False,path='vhdl_gen', name="fetch" )


    # processor Backend
    i_backend = backend.backend(fetch_bundle,fetch_unit,dbus,clock,reset,out,debug)

    # Simulated Code RAM 
   
    c_mem = sim_ram()
    c_mem.setLatency(1)
    c_mem_i = c_mem.ram_interface(code_ram,ibus,clock,reset,readOnly=True)

    # Simulated Data RAM
    d_mem = sim_ram()
    d_mem.setLatency(1)
    d_mem_i = d_mem.ram_interface(data_ram,dbus,clock,reset)

    
    @always_comb
    def comb():
        fetch_unit.jump_dest_i.next=out.jump_dest_o
        fetch_unit.jump_i.next = out.jump_o
        fetch_unit.stall_i.next = out.busy_o

        result_o.next =debug.result_o
        rd_o.next = debug.rd_adr_o
        we_o.next = debug.reg_we_o
        jump_o.next = out.jump_o
        jump_dest_o.next = out.jump_dest_o
        take_branch.next = debug.jump and debug.jump_exec


    current_ip_r = Signal(intbv(0))
  
    @always_seq(clock.posedge,reset=reset)
    def sim_observe():

        if backend.execute.taken:
            t_ip = backend.decode.debug_current_ip_o
            print("@{}ns exc: {} : {} ".format(now(),t_ip,backend.decode.debug_word_o))
            assert code_ram[t_ip>>2]==backend.decode.debug_word_o, "pc vs ram content mismatch" 
            assert backend.decode.next_ip_o == t_ip + 4, "next_ip vs. current_ip mismatch" 
            current_ip_r.next = t_ip >> 2
          
        # if out.jump_o:
        #     raise StopSimulation   


   
    jump_cnt = Signal(intbv(0))

    def check(cmd):
        t=cmd["t"]
        if type(t) == types.FunctionType:
            if t():
                print("OK")
            else:
                print("FAIL")
                raise StopSimulation
        print("----")


    @always_seq(clock.posedge,reset=reset)
    def commit_check():

        if jump_cnt > 0:
            print("Simulation finished")
            raise StopSimulation

        if backend.execute.taken:
            idx = backend.decode.debug_current_ip_o >> 2
        else:
            idx = current_ip_r

        if debug.valid_o:    
            cmd = commands[ idx]
            if debug.reg_we_o:
                print("@{}ns {}:  commmit to reg {} value {}".format(now(), cmd["source"], 
                abi_name(debug.rd_adr_o), debug.result_o))
            else:
                print("@{}ns {}:  commmit without reg write".format(now(), cmd["source"]))    
            check(cmd)


        if debug.jump_exec:
            cmd = commands[idx]
            print ("at {}ns: {}, do: {}".format(now(),cmd["source"],debug.jump))
            check(cmd)
            

        if jump_o:
            cmd = commands[idx] 
            print ("at {}ns: {}, destination: {}".format(now(),cmd["source"], jump_dest_o )) 
            jump_cnt.next = jump_cnt + 1
         


    @instance
    def stimulus():
         # Copy code to RAM
        i=0
        for cmd in commands:
            code_ram[i].next=cmd["opcode"]
            i += 1
        for i in range(1,3):    
            yield clock.posedge

        reset.next=0



    return instances()
Beispiel #10
0
"""
Simple 3 Stage Pipeline for bonfire_core 
(c) 2019 The Bonfire Project
License: See LICENSE
"""


from myhdl import *

from rtl.decode import *
from rtl.execute import *
from rtl.regfile import * 

from  rtl import config
def_config= config.BonfireConfig()

class FetchInputBundle:
     def __init__(self,config=def_config):
        self.config=config
        xlen=config.xlen

        self.en_i = Signal(bool(0)) # Fetch Data valid/ enable
        self.word_i = Signal(intbv(0)[xlen:]) # actual instruction to decode
        self.current_ip_i = Signal(modbv(0)[xlen:]) # ip (PC) of current instruction 
        self.next_ip_i = Signal(modbv(0)[xlen:]) # ip (PC) of next instruction 

class BackendOutputBundle:
    def __init__(self,config=def_config):
        self.config=config
        xlen=config.xlen
def tb(config=config.BonfireConfig(),test_conversion=False):

    print("Testing LSU with loadstore_outstanding={}, registered_read_stage={} ".format(config.loadstore_outstanding,config.registered_read_stage))
    clock=Signal(bool(0))
    reset = ResetSignal(0, active=1, isasync=False)

    clk_driver= ClkDriver(clock)

   
    bus = DbusBundle(config)
    ls = LoadStoreBundle(config)

    dut=LoadStoreBundle.LoadStoreUnit(ls,bus,clock,reset)

    if test_conversion:
        dut.convert(hdl='VHDL',std_logic_ports=False,path='vhdl_gen', name="loadstore" )


    ram = [Signal(modbv(0)[32:]) for ii in range(0, ram_size)]
    mem = sim_ram()
    mem_i = mem.ram_interface(ram,bus,clock,reset)

    cnt = Signal(intbv(0))

    fetch_index = Signal(intbv(0))
    
    def sw_test():
        fetch_index.next = 0
        yield clock.posedge

        ls.funct3_i.next = StoreFunct3.RV32_F3_SW
        ls.store_i.next = True
        ls.op1_i.next = 0
        ls.rd_i.next = 5

        countdown=len(store_words)

        while countdown>0:

            if ls.valid_o:
                countdown -= 1

            if fetch_index<len(store_words):
                ls.en_i.next = True
                if not ls.busy_o:
                    ls.displacement_i.next = fetch_index * 4
                    ls.op2_i.next = store_words[fetch_index]
                    fetch_index.next += 1

            else:
                if not ls.busy_o:   
                    ls.en_i.next=False    

            yield clock.posedge

        # Verify memory content 
        i=0
        for v in store_words:
            print("write check ram[{}]: {}=={} ".format(i,ram[i],hex(v)))
            assert ram[i]==v, "loadstore sw test failed"
            i += 1

   

    def lw_test():
        yield clock.posedge
        ls.funct3_i.next = LoadFunct3.RV32_F3_LW
        ls.store_i.next= False
        ls.op1_i.next=0
       
        count=len(store_words)
        finish=False
        i=Signal(intbv(0))

        while not finish:
            if not ls.busy_o:
                ls.displacement_i.next= i*4
                ls.rd_i.next= i # "Misuse" rd register as index into test data
                i.next +=  1
                ls.en_i.next = i<count 
                
            if ls.valid_o:
                assert ls.we_o, "loadstore lw test, ls.we_o not set"
                print("read check x{}: {} == {}".format(ls.rd_o,ls.result_o,hex(store_words[ls.rd_o])))
                assert(ls.result_o==store_words[ls.rd_o]), "loadstore lw test failed"
                finish = ls.rd_o==count-1
            
            yield clock.posedge            


    def sb_test():
        yield clock.posedge
        ls.funct3_i.next = StoreFunct3.RV32_F3_SB
        ls.store_i.next = True
        ls.op1_i.next = 5<<2 # Base Memory address for test
        ls.rd_i.next = 5

        countdown=8
        displacement=0

        while countdown>0:

            if ls.valid_o:
                countdown -=  1

            if displacement<8:
                ls.en_i.next = True
                if not ls.busy_o:
                    ls.displacement_i.next = displacement
                    # Extract next byte from store_words 
                    ls.op2_i.next = store_words[displacement>>2] >> (displacement % 4* 8)
                    displacement += 1

            else:
                if not ls.busy_o:   
                    ls.en_i.next=False    

            yield clock.posedge

        print("Store Byte result: {} {}".format(ram[5],ram[6]))
        assert (ram[5]==store_words[0] and ram[6]==store_words[1]), "loadstore sb test failed"


    def sh_test():
        yield clock.posedge
        ls.funct3_i.next = StoreFunct3.RV32_F3_SH
        ls.store_i.next = True
        ls.op1_i.next = 7<<2 # Base Memory address for test
        ls.rd_i.next = 5

        countdown=4
        displacement=0

        while countdown>0:

            if ls.valid_o:
                countdown -= 1

            if displacement<8:
                ls.en_i.next = True
                if not ls.busy_o:
                    ls.displacement_i.next = displacement
                    # Extract next half word from store_words 
                    ls.op2_i.next = store_words[displacement>>2] >> ((displacement >> 1 & 1)  * 16)
                    displacement +=  2

            else:
                if not ls.busy_o:   
                    ls.en_i.next=False    

            yield clock.posedge

        print("Store word result: {} {}".format(ram[7],ram[8]))
        assert(ram[7]==store_words[0] and ram[8]==store_words[1]), "loadstore sh test failed"


    def load_single(base,displacement,funct3): 
        ls.funct3_i.next = funct3
        ls.store_i.next = False
        ls.op1_i.next = base 
        ls.rd_i.next = 5
        ls.displacement_i.next = displacement
        ls.en_i.next = True
        yield clock.posedge
        while ls.busy_o:
            yield clock.posedge
        ls.en_i.next = False 

        while not ls.valid_o:
            yield clock.posedge
        print(now())

    def wait_valid():
         while ls.valid_o:
           yield clock.posedge

       

    def _check(a,b,message):
       s= "{}: checking {}=={}".format(message,hex(a),hex(b))
       assert a==b, s + " failed"
       print(s," OK")

    def _check_we():
        assert ls.we_o,"Register we signal not set"

    def load_other_test():
        """
        Test lb,lbu,lh,lhu
        """
        assert ram[3]==0x705a8000, "load_other:  ram[3] does not contain the expected content"
        yield clock.posedge

        print("Testing lbu")
        yield load_single(3<<2,1,LoadFunct3.RV32_F3_LBU) ## Should read the ff byte 
        _check_we()
        _check(ls.result_o,0x80,"lbu test" )
       
        print("Testing lb negative")
        yield load_single(3<<2,1,LoadFunct3.RV32_F3_LB) ## Should read and sign extend the ff byte 
        _check_we()
        _check(ls.result_o,0xffffff80,"lb negative test" )
       
        print("Testing lb positive")
        yield load_single(3<<2,2,LoadFunct3.RV32_F3_LB) ## Should read and sign extend the 55 byte 
        _check_we()
        _check(ls.result_o,0x5a,"lb positive test" )

        print("Testing lhu")
        yield load_single(3<<2,0,LoadFunct3.RV32_F3_LHU) ## Should read the ff00 hword 
        _check_we()
        _check(ls.result_o,0x8000,"lhu test" )

        print("Testing lh negative")
        yield load_single(3<<2,0,LoadFunct3.RV32_F3_LH) ## Should read and sign extend the ff00 hword 
        _check_we()
        _check(ls.result_o,0xffff8000,"lh negative test" )

        print("Testing lh positive")
        yield load_single(3<<2,2,LoadFunct3.RV32_F3_LH) ## Should read and sign extend the 0055 hword 
        _check_we()
        _check(ls.result_o,0x705a,"lh positive test" )


    def run_all():
       yield sw_test()
       yield wait_valid()
      
       yield lw_test()
       yield wait_valid()
       yield sb_test()   
       yield wait_valid() 
       yield sh_test()
       yield wait_valid()
       yield load_other_test()


    def clear_ram():
        for m in ram:
           m.next = 0
        yield clock.posedge


        
    
    @instance
    def stimulus():
      

       mem.setLatency(1) 
       yield run_all()
       yield clear_ram()
       print("Run with RAM wait state")
       mem.setLatency(2) 
       yield run_all()
       raise StopSimulation
         

    return instances()