Пример #1
0
    def _bench_fifo_ramp():
        tbdut = fifo_ramp(clock, reset, regbus, fifobus,
                          base_address=0x0000)
        tbrbor = regbus.interconnect()
        tbclk = clock.gen()
        
        asserr = Signal(bool(0))
                
        @instance 
        def tbstim():
            print("start fifo ramp test")
            try:
                yield delay(100)
                yield reset.pulse(111)

                # verify an incrementing pattern over the fifobus
                yield regbus.writetrans(0x07, 2)  # div of two
                yield regbus.readtrans(0x07)
                assert 2 == regbus.get_read_data()

                yield regbus.writetrans(0x00, 1)  # enable
                yield regbus.readtrans(0x00)
                assert 1 == regbus.get_read_data(), "cfg reg write failed"

                # monitor the bus until ?? ramps
                Nramps, rr, timeout = 128, 0, 0
                while rr < Nramps and timeout < (20*Nramps):
                    cnt = 0
                    for ii, sh in enumerate((24, 16, 8, 0,)):
                        yield delay(1000)
                        yield regbus.readtrans(0x08+ii)
                        cntpart = regbus.get_read_data()
                        cnt = cnt | (cntpart << sh)
                        print("{:<8d}: ramp count[{:<4d}, {:d}]: {:08X}, {:02X} - timeout {:d}".format(
                               now(), rr, ii, cnt, cntpart, timeout))
                    timeout += 1
                    # @todo: add ramp check
                    if cnt != rr or (timeout % 1000) == 0:
                        print("   ramp {}  {}".format(int(cnt), int(rr),))
                    rr = int(cnt)
                print("{}, {}, {}".format(Nramps, rr, timeout))
            except AssertionError as err:
                asserr.next = True
                for _ in range(10):
                    yield clock.posedge
                raise err

            raise StopSimulation

        # monitor the values from the fifo bus, it should
        # be a simple "ramp" increasing values
        _mask = 0xFF
        _cval = Signal(modbv(0, min=0, max=256))

        @always(clock.posedge)
        def tbmon():
            if fifobus.wr:
                assert _cval == fifobus.wdata
                _cval.next = _cval+1

        return tbclk, tbdut, tbstim, tbmon, tbrbor
Пример #2
0
def testbench(vhdl_output_path=None):
    fxp = FixedDef(128, 8)

    reset = ResetSignal(0, active=0, async=False)
    clk = Signal(bool(0))

    x = Signal(intbv(0)[fxp.width:])
    y = Signal(intbv(0)[fxp.width:])

    period = 10
    # clk_gen = clk_stim(clk, period=10)

    low_time = int(period / 2)
    high_time = period - low_time

    @instance
    def drive_clk():
        while True:
            yield delay(low_time)
            clk.next = 1
            yield delay(high_time)
            clk.next = 0

    @instance
    def reset_gen():
        reset.next = 0
        yield delay(10)
        yield clk.negedge
        reset.next = 1
        # yield delay(10)
        # yield clk.negedge
        # reset.next = 0

    @instance
    def write_stim():
        yield reset.posedge
        yield clk.negedge
        x.next = fxp.to_fixed(60)
        yield clk.negedge
        for i in range(8):
            yield clk.negedge
        raise StopSimulation()

    # @instance
    # def read_stim():
    #     yield reset.posedge
    #     yield delay(601)
    #     yield clk.negedge
    #     axis_sum.tready.next = 1
    #     while True:
    #         yield clk.negedge
    #         if axis_sum.tlast == 1:
    #             break
    #
    #     for i in range(10):
    #         yield clk.negedge
    #     raise StopSimulation()

    uut = tanh(clk, reset, x, y, dokladnosc=5, fxp=fxp)

    if vhdl_output_path is not None:
        uut.convert(hdl='VHDL', path=vhdl_output_path, initial_values=True)
    return instances()
Пример #3
0
 def f():
     (i for i in all_out).next = Signal(0)
     all_out[select].next = inp
Пример #4
0
def testBench():

    pc_adder_in, data1_in, data2_in, address32_in = [Signal(intbv(random.randint(-255, 255), min=-(2**31), max=2**31-1)) for i in range(4)]
    pc_adder_out, data1_out, data2_out, address32_out = [Signal(intbv(0, min=-(2**31), max=2**31-1)) for i in range(4)]

    rs_in, rd_in, rt_in, rd_out, rt_out, rs_out, = [Signal(intbv(0)[5:]) for i in range(6)]
    func_in, func_out = [Signal(intbv(0)[6:]) for i in range(2)]

    RegDst_in, ALUop_in, ALUSrc_in = [Signal(intbv(0)[1:]) for i in range(3)]   
    Branch_in, MemRead_in, MemWrite_in = [Signal(intbv(0)[1:]) for i in range(3)] 
    RegWrite_in, MemtoReg_in = [Signal(intbv(0)[1:]) for i in range(2)]

    RegDst_out, ALUop_out, ALUSrc_out = [Signal(intbv(0)[1:]) for i in range(3)]   
    Branch_out, MemRead_out, MemWrite_out = [Signal(intbv(0)[1:]) for i in range(3)] 
    RegWrite_out, MemtoReg_out = [Signal(intbv(0)[1:]) for i in range(2)]

    clk = Signal(intbv(0)[1:])
    rst = Signal(intbv(0)[1:])
   
    latch_inst = toVHDL(latch_id_ex, clk, rst,
                                pc_adder_in, 
                                data1_in, data2_in, address32_in,
                                rs_in, rt_in, rd_in, func_in,
                                RegDst_in, ALUop_in, ALUSrc_in,     #signals to EX pipeline stage
                                Branch_in, MemRead_in, MemWrite_in,  #signals to MEM pipeline stage
                                RegWrite_in, MemtoReg_in,     #signals to WB pipeline stage
                                pc_adder_out, 
                                data1_out, data2_out, address32_out,
                                rs_out, rt_out, rd_out, func_out, 
                                RegDst_out, ALUop_out, ALUSrc_out,     
                                Branch_out, MemRead_out, MemWrite_out, 
                                RegWrite_out, MemtoReg_out)    

    @instance
    def stimulus():
        for i in range(5):            
            if random.random() > 0.25:
                clk.next = 1
            if random.random() > 0.75:
                rst.next = 1
            
            pc_adder_in.next, data1_in.next, data2_in.next, address32_in.next = [intbv(random.randint(-255, 255)) for i in range(4)]

            rs_in.next, rd_in.next, rt_in.next, func_in.next = [intbv(random.randint(0, 15)) for i in range(4)]

            RegDst_in.next, ALUop_in.next, ALUSrc_in.next = [random.randint(0,1) for i in range(3)]
            Branch_in.next , MemRead_in.next , MemWrite_in.next  = [random.randint(0,1) for i in range(3)]
            RegWrite_in.next , MemtoReg_in.next = [random.randint(0,1) for i in range(2)]

            yield delay(1)
            print ("-" * 79)
            print ("%i %i %i | %i %i %i | %i | %i  %i  %i  %i  %i  %i  %i  %i " % ( data1_in, data2_in, address32_in, 
                                                                                rs_in, rt_in, rd_in, func_in, 
                                                                                RegDst_in, ALUop_in, ALUSrc_in,     
                                                                                                Branch_in, MemRead_in, MemWrite_in, 
                                                                                                RegWrite_in, MemtoReg_in))
            print ("clk: %i  rst: %i " % (clk, rst))

            print ("%i %i %i | %i %i %i | %i | %i  %i  %i  %i  %i  %i  %i  %i " % ( data1_out, data2_out, address32_out, 
                                                                        rs_out, rt_out, rd_out, func_out, RegDst_out, ALUop_out, ALUSrc_out,     
                                                                                                Branch_out, MemRead_out, MemWrite_out, 
                                                                                                RegWrite_out, MemtoReg_out))

            clk.next = 0
            rst.next = 0
            yield delay(1)

    return instances()
Пример #5
0
def bench_fifo_mem_rand():
    nloops = 100
    w = width = 8
    wmax = 2**width

    # random data and addresses for test
    rand_data = tuple([randint(0, wmax - 1) for _ in range(nloops)])
    rand_addr = tuple([randint(0, wmax - 1) for _ in range(nloops)])

    clock, write, read = Signals(bool(0), 3)
    write_data, write_addr, read_data, read_addr = Signals(intbv(0)[w:0], 4)
    wad = Signal(write_addr.val)

    tbdut = fifo_mem(clock, write, write_data, write_addr, clock, read,
                     read_data, read_addr, wad)

    @instance
    def tbclkw():
        clock.next = False
        while True:
            yield delay(5)
            clock.next = not clock

    @instance
    def tbstim():
        print("start sim")
        write.next = False
        write_data.next = 0
        write_addr.next = 0
        read.next = False
        read_addr.next = 0

        print("delay some")
        yield delay(10)
        for ii in range(5):
            yield clock.posedge

        for ii in range(wmax):
            write.next = True
            write_data.next = 0
            yield clock.posedge
        write.next = False

        print("write loop")
        for ii in range(nloops):
            write.next = True
            write_data.next = rand_data[ii]
            write_addr.next = rand_addr[ii]
            read_addr.next = wad
            yield clock.posedge
            write.next = False
            for jj in range(3):
                yield clock.posedge
            print("%d %d %d %d" %
                  (write_addr, write_data, read_addr, read_data))
        write.next = False

        print("read loop")
        for ii in range(nloops):
            write_data.next = rand_data[ii]
            write_addr.next = rand_addr[ii]
            read_addr.next = rand_addr[ii]
            yield clock.posedge
            print("%d %d %d %d" %
                  (write_addr, write_data, read_addr, read_data))
        write.next = False
        yield clock.posedge

        print("end sim")
        raise StopSimulation

    return myhdl.instances()
Пример #6
0
    sel -- control input: select a if asserted, otherwise b
    
    """
    @always_comb
    def muxLogic():
        if sel == 1:
            z.next = a
        else:
            z.next = b

    return muxLogic


from random import randrange

z, a, b, sel = [Signal(0) for i in range(4)]

mux_1 = Mux(z, a, b, sel)


def test():
    print "z a b sel"
    for i in range(8):
        a.next, b.next, sel.next = randrange(8), randrange(8), randrange(2)
        yield delay(10)
        print "%s %s %s %s" % (z, a, b, sel)


test_1 = test()

Пример #7
0
import sys
import os
sys.path.append( os.path.abspath("../../src/") )
import myhdl
from myhdl import block, Signal, intbv

from ClkDriver import ClkDriver
#from fpga25_snip4 import led_stroby
from shift import shift

num_led = 8
clock = Signal(False)
leds = Signal(intbv(0)[num_led:])


@block
def test_shifter(clock,leds):
    clkdrv = ClkDriver(clock, period=10)
    tbdut = shift(clock, leds, num_led=num_led, cnt_max=5)
    return tbdut, clkdrv

@block
def shifter(clock,leds):
    tbdut = shift(clock, leds, num_led)
    return tbdut

if "--test" in str(sys.argv):
    do_test=True
else:
    do_test=False
Пример #8
0
def fun():
    clk = Signal(bool(0))
    inst = gen(clk)
    return inst
Пример #9
0
def dummy():
    clk = Signal(bool(0))
    inst = gen(clk)
    return 1
Пример #10
0
def fifo_fast(clock, reset, fbus, use_srl_prim=False):
    """
    Often small simple, synchronous, FIFOs can be implemented with 
    specialized hardware in an FPGA (e.g. vertically chaining LUTs).

    This FIFO is intended to be used for small fast FIFOs.  But when
    used for large ...
    
    This FIFO is a small FIFO (currently fixed to 16) that is implemented
    to take advantage of some hardware implementations.

    Typical FPGA synthesis will infer shift-register-LUT (SRL) for small
    synchronous FIFOs.  This FIFO is implemented generically, consult the
    synthesis and map reports.

    PORTS
    =====

    PARAMETERS
    ==========
    use_slr_prim: this parameter indicates to use the SRL primitive
      (inferrable primitive).  If SRL are not inferred from the generic
      description this option can be used.  Note, srl_prim will only
      use a size (FIFO depth) of 16.
    """

    # @todo: this is intended to be used for small fast fifo's but it
    #        can be used for large synchronous fifo as well

    N = 32  # default and max size
    if use_srl_prim:
        N = 16
    elif fbus.size > N:
        print("@W: m_fifo_fast only supports size < %d, for fast" % (N))
        print("    forcing size (depth) to %d" % (N))
    else:
        N = fbus.size

    mem = [Signal(intbv(0)[fbus.width:]) for _ in range(N)]
    addr = Signal(intbv(0, min=0, max=N))

    # aliases to the FIFO bus interface
    srlce = fbus.wr  # single cycle write

    # note: use_srl_prim has not been tested!
    # note: signal slices wdata() will need to be used instead of
    #       bit slices wsdata[].  Have add
    if use_srl_prim:
        gsrl = [None for _ in range(N)]
        for ii in range(N):
            gsrl[ii] = fifo_srl(clock, fbus.wdata(ii), fbus.wr, addr,
                                fbus.rdata(ii))
    else:
        # the SRL based FIFO always writes to address 0 and shifts
        # the FIFO, only a read address is accounted.
        @always(clock.posedge)
        def rtl_srl_in():
            if srlce:
                mem[0].next = fbus.wdata
                for ii in range(1, N):
                    mem[ii].next = mem[ii - 1]

    @always_comb
    def rtl_srl_out():
        fbus.rdata.next = mem[addr]

    @always_comb
    def rtl_vld():
        fbus.rvld.next = fbus.rd  # no delay on reads

    # the address is the read address, the write address is always
    # zero but on a write all values are shifted up one index, only
    # the read address is accounted in the following.
    @always_seq(clock.posedge, reset=reset)
    def rtl_fifo():
        if fbus.clear:
            addr.next = 0
            fbus.empty.next = True
            fbus.full.next = False

        elif fbus.rd and not fbus.wr:
            fbus.full.next = False
            if addr == 0:
                fbus.empty.next = True
            else:
                addr.next = addr - 1

        elif fbus.wr and not fbus.rd:
            fbus.empty.next = False
            if not fbus.empty:
                addr.next = addr + 1
            if addr == N - 2:
                fbus.full.next = True

        # nothing happens if read and write at the same time

    # note: failures occur if write/read when full/empty respectively

    nvacant = Signal(intbv(N, min=0, max=N + 1))  # # empty slots
    ntenant = Signal(intbv(0, min=0, max=N + 1))  # # filled slots

    @always_seq(clock.posedge, reset=reset)
    def rtl_occupancy():
        if fbus.clear:
            nvacant.next = N
            ntenant.next = 0
        elif fbus.rd and not fbus.wr:
            nvacant.next = nvacant + 1
            ntenant.next = ntenant - 1
        elif fbus.wr and not fbus.rd:
            nvacant.next = nvacant - 1
            ntenant.next = ntenant + 1

    @always_comb
    def rtl_count():
        fbus.count.next = ntenant

    gens = (
        rtl_srl_in,
        rtl_srl_out,
        rtl_vld,
        rtl_fifo,
        rtl_occupancy,
        rtl_count,
    )
    return gens
Пример #11
0
def CPU():  # the main block which will connect all of our blocks
    ''' creating the nessecry signal to connect the blocks '''

    enable, enable2, clock, RestClk, MEMread, MEMwrite, REGwrite, PCSrc, ALUMUXsig, MEMtoREG, zero, Branch = [
        Signal(bool(0)) for i in range(12)
    ]
    instructionIN = Signal(intbv(0)[32:])
    PCsignal = Signal(intbv(0, min=-1024))
    PC_Mux_result = Signal(intbv(0, min=-1024))
    PC_Branch_result = Signal(intbv(0, min=-1024))
    PC_adder_result = Signal(intbv(0, min=-1024))
    instruction = Signal(intbv(0))
    rs1OUT, rs2OUT = [
        Signal(intbv(0, min=-2**31, max=2**31)) for i in range(2)
    ]
    rd, rs1, rs2, ALUsig, MEMsignal = [Signal(intbv(0)[5:]) for i in range(5)]
    Mux_RB_result = Signal(intbv(0, min=-2**31, max=2**31))
    imm = Signal(intbv(0, min=-2**31, max=2**31))
    Mux_ALUsrc_result = Signal(intbv(0, min=-2**31, max=2**31))
    ALUoutput = Signal(intbv(0, min=-2**31, max=2**31))
    MEMoutput = Signal(intbv(0, min=-2**31, max=2**31))
    PCclk = Signal(bool(0))
    counter = Signal(intbv(0))
    '''a clock specified for the PC to slow the process of sending an instruction (to prevent pipelining )'''
    @always(delay(25))
    def clockGENpc():
        PCclk.next = not PCclk

    '''a faster clock for the instructions '''

    @always(delay(5))
    def clockGEN():
        if counter == 4:
            RestClk.next = 1
            counter.next = 0
            enable2.next = 1
        else:
            RestClk.next = 0
            counter.next = counter + 1
        clock.next = not clock
        PCSrc.next = (
            Branch & zero
        )  # an and gate updated by each clock to determine if the branch is taken or not

    '''<----------------------------connecting the blocks----------------------->'''

    PC_driver = pc(PCclk, PC_Mux_result, enable, PCsignal)

    Adder = adder(PCsignal, PC_adder_result)

    Adder_Branch = BranchAdder(PCsignal, imm, PC_Branch_result)

    Mux_pc = mux(PC_Mux_result, PC_adder_result, PC_Branch_result, PCSrc)

    Instruction_MEM = inst_memory(clock, enable, PCsignal, instructionIN,
                                  instruction, RestClk)

    DECODE = decoder(instruction, rs1, rs2, rd, imm)

    CONTROL = ControlUnit(instruction, ALUsig, ALUMUXsig, REGwrite, Branch,
                          MEMwrite, MEMtoREG, MEMread, MEMsignal, clock,
                          enable2, RestClk)

    Regsters = RegisterFile(rs1, rs2, rd, rs1OUT, rs2OUT, REGwrite,
                            Mux_RB_result, clock, enable2, RestClk)

    Mux_ALUsrc = mux(Mux_ALUsrc_result, rs2OUT, imm, ALUMUXsig)

    Perform_operations = ALU(rs1OUT, Mux_ALUsrc_result, ALUsig, ALUoutput,
                             zero, PCsignal)

    MEMaccess = MainMemory(ALUoutput, rs2OUT, MEMoutput, MEMwrite, MEMread,
                           MEMsignal, clock, RestClk)

    Mux_RB = mux(Mux_RB_result, ALUoutput, MEMoutput, MEMtoREG)

    @instance
    def stimulate():
        '''<---------------------start load the instructions into the instruction memory-------------------->'''
        enable.next = 0

        # 1
        instructionIN.next = 0b00011111010000000000001110010011
        yield PCclk.posedge

        # 2
        instructionIN.next = 0b00000000000000000000010110010011
        yield PCclk.posedge

        # 3
        instructionIN.next = 0b00000000000100000000011000010011
        yield PCclk.posedge

        # 4
        instructionIN.next = 0b00011111010000000000001100010011
        yield PCclk.posedge

        # 5
        instructionIN.next = 0b00000000101101100000011000110011
        yield PCclk.posedge

        # 6
        instructionIN.next = 0b00000000110000110010001000100011
        yield PCclk.posedge

        # 7
        instructionIN.next = 0b00000000010000110000001100010011
        yield PCclk.posedge
        # 8
        instructionIN.next = 0b00000000000101011000010110010011
        yield PCclk.posedge
        # 9
        instructionIN.next = 0b11111110011101011100100011100011
        yield PCclk.posedge
        # 10
        instructionIN.next = 0b00011111010000000000001100010011
        yield PCclk.posedge
        # 11
        instructionIN.next = 0b00000000110000110010000000100011
        yield PCclk.posedge
        # 12
        instructionIN.next = 0b00000000000000110010010100000011
        yield PCclk.posedge
        '''<------------------------done loading the instructions ------------------------>'''

        enable.next = 1  # enable the the instructions memory and the PC to start running
        yield clock.negedge

        while True:  # a while loop to print each instruction when it's executing
            print('time: ', now(), 'PC---->', int(PCsignal))
            print(
                '_________________________________________________________________'
                '_______________________________________________________________________________'
            )
            print(
                '\nthe instruction is : %s ||operands: rd: x%d , rs1: x%d , rs2: x%d , imm: %d '
                %
                (bin(instruction, 32), int(rd), int(rs1), int(rs2), int(imm)))
            print(
                'the signals are : ALUsignal: %s | ALUMUXsig: %s | REGwrite: %s | PCSrc: %s '
                '| MEMwrite: %s | MEMtoREG: %s | MEMread: %s | MEMsignal: %s '
                % (bin(ALUsig, 5), bin(ALUMUXsig, 1), bin(REGwrite, 1),
                   bin(PCSrc, 1), bin(MEMwrite, 1), bin(
                       MEMtoREG, 6), bin(MEMread, 1), bin(MEMsignal, 3)))

            print('PC Equals: ', int(PCsignal))
            print(
                '______________________________________________________________________________________'
                '__________________________________________________________')

            yield PCclk.negedge

    return instances()
Пример #12
0
def sim_streaming_chain_mult(pars_obj):
    global rxdata_filename
    global txdata0_filename
    global txdata1_filename

    # removing the files if already available
    for i in range(NB_CHAIN_MULTIPLIERS):
        txdata0_filename[i] = "transmit_data_inpA_mult{:d}.log".format(i)
        if (os.path.exists(txdata0_filename[i])):
            os.remove(txdata0_filename[i])
        txdata1_filename[i] = "transmit_data_inpB_mult{:d}.log".format(i)
        if (os.path.exists(txdata1_filename[i])):
            os.remove(txdata1_filename[i])

    if (os.path.exists(rxdata_filename)):
        os.remove(rxdata_filename)

    reset = Signal(bool(1))
    clk = Signal(bool(0))
    elapsed_time = Signal(0)

    nb_transmit = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
    nb_transmit0 = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
    nb_transmit1 = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
    nb_receive = Signal(int(0))

    av_src0_bfm = [
        AvalonST_SRC(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    av_src1_bfm = [
        AvalonST_SRC(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    av_snk0 = [
        AvalonST_SNK(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    av_snk1 = [
        AvalonST_SNK(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    av_snk_bfm = AvalonST_SNK(STREAM_DATA_WIDTH)
    src_bfm_i = [
        AvalonST_SNK(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    src_bfm_0 = [
        AvalonST_SNK(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    src_bfm_1 = [
        AvalonST_SNK(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    src_bfm_o = AvalonST_SRC(STREAM_DATA_WIDTH)

    clkgen = clk_driver(elapsed_time, clk, period=20)

    src0_bfm_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    src1_bfm_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    snk_bfm_inst = None

    VALID_PATTERN0 = [
        random.randint(0x0100, 0xffff) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    VALID_PATTERN1 = [
        random.randint(0x0100, 0xffff) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    READY_PATTERN = [
        random.randint(0x0100, 0xffff) for i in range(NB_CHAIN_MULTIPLIERS)
    ]

    for i in range(NB_CHAIN_MULTIPLIERS):
        print("Chain Mult: " + str(i) + " Valid0: " + str(VALID_PATTERN0[i]) +
              " Valid1: " + str(VALID_PATTERN1[i]) + " Ready: " +
              str(READY_PATTERN[i]))
        src0_bfm_inst[i] = src_bfm(reset, clk, VALID_PATTERN0[i], src_bfm_0[i],
                                   av_src0_bfm[i])

        src1_bfm_inst[i] = src_bfm(reset, clk, VALID_PATTERN1[i], src_bfm_1[i],
                                   av_src1_bfm[i])

    snk_bfm_inst = snk_bfm(reset, clk, READY_PATTERN[0], av_snk_bfm, src_bfm_o)

    i = NB_CHAIN_MULTIPLIERS * 2

    nb_chain_mults = 0
    nb_chain_mults_list = []
    mod_list = []
    nb_mult_stages = 0
    while i > 1:
        mod_val = 0 if (i % 2 == 0 or i == 1) else 1
        mod_list.append(mod_val)
        i = i / 2 if (i % 2 == 0) else i / 2 + 1
        nb_chain_mults += i
        nb_chain_mults_list.append(i)
        nb_mult_stages += 1

    print("nb_chain_mults: " + str(nb_chain_mults))
    print("nb_mult_stages: " + str(nb_mult_stages))
    print("mod_list: " + str(mod_list))
    print("nb_chain_mults_list: " + str(nb_chain_mults_list))

    av_snk0_cmb = [[
        AvalonST_SNK(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ] for j in range(nb_mult_stages)]
    av_snk1_cmb = [[
        AvalonST_SNK(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ] for j in range(nb_mult_stages)]
    av_src = [[
        AvalonST_SRC(STREAM_DATA_WIDTH) for i in range(NB_CHAIN_MULTIPLIERS)
    ] for j in range(nb_mult_stages)]

    snk0_valid_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    snk0_data_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    snk0_ready_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    snk1_valid_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    snk1_data_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    snk1_ready_inst = [None for i in range(NB_CHAIN_MULTIPLIERS)]
    src_valid_inst = None
    src_data_inst = None
    src_ready_inst = None

    streaming_chain_mult_inst = [None for i in range(nb_mult_stages)]
    add_i = [None for i in range(nb_mult_stages)]
    add_pars = [None for i in range(nb_mult_stages)]
    snk0_inst = []
    snk1_inst = []

    for i in range(nb_mult_stages):
        add_pars[i] = StreamingChainMultPars()
        add_pars[i].SNK0_DATAWIDTH = STREAM_DATA_WIDTH
        add_pars[i].SNK1_DATAWIDTH = STREAM_DATA_WIDTH
        add_pars[i].SRC_DATAWIDTH = STREAM_DATA_WIDTH
        add_pars[i].NB_CHAIN_MULTIPLIERS = NB_CHAIN_MULTIPLIERS
        add_pars[i](add_pars[i])
        add_i[i] = StreamingChainMult()

        if (i != 0 and i <= nb_mult_stages - 1):
            for j in range(nb_chain_mults_list[i]):
                k = j * 2
                snk0_inst.append(
                    simple_wire_assign(av_snk0_cmb[i][j].valid_i,
                                       av_src[i - 1][k].valid_o))
                snk0_inst.append(
                    simple_wire_assign(av_snk0_cmb[i][j].data_i,
                                       av_src[i - 1][k].data_o))
                snk0_inst.append(
                    simple_wire_assign(av_src[i - 1][k].ready_i,
                                       av_snk0_cmb[i][j].ready_o))

                if (mod_list[i] == 1 and j == (nb_chain_mults_list[i]) - 1):
                    snk1_inst.append(
                        simple_wire_assign(av_snk1_cmb[i][j].valid_i,
                                           Signal(1)))
                    snk1_inst.append(
                        simple_wire_assign(av_snk1_cmb[i][j].data_i,
                                           Signal(1)))
                    snk1_inst.append(
                        simple_wire_assign(Signal(1),
                                           av_snk1_cmb[i][j].ready_o))

                else:
                    snk1_inst.append(
                        simple_wire_assign(av_snk1_cmb[i][j].valid_i,
                                           av_src[i - 1][k + 1].valid_o))
                    snk1_inst.append(
                        simple_wire_assign(av_snk1_cmb[i][j].data_i,
                                           av_src[i - 1][k + 1].data_o))
                    snk1_inst.append(
                        simple_wire_assign(av_src[i - 1][k + 1].ready_i,
                                           av_snk1_cmb[i][j].ready_o))

        elif (i == 0):
            for k in range(NB_CHAIN_MULTIPLIERS):
                snk0_valid_inst[k] = simple_wire_assign(
                    av_snk0_cmb[0][k].valid_i, av_src0_bfm[k].valid_o)
                snk0_data_inst[k] = simple_wire_assign(
                    av_snk0_cmb[0][k].data_i, av_src0_bfm[k].data_o)
                snk0_ready_inst[k] = simple_wire_assign(
                    av_src0_bfm[k].ready_i, av_snk0_cmb[0][k].ready_o)

                snk1_valid_inst[k] = simple_wire_assign(
                    av_snk1_cmb[0][k].valid_i, av_src1_bfm[k].valid_o)
                snk1_data_inst[k] = simple_wire_assign(
                    av_snk1_cmb[0][k].data_i, av_src1_bfm[k].data_o)
                snk1_ready_inst[k] = simple_wire_assign(
                    av_src1_bfm[k].ready_i, av_snk1_cmb[0][k].ready_o)

        streaming_chain_mult_inst[i] = add_i[i].block_connect(
            add_pars[i], reset, clk, av_snk0_cmb[i], av_snk1_cmb[i], av_src[i])

    src_valid_inst = simple_wire_assign(av_snk_bfm.valid_i,
                                        av_src[nb_mult_stages - 1][0].valid_o)
    src_data_inst = simple_wire_assign(av_snk_bfm.data_i,
                                       av_src[nb_mult_stages - 1][0].data_o)
    src_ready_inst = simple_wire_assign(av_src[nb_mult_stages - 1][0].ready_i,
                                        av_snk_bfm.ready_o)

    @always(clk.posedge)
    def stimulus():
        if elapsed_time == 40:
            reset.next = 0

    INIT_DATA0 = [
        random.randint(1, RANDRANGE) for i in range(NB_CHAIN_MULTIPLIERS)
    ]
    INIT_DATA1 = [
        random.randint(1, RANDRANGE) for i in range(NB_CHAIN_MULTIPLIERS)
    ]

    data_in0 = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
    data_in1 = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
    src_bfm_0_valid_inst = []
    src_bfm_1_valid_inst = []
    src_bfm_0_data_inst = []
    src_bfm_1_data_inst = []

    for i in range(NB_CHAIN_MULTIPLIERS):
        src_bfm_0_data_inst.append(
            conditional_wire_assign(
                src_bfm_0[i].data_i,
                (av_src0_bfm[i].ready_i and av_src0_bfm[i].valid_o),
                data_in0[i], src_bfm_0[i].data_i))
        src_bfm_1_data_inst.append(
            conditional_wire_assign(
                src_bfm_1[i].data_i,
                (av_src1_bfm[i].ready_i and av_src1_bfm[i].valid_o),
                data_in1[i], src_bfm_1[i].data_i))

    for i in range(NB_CHAIN_MULTIPLIERS):
        src_bfm_0_valid_inst.append(
            conditional_wire_assign_lt(src_bfm_0[i].valid_i, nb_transmit0[i],
                                       Signal(MAX_NB_TRANSFERS), 1, 0))
        src_bfm_1_valid_inst.append(
            conditional_wire_assign_lt(src_bfm_1[i].valid_i, nb_transmit1[i],
                                       Signal(MAX_NB_TRANSFERS), 1, 0))

    data_in0_inst = []
    data_in1_inst = []
    nb_transmit0_inst = []
    nb_transmit1_inst = []
    transmit_data0_append_inst = []
    transmit_data1_append_inst = []
    receive_data_append_inst = []

    for i in range(NB_CHAIN_MULTIPLIERS):
        data_in0_inst.append(
            conditional_random_generator(
                reset, clk, data_in0[i], int(INIT_DATA0[i]),
                (av_src0_bfm[i].ready_i and av_src0_bfm[i].valid_o
                 and src_bfm_0[i].valid_i), RANDRANGE))
        data_in1_inst.append(
            conditional_random_generator(
                reset, clk, data_in1[i], int(INIT_DATA1[i]),
                (av_src1_bfm[i].ready_i and av_src1_bfm[i].valid_o
                 and src_bfm_1[i].valid_i), RANDRANGE))

        nb_transmit0_inst.append(
            conditional_reg_counter(
                reset, clk, nb_transmit0[i], Reset.LOW,
                (av_src0_bfm[i].ready_i and av_src0_bfm[i].valid_o
                 and src_bfm_0[i].valid_i)))
        nb_transmit1_inst.append(
            conditional_reg_counter(
                reset, clk, nb_transmit1[i], Reset.LOW,
                (av_src1_bfm[i].ready_i and av_src1_bfm[i].valid_o
                 and src_bfm_1[i].valid_i)))

        transmit_data0_append_inst.append(
            conditional_clocked_appendfile(
                reset, clk, (av_src0_bfm[i].ready_i and av_src0_bfm[i].valid_o
                             and src_bfm_0[i].valid_i), data_in0[i],
                txdata0_filename[i]))
        transmit_data1_append_inst.append(
            conditional_clocked_appendfile(
                reset, clk, (av_src1_bfm[i].ready_i and av_src1_bfm[i].valid_o
                             and src_bfm_1[i].valid_i), data_in1[i],
                txdata1_filename[i]))

    receive_data_append_inst.append(
        conditional_clocked_appendfile(reset, clk, (src_bfm_o.valid_o),
                                       src_bfm_o.data_o, rxdata_filename))

    recv_inst = None
    recv_inst = conditional_reg_counter(reset, clk, nb_receive, Reset.LOW,
                                        src_bfm_o.valid_o)

    @always(clk.posedge)
    def receive_data_process():
        TIME_SHUTDOWN = 5000
        nb_recv = 0
        sim_time_now = now()
        nb_recv += nb_receive
        if (nb_recv == (MAX_NB_TRANSFERS)):
            print("INF242: Num ready pulses: " + str(int(ready_pulses)))
            raise StopSimulation("Simulation Finished in %d clks: In total " %
                                 now() + str(nb_recv) + " data words received")

    @always(clk.posedge)
    def simulation_time_check():
        sim_time_now = now()
        if (sim_time_now > MAX_SIM_TIME):
            raise StopSimulation(
                "Warning! Simulation Exited upon reaching max simulation time of "
                + str(MAX_SIM_TIME) + " clocks")

    ready_pulse_cnt_inst = None
    ready_pulse_cnt_inst = conditional_reg_counter(reset, clk, ready_pulses,
                                                   Reset.LOW,
                                                   (av_snk_bfm.ready_o))

    return instances()
Пример #13
0
import random  # for randomized test
#from __future__ import print_function

MAX_NB_TRANSFERS = 10
NB_CHAIN_MULTIPLIERS = 5
STREAM_DATA_WIDTH = 32

RANDRANGE = pow(2,
                3) - 1  # Maximum value allowed is 2^15-1 for avoiding overflow
MAX_SIM_TIME = 100000

txdata0_filename = ["" for i in range(NB_CHAIN_MULTIPLIERS)]
txdata1_filename = ["" for i in range(NB_CHAIN_MULTIPLIERS)]
rxdata_filename = "receive_data.log"
ready_pulses = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
ready_pulses0 = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
ready_pulses1 = [Signal(int(0)) for i in range(NB_CHAIN_MULTIPLIERS)]
ready_pulses = Signal(int(0))


def sim_streaming_chain_mult(pars_obj):
    global rxdata_filename
    global txdata0_filename
    global txdata1_filename

    # removing the files if already available
    for i in range(NB_CHAIN_MULTIPLIERS):
        txdata0_filename[i] = "transmit_data_inpA_mult{:d}.log".format(i)
        if (os.path.exists(txdata0_filename[i])):
            os.remove(txdata0_filename[i])
Пример #14
0
def lt24lcd(glbl, vmem, lcd):
    """ A video display driver for the terasic LT24 LCD display. 
    
    This driver reads pixels from the VideoMemory interface and transfers
    them to the LT24 display.  This hardware module (component) will also
    perform the initial display configuration.
    
    Ports:
        glbl (Global): global signals, clock, reset, enable, etc. 
        vmem (VideoMemory): video memory interface, the driver will read 
                            pixels from this interface. 
        lcd (LT24Interface): The external LT24 interface. 
        
    Parameters:
        None 
        
    RGB 5-6-5 (8080-system 16bit parallel bus)
    """
    assert isinstance(lcd, LT24Interface)
    resolution, refresh_rate = (240, 320), 60
    number_of_pixels = resolution[0] * resolution[1]

    # local references to signals in interfaces
    clock, reset = glbl.clock, glbl.reset

    # make sure the user timer is configured
    assert glbl.tick_user is not None

    # write out a new VMEM to the LCD display, a write cycle
    # consists of putting the video data on the bus and latching
    # with the `wrx` signal.  Init (write once) the column and
    # page addresses (cmd = 2A, 2B) then write mem (2C)
    states = enum(
        'init_wait_reset',  # wait for the controller to reset the LCD
        'init_start',  # start the display init sequence
        'init_start_cmd',  # send a command, port of the display seq
        'init_next',  # determine if another command
        'write_cmd_start',  # command subroutine
        'write_cmd',  # command subroutine
        'display_update_start',  # update the display
        'display_update_start_p',  # delay for command ack
        'display_update',  # update the display
        'display_update_next',  # wait for driver to ack pixel xfered
        'display_update_end'  # end of display update 
    )

    state = Signal(states.init_wait_reset)
    state_prev = Signal(states.init_wait_reset)
    cmd = Signal(intbv(0)[8:])
    return_state = Signal(states.init_wait_reset)

    num_hor_pxl, num_ver_pxl = resolution
    print("resolution {}x{} = {} number of pixes".format(
        num_hor_pxl, num_ver_pxl, number_of_pixels))
    hcnt = intbv(0, min=0, max=num_hor_pxl)
    vcnt = intbv(0, min=0, max=num_ver_pxl)

    # signals to start a new command transaction to the LCD
    datalen = Signal(intbv(0, min=0, max=number_of_pixels + 1))
    data = Signal(intbv(0)[16:])
    datasent = Signal(bool(0))
    datalast = Signal(bool(0))
    cmd_in_progress = Signal(bool(0))

    # --------------------------------------------------------
    # LCD driver
    gdrv = lt24lcd_driver(glbl, lcd, cmd, datalen, data, datasent, datalast,
                          cmd_in_progress)

    # --------------------------------------------------------
    # build the display init sequency ROM
    rom, romlen, maxpause = build_init_rom(init_sequence)
    offset = Signal(intbv(0, min=0, max=romlen + 1))
    pause = Signal(intbv(0, min=0, max=maxpause + 1))

    # --------------------------------------------------------
    # state-machine

    @always_seq(clock.posedge, reset=reset)
    def rtl_state_machine():
        state_prev.next = state
        if state == states.init_wait_reset:
            if lcd.reset_complete:
                state.next = states.init_start

        elif state == states.init_start:
            v = rom[offset]
            # @todo: change the table to only contain the number of
            # @todo: bytes to be transferred
            datalen.next = v - 3
            p = rom[offset + 1]
            pause.next = p
            offset.next = offset + 2
            state.next = states.init_start_cmd

        elif state == states.init_start_cmd:
            v = rom[offset]
            cmd.next = v
            if datalen > 0:
                v = rom[offset + 1]
                data.next = v
                offset.next = offset + 2
            else:
                offset.next = offset + 1
            state.next = states.write_cmd_start
            return_state.next = states.init_next

        elif state == states.init_next:
            if pause == 0:
                if offset == romlen:
                    state.next = states.display_update_start
                else:
                    state.next = states.init_start
            elif glbl.tick_ms:
                pause.next = pause - 1

        elif state == states.write_cmd_start:
            state.next = states.write_cmd

        elif state == states.write_cmd:
            if cmd_in_progress:
                if datasent and not datalast:
                    v = rom[offset]
                    data.next = v
                    offset.next = offset + 1
            else:
                cmd.next = 0
                state.next = return_state

        elif state == states.display_update_start:
            if glbl.tick_user:
                cmd.next = 0x2C
                state.next = states.display_update_start_p
                datalen.next = number_of_pixels

        elif state == states.display_update_start_p:
            state.next = states.display_update

        elif state == states.display_update:
            assert cmd_in_progress
            if vcnt == num_ver_pxl - 1:
                hcnt[:] = 0
                vcnt[:] = 0
            elif hcnt == num_hor_pxl - 1:
                hcnt[:] = 0
                vcnt[:] = vcnt + 1
            else:
                hcnt[:] = hcnt + 1

            # this will be the pixel for the next write cycle
            vmem.hpxl.next = hcnt
            vmem.vpxl.next = vcnt

            # this is the pixel for the current write cycle
            if hcnt == 0 and vcnt == 0:
                cmd.next = 0
                state.next = states.display_update_end
            else:
                data.next = concat(vmem.red, vmem.green, vmem.blue)
                state.next = states.display_update_next

        elif state == states.display_update_next:
            if cmd_in_progress:
                if datasent and not datalast:
                    state.next = states.display_update
            else:
                cmd.next = 0
                state.next = states.display_update_end

        elif state == states.display_update_end:
            # wait till the driver ack the command completion
            if not cmd_in_progress:
                state.next = states.display_update_start

    return gdrv, rtl_state_machine
Пример #15
0
def gain_corrector(clearn, clock, gain_i, gain_q, in_sign, out_sign):
    """Analog quadrature gain corrector.

    Lets you correct for gain imbalance with an AQM.

    :param clearn: The reset signal.
    :param clock: The clock.
    :param correct_i: An intbv to add to multiply each sample's i channel by.
    :param correct_q: An intbv to add to multiply each sample's q channel by.
    :param in_sign: The incomming signature.
    :param out_sign: The outgoing signature.
    :returns: A synthesizable MyHDL instance.
    """

    in_valid = in_sign.valid
    in_last = in_sign.last
    in_i = in_sign.i
    in_q = in_sign.q

    out_valid = out_sign.valid
    out_last = out_sign.last
    out_i = out_sign.i
    out_q = out_sign.q

    s = len(in_i) + len(gain_i)
    mul_i = Signal(intbv(0, min=-2**s, max=2**s))
    mul_q = Signal(intbv(0, min=-2**s, max=2**s))
    mul_valid = Signal(bool(False))
    mul_last = Signal(bool(False))

    @always_seq(clock.posedge, reset=clearn)
    def gain_correct():
        if in_valid:
            mul_valid.next = in_valid
            mul_last.next = in_last

            #print 'i', ia.signed()/2.**9, '*', ix.signed() / float(ix.max), '=', ia.signed()/2**9 * (ix.signed() / float(ix.max))

            mul_i.next = in_i.signed() * concat(bool(0), gain_i).signed()
            mul_q.next = in_q.signed() * concat(bool(0), gain_q).signed()
        else:
            mul_valid.next = False
            mul_last.next = False
            mul_i.next = 0
            mul_q.next = 0

        if mul_valid:
            out_valid.next = mul_valid
            out_last.next = mul_last
            #print 'm', mul_q[len(mul_q)-2] ^ mul_q[len(mul_q)-3]
            out_i.next = mul_i[len(mul_i) - 2:len(mul_i) - len(out_i) -
                               2].signed()
            out_q.next = mul_q[len(mul_q) - 2:len(mul_q) - len(out_q) -
                               2].signed()
        else:
            out_valid.next = False
            out_last.next = False
            out_i.next = 0
            out_q.next = 0

    return gain_correct
Пример #16
0
def get_nibbles(n):
    return [Signal(intbv(0)[4:]) for i in range(n)]
Пример #17
0
from myhdl._compat import to_bytes
from myhdl._Cosimulation import Cosimulation, CosimulationError, _error
from utils import raises_kind

random.seed(1)  # random, but deterministic

MAXLINE = 4096

exe = "python {0} ".format(os.path.abspath(__file__))

fromSignames = ['a', 'bb', 'ccc']
fromSizes = [1, 11, 63]
fromVals = [0x2, 0x43, 0x24]
fromSigs = {}
for s, v in zip(fromSignames, fromVals):
    fromSigs[s] = Signal(v)
toSignames = ['d', 'ee', 'fff', 'g']
toSizes = [32, 12, 3, 6]
toSigs = {}
for s in toSignames:
    toSigs[s] = Signal(0)
toVals = [0x3, 0x45, 0x14, 0x12]
toXVals = ["X00", "FZ3", "34XZ", "56U"]
allSigs = fromSigs.copy()
allSigs.update(toSigs)


class TestCosimulation:
    def setup_method(self, method):
        gc.collect()
Пример #18
0
def rfe(
        resetn,
        pclk,
        paddr,
        psel,
        penable,
        pwrite,
        pwdata,
        pready,
        prdata,  #pslverr,
        clearn,
        clear_enable,
        loopen,
        tx_status_led,
        tx_dmaready,
        rx_status_led,
        rx_dmaready,
        tx_fifo_we,
        tx_fifo_wdata,
        tx_fifo_empty,
        tx_fifo_full,
        tx_fifo_afval,
        tx_fifo_aeval,
        tx_fifo_afull,
        tx_fifo_aempty,
        tx_fifo_wack,
        tx_fifo_dvld,
        tx_fifo_overflow,
        tx_fifo_underflow,
        tx_fifo_rdcnt,
        tx_fifo_wrcnt,
        rx_fifo_re,
        rx_fifo_rdata,
        rx_fifo_empty,
        rx_fifo_full,
        rx_fifo_afval,
        rx_fifo_aeval,
        rx_fifo_afull,
        rx_fifo_aempty,
        rx_fifo_wack,
        rx_fifo_dvld,
        rx_fifo_overflow,
        rx_fifo_underflow,
        rx_fifo_rdcnt,
        rx_fifo_wrcnt,
        fir_load_coeff_ram_addr,
        fir_load_coeff_ram_din0,
        fir_load_coeff_ram_din1,
        fir_load_coeff_ram_blk,
        fir_load_coeff_ram_wen,
        fir_load_coeff_ram_dout0,
        fir_load_coeff_ram_dout1,
        firen,
        fir_bank1,
        fir_bank0,
        fir_N,
        interp,
        shift,
        fcw,
        tx_correct_i,
        tx_correct_q,
        tx_gain_i,
        tx_gain_q,
        txen,
        txstop,
        ddsen,
        txfilteren,
        decim,
        rx_correct_i,
        rx_correct_q,
        rxen,
        rxstop,
        rxfilteren,
        duc_underrun,
        dac_last,
        ddc_overrun,
        adc_last,
        **kwargs):
    """The Radio Front End glues together the APB3 interface and the
    DSP chains.  It consists of a synchronizer and a controller.

    The synchronizer safely transfers register data between the system and
    sample clock domains.

    The controller responds to read and write requests to the register file
    on the APB3 bus.

    :returns: A MyHDL synthesizable module
    """

    state_t = enum(
        'IDLE',
        'ACCESS',
        'READ',
        'READ2',
        'READ_SAMPLE',
        'READ_SAMPLE2',
        'READ_SAMPLE3',
        'READ_SAMPLE4',
        'DONE',
    )
    state = Signal(state_t.IDLE)

    addr = Signal(intbv(0)[8:])

    # Local registers #
    overrun = Signal(modbv(0, min=0, max=2**16))
    underrun = Signal(modbv(0, min=0, max=2**16))
    counter = Signal(intbv(0)[len(prdata):])
    afval = Signal(intbv(0)[len(tx_fifo_afval):])
    aeval = Signal(intbv(0)[len(tx_fifo_aeval):])

    # Synchronizer registers #
    sync_clearn = Signal(bool(1))
    clear_ackn = Signal(bool(1))

    sync_tx_afull = Signal(bool(0))
    tx_afull = Signal(bool(0))
    sync_tx_aempty = Signal(bool(1))
    tx_aempty = Signal(bool(1))
    sync_tx_underrun = Signal(modbv(0, min=0, max=2**16))
    tx_underrun = Signal(modbv(0, min=0, max=2**16))
    sync_txlast = Signal(bool(0))
    txlast = Signal(bool(0))

    sync_rx_afull = Signal(bool(0))
    rx_afull = Signal(bool(0))
    sync_rx_aempty = Signal(bool(1))
    rx_aempty = Signal(bool(1))
    sync_rx_overrun = Signal(modbv(0, min=0, max=2**16))
    rx_overrun = Signal(modbv(0, min=0, max=2**16))
    sync_rxlast = Signal(bool(0))
    rxlast = Signal(bool(0))

    write_count = Signal(intbv(0)[32:])
    read_count = Signal(intbv(0)[32:])

    @always_seq(pclk.posedge, reset=resetn)
    def synchronizer():
        sync_clearn.next = clearn
        clear_ackn.next = sync_clearn

        sync_tx_afull.next = tx_fifo_afull
        tx_afull.next = sync_tx_afull
        sync_tx_aempty.next = tx_fifo_aempty
        tx_aempty.next = sync_tx_aempty
        sync_tx_underrun.next = duc_underrun
        tx_underrun.next = sync_tx_underrun
        sync_txlast.next = dac_last
        txlast.next = sync_txlast

        sync_rx_afull.next = rx_fifo_afull
        rx_afull.next = sync_rx_afull
        sync_rx_aempty.next = rx_fifo_aempty
        rx_aempty.next = sync_rx_aempty
        sync_rx_overrun.next = ddc_overrun
        rx_overrun.next = sync_rx_overrun
        sync_rxlast.next = adc_last
        rxlast.next = sync_rxlast

    len_fir_load_coeff_ram_din = len(fir_load_coeff_ram_din0) + len(
        fir_load_coeff_ram_din1)
    len_fir_N = len(fir_N)
    fir_load_coeff_k = Signal(intbv(0, min=0, max=fir_N.max))
    fir_accessing = Signal(bool(0))
    fir_accessing_next = Signal(bool(0))

    @always_seq(pclk.posedge, reset=resetn)
    def coeff_controller():
        if state == state_t.IDLE:
            if psel and fir_accessing:
                fir_load_coeff_ram_blk.next = False
                fir_load_coeff_ram_addr.next = concat(fir_bank1, fir_bank0,
                                                      fir_load_coeff_k)
                fir_load_coeff_ram_wen.next = not pwrite  # active high to active low
                fir_load_coeff_ram_din0.next = pwdata[9:]
                fir_load_coeff_ram_din1.next = pwdata[18:9]
            else:
                fir_load_coeff_ram_blk.next = True
        elif state == state_t.ACCESS:
            if psel and fir_accessing and not pwrite:
                fir_load_coeff_ram_blk.next = False  # Pipelined read
            else:
                fir_load_coeff_ram_blk.next = True
        else:
            fir_load_coeff_ram_blk.next = True

    @always_seq(pclk.posedge, reset=resetn)
    def controller():
        #pslverr.next = 0
        tx_dmaready.next = not tx_fifo_full
        rx_dmaready.next = not rx_fifo_empty

        tx_status_led.next = txen or ddsen
        rx_status_led.next = rxen

        if not clear_ackn:
            clear_enable.next = False
            txen.next = 0
            txstop.next = 0
            ddsen.next = 0
            overrun.next = 0
            rxen.next = 0
            rxstop.next = 0
            underrun.next = 0
            write_count.next = 0
            fir_accessing.next = 0

        if txlast:
            txen.next = 0
            txstop.next = 0

        if rxlast:
            rxen.next = 0
            rxstop.next = 0

        if state == state_t.IDLE:
            if not psel:
                state.next = state_t.IDLE
            else:
                state.next = state_t.ACCESS
                addr.next = paddr[8:]
                pready.next = False
        if state == state_t.ACCESS:
            if fir_accessing:
                fir_load_coeff_k.next = fir_load_coeff_k + 1
                if pwrite:
                    state.next = state_t.DONE
                    pready.next = True
                else:
                    pready.next = False
                    state.next = state_t.READ
            else:
                if not pwrite and addr == WR_SAMPLE_ADDR:
                    pready.next = False
                    state.next = state_t.READ_SAMPLE
                else:
                    pready.next = True
                    state.next = state_t.DONE
                if pwrite:
                    if addr == WE_SAMPLE_ADDR:
                        write_count.next = write_count + 1
                        if tx_fifo_full:
                            overrun.next = overrun + 1
                        else:
                            tx_fifo_wdata.next = pwdata
                            tx_fifo_we.next = True
                    elif addr == WE_STATUS_ADDR:
                        if pwdata[WS_CLEAR]:
                            clear_enable.next = True
                        elif pwdata[WS_LOOPEN]:
                            loopen.next = pwdata[WS_LOOPEN]
                        elif pwdata[WES_TXSTOP]:
                            txstop.next = True
                        else:
                            txen.next = pwdata[WES_TXEN]
                            txfilteren.next = pwdata[WES_FILTEREN]
                            ddsen.next = pwdata[WES_DDSEN]
                            firen.next = pwdata[WS_FIREN]
                    elif addr == WE_INTERP_ADDR:
                        interp.next = pwdata[len(interp):]
                        shift.next = pwdata[len(shift) + 16:16]
                    elif addr == WE_FCW_ADDR:
                        fcw.next = pwdata
                    elif addr == WE_THRESHOLD_ADDR:
                        tx_fifo_afval.next = pwdata[26:16]
                        tx_fifo_aeval.next = pwdata[10:]
                    elif addr == WE_CORRECTION_ADDR:
                        tx_correct_q.next = pwdata[26:16].signed()
                        tx_correct_i.next = pwdata[10:].signed()
                    elif addr == WE_GAIN_ADDR:
                        tx_gain_q.next = pwdata[26:16]
                        tx_gain_i.next = pwdata[10:]
                    elif addr == W_FIR_ADDR:
                        fir_bank1.next = pwdata[len_fir_N + 2]
                        fir_bank0.next = pwdata[len_fir_N + 1]
                        fir_N.next = pwdata[len_fir_N + 1:]
                        #fir_accessing.next = pwdata[WF_ACCESS_COEFFS]
                        fir_accessing_next.next = pwdata[WF_ACCESS_COEFFS]
                        fir_load_coeff_k.next = 0
                    elif addr == WR_STATUS_ADDR:
                        if pwdata[WS_CLEAR]:
                            clear_enable.next = True
                        elif pwdata[WS_LOOPEN]:
                            loopen.next = pwdata[WS_LOOPEN]
                        elif pwdata[WRS_RXSTOP]:
                            rxstop.next = True
                        else:
                            rxen.next = pwdata[WRS_RXEN]
                            rxfilteren.next = pwdata[WRS_FILTEREN]
                    elif addr == WR_DECIM_ADDR:
                        decim.next = pwdata[len(decim):]
                    elif addr == WR_THRESHOLD_ADDR:
                        rx_fifo_afval.next = pwdata[26:16]
                        rx_fifo_aeval.next = pwdata[10:]
                    elif addr == WR_CORRECTION_ADDR:
                        rx_correct_q.next = pwdata[26:16].signed()
                        rx_correct_i.next = pwdata[10:].signed()
                else:
                    if addr == WE_STATUS_ADDR:
                        prdata.next = concat(
                            # BYTE 3 NIBBLE 2 - RESERVED
                            intbv(0)[4:],
                            # BYTE 3 NIBBLE 1 - COMBINED FLAGS
                            intbv(0)[3:],
                            firen,
                            # BYTE 2 NIBBLE 2 - RX FIFO FLAGS
                            intbv(0)[4:],
                            # BYTE 2 NIBBLE 1 - RX DSP FLAGS
                            intbv(0)[4:],
                            # BYTE 1 NIBBLE 2 - TX FIFO FLAGS
                            not tx_fifo_empty,
                            not tx_fifo_full,
                            tx_afull,
                            tx_aempty,
                            # BYTE 1 NIBBLE 1 - TX DSP FLAGS
                            bool(0),
                            ddsen,
                            txfilteren,
                            txen,
                            # BYTE 0 - RESERVED
                            intbv(0)[6:],
                            loopen,
                            not clearn)
                    elif addr == WE_INTERP_ADDR:
                        prdata.next = concat(
                            intbv(0)[16 - len(shift):], shift,
                            intbv(0)[16 - len(interp):], interp)
                    elif addr == WE_FCW_ADDR:
                        prdata.next = fcw
                    elif addr == WE_RUNS_ADDR:
                        prdata.next = concat(tx_underrun, overrun)
                    elif addr == WE_THRESHOLD_ADDR:
                        prdata.next = concat(
                            intbv(0)[6:], tx_fifo_afval,
                            intbv(0)[6:], tx_fifo_aeval)
                    elif addr == WE_CORRECTION_ADDR:
                        prdata.next = concat(
                            intbv(0)[6:], tx_correct_q,
                            intbv(0)[6:], tx_correct_i)
                    elif addr == WE_GAIN_ADDR:
                        prdata.next = concat(
                            intbv(0)[6:], tx_gain_q,
                            intbv(0)[6:], tx_gain_i)
                    elif addr == WE_AVAILABLE_ADDR:
                        prdata.next = concat(
                            intbv(0)[32 - len(tx_fifo_wrcnt):], tx_fifo_wrcnt)
                    elif addr == WE_DEBUG_ADDR:
                        prdata.next = write_count
                    elif addr == W_FIR_ADDR:
                        prdata.next = concat(
                            intbv(0)[32 - len_fir_N - 2:], fir_bank1,
                            fir_bank0, fir_N)
                    elif addr == WR_SAMPLE_ADDR:
                        read_count.next = read_count + 1
                        if rx_fifo_empty:
                            underrun.next = underrun + 1
                        else:
                            rx_fifo_re.next = True
                    elif addr == WR_STATUS_ADDR:
                        prdata.next = concat(
                            # BYTE 3 NIBBLE 2 - RESERVED
                            intbv(0)[4:],
                            # BYTE 3 NIBBLE 1 - COMBINED FLAGS
                            intbv(0)[3:],
                            firen,
                            # BYTE 2 NIBBLE 2 - RX FIFO FLAGS
                            not rx_fifo_empty,
                            not rx_fifo_full,
                            rx_afull,
                            rx_aempty,
                            # BYTE 2 NIBBLE 1 - RX DSP FLAGS
                            bool(0),
                            bool(0),
                            rxfilteren,
                            rxen,
                            # BYTE 1 NIBBLE 2 - TX FIFO FLAGS
                            intbv(0)[4:],
                            # BYTE 1 NIBBLE 1 - TX DSP FLAGS
                            intbv(0)[4:],
                            # BYTE 0 - Misc Flags
                            intbv(0)[6:],
                            loopen,
                            not clearn)
                    elif addr == WR_DECIM_ADDR:
                        prdata.next = concat(intbv(0)[32 - len(decim):], decim)
                    elif addr == WR_RUNS_ADDR:
                        prdata.next = concat(rx_overrun, underrun)
                    elif addr == WR_THRESHOLD_ADDR:
                        prdata.next = concat(
                            intbv(0)[6:], rx_fifo_afval,
                            intbv(0)[6:], rx_fifo_aeval)
                    elif addr == WR_CORRECTION_ADDR:
                        prdata.next = concat(
                            intbv(0)[6:], rx_correct_q,
                            intbv(0)[6:], rx_correct_i)
                    elif addr == WR_AVAILABLE_ADDR:
                        prdata.next = concat(
                            intbv(0)[32 - len(rx_fifo_rdcnt):], rx_fifo_rdcnt)
                    elif addr == WR_DEBUG_ADDR:
                        prdata.next = intbv(0)[32:]
                    else:
                        prdata.next = 0
        elif state == state_t.READ:
            pready.next = False
            state.next = state_t.READ2
        elif state == state_t.READ2:
            pready.next = True
            prdata.next = concat(fir_load_coeff_ram_dout1,
                                 fir_load_coeff_ram_dout0).signed()
            state.next = state_t.DONE
        elif state == state_t.READ_SAMPLE:
            pready.next = False
            rx_fifo_re.next = False
            state.next = state_t.READ_SAMPLE2
        elif state == state_t.READ_SAMPLE2:
            pready.next = False
            rx_fifo_re.next = False
            state.next = state_t.READ_SAMPLE3
        elif state == state_t.READ_SAMPLE3:
            pready.next = False
            rx_fifo_re.next = False
            state.next = state_t.READ_SAMPLE4
        elif state == state_t.READ_SAMPLE4:
            pready.next = True
            rx_fifo_re.next = False
            prdata.next = rx_fifo_rdata
            state.next = state_t.DONE
        elif state == state_t.DONE:
            tx_fifo_we.next = False
            rx_fifo_re.next = False
            pready.next = True
            state.next = state_t.IDLE
            fir_accessing_next.next = False
            if not fir_accessing:
                fir_accessing.next = fir_accessing_next
            elif fir_load_coeff_k == fir_N:
                fir_accessing.next = False

    return synchronizer, controller, coeff_controller
Пример #19
0
def testbench(vhdl_output_path=None):

    reset = ResetSignal(0, active=0, async=False)
    clk = Signal(bool(0))

    axis_raw = Axis(32)
    axis_sum = Axis(32)

    clk_gen = clk_stim(clk, period=10)

    @instance
    def reset_gen():
        reset.next = 0
        yield delay(54)
        yield clk.negedge
        reset.next = 1

    @instance
    def write_stim():
        #values = [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
        values = [106, 118, 151, 147, 149, 145, 155, 129, 166, 156, 141, 153, 130, 150, 160, 137, 150, 133, 105, 106, 131, 101, 112, 108, 83, 100, 102, 72, 70, 105, 78, 91, 108, 83, 93, 87, 89, 97, 114, 126, 136, 114, 146, 140, 138, 127, 127, 146, 135, 138, 148, 148, 137, 125, 161, 133, 123, 117, 116, 135, 132, 124, 90, 97, 88, 99, 105, 90, 106, 76, 90, 105, 108, 99, 102, 105, 99, 91, 116, 105, 115, 115, 117, 146, 156, 163, 135, 153, 140, 145, 138, 148, 134, 131, 131, 136, 126, 144, 127, 0]

        # values = []
        # for i in range(1, 500):
        #     values.append(int(100 + 40*random() + 30 * math.sin(2 * math.pi * 0.005 * i)))
        #
        # values.append(0)
        i = 0
        yield reset.posedge
        while i < len(values):
            yield clk.negedge
            axis_raw.tvalid.next = 1
            axis_raw.tdata.next = values[i]
            if i == len(values) - 1:
                axis_raw.tlast.next = 1
            else:
                axis_raw.tlast.next = 0
            if axis_raw.tready == 1:
                i += 1
        yield clk.negedge
        axis_raw.tvalid.next = 0

    @instance
    def read_stim():
        yield reset.posedge
        yield delay(601)
        yield clk.negedge
        axis_sum.tready.next = 1
        for _ in range(200):
        # while True:
            yield clk.negedge
            if axis_sum.tlast == 1:
                break

        for i in range(10):
            yield clk.negedge
        raise StopSimulation()

    uut = my_rc(clk, reset, axis_raw, axis_sum)

    if vhdl_output_path is not None:
        uut.convert(hdl='VHDL', path=vhdl_output_path)
    return instances()
Пример #20
0
def test_underflow_fifo_fast(args=None):
    """ verify the synchronous FIFO
    """
    reset = ResetSignal(0, active=1, async=True)
    clock = Signal(bool(0))

    if args is None:
        args = Namespace(width=8, size=16, name='test')
    else:
        # @todo: verify args has the attributes needed for the FIFOBus
        pass

    fbus = FIFOBus(width=args.width)
    glbl = Global(clock, reset)

    @myhdl.block
    def bench_fifo_underflow():
        # @todo: use args.fast, args.use_srl_prim
        tbdut = cores.fifo.fifo_fast(glbl,
                                     fbus,
                                     size=args.size,
                                     use_srl_prim=False)

        @always(delay(10))
        def tbclk():
            clock.next = not clock

        @instance
        def tbstim():
            fbus.write_data.next = 0xFE
            reset.next = reset.active
            yield delay(33)
            reset.next = not reset.active
            for ii in range(5):
                yield clock.posedge

            rand = randrange(args.size + 2, 2 * args.size + 1)
            for num_bytes in range(args.size, rand):

                for ii in range(args.size):
                    try:
                        fbus.write_data.next = ii
                        fbus.write.next = True
                        yield clock.posedge
                    except ValueError:
                        assert fbus.count == args.size
                        assert fbus.full, "FIFO should be full!"
                        assert not fbus.empty, "FIFO should not be empty"
                    else:
                        assert fbus.count <= args.size
                        if (fbus.count < args.size):
                            assert not fbus.full

                fbus.write.next = False
                fbus.write_data.next = 0xFE
                for delay_clk in range(5):
                    yield clock.posedge

                if ii == (args.size - 1):
                    assert fbus.count == args.size
                    assert fbus.full, "FIFO should be full!"
                    assert not fbus.empty, "FIFO should not be empty"

                yield clock.posedge

                for ii in range(num_bytes):
                    try:
                        fbus.read.next = True
                        yield clock.posedge
                        # yield clock.posedge
                        # test works for 2
                        # yield clock.posedge stmts
                    except ValueError:
                        assert fbus.empty
                    else:
                        # print("rdata %x ii %x " % (fbus.read_data, ii))
                        assert fbus.read_valid
                        assert fbus.read_data == ii, "rdata %x ii %x " % (
                            fbus.read_data, ii)

                fbus.read.next = False
                yield clock.posedge
                assert fbus.empty

            fbus.clear.next = True
            yield clock.posedge
            fbus.clear.next = not fbus.clear
            for ii in range(5):
                yield clock.posedge
            raise StopSimulation

        return myhdl.instances()

    with pytest.raises(ValueError):
        run_testbench(bench_fifo_underflow)
Пример #21
0
def core_testbench(hex_file):
    """
    Connect the Core to the simulation memory, using wishbone interconnects.
    Assert the core for RESET_TIME.

    Finish the test after TIMEOUT units of time, or a write to toHost register.
    If toHost is different of 1, the test failed.
    """
    clk = Signal(True)
    rst = Signal(False)
    imem = WishboneIntercon()
    dmem = WishboneIntercon()

    toHost = Signal(modbv(0)[32:])

    config = cp.ConfigParser()
    config.read('Simulation/core/algol.ini')

    dut_core = Core(clk_i=clk,
                    rst_i=rst,
                    imem=imem,
                    dmem=dmem,
                    toHost=toHost,
                    IC_ENABLE=config.getboolean('ICache', 'Enable'),
                    IC_BLOCK_WIDTH=config.getint('ICache', 'BlockWidth'),
                    IC_SET_WIDTH=config.getint('ICache', 'SetWidth'),
                    IC_NUM_WAYS=config.getint('ICache', 'Ways'),
                    DC_ENABLE=config.getboolean('DCache', 'Enable'),
                    DC_BLOCK_WIDTH=config.getint('DCache', 'BlockWidth'),
                    DC_SET_WIDTH=config.getint('DCache', 'SetWidth'),
                    DC_NUM_WAYS=config.getint('DCache', 'Ways'))

    memory = Memory(clka_i=clk,
                    rsta_i=rst,
                    imem=imem,
                    clkb_i=clk,
                    rstb_i=rst,
                    dmem=dmem,
                    SIZE=int(config.get('Memory', 'Size'), 16),
                    HEX=hex_file,
                    BYTES_X_LINE=config.getint('Memory', 'Bytes_x_line'))

    @always(delay(int(TICK_PERIOD / 2)))
    def gen_clock():
        clk.next = not clk

    @always(toHost)
    def toHost_check():
        """
        Wait for a write to toHost register.
        """
        if toHost != 1:
            raise Error('Test failed. MTOHOST = {0}. Time = {1}'.format(
                toHost, now()))
        print("Time: {0}".format(now()))
        raise StopSimulation

    @instance
    def timeout():
        """
        Wait until timeout.
        """
        rst.next = True
        yield delay(RESET_TIME * TICK_PERIOD)
        rst.next = False
        yield delay(TIMEOUT * TICK_PERIOD)
        raise Error("Test failed: Timeout")

    return dut_core, memory, gen_clock, timeout, toHost_check
Пример #22
0
def trellis2(clk,
             rst,
             selState,
             state,
             selTrans,
             weight,
             llr0,
             llr1,
             llr2,
             llr3,
             a,
             b,
             m=10,
             q=8):
    """ Second trellis and revision logic.
    
    m           -- second trellis length
    q           -- accumulated distance width
    clk, rst    -- in  : clock and negative reset
    selState    -- in  : selected state at time (l - 1)
    state       -- in  : 4 possible states at time (l - 1)
    selTrans    -- in  : 8 selected transitions (1 per state) at time (l - 1)
    weight      -- in  : four weights sorted by transition code at time (l - 1)
    llr0        -- out : LLR for (a, b) = (0, 0) at time (l + m - 1)
    llr1        -- out : LLR for (a, b) = (0, 1) at time (l + m - 1)
    llr2        -- out : LLR for (a, b) = (1, 0) at time (l + m - 1)
    llr3        -- out : LLR for (a, b) = (1, 1) at time (l + m - 1)
    a, b        -- out : decoded values of (a, b) at time (l + m - 1)

    """
    reg = [[Signal(intbv(0, 0, 4)) for i in range(8)] for j in range(m)]
    free = intbv(255, 0, 256)
    freeBeg = [bool(1) for i in range(8)]
    pastState = [intbv(0, 0, 8) for i in range(8)]
    pathIdReg = [Signal(intbv(i, 0, 8)) for i in range(8)]
    pathId = [intbv(0, 0, 8) for i in range(8)]
    freePathId = intbv(0, 0, 8)
    revWeight = [[Signal(intbv(0, 0, 2**q)) for i in range(m)]
                 for j in range(4)]
    revWeightTmp = [[intbv(0, 0, 2**q) for i in range(m)] for j in range(4)]
    revWeightFilt = [intbv(0, 0, 2**q) for j in range(3)]
    op = [intbv(0, 0, 2**q) for i in range(4)]
    tmp = [intbv(0, 0, 2**q) for i in range(4)]
    tmp4 = intbv(0, 0, 2**(q + 1))
    notZero = [[intbv(0, 0, 4) for i in range(3)] for j in range(2)]
    ind = [[intbv(0, 0, 4) for i in range(3)] for j in range(2)]
    minTmp = [bool(0) for i in range(3)]

    @always(clk.posedge, rst.negedge)
    def trellis2Logic():
        if rst.val == 0:
            for i in range(4):
                for j in range(m):
                    revWeight[i][j].next = 0
            a.next = 0
            b.next = 0
            llr0.next = 0
            llr1.next = 0
            llr2.next = 0
            llr3.next = 0
            for i in range(8):
                pathIdReg[i].next = i
                for j in range(m):
                    reg[j][i].next = 0
        else:
            free = intbv(255)
            for i in range(8):
                pastState[i] = trans2state[i][int(selTrans[i].val)]
                pathId[i] = pathIdReg[pastState[i]].val
                free[int(pathId[i])] = 0
            freeBeg = [bool(1) for i in range(8)]
            for i in range(8):
                if freeBeg[int(pathId[i])] == 1:
                    reg[0][int(pathId[i])].next = selTrans[i].val
                    freeBeg[int(pathId[i])] = 0
                    pathIdReg[i].next = pathId[i]
                    for j in range(m - 1):
                        reg[j + 1][int(pathId[i])].next = reg[j][int(
                            pathId[i])].val
                else:
                    if free[1:0] == 1:
                        freePathId = 0
                    if free[2:0] == 2:
                        freePathId = 1
                    if free[3:0] == 4:
                        freePathId = 2
                    if free[4:0] == 8:
                        freePathId = 3
                    if free[5:0] == 16:
                        freePathId = 4
                    if free[6:0] == 32:
                        freePathId = 5
                    if free[7:0] == 64:
                        freePathId = 6
                    if free[8:0] == 128:
                        freePathId = 7
                    reg[0][freePathId].next = selTrans[i].val
                    free[freePathId] = 0
                    pathIdReg[i].next = freePathId
                    for j in range(m - 1):
                        reg[j + 1][freePathId].next = reg[j][int(
                            pathId[i])].val
            a.next = reg[m - 1][int(pathId[int(selState.val)])].val[1]
            b.next = reg[m - 1][int(pathId[int(selState.val)])].val[0]
            for i in range(4):
                for j in range(m - 1):
                    for k in range(4):
                        if reg[j][int(
                                pathId[int(state[k].val)]
                        )].val == i and state[k].val != selState.val:
                            op[k] = weight[k].val
                        else:
                            op[k] = (2**q) - 1
                    if op[0] < op[1]:
                        tmp[0] = op[0]
                    else:
                        tmp[0] = op[1]
                    if op[2] < op[3]:
                        tmp[1] = op[2]
                    else:
                        tmp[1] = op[3]
                    if tmp[0] < tmp[1]:
                        tmp[2] = tmp[0]
                    else:
                        tmp[2] = tmp[1]
                    if tmp[2] < revWeight[i][j].val:
                        revWeightTmp[i][j + 1] = tmp[2]
                    else:
                        revWeightTmp[i][j + 1] = revWeight[i][j].val
                revWeightTmp[i][0] = weight[i].val
            for j in range(2):
                if revWeightTmp[0][j] == 0:
                    notZero[j] = [1, 2, 3]
                elif revWeightTmp[1][j] == 0:
                    notZero[j] = [0, 2, 3]
                elif revWeightTmp[2][j] == 0:
                    notZero[j] = [0, 1, 3]
                elif revWeightTmp[3][j] == 0:
                    notZero[j] = [0, 1, 2]
                if revWeightTmp[int(notZero[j][0])][j] <= revWeightTmp[int(
                        notZero[j][1])][j]:
                    minTmp[0] = 0
                else:
                    minTmp[0] = 1
                if revWeightTmp[int(notZero[j][0])][j] <= revWeightTmp[int(
                        notZero[j][2])][j]:
                    minTmp[1] = 0
                else:
                    minTmp[1] = 1
                if revWeightTmp[int(notZero[j][1])][j] <= revWeightTmp[int(
                        notZero[j][2])][j]:
                    minTmp[2] = 0
                else:
                    minTmp[2] = 1
                if minTmp == [0, 0, 0]:
                    ind[j] = [0, 1, 2]
                elif minTmp == [0, 0, 1]:
                    ind[j] = [0, 2, 1]
                elif minTmp == [1, 0, 0]:
                    ind[j] = [1, 0, 2]
                elif minTmp == [0, 1, 1]:
                    ind[j] = [1, 2, 0]
                elif minTmp == [1, 1, 0]:
                    ind[j] = [2, 0, 1]
                elif minTmp == [1, 1, 1]:
                    ind[j] = [2, 1, 0]
                else:
                    print("ERROR: Configuration does not exist", minTmp)
            for i in range(3):
                tmp[3] = revWeightTmp[int(notZero[0][int(ind[0][i])])][0]
                tmp4 = revWeightTmp[int(notZero[1][int(
                    ind[1][i])])][1] + (2**(q - 4))
                if tmp[3] < tmp4:
                    revWeightFilt[int(ind[0][i])] = tmp[3]
                else:
                    revWeightFilt[int(ind[0][i])] = intbv(tmp4)[q:0]
            for i in range(3):
                revWeightTmp[int(notZero[0][i])][0] = revWeightFilt[i]
            for i in range(4):
                for j in range(m):
                    revWeight[i][j].next = revWeightTmp[i][j]
            llr0.next = revWeight[0][m - 1]
            llr1.next = revWeight[1][m - 1]
            llr2.next = revWeight[2][m - 1]
            llr3.next = revWeight[3][m - 1]

    return trellis2Logic
Пример #23
0
 def __init__(self, n):
     self.a = Signal(False)
     self.b = Signal(intbv(0)[n:])
     self.c = Signal(False)
Пример #24
0
def trellis1(clk,
             rst,
             selState,
             selTrans,
             selStateL2,
             selStateL1,
             stateL1,
             selTransL2,
             l=20):
    """ First trellis.

    l           -- first trellis length
    clk, rst    -- in  : clock and negative reset
    selState    -- in  : selected state at time 0
    selTrans    -- in  : 8 selected transitions (1 per state) at time 0
    selStateL2  -- out : selected state at time (l - 2)
    selStateL1  -- out : selected state at time (l - 1)
    stateL1     -- out : 4 possible states at time (l - 1)
    selTransL2  -- out : selected transition at time (l - 2)

    """
    reg = [[Signal(intbv(0, 0, 4)) for i in range(8)] for j in range(l)]
    free = intbv(255, 0, 256)
    freeBeg = [bool(1) for i in range(8)]
    pastState = [intbv(0, 0, 8) for i in range(8)]
    pathIdReg = [Signal(intbv(i, 0, 8)) for i in range(8)]
    pathId = [intbv(0, 0, 8) for i in range(8)]
    freePathId = intbv(0, 0, 8)
    current_state = intbv(0, 0, 8)
    outState_l2 = intbv(0, 0, 8)
    outState_l1 = intbv(0, 0, 8)
    state_l3 = intbv(0, 0, 4)
    state_l2 = intbv(0, 0, 4)
    state_l1 = intbv(0, 0, 4)

    @always(clk.posedge, rst.negedge)
    def trellis1Logic():
        if rst.val == 0:
            for i in range(4):
                stateL1[i].next = 0
            selStateL1.next = 0
            selStateL2.next = 0
            selTransL2.next = 0
            for i in range(8):
                pathIdReg[i].next = i
                for j in range(l):
                    reg[j][i].next = 0
        else:
            free = intbv(255)
            for i in range(8):
                pastState[i] = trans2state[i][int(selTrans[i].val)]
                pathId[i] = pathIdReg[pastState[i]].val
                free[int(pathId[i])] = 0
            freeBeg = [bool(1) for i in range(8)]
            for i in range(8):
                current_state = intbv(i)
                if freeBeg[int(pathId[int(current_state)])] == 1:
                    reg[0][int(
                        pathId[int(current_state)])].next = current_state[2:0]
                    freeBeg[int(pathId[i])] = 0
                    pathIdReg[int(current_state)].next = pathId[int(
                        current_state)]
                    for j in range(l - 1):
                        reg[j + 1][int(
                            pathId[int(current_state)])].next = reg[j][int(
                                pathId[int(current_state)])].val
                else:
                    if free[0] == 1:
                        freePathId = 0
                    if free[2:0] == 2:
                        freePathId = 1
                    if free[3:0] == 4:
                        freePathId = 2
                    if free[4:0] == 8:
                        freePathId = 3
                    if free[5:0] == 16:
                        freePathId = 4
                    if free[6:0] == 32:
                        freePathId = 5
                    if free[7:0] == 64:
                        freePathId = 6
                    if free[8:0] == 128:
                        freePathId = 7
                    reg[0][freePathId].next = current_state[2:0]
                    free[freePathId] = 0
                    pathIdReg[int(current_state)].next = freePathId
                    for j in range(l - 1):
                        reg[j + 1][freePathId].next = reg[j][int(
                            pathId[int(current_state)])].val
            state_l3 = reg[l - 3][int(pathId[int(selState.val)])].val
            state_l2 = reg[l - 2][int(pathId[int(selState.val)])].val
            state_l1 = reg[l - 1][int(pathId[int(selState.val)])].val
            outState_l2[2] = state_l3[1] ^ (state_l3[0] ^ state_l2[1])
            outState_l2[2:0] = state_l2
            outState_l1[2] = state_l2[1] ^ (state_l2[0] ^ state_l1[1])
            outState_l1[2:0] = state_l1
            selStateL1.next = outState_l1
            selStateL2.next = outState_l2
            selTransL2.next = state2trans[int(outState_l2)][int(state_l1)]
            for i in range(4):
                stateL1[i].next = trans2state[int(outState_l2)][i]
            if __debug__:
                # Monitor: checks that in the first trellis, from each of the 8 states (trellis' beginning) we arrive at the same state (trellis' end).
                #          (Ignore this message until every iteration is fully started)
                diff = 0
                ref = intbv(0)
                tmp = intbv(0)
                state_l2_deb = reg[l - 2][int(pathId[7])].val
                state_l1_deb = reg[l - 1][int(pathId[7])].val
                ref[2] = state_l2_deb[1] ^ (state_l2_deb[0] ^ state_l1_deb[1])
                ref[2:0] = state_l1_deb
                for i in range(7):
                    state_l2_deb = reg[l - 2][int(pathId[i])].val
                    state_l1_deb = reg[l - 1][int(pathId[i])].val
                    tmp[2] = state_l2_deb[1] ^ (state_l2_deb[0]
                                                ^ state_l1_deb[1])
                    tmp[2:0] = state_l1_deb
                    if ref != tmp:
                        diff = 1
                if diff == 1:
                    print(
                        "WARNING: all paths don't arrive at same state at end of first trellis (you should think about increasing its length)"
                    )

    return trellis1Logic
Пример #25
0
def spi_slave_fifo(glbl, spibus, fifobus):
    """
    This is an SPI slave peripheral, when the master starts clocking
    any data in the TX FIFO (fifobus.write) will be sent (the next
    byte) and the received byte will be copied to RX FIFO
    (fifobus.read).  The `cso` interface can be used to configure
    how the SPI slave peripheral behaves.

    Arguments (Ports):
        glbl (Global): global clock and reset
        spibus  (SPIBus): the external SPI interface
        fifobus (FIFOBus): the fifo interface
        cso (ControlStatus): the control status signals
    """

    # Use an async FIFO to transfer from the SPI SCK clock domain and
    # the internal clock domain.  This allows for high-speed SCK.
    clock, reset = glbl.clock, glbl.reset
    assert isinstance(spibus, SPIBus)
    assert isinstance(fifobus, FIFOBus)

    sck, csn = spibus.sck, spibus.csn
    # the FIFOs for the receive and transmit (external perspective)
    readpath = FIFOBus(size=fifobus.size, width=fifobus.width)
    writepath = FIFOBus(size=fifobus.size, width=fifobus.width)

    # the FIFO instances
    # @todo: replace with fifo_fast
    tx_fifo_inst = fifo_fast(reset, clock, writepath)
    rx_fifo_inst = fifo_fast(reset, clock, readpath)
    mp_fifo_inst = fifobus.assign_read_write_paths(readpath, writepath)

    spi_start = Signal(bool(0))
    ireg, icap, icaps = Signals(intbv(0)[8:], 3)
    oreg, ocap = Signals(intbv(0)[8:], 2)
    bitcnt, b2, b3 = Signals(intbv(0, min=0, max=10), 3)

    @always(sck.posedge, csn.negedge)
    def csn_falls():
        if sck:
            spi_start.next = False
        elif not csn:
            spi_start.next = True

    # SCK clock domain, this allows high SCK rates
    @always(sck.posedge, csn.posedge)
    def sck_capture_send():
        if csn:
            b2.next = 0
            bitcnt.next = 0
        else:
            if bitcnt == 0 or spi_start:
                spibus.miso.next = ocap[7]
                oreg.next = (ocap << 1) & 0xFF
            else:
                spibus.miso.next = oreg[7]
                oreg.next = (oreg << 1) & 0xFF

            ireg.next = concat(ireg[7:0], spibus.mosi)
            bitcnt.next = bitcnt + 1
            if bitcnt == (8 - 1):
                bitcnt.next = 0
                b2.next = 8
                icap.next = concat(ireg[7:0], spibus.mosi)
            else:
                b2.next = 0

    # synchronize the SCK domain to the clock domain
    isync1_inst = syncro(clock, icap, icaps)
    isync2_inst = syncro(clock, b2, b3)

    gotit = Signal(bool(0))

    @always(clock.posedge)
    def beh_io_capture():
        # default no writes
        readpath.write.next = False
        writepath.read.next = False

        if b3 == 0:
            gotit.next = False
        elif b3 == 8 and not gotit:
            readpath.write.next = True
            readpath.write_data.next = icaps
            gotit.next = True
            ocap.next = writepath.read_data
            if not writepath.empty:
                writepath.read.next = True

    return myhdl.instances()
Пример #26
0
def latch_if_id(clk, rst, instruction_in, pc_adder_in, instruction_out, pc_adder_out, stall=Signal(intbv(0)[1:]) ):
    """
    Latch to control state between Instruction Fetch and Instruction Decoder

    clk -- trigger
    rst -- reset 
    instruction_in  -- 32 bits signal input
    pc_adder_in -- 32 bits signal input
    instruction_out  -- 32 bits signal output for instruction decoder
    pc_adder_out -- 32 bits signal output for pc_add

    stall -- inhibit the count increment
    """

    @always(clk.posedge, rst.posedge)

    def latch():
        if rst == 1:
            instruction_out.next = 0
            pc_adder_out.next = 0
        
        else:
            if not stall:
                instruction_out.next = instruction_in
                pc_adder_out.next = pc_adder_in


    return latch
Пример #27
0
def DCache(clk_i,
           rst_i,
           cpu,
           mem,
           invalidate,
           ENABLE=True,
           D_WIDTH=32,
           BLOCK_WIDTH=5,
           SET_WIDTH=9,
           WAYS=2,
           LIMIT_WIDTH=32):
    """
    The Instruction Cache module.

    :param clk:         System clock
    :param rst:         System reset
    :param cpu:         CPU slave interface (Wishbone Interconnect to master port)
    :param mem:         Memory master interface (Wishbone Interconnect to slave port)
    :param invalidate:  Invalidate the cache
    :param D_WIDTH:     Data width
    :param BLOCK_WIDTH: Address width for byte access inside a block line
    :param SET_WIDTH:   Address width for line access inside a block
    :param WAYS:        Number of ways for associative cache (Minimum: 2)
    :param LIMIT_WIDTH: Maximum width for address
    """
    if ENABLE:
        assert D_WIDTH == 32, "Error: Unsupported D_WIDTH. Supported values: {32}"
        assert BLOCK_WIDTH > 0, "Error: BLOCK_WIDTH must be a value > 0"
        assert SET_WIDTH > 0, "Error: SET_WIDTH must be a value > 0"
        assert not (WAYS & (WAYS - 1)), "Error: WAYS must be a power of 2"

        # --------------------------------------------------------------------------
        WAY_WIDTH            = BLOCK_WIDTH + SET_WIDTH  # cache mem address width
        TAG_WIDTH            = LIMIT_WIDTH - WAY_WIDTH  # tag size
        TAGMEM_WAY_WIDTH     = TAG_WIDTH + 2         # Add the valid and dirty bit
        TAGMEM_WAY_VALID     = TAGMEM_WAY_WIDTH - 2  # Valid bit index
        TAGMEM_WAY_DIRTY     = TAGMEM_WAY_WIDTH - 1  # Dirty bit index
        TAG_LRU_WIDTH        = (WAYS * (WAYS - 1)) >> 1  # (N*(N-1))/2
        # --------------------------------------------------------------------------
        dc_states = enum('IDLE',
                         'SINGLE',
                         'READ',
                         'WRITE',
                         'FETCH',
                         'EVICTING',
                         'FLUSH1',
                         'FLUSH2',
                         'FLUSH3')

        tag_rw_port        = [RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAGMEM_WAY_WIDTH) for i in range(WAYS)]
        tag_flush_port     = [RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAGMEM_WAY_WIDTH) for i in range(WAYS)]
        tag_lru_rw_port    = RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAG_LRU_WIDTH)
        tag_lru_flush_port = RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAG_LRU_WIDTH)
        cache_read_port   = [RAMIOPort(A_WIDTH=WAY_WIDTH - 2, D_WIDTH=D_WIDTH) for _ in range(0, WAYS)]
        cache_update_port = [RAMIOPort(A_WIDTH=WAY_WIDTH - 2, D_WIDTH=D_WIDTH) for _ in range(0, WAYS)]
        data_cache        = [cache_read_port[i].data_o for i in range(0, WAYS)]
        data_cache2       = [cache_update_port[i].data_o for i in range(0, WAYS)]
        tag_entry         = Signal(modbv(0)[TAG_WIDTH:])

        tag_in            = [Signal(modbv(0)[TAGMEM_WAY_WIDTH:]) for _ in range(0, WAYS)]
        tag_out           = [Signal(modbv(0)[TAGMEM_WAY_WIDTH:]) for _ in range(0, WAYS)]
        lru_in            = Signal(modbv(0)[TAG_LRU_WIDTH:])
        lru_out           = Signal(modbv(0)[TAG_LRU_WIDTH:])
        tag_we            = Signal(False)

        lru_select        = Signal(modbv(0)[WAYS:])
        current_lru       = Signal(modbv(0)[TAG_LRU_WIDTH:])
        update_lru        = Signal(modbv(0)[TAG_LRU_WIDTH:])
        access_lru        = Signal(modbv(0)[WAYS:])
        lru_pre           = Signal(modbv(0)[WAYS:])

        flush_addr        = Signal(modbv(0)[SET_WIDTH:])
        flush_we          = Signal(False)
        n_flush_addr      = Signal(modbv(0)[SET_WIDTH:])
        n_flush_we        = Signal(False)

        dc_update_addr    = Signal(modbv(0)[LIMIT_WIDTH - 2:])
        evict_data        = Signal(modbv(0)[32:])

        state             = Signal(dc_states.IDLE)
        n_state           = Signal(dc_states.IDLE)

        miss              = Signal(False)
        miss_w            = Signal(modbv(0)[WAYS:])
        miss_w_and        = Signal(False)
        valid             = Signal(False)
        dirty             = Signal(False)
        done              = Signal(False)

        final_flush       = Signal(False)
        final_access      = Signal(False)
        fetch             = Signal(False)
        evict             = Signal(False)

        use_cache         = Signal(False)

        cpu_wbs   = WishboneSlave(cpu)
        mem_wbm   = WishboneMaster(mem)
        cpu_busy  = Signal(False)
        cpu_err   = Signal(False)
        cpu_wait  = Signal(False)
        mem_read  = Signal(False)
        mem_write = Signal(False)
        mem_rmw   = Signal(False)

        @always_comb
        def next_state_logic():
            n_state.next = state
            if state == dc_states.IDLE:
                if invalidate:
                    # flush request
                    n_state.next = dc_states.FLUSH1
                elif cpu_wbs.cyc_i and not cpu_wbs.we_i and not use_cache:
                    # read (uncached)
                    n_state.next = dc_states.SINGLE
                elif cpu_wbs.cyc_i and not cpu_wbs.we_i:
                    # read (cached)
                    n_state.next = dc_states.READ
                elif cpu_wbs.cyc_i and cpu_wbs.we_i and not use_cache:
                    # write (uncached)
                    n_state.next = dc_states.SINGLE
                elif cpu_wbs.cyc_i and cpu_wbs.we_i:
                    # write (cached)
                    n_state.next = dc_states.WRITE
            elif state == dc_states.SINGLE:
                if done:
                    n_state.next = dc_states.IDLE
            elif state == dc_states.READ:
                if not miss:
                    # cache hit
                    n_state.next = dc_states.IDLE
                elif valid and dirty:
                    # cache is valid but dirty
                    n_state.next = dc_states.EVICTING
                else:
                    # cache miss
                    n_state.next = dc_states.FETCH
            elif state == dc_states.WRITE:
                if not miss:
                    # Hit
                    n_state.next = dc_states.IDLE
                elif valid and dirty:
                    # Cache miss. Line is valid but dirty: write back
                    n_state.next = dc_states.EVICTING
                else:
                    n_state.next = dc_states.FETCH
            elif state == dc_states.EVICTING:
                if done:
                    n_state.next = dc_states.FETCH
            elif state == dc_states.FETCH:
                if done:
                    n_state.next = dc_states.IDLE
            elif state == dc_states.FLUSH1:
                n_state.next = dc_states.FLUSH2
            elif state == dc_states.FLUSH2:
                if dirty:
                    n_state.next = dc_states.FLUSH3
                if final_flush:
                    n_state.next = dc_states.IDLE
                else:
                    n_state.next = dc_states.FLUSH1
            elif state == dc_states.FLUSH3:
                if done:
                    if final_flush:
                        n_state.next = dc_states.IDLE
                    else:
                        n_state.next = dc_states.FLUSH1

        @always(clk_i.posedge)
        def update_state():
            if rst_i:
                state.next = dc_states.IDLE
            else:
                state.next = n_state

        @always_comb
        def assignments():
            final_access.next = (dc_update_addr[BLOCK_WIDTH - 2:] == modbv(-1)[BLOCK_WIDTH - 2:]) and mem_wbm.ack_i and mem_wbm.cyc_o and mem_wbm.stb_o
            final_flush.next  = flush_addr == 0
            lru_select.next   = lru_pre
            current_lru.next  = lru_out
            access_lru.next   = ~miss_w
            use_cache.next    = not cpu_wbs.addr_i[31]  # Address < 0x8000_0000 use the cache

        @always_comb
        def tag_entry_assign():
            """
            Using the lru history, get the tag entry needed in case of evicting.
            """
            for i in range(0, WAYS):
                if lru_select[i]:
                    tag_entry.next = tag_out[i][TAG_WIDTH:]

        @always_comb
        def done_fetch_evict_assign():
            """
            Flags to indicate current state of the FSM.
            fetch: getting data from memory.
            evic: writing data from cache to memory.
            done: the last access to memory.
            """
            fetch.next = state == dc_states.FETCH and not final_access
            evict.next = (state == dc_states.EVICTING or state == dc_states.FLUSH3) and not final_access
            done.next  = final_access if use_cache else mem_wbm.ack_i

        @always_comb
        def miss_check():
            """
            For each way, check tag and valid flag, and reduce the vector using AND.
            If the vector is full of ones, the data is not in the cache: assert the miss flag.

            MISS: data not in cache and the memory operation is a valid read. Ignore this if
            the module is flushing data.
            """
            value = modbv(0)[WAYS:]
            for i in range(0, WAYS):
                value[i] = (not tag_out[i][TAGMEM_WAY_VALID] or tag_out[i][TAG_WIDTH:0] != cpu_wbs.addr_i[LIMIT_WIDTH:WAY_WIDTH])
            miss_w.next = value

        @always_comb
        def miss_check_2():
            """
            Vector reduce: check for full miss.
            """
            value = True
            for i in range(0, WAYS):
                value = value and miss_w[i]
            miss_w_and.next = value

        @always_comb
        def miss_check_3():
            """
            Check for valid wishbone cycle, and full miss.
            """
            valid_access = cpu_wbs.cyc_i and cpu_wbs.stb_i and use_cache
            miss.next    = miss_w_and and valid_access and not invalidate

        @always_comb
        def get_valid_n_dirty():
            """
            In case of miss get the valid and dirty flags, needed to detect
            if a evicting must be done first.
            """
            for i in range(0, WAYS):
                if lru_select[i]:
                    valid.next = tag_out[i][TAGMEM_WAY_VALID]
                    dirty.next = tag_out[i][TAGMEM_WAY_DIRTY]

        trwp_clk    = [tag_rw_port[i].clk for i in range(WAYS)]
        trwp_addr   = [tag_rw_port[i].addr for i in range(WAYS)]
        trwp_data_i = [tag_rw_port[i].data_i for i in range(WAYS)]
        trwp_data_o = [tag_rw_port[i].data_o for i in range(WAYS)]
        trwp_we     = [tag_rw_port[i].we for i in range(WAYS)]

        @always_comb
        def tag_rport():
            for i in range(WAYS):
                trwp_clk[i].next    = clk_i
                trwp_addr[i].next   = cpu_wbs.addr_i[WAY_WIDTH:BLOCK_WIDTH]
                trwp_data_i[i].next = tag_in[i]
                trwp_we[i].next     = tag_we
                tag_out[i].next     = trwp_data_o[i]
            # LRU memory
            tag_lru_rw_port.clk.next    = clk_i
            tag_lru_rw_port.data_i.next = lru_in
            lru_out.next                = tag_lru_rw_port.data_o
            tag_lru_rw_port.addr.next   = cpu_wbs.addr_i[WAY_WIDTH:BLOCK_WIDTH]
            tag_lru_rw_port.we.next     = tag_we

        @always_comb
        def tag_write():
            for i in range(0, WAYS):
                tag_in[i].next = tag_out[i]
            tag_we.next = False
            lru_in.next = lru_out

            if state == dc_states.READ or state == dc_states.WRITE:
                if miss:
                    for i in range(0, WAYS):
                        if lru_select[i]:
                            tag_in[i].next = concat(False, True, cpu_wbs.addr_i[LIMIT_WIDTH:WAY_WIDTH])
                    tag_we.next = True
                else:
                    if cpu_wbs.ack_o and cpu_wbs.cyc_i:
                        for i in range(0, WAYS):
                            if lru_select[i]:
                                tag_in[i].next = tag_out[i] | (cpu_wbs.we_i << TAGMEM_WAY_DIRTY)  # TODO: Optimize
                        lru_in.next = update_lru
                        tag_we.next = True

        @always_comb
        def flush_next_state():
            n_flush_we.next   = False
            n_flush_addr.next = flush_addr

            if state == dc_states.IDLE:
                if invalidate:
                    n_flush_addr.next = modbv(-1)[SET_WIDTH:]
            elif state == dc_states.FLUSH1:
                n_flush_we.next = True
            elif state == dc_states.FLUSH2:
                n_flush_we.next = False
                n_flush_addr.next = flush_addr - modbv(1)[SET_WIDTH:]

        @always(clk_i.posedge)
        def update_flush():
            if rst_i:
                flush_addr.next = modbv(-1)[SET_WIDTH:]
                flush_we.next   = False
            else:
                flush_addr.next = n_flush_addr
                flush_we.next   = n_flush_we and not dirty

        @always(clk_i.posedge)
        def update_addr_fsm():
            if rst_i:
                dc_update_addr.next  = 0
            else:
                if state == dc_states.READ or state == dc_states.WRITE:
                    if miss and not dirty:
                        dc_update_addr.next = concat(cpu_wbs.addr_i[LIMIT_WIDTH:BLOCK_WIDTH], modbv(0)[BLOCK_WIDTH - 2:])
                    elif miss and dirty:
                        dc_update_addr.next = concat(tag_entry, cpu_wbs.addr_i[WAY_WIDTH:2])
                elif state == dc_states.FLUSH2:
                    if dirty:
                        dc_update_addr.next = concat(tag_entry, modbv(0)[WAY_WIDTH - 2:])
                elif state == dc_states.EVICTING or state == dc_states.FETCH or state == dc_states.FLUSH3:
                    if final_access:
                        dc_update_addr.next = concat(cpu_wbs.addr_i[LIMIT_WIDTH:BLOCK_WIDTH], modbv(0)[BLOCK_WIDTH - 2:])
                    elif mem_wbm.ack_i and mem_wbm.stb_o:
                        dc_update_addr.next = dc_update_addr + modbv(1)[BLOCK_WIDTH - 2:]
                else:
                    dc_update_addr.next = 0

        tfp_clk    = [tag_flush_port[i].clk for i in range(WAYS)]
        tfp_addr   = [tag_flush_port[i].addr for i in range(WAYS)]
        tfp_data_i = [tag_flush_port[i].data_i for i in range(WAYS)]
        tfp_we     = [tag_flush_port[i].we for i in range(WAYS)]

        @always_comb
        def tag_flush_port_assign():
            for i in range(WAYS):
                tfp_clk[i].next    = clk_i
                tfp_addr[i].next   = flush_addr
                tfp_data_i[i].next = modbv(0)[TAGMEM_WAY_WIDTH:]
                tfp_we[i].next     = flush_we
            # connect to the LRU memory
            tag_lru_flush_port.clk.next    = clk_i
            tag_lru_flush_port.addr.next   = flush_addr
            tag_lru_flush_port.data_i.next = modbv(0)[TAG_LRU_WIDTH:]
            tag_lru_flush_port.we.next     = flush_we

        @always_comb
        def cpu_data_assign():
            temp = data_cache[0]
            for i in range(0, WAYS):
                if not miss_w[i]:
                    temp = data_cache[i]
            cpu_wbs.dat_o.next = temp if use_cache else mem_wbm.dat_i

        @always_comb
        def evict_data_assign():
            for i in range(0, WAYS):
                if lru_select[i]:
                    evict_data.next = data_cache2[i]

        @always_comb
        def mem_port_assign():
            mem_wbm.addr_o.next = concat(dc_update_addr, modbv(0)[2:]) if use_cache else cpu_wbs.addr_i
            mem_wbm.dat_o.next  = evict_data if use_cache else cpu_wbs.dat_i
            mem_wbm.sel_o.next  = modbv(0b1111)[4:] if use_cache else cpu_wbs.sel_i

        # To Verilog
        crp_clk    = [cache_read_port[i].clk for i in range(0, WAYS)]
        crp_addr   = [cache_read_port[i].addr for i in range(0, WAYS)]
        crp_data_i = [cache_read_port[i].data_i for i in range(0, WAYS)]
        crp_we     = [cache_read_port[i].we for i in range(0, WAYS)]

        @always_comb
        def cache_mem_rw():
            for i in range(0, WAYS):
                crp_clk[i].next    = clk_i
                crp_addr[i].next   = cpu_wbs.addr_i[WAY_WIDTH:2]
                crp_data_i[i].next = concat(cpu_wbs.dat_i[32:24] if cpu_wbs.sel_i[3] else data_cache[i][32:24],
                                            cpu_wbs.dat_i[24:16] if cpu_wbs.sel_i[2] else data_cache[i][24:16],
                                            cpu_wbs.dat_i[16:8] if cpu_wbs.sel_i[1] else data_cache[i][16:8],
                                            cpu_wbs.dat_i[8:0] if cpu_wbs.sel_i[0] else data_cache[i][8:0])
                crp_we[i].next     = state == dc_states.WRITE and not miss_w[i] and cpu_wbs.ack_o and cpu_wbs.we_i  # TODO: check for not ACK or ACK?

        # To Verilog
        cup_clk    = [cache_update_port[i].clk for i in range(0, WAYS)]
        cup_addr   = [cache_update_port[i].addr for i in range(0, WAYS)]
        cup_data_i = [cache_update_port[i].data_i for i in range(0, WAYS)]
        cup_we     = [cache_update_port[i].we for i in range(0, WAYS)]

        @always_comb
        def cache_mem_update():
            for i in range(0, WAYS):
                cup_clk[i].next    = clk_i
                cup_addr[i].next   = dc_update_addr[WAY_WIDTH - 2:]
                cup_data_i[i].next = mem_wbm.dat_i
                cup_we[i].next     = lru_select[i] and mem_wbm.ack_i and state == dc_states.FETCH

        @always_comb
        def wbs_cpu_flags():
            cpu_err.next  = mem_wbm.err_i
            cpu_wait.next = miss_w_and or not (state == dc_states.READ or state == dc_states.WRITE) if use_cache else not mem_wbm.ack_i
            cpu_busy.next = False

        @always_comb
        def wbm_mem_flags():
            mem_read.next  = fetch if use_cache else not cpu_wbs.we_i and cpu_wbs.cyc_i
            mem_write.next = evict if use_cache else cpu_wbs.we_i and cpu_wbs.cyc_i
            mem_rmw.next   = False

        # Remove warnings: Signal is driven but not read
        for i in range(WAYS):
            tag_flush_port[i].data_o    = None
            tag_lru_flush_port.data_o   = None

        # Generate the wishbone interfaces
        wbs_cpu = WishboneSlaveGenerator(clk_i, rst_i, cpu_wbs, cpu_busy, cpu_err, cpu_wait).gen_wbs()  # noqa
        wbm_mem = WishboneMasterGenerator(clk_i, rst_i, mem_wbm, mem_read, mem_write, mem_rmw).gen_wbm()  # noqa

        # Instantiate tag memories
        tag_mem = [RAM_DP(tag_rw_port[i], tag_flush_port[i], A_WIDTH=SET_WIDTH, D_WIDTH=TAGMEM_WAY_WIDTH) for i in range(WAYS)]  # noqa
        tag_lru = RAM_DP(tag_lru_rw_port, tag_lru_flush_port, A_WIDTH=SET_WIDTH, D_WIDTH=TAG_LRU_WIDTH)  # noqa

        # Instantiate main memory (Cache)
        cache_mem = [RAM_DP(cache_read_port[i], cache_update_port[i], A_WIDTH=WAY_WIDTH - 2, D_WIDTH=D_WIDTH) for i in range(0, WAYS)]  # noqa

        # LRU unit
        lru_m = CacheLRU(current_lru, access_lru,  update_lru,  lru_pre, None, NUMWAYS=WAYS)  # noqa

        return instances()
    else:
        @always_comb
        def rtl():
            mem.addr.next  = cpu.addr
            mem.dat_o.next = cpu.dat_o
            mem.sel.next   = cpu.sel
            mem.we.next    = cpu.we
            cpu.dat_i.next = mem.dat_i
            cpu.ack.next   = mem.ack
            cpu.err.next   = mem.err

        @always(clk_i.posedge)
        def classic_cycle():
            mem.cyc.next   = cpu.cyc if not mem.ack else False
            mem.stb.next   = cpu.stb if not mem.ack else False
        return instances()
Пример #28
0
def fifo_sync(clock, reset, fbus):
    """ Simple synchronous FIFO

    PORTS
    =====

    PARAMETERS
    ==========
    """

    # @todo: this is intended to be used for small fast fifo's but it
    #        can be used for large synchronous fifo as well
    N = fbus.size

    if fmod(log(N, 2), 1) != 0:
        Asz = int(ceil(log(N, 2)))
        N = 2**Asz
        print("@W: m_fifo_sync only supports power of 2 size")
        print("    forcing size (depth) to %d instread of %d" % (N, fbus.size))

    wptr = Signal(modbv(0, min=0, max=N))
    rptr = Signal(modbv(0, min=0, max=N))
    _vld = Signal(False)

    # generic memory model
    g_fifomem = fifo_mem_generic(clock,
                                 fbus.write,
                                 fbus.write_data,
                                 wptr,
                                 clock,
                                 fbus.read_data,
                                 rptr,
                                 mem_size=fbus.size)

    # @todo: almost full and almost empty flags
    read = fbus.read
    write = fbus.write

    @always_seq(clock.posedge, reset=reset)
    def rtl_fifo():
        if fbus.clear:
            wptr.next = 0
            rptr.next = 0
            fbus.full.next = False
            fbus.empty.next = True

        elif read and not write:
            fbus.full.next = False
            if not fbus.empty:
                rptr.next = rptr + 1
            if rptr == (wptr - 1):
                fbus.empty.next = True

        elif write and not read:
            fbus.empty.next = False
            if not fbus.full:
                wptr.next = wptr + 1
            if wptr == (rptr - 1):
                fbus.full.next = True

        elif write and read:
            wptr.next = wptr + 1
            rptr.next = rptr + 1

        _vld.next = read

    @always_comb
    def rtl_assign():
        fbus.read_valid.next = _vld & fbus.read

    nvacant = Signal(intbv(N, min=-0, max=N + 1))  # # empty slots
    ntenant = Signal(intbv(0, min=-0, max=N + 1))  # # filled slots

    @always_seq(clock.posedge, reset=reset)
    def dbg_occupancy():
        if fbus.clear:
            nvacant.next = N
            ntenant.next = 0
        else:
            v = nvacant
            f = ntenant

            if fbus.read_valid:
                v = v + 1
                f = f - 1
            if fbus.write:
                v = v - 1
                f = f + 1

            nvacant.next = v
            ntenant.next = f

    fbus.count = ntenant

    return (
        g_fifomem,
        rtl_fifo,
        rtl_assign,
        dbg_occupancy,
    )
Пример #29
0
def test_block_conversion():
    """Test bench used for conversion purpose"""

    # clock and reset signals
    clock = Signal(bool(0))
    reset = ResetSignal(0, active=1, async=True)

    # width of the runlength
    width_runlength = 4
    # width of the vli size
    width_size = 4
    # width of the vli amplitude ref
    width_amplitude = 12
    # width of address register
    width_addr = 6
    # width of the output data
    width_packed_byte = 8
    # image width
    width = 8
    # image height
    height = 8

    huffmandatastream = HuffmanDataStream(width_runlength, width_size,
                                          width_amplitude, width_addr)
    assert isinstance(huffmandatastream, HuffmanDataStream)

    bufferdatabus = HuffBufferDataBus(width_packed_byte)
    assert isinstance(bufferdatabus, HuffBufferDataBus)

    huffmancntrl = HuffmanCntrl()
    assert isinstance(huffmancntrl, HuffmanCntrl)

    # color component class
    component = Component()
    assert isinstance(component, Component)

    # image size class
    img_size = ImgSize(width, height)
    assert isinstance(img_size, ImgSize)

    # input fifo is empty
    rle_fifo_empty = Signal(bool(0))

    @block
    def bench_entropycoder():
        """This bench is used for conversion purpose"""

        # instantiate module, clock and reset
        inst = huffman(clock, reset, huffmancntrl, bufferdatabus,
                       huffmandatastream, img_size, rle_fifo_empty)
        inst_clock = clock_driver(clock)
        inst_reset = reset_on_start(reset, clock)

        @instance
        def tbstim():
            """dummy tests for conversion purpose"""

            yield clock.posedge
            print("Conversion done!!")
            raise StopSimulation

        return tbstim, inst, inst_clock, inst_reset

    # verify conversion using iverilog
    verify.simulator = 'iverilog'
    assert bench_entropycoder().verify_convert() == 0
Пример #30
0
from __future__ import generators

from myhdl import Signal, Simulation, Cosimulation
from myhdl import delay, intbv, now

import os
cmd = "iverilog -o tb_test.o ./tb_test.v "
os.system(cmd)

a = Signal(intbv(1))
b = Signal(intbv(2))
c = Signal(intbv(3))

cosim = Cosimulation("vvp -v -m ../myhdl.vpi tb_test.o", a=a, b=b, c=c)


def stimulus(a, b):
    for i in range(10):
        yield delay(10)
        # print "Python a=%s b=%s" % (a, b)
        a.next = a + 1
        b.next = b + 2


def response(c):
    while 1:
        yield c
        print "Python: %s %s %s %s" % (now(), c, a, b)


sim = Simulation(stimulus(a=a, b=b), response(c=c), cosim)