コード例 #1
0
ファイル: reset_visitor.py プロジェクト: jszheng/codegen
 def visit_Cat(self, node):
     left = []
     right = []
     for v in node.vars:
         val = self.visit(v)
         right = vtypes.IntX() if val is None else val.right
         left.append(v)
         right.append(right)
     return vtypes.Subst(vtypes.Cat(tuple(left)), vtypes.Cat(tuple(right)))
コード例 #2
0
def mkMultiplierCore(name,
                     lsigned=True,
                     rsigned=True,
                     depth=6,
                     with_update=True):

    m = module.Module(name + '_core')

    lwidth = m.Parameter('lwidth', 32)
    rwidth = m.Parameter('rwidth', 32)
    retwidth = lwidth + rwidth

    clk = m.Input('CLK')

    if with_update:
        update = m.Input('update')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    _a = m.Reg('_a', lwidth, signed=lsigned)
    _b = m.Reg('_b', rwidth, signed=rsigned)
    _mul = m.Wire('_mul', retwidth, signed=True)
    _pipe_mul = [
        m.Reg('_pipe_mul%d' % i, retwidth, signed=True)
        for i in range(depth - 1)
    ]

    __a = _a
    __b = _b
    if not lsigned:
        __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _a))
    if not rsigned:
        __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _b))

    m.Assign(_mul(__a * __b))
    m.Assign(c(_pipe_mul[depth - 2]))

    body = (_a(a), _b(b), _pipe_mul[0](_mul),
            [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)])

    if with_update:
        body = vtypes.If(update)(body)

    m.Always(vtypes.Posedge(clk))(body)

    return m
コード例 #3
0
def mkMaddCore(index, awidth=32, bwidth=32, cwidth=32,
               asigned=True, bsigned=True, csigned=True, depth=6):

    retwidth = max(awidth + bwidth, cwidth)

    m = module.Module('madd_core_%d' % index)

    clk = m.Input('CLK')
    update = m.Input('update')

    a = m.Input('a', awidth)
    b = m.Input('b', bwidth)
    c = m.Input('c', cwidth)
    d = m.Output('d', retwidth)

    _a = m.Reg('_a', awidth, signed=asigned)
    _b = m.Reg('_b', bwidth, signed=bsigned)
    _c = m.Reg('_c', cwidth, signed=csigned)
    _mul = m.Wire('_mul', retwidth, signed=True)
    _madd = m.Wire('_madd', retwidth, signed=True)
    _pipe_madd = [m.Reg('_pipe_madd%d' % i, retwidth, signed=True)
                  for i in range(depth - 1)]

    __a = _a
    __b = _b
    __c = _c
    if not asigned:
        __a = vtypes.SystemTask(
            'signed', vtypes.Cat(vtypes.Int(0, width=1), _a))
    if not bsigned:
        __b = vtypes.SystemTask(
            'signed', vtypes.Cat(vtypes.Int(0, width=1), _b))
    if not csigned:
        __c = vtypes.SystemTask(
            'signed', vtypes.Cat(vtypes.Int(0, width=1), _c))

    m.Assign(_mul(__a * __b))
    m.Assign(_madd(_mul + __c))
    m.Assign(d(_pipe_madd[depth - 2]))

    m.Always(vtypes.Posedge(clk))(
        vtypes.If(update)(
            _a(a),
            _b(b),
            _c(c),
            _pipe_madd[0](_madd),
            [_pipe_madd[i](_pipe_madd[i - 1]) for i in range(1, depth - 1)]
        ))

    return m
コード例 #4
0
ファイル: mul.py プロジェクト: yinxx/veriloggen
def mkMultiplierCore(index,
                     lwidth=32,
                     rwidth=32,
                     lsigned=True,
                     rsigned=True,
                     depth=6):
    if lwidth <= 0:
        raise ValueError("data width must be greater than 0.")
    if rwidth <= 0:
        raise ValueError("data width must be greater than 0.")
    if depth < 2:
        raise ValueError("depth must be greater than 1.")

    retwidth = lwidth + rwidth

    m = module.Module('multiplier_core_%d' % index)

    clk = m.Input('CLK')
    update = m.Input('update')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    _a = m.Reg('_a', lwidth, signed=lsigned)
    _b = m.Reg('_b', rwidth, signed=rsigned)
    _mul = m.Wire('_mul', retwidth, signed=True)
    _pipe_mul = [
        m.Reg('_pipe_mul%d' % i, retwidth, signed=True)
        for i in range(depth - 1)
    ]

    __a = _a
    __b = _b
    if not lsigned:
        __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _a))
    if not rsigned:
        __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _b))

    m.Assign(_mul(__a * __b))
    m.Assign(c(_pipe_mul[depth - 2]))

    m.Always(vtypes.Posedge(clk))(vtypes.If(update)(
        _a(a), _b(b), _pipe_mul[0](_mul),
        [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)]))

    return m
コード例 #5
0
ファイル: mul.py プロジェクト: jszheng/codegen
def mkMultiplierCore(index,
                     lwidth=32,
                     rwidth=32,
                     lsigned=True,
                     rsigned=True,
                     depth=6):
    retwidth = lwidth + rwidth

    m = module.Module('multiplier_core_%d' % index)

    clk = m.Input('CLK')
    update = m.Input('update')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    _a = m.Reg('_a', lwidth, signed=lsigned)
    _b = m.Reg('_b', rwidth, signed=rsigned)
    tmpval = [
        m.Reg('_tmpval%d' % i, retwidth, signed=True) for i in range(depth - 1)
    ]
    rslt = m.Wire('rslt', retwidth, signed=True)

    __a = _a
    __b = _b
    if not lsigned:
        __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _a))
    if not rsigned:
        __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _b))

    m.Assign(rslt(__a * __b))
    m.Assign(c(tmpval[depth - 2]))

    m.Always(vtypes.Posedge(clk))(vtypes.If(update)(
        _a(a), _b(b), tmpval[0](rslt),
        [tmpval[i](tmpval[i - 1]) for i in range(1, depth - 1)]))

    return m
コード例 #6
0
    def visit_Cat(self, node):
        left_values = []
        right_values = []

        for v in node.vars:
            val = self.visit(v)
            width = v.bit_length()
            if width is None:
                width = 1
            if val is None:
                right = vtypes.IntX(width)
            elif isinstance(val.right, int):
                right = vtypes.Int(val.right, width)
            elif isinstance(val.right, vtypes._Constant):
                right = copy.deepcopy(val.right)
                right.width = width
            else:
                right = v._get_module().TmpLocalparam(val.right, width)

            left_values.append(v)
            right_values.append(right)

        return vtypes.Subst(vtypes.Cat(*left_values), vtypes.Cat(*right_values))
コード例 #7
0
def mkUartRx(baudrate=19200, clockfreq=100 * 1000 * 1000):
    m = Module("UartRx")
    waitnum = int(clockfreq / baudrate)

    clk = m.Input('CLK')
    rst = m.Input('RST')

    rxd = m.Input('rxd')
    dout = m.OutputReg('dout', 8, initval=0)
    valid = m.OutputReg('valid', initval=0)

    fsm = FSM(m, 'fsm', clk, rst)

    mem = m.TmpReg(9, initval=0)
    waitcount = m.TmpReg(int(math.log(waitnum, 2)) + 1, initval=0)

    fsm(valid(0), waitcount(int(waitnum / 2) - 1),
        mem(vtypes.Cat(rxd, mem[1:9])))

    fsm.If(rxd == 0).goto_next()

    for i in range(10):
        if i == 0:  # check the start bit again
            fsm.If(vtypes.Ands(waitcount == 1, rxd != 0)).goto_init()

        fsm.If(waitcount > 0)(waitcount.dec()).Else(
            mem(vtypes.Cat(rxd, mem[1:9])), waitcount(waitnum - 1))
        fsm.Then().goto_next()

    fsm(valid(1), dout(mem[0:9]))

    fsm.goto_init()

    fsm.make_always()

    return m
コード例 #8
0
def mkUartTx(baudrate=19200, clockfreq=100 * 1000 * 1000):
    m = Module("UartTx")
    waitnum = int(clockfreq / baudrate)

    clk = m.Input('CLK')
    rst = m.Input('RST')

    din = m.Input('din', 8)
    enable = m.Input('enable')
    ready = m.OutputReg('ready', initval=1)
    txd = m.OutputReg('txd', initval=1)

    fsm = FSM(m, 'fsm', clk, rst)

    mem = m.TmpReg(9, initval=0)
    waitcount = m.TmpReg(int(math.log(waitnum, 2)) + 1, initval=0)

    fsm(waitcount(waitnum - 1), txd(1), mem(vtypes.Cat(din, vtypes.Int(0, 1))))

    fsm.If(enable)(ready(0))

    fsm.Then().goto_next()

    for i in range(10):
        fsm.If(waitcount > 0)(waitcount.dec()).Else(
            txd(mem[0]), mem(vtypes.Cat(vtypes.Int(1, 1), mem[1:9])),
            waitcount(waitnum - 1))
        fsm.Then().goto_next()

    fsm(ready(1))

    fsm.goto_init()

    fsm.make_always()

    return m
コード例 #9
0
 def visit_LConcat(self, node):
     vars = [self.visit(var) for var in node.list]
     return vtypes.Cat(*vars)
コード例 #10
0
 def visit_Repeat(self, node):
     var = (self.visit(node.var) if isinstance(node.var, vtypes.Cat) else
            self.visit(vtypes.Cat(node.var)))
     times = self.visit(node.times)
     return vast.Repeat(var, times)
コード例 #11
0
ファイル: rename_visitor.py プロジェクト: yinxx/veriloggen
 def visit_Cat(self, node):
     vars = [self.visit(var) for var in node.vars]
     return vtypes.Cat(*vars)
コード例 #12
0
    def _synthesize_read_fsm_fifo_narrow(self, fifo, fifo_datawidth):
        """ axi.datawidth < fifo.datawidth """

        if fifo_datawidth % self.datawidth != 0:
            raise ValueError(
                'fifo_datawidth must be multiple number of axi.datawidth')

        pack_size = fifo_datawidth // self.datawidth
        dma_size = (self.read_size << int(math.log(pack_size, 2))
                    if math.log(pack_size, 2) % 1.0 == 0.0 else
                    self.read_size * pack_size)

        op_id = self._get_read_op_id_fifo(fifo)

        if op_id in self.read_ops:
            """ already synthesized op """
            return

        if pack_size in self.read_narrow_fsms:
            """ new op """
            self.read_ops.append(op_id)

            fsm = self.read_narrow_fsms[pack_size]
            pack_count = self.read_narrow_pack_counts[pack_size]
            data = self.read_narrow_data_wires[pack_size]
            valid = self.read_narrow_valid_wires[pack_size]
            rest_size = self.read_narrow_rest_size_wires[pack_size]

            # state 0
            fsm.set_index(0)
            cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id)

            fsm.If(cond).goto_next()

            # state 1
            fsm.set_index(1)

            wdata = self.m.Reg('_'.join(['', self.name,
                                         'read_narrow', str(pack_size),
                                         'wdata']),
                               fifo_datawidth, initval=0)
            wvalid = self.m.Reg('_'.join(['', self.name,
                                          'read_narrow', str(pack_size),
                                          'wvalid']))

            valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id)
            ack, _ = fifo.enq_rtl(wdata, cond=wvalid)

            fsm.Delay(1)(
                wvalid(0)
            )
            fsm.If(rest_size == 0, pack_count > 0)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
                wvalid(0),
                pack_count.inc()
            )
            fsm.If(valid_cond)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
                wvalid(0),
                pack_count.inc()
            )
            fsm.If(rest_size == 0, pack_count == pack_size - 1)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
                wvalid(1),
                pack_count(0)
            )
            fsm.If(valid_cond, pack_count == pack_size - 1)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
                wvalid(1),
                pack_count(0)
            )
            fsm.If(valid_cond)(
                rest_size.dec()
            )

            return

        """ new op and fsm """
        fsm = FSM(self.m, '_'.join(['', self.name,
                                    'read_narrow', str(pack_size),
                                    'fsm']),
                  self.clk, self.rst, as_module=self.fsm_as_module)
        self.read_narrow_fsms[pack_size] = fsm

        self.read_ops.append(op_id)

        rest_size = self.m.Reg('_'.join(['', self.name,
                                         'read_narrow', str(pack_size),
                                         'rest_size']),
                               self.addrwidth + 1, initval=0)
        self.read_narrow_rest_size_wires[pack_size] = rest_size

        # state 0
        cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id)

        fsm.If(self.read_start)(
            rest_size(dma_size)
        )
        fsm.If(cond).goto_next()

        # state 1
        pack_count = self.m.Reg('_'.join(['', self.name,
                                          'read_narrow', str(pack_size),
                                          'pack_count']),
                                int(math.ceil(math.log(pack_size, 2))), initval=0)
        self.read_narrow_pack_counts[pack_size] = pack_count

        ready = vtypes.Not(fifo.almost_full)
        read_cond = vtypes.Ands(fsm.here, ready)

        data, last, _id, user, dest, valid = self.read_data(cond=read_cond)
        self.read_narrow_data_wires[pack_size] = data
        self.read_narrow_valid_wires[pack_size] = valid

        wdata = self.m.Reg('_'.join(['', self.name,
                                     'read_narrow', str(pack_size),
                                     'wdata']),
                           fifo_datawidth, initval=0)
        wvalid = self.m.Reg('_'.join(['', self.name,
                                      'read_narrow', str(pack_size),
                                      'wvalid']))

        valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id)
        ack, _ = fifo.enq_rtl(wdata, cond=wvalid)

        fsm.Delay(1)(
            wvalid(0)
        )
        fsm.If(rest_size == 0, pack_count > 0)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
            wvalid(0),
            pack_count.inc()
        )
        fsm.If(valid_cond)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
            wvalid(0),
            pack_count.inc()
        )
        fsm.If(rest_size == 0, pack_count == pack_size - 1)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
            wvalid(1),
            pack_count(0)
        )
        fsm.If(valid_cond, pack_count == pack_size - 1)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:fifo_datawidth])),
            wvalid(1),
            pack_count(0)
        )
        fsm.If(valid_cond)(
            rest_size.dec()
        )

        fsm.If(wvalid, rest_size == 0).goto_next()

        # state 2
        set_idle = self._set_flag(fsm)
        self.seq.If(set_idle)(
            self.read_idle(1)
        )

        fsm.goto_init()
コード例 #13
0
    def _synthesize_read_fsm_narrow(self, ram, port, ram_method, ram_datawidth):
        """ axi.datawidth < ram.datawidth """

        if ram_datawidth % self.datawidth != 0:
            raise ValueError(
                'ram_datawidth must be multiple number of axi.datawidth')

        pack_size = ram_datawidth // self.datawidth
        dma_size = (self.read_size << int(math.log(pack_size, 2))
                    if math.log(pack_size, 2) % 1.0 == 0.0 else
                    self.read_size * pack_size)

        op_id = self._get_read_op_id(ram, port, ram_method)
        port = vtypes.to_int(port)

        if op_id in self.read_ops:
            """ already synthesized op """
            return

        if pack_size in self.read_narrow_fsms:
            """ new op """
            self.read_ops.append(op_id)

            fsm = self.read_narrow_fsms[pack_size]
            pack_count = self.read_narrow_pack_counts[pack_size]
            data = self.read_narrow_data_wires[pack_size]
            valid = self.read_narrow_valid_wires[pack_size]
            rest_size = self.read_narrow_rest_size_wires[pack_size]

            # state 0
            fsm.set_index(0)
            wdata, wvalid, w = self._get_op_write_dataflow(ram_datawidth)
            cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id)
            ram_method(port, self.read_local_addr, w, self.read_size,
                       stride=self.read_local_stride, cond=cond)

            fsm.If(cond).goto_next()

            # state 1
            fsm.set_index(1)
            valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id)

            fsm.Delay(1)(
                wvalid(0)
            )
            fsm.If(rest_size == 0, pack_count > 0)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
                wvalid(0),
                pack_count.inc()
            )
            fsm.If(valid_cond)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
                wvalid(0),
                pack_count.inc()
            )
            fsm.If(rest_size == 0, pack_count == pack_size - 1)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
                wvalid(1),
                pack_count(0)
            )
            fsm.If(valid_cond, pack_count == pack_size - 1)(
                wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
                wvalid(1),
                pack_count(0)
            )
            fsm.If(valid_cond)(
                rest_size.dec()
            )

            return

        """ new op and fsm """
        fsm = FSM(self.m, '_'.join(['', self.name,
                                    'read_narrow', str(pack_size),
                                    'fsm']),
                  self.clk, self.rst, as_module=self.fsm_as_module)
        self.read_narrow_fsms[pack_size] = fsm

        self.read_ops.append(op_id)

        rest_size = self.m.Reg('_'.join(['', self.name,
                                         'read_narrow', str(pack_size),
                                         'rest_size']),
                               self.addrwidth + 1, initval=0)
        self.read_narrow_rest_size_wires[pack_size] = rest_size

        # state 0
        wdata, wvalid, w = self._get_op_write_dataflow(ram_datawidth)
        cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id)
        ram_method(port, self.read_local_addr, w, self.read_size,
                   stride=self.read_local_stride, cond=cond)

        fsm.If(self.read_start)(
            rest_size(dma_size)
        )
        fsm.If(cond).goto_next()

        # state 1
        pack_count = self.m.Reg('_'.join(['', self.name,
                                          'read_narrow', str(pack_size),
                                          'pack_count']),
                                int(math.ceil(math.log(pack_size, 2))), initval=0)
        self.read_narrow_pack_counts[pack_size] = pack_count

        data, last, _id, user, dest, valid = self.read_data(cond=fsm)
        self.read_narrow_data_wires[pack_size] = data
        self.read_narrow_valid_wires[pack_size] = valid

        valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id)

        fsm.Delay(1)(
            wvalid(0)
        )
        fsm.If(rest_size == 0, pack_count > 0)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
            wvalid(0),
            pack_count.inc()
        )
        fsm.If(valid_cond)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
            wvalid(0),
            pack_count.inc()
        )
        fsm.If(rest_size == 0, pack_count == pack_size - 1)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
            wvalid(1),
            pack_count(0)
        )
        fsm.If(valid_cond, pack_count == pack_size - 1)(
            wdata(vtypes.Cat(data, wdata[self.datawidth:ram_datawidth])),
            wvalid(1),
            pack_count(0)
        )
        fsm.If(valid_cond)(
            rest_size.dec()
        )

        fsm.If(wvalid, rest_size == 0).goto_next()

        for _ in range(self.num_data_delay):
            fsm.goto_next()

        # state 2
        set_idle = self._set_flag(fsm)
        self.seq.If(set_idle)(
            self.read_idle(1)
        )

        fsm.goto_init()