Exemple #1
0
    class _MAC(m.Circuit):
        name = "MAC" + str(n)
        logn = log2(n) + 1
        IO = ['CLK', m.In(m.Clock), 'I0', m.In(m.Bits(n)),
              'I1', m.In(m.Bits(n)), 'P', m.Out(m.Bits(logn)),
              'O', m.Out(m.Bit)]

        @classmethod
        def definition(io):
            # XNOR for binary affine mapped multiplication
            mul = mantle.NXOr(height=2, width=n)
            m.wire(mul.I0, io.I0)
            m.wire(mul.I1, io.I1)

            pop = PopCount(n)

            m.wire(mul.O, pop.I)
            m.wire(pop.O, io.P)

            width = log2(n)+2
            sign = mantle.UGE(width)
            m.wire(m.zext(pop.O, 1), sign.I0)
            m.wire(m.bits(n, width), sign.I1)

            m.wire(sign.O, io.O)
Exemple #2
0
def PopCount_typegen(context, values):
    width = values['width'].value
    typ = {
        "I": context.Array(width, context.BitIn()),
        "O": context.Array(log2(width) + 1, context.Bit())
    }
    return context.Record(typ)
Exemple #3
0
    class _PopCount(Circuit):
        name = 'PopCount{}'.format(n)
        IO = ['I', In(Bits[n]), 'O', Out(Bits[log2(n) + 1])]

        @classmethod
        def definition(io):
            r = compressor([io.I.as_list()])
            wire(bits(r), io.O)
Exemple #4
0
def RAMB16(rom, width, init=None):
    """
    Configure a blocked RAM.
    """

    params = OrderedDict()

    #params['DOA_REG'] = 0 # default=0
    #params['DOB_REG'] = 0
    params['WRITE_MODE_A'] = '"WRITE_FIRST"'
    params['WRITE_MODE_B'] = '"WRITE_FIRST"'

    # initialize RAM register
    init = (0, width) if init is None else (init, width)
    params["INIT_A"] = init
    params["INIT_B"] = init
    params["SRVAL_A"] = init
    params["SRVAL_B"] = init

    #   512X36  512X32
    #  1024X18 1024X16
    #  2048X9  2048X8
    #  4096X4
    #  8192X2
    # 16384X1
    n = len(rom)
    logn = log2(n)

    ramb16_init_bits(rom, width, params)
    ram = RAMB16BWER(**params)

    A = array([ram.ADDRB[i] for i in range(14)])

    I = array([ram.DIB[i] for i in range(ram.DIB.N)])

    IP = array([ram.DIPB[i] for i in range(ram.DIPB.N)])

    wire(array([0, 0, 0, 0]), ram.WEB)
    wire(clock(0), ram.CLKB)
    wire(0, ram.RSTB)
    wire(0, ram.REGCEB)
    wire(0, ram.ENB)

    wire(array([0, 0, 0, 0]),
         ram.WEA)  # WE  defaults to active high - inverted
    wire(0, ram.RSTA)  # RST defaults to active high - inverted
    wire(0, ram.REGCEA)

    A = config_ramb16_addr_pins(logn, ram, p="A")
    I, O = config_ramb16_io_pins(width, ram, p="A")
    args = ['I', I, "A", A, "O", O]

    args += ['CLK', ram.CLKA, 'CE', ram.ENA]

    return AnonymousCircuit(*args)
Exemple #5
0
def RAMB16D(rom, width, init = None):

    """
    Configure a dual-port blocked RAM
    """

    params = OrderedDict()

    params['DOA_REG'] = 0
    params['DOB_REG'] = 0

    params['WRITE_MODE_A'] = '"WRITE_FIRST"'
    params['WRITE_MODE_B'] = '"WRITE_FIRST"'

    # initialize RAM register
    init = (0, width) if init is None else (init, width)
    params["INIT_A"] = init
    params["INIT_B"] = init
    params["SRVAL_A"] = init
    params["SRVAL_B"] = init

    #   512X36  512X32
    #  1024X18 1024X16
    #  2048X9  2048X8
    #  4096X4
    #  8192X2
    # 16384X1
    n = len(rom)
    logn = log2(n)

    ramb16_init_bits(rom, width, params)
    ram = RAMB16BWER(**params)

    args  = ["CLKA", ram.CLKA, "CLKB", ram.CLKB]
    args += ["ENA", ram.ENA, "ENB", ram.ENB]
    args += ["WEA", ram.WEA, "WEB", ram.WEB]
    args += ["REGCEA", ram.REGCEA, "REGCEB", ram.REGCEB]

    wire(0, ram.RSTA)
    wire(0, ram.RSTB)

    AA = config_ramb16_addr_pins(logn, ram, p = "A")
    IA, OA = config_ramb16_io_pins(width, ram, p = "A")
    args += ['IA', IA, "AA", AA, "OA", OA]

    AB = config_ramb16_addr_pins(logn, ram, p = "B")
    IB, OB = config_ramb16_io_pins(width, ram, p = "B")
    args += ['IB', IB, "AB", AB, "OB", OB]

    return AnonymousCircuit(*args)
Exemple #6
0
def DefineBarrel(n):
    assert n in [2, 4, 8, 16]
    logn = log2(n)
    T = Bits(n)
    class _Barrel(Circuit):
        name = 'Barrel{}'.format(n)
        IO = ['I', In(T), 'S', In(Bits(logn)), 'SI', In(Bit), "O", Out(T)]
        @classmethod
        def definition(io):
            I = io.I
            for k in range(logn):
                 I = BarrelShift(n, 1<<k)(I, io.S[k], io.SI)
            wire(I, io.O)
    return _Barrel
Exemple #7
0
def DefineShift(n, op):
    assert n in [2, 4, 8, 16]
    logn = log2(n)
    T = Bits(n)

    class _Shift(Circuit):
        name = f'Shift{n}'
        IO = ['I', In(T), 'S', In(Bits(logn)), 'SI', In(Bit), "O", Out(T)]

        @classmethod
        def definition(io):
            I = io.I
            for k in range(logn):
                I = ShiftK(n, 1 << k, op)(I, io.S[k], io.SI)
            wire(I, io.O)

    return _Shift
Exemple #8
0
def DefineRotate(n, op):
    assert n in [2, 4, 8, 16]
    logn = log2(n)
    T = Bits(n)

    class _Rotate(Circuit):
        name = f'Rotate{n}'
        IO = ['I', In(T), 'S', In(Bits(logn)), "O", Out(T)]

        @classmethod
        def definition(io):
            I = io.I
            for k in range(logn):
                I = RotateK(n, 1 << k, op)(I, io.S[k])
            wire(I, io.O)

    return _Rotate
Exemple #9
0
        def definition(io):
            # XNOR for binary affine mapped multiplication
            mul = mantle.NXOr(height=2, width=n)
            m.wire(mul.I0, io.I0)
            m.wire(mul.I1, io.I1)

            pop = PopCount(n)

            m.wire(mul.O, pop.I)
            m.wire(pop.O, io.P)

            width = log2(n)+2
            sign = mantle.UGE(width)
            m.wire(m.zext(pop.O, 1), sign.I0)
            m.wire(m.bits(n, width), sign.I1)

            m.wire(sign.O, io.O)
Exemple #10
0
def RAM128D(ram):
    width = 1
    n = 128
    logn = log2(n)

    ram = RAM128x1D(INIT=lutinit(ram,128))

    args  = ['A0', ram.A]
    args += ['A1', ram.DPRA]
    
    args += ['I', ram.D]

    args += ['O0', ram.SPO]
    args += ['O1', ram.DPO]

    args += ["WE", ram.WE]
    args += ["CLK", ram.WCLK]
    return AnonymousCircuit(*args)
Exemple #11
0
def DefineEncoder(n):
    assert n <= 8
    logn = log2(n)
    class _Encoder(Circuit):
        name = 'Encoder'+str(n)
        IO = ['I', In(Bits(n)), 'O', Out(Bits(logn))]
        @classmethod
        def definition(Enc):
            def f(y):
                or_ = uncurry(Or(n//2))
                os = []
                for i in range(n):
                    if i & (1 << y): os.append(Enc.I[i])
                wire(array(os), or_)
                return AnonymousCircuit("O", or_.O)
            enc = join( col(f, logn) )
            wire(enc.O, Enc.O)
    return _Encoder
Exemple #12
0
def shift(i, s, si, op):
    n = len(i)
    assert log2(n) == len(s)
    return Shift(n, op)(i, s, si)
Exemple #13
0
def rotate(i, s, op):
    n = len(i)
    assert log2(n) == len(s)
    return Rotate(n, op)(i, s)
Exemple #14
0
def barrel(i, s, si):
    n = len(i)
    assert log2(n) == len(s)
    return Barrel(n)(i, s, si)
Exemple #15
0
def RAMB16D(rom, init=None):
    """
    Configure a dual-port blocked RAM (currently only one setting)
    """

    width = 16

    params = OrderedDict()
    params['WRITE_MODE_A'] = '"WRITE_FIRST"'
    params['WRITE_MODE_B'] = '"WRITE_FIRST"'
    # initialize RAM output register
    if init is None:
        #init = "%d'h%05X" % (width, 0)
        init = (0, width)
    else:
        #init = "%d'h%05X" % (width, init)
        init = (init, width)
    params["INIT_A"] = init
    params["INIT_B"] = init
    params["SRVAL_A"] = init
    params["SRVAL_B"] = init

    #   512X36  512X32
    #  1024X18 1024X16
    #  2048X9  2048X8
    #  4096X4
    #  8192X2
    # 16384X1
    n = len(rom)
    logn = log2(n)

    ramb16_init_bits(rom, width, params)
    ram = RAMB16_S18_S18(**params)

    args = ["CLKA", ram.CLKA, "CLKB", ram.CLKB]
    args += ["ENA", ram.ENA, "ENB", ram.ENB]
    args += ["WEA", ram.WEA, "WEB", ram.WEB]

    # Default: We wanted a dual port ram in the first place,
    # so why not just turn them on all the time?
    wire(array([0, 0]), ram.DIPA)
    wire(array([0, 0]), ram.DIPB)
    # wire(1, ram.ENB)
    # wire(1, ram.ENA)
    # wire(1, ram.ENB)
    wire(0, ram.SSRA)
    wire(0, ram.SSRB)

    # reverse the address bits
    # AA = [ram.ADDRA[logn-1-i] for i in range(logn)]
    AA = [ram.ADDRA[i] for i in range(logn)]
    AA = array(AA)

    # reverse the order DI
    #IA = [ram.DIA[ram.DIA.N-1-i] for i in range(ram.DIA.N)]
    IA = [ram.DIA[i] for i in range(ram.DIA.N)]
    IA = array(IA)

    OA = [ram.DOA[i] for i in range(ram.DOA.N)]
    OA = array(OA)

    args += ['IA', IA, "AA", AA, "OA", OA]

    # reverse the address bits
    #AB = [ram.ADDRB[logn-1-i] for i in range(logn)]
    AB = [ram.ADDRB[i] for i in range(logn)]
    AB = array(AB)

    # reverse the order DI
    #IB = [ram.DIB[ram.DIB.N-1-i] for i in range(ram.DIB.N)]
    IB = [ram.DIB[i] for i in range(ram.DIB.N)]
    IB = array(IB)

    # reverse the order DI
    #OB = [ram.DOB[ram.DOB.N-1-i] for i in range(ram.DOB.N)]
    OB = [ram.DOB[i] for i in range(ram.DOB.N)]
    OB = array(OB)

    args += ['IB', IB, "AB", AB, "OB", OB]

    return AnonymousCircuit(args)
Exemple #16
0
def RAMB16(rom, width, init=None):
    """
    Configure a blocked RAM.
    """

    params = OrderedDict()
    params['WRITE_MODE'] = '"WRITE_FIRST"'
    # initialize RAM output register
    if init is None:
        #init = "%d'h%05X" % (width, rom[0])
        init = (rom[0], width)
    else:
        #init = "%d'h%05X" % (width, init)
        init = (init, width)
    params["INIT"] = init
    params["SRVAL"] = init

    #   512X36  512X32
    #  1024X18 1024X16
    #  2048X9  2048X8
    #  4096X4
    #  8192X2
    # 16384X1
    n = len(rom)
    logn = log2(n)

    if width == 8 or width == 9:
        assert n in [256, 512, 1024, 2048]
        if n != 2048:
            rom += (2048 - n) * [0]

        params = romX8(rom, 2048, params)
        if width == 9:
            params = romX1P(rom, 2048, params)

        ram = RAMB16_S9(**params)

    if width == 16 or width == 18:
        assert n in [256, 512, 1024]
        if n != 1024:
            rom += (1024 - n) * [0]

        params = romX16(rom, 1024, params)
        if width == 18:
            params = romX2P(rom, 1024, params)

        ram = RAMB16_S18(**params)

    # reverse the address bits
    #A = [ram.ADDR[logn-1-i] for i in range(logn)]
    A = [ram.ADDR[i] for i in range(logn)]
    A = array(A)

    # reverse the order DI
    #I = [ram.DI[ram.DI.N-1-i] for i in range(ram.DI.N)]
    I = [ram.DI[i] for i in range(ram.DI.N)]

    # reverse the order DI
    #O = [ram.DO[ram.DO.N-1-i] for i in range(ram.DO.N)]
    O = [ram.DO[i] for i in range(ram.DO.N)]

    if width == 8:
        wire(0, ram.DIP[0])
    elif width == 9:
        I += [ram.DIP[0]]
        O += [ram.DOP[0]]
    elif width == 16:
        wire(0, ram.DIP[0])
        wire(0, ram.DIP[1])
    elif width == 18:
        # reverse
        #I += [ram.DIP[1], ram.DIP[0]]
        #O += [ram.DOP[1], ram.DOP[0]]
        I += [ram.DIP[0], ram.DIP[1]]
        O += [ram.DOP[0], ram.DOP[1]]

    I = array(I)
    O = array(O)

    wire(0, ram.SSR)  # SSR defaults to active high - inverted
    wire(0, ram.WE)  # WE  defaults to active high - inverted

    args = ram.interface.clockargs() + ['CE', ram.EN]
    args += ['I', I, "A", A, "O", O]

    return AnonymousCircuit(args)