Пример #1
0
    def try_lock(self, fsm):
        name = fsm.name
        new_lock_id = self._get_id(name)

        if new_lock_id > 2**self.width - 1:
            raise ValueError('too many lock IDs')

        # try
        try_state = fsm.current

        state_cond = fsm.state == fsm.current
        try_cond = vtypes.Not(self.lock_reg)

        self.seq.If(state_cond, try_cond)(self.lock_reg(1),
                                          self.lock_id(new_lock_id))

        fsm.goto_next()

        # verify
        cond = vtypes.And(self.lock_reg, self.lock_id == new_lock_id)
        result = self.m.TmpReg(initval=0)
        fsm(result(cond))
        fsm.goto_next()

        return result
Пример #2
0
    def dma_read_async(self, fsm, ram, local_addr, global_addr, size,
                       local_stride=1, port=0, ram_method=None):

        if ram_method is None:
            ram_method = getattr(ram, 'write_dataflow')

        ram_method_name = (ram_method.func.__name__
                           if isinstance(ram_method, functools.partial) else
                           ram_method.__name__)
        ram_datawidth = (ram.datawidth if ram_method is None else
                         ram.orig_datawidth if 'bcast' in ram_method_name else
                         ram.orig_datawidth if 'block' in ram_method_name else
                         ram.datawidth)

        if ram_datawidth == self.datawidth:
            dma_size = size
        elif ram_datawidth > self.datawidth:
            pack_size = ram_datawidth // self.datawidth
            dma_size = (size << int(math.log(pack_size, 2))
                        if math.log(pack_size, 2) % 1.0 == 0.0 else
                        size * pack_size)
        else:
            pack_size = self.datawidth // ram_datawidth
            shamt = int(math.log(pack_size, 2))
            res = vtypes.Mux(
                vtypes.And(size, 2 ** shamt - 1) > 0, 1, 0)
            dma_size = (size >> shamt) + res

        AXIM_for_AXIStreamIn.dma_read_async(self, fsm, global_addr, dma_size)
        self.streamin.write_ram_async(fsm, ram, local_addr, size,
                                      local_stride, port, ram_method)
Пример #3
0
 def visit_Slice(self, node):
     val = self.visit(node.var)
     if val is None:
         return None
     if isinstance(val.right, vtypes._Variable):
         right = vtypes.Slice(val.right, node.msb, node.lsb)
     else:
         right = vtypes.And(vtypes.Srl(val.right, node.lsb),
                            vtypes.Repeat(vtypes.Int(1, width=1), node.msb - node.lsb + 1))
     return vtypes.Subst(vtypes.Slice(val.left, node.msb, node.lsb), right)
Пример #4
0
def fixed_to_int_low(value, point):
    if point < 0:
        return 0

    if point == 0:
        return 0

    if isinstance(value, (int, bool, float)) and isinstance(point, int):
        mag = 2 ** point
        return int(value % mag)

    return vtypes.And(value, vtypes.Repeat(vtypes.Int(1, 1), point))
Пример #5
0
 def visit_Pointer(self, node):
     val = self.visit(node.var)
     if val is None:
         return None
     left = vtypes.Pointer(val.left, node.pos)
     if not isinstance(val.right, (vtypes._Variable, vtypes.Scope)):
         if isinstance(val.right, (int, bool)):
             val_right = vtypes.Int(val.right)
         elif isinstance(val.right, float):
             val_right = vtypes.Float(val.right)
         else:
             raise TypeError("unsupported value type: %s" % str(val.right))
         right = vtypes.And(vtypes.Srl(
             val_right, node.pos), vtypes.Int(1, width=1))
     else:
         right = vtypes.Pointer(val.right, node.pos)
     return vtypes.Subst(left, right)
Пример #6
0
 def visit_And(self, node):
     left = self.visit(node.left)
     right = self.visit(node.right)
     return vtypes.And(left, right)
Пример #7
0
    def _synthesize_read_fsm_wide(self, ram, port, ram_method, ram_datawidth):
        """ axi.datawidth > ram.datawidth """

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

        pack_size = self.datawidth // ram_datawidth
        shamt = int(math.log(pack_size, 2))
        res = vtypes.Mux(
            vtypes.And(self.read_size, 2 ** shamt - 1) > 0, 1, 0)
        dma_size = (self.read_size >> shamt) + res

        actual_read_size = dma_size << shamt

        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_wide_fsms:
            """ new op """
            self.read_ops.append(op_id)

            fsm = self.read_wide_fsms[pack_size]
            pack_count = self.read_wide_pack_counts[pack_size]
            data = self.read_wide_data_wires[pack_size]
            valid = self.read_wide_valid_wires[pack_size]
            rest_size = self.read_wide_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, actual_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)
            stay_cond = self.read_op_sel == op_id

            fsm.Delay(1)(
                wvalid(0)
            )
            fsm.If(pack_count == 0, valid_cond)(
                wdata(data),
                wvalid(1),
                pack_count.inc()
            )
            fsm.If(pack_count > 0, stay_cond)(
                wdata(wdata >> ram_datawidth),
                wvalid(1),
                pack_count.inc()
            )
            fsm.If(valid_cond)(
                rest_size.dec()
            )

            return

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

        self.read_ops.append(op_id)

        rest_size = self.m.Reg('_'.join(['', self.name,
                                         'read_wide', str(pack_size),
                                         'rest_size']),
                               self.addrwidth + 1, initval=0)
        self.read_wide_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, actual_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_wide', str(pack_size),
                                          'pack_count']),
                                int(math.ceil(math.log(pack_size, 2))), initval=0)
        self.read_wide_pack_counts[pack_size] = pack_count

        cond = vtypes.Ands(fsm.here, pack_count == 0)
        data, last, _id, user, dest, valid = self.read_data(cond=cond)
        self.read_wide_data_wires[pack_size] = data
        self.read_wide_valid_wires[pack_size] = valid

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

        wlast = self.m.Reg('_'.join(['', self.name,
                                     'read_wide', str(pack_size),
                                     'wlast']),
                           initval=0)

        fsm.Delay(1)(
            wvalid(0)
        )
        fsm.If(pack_count == 0, valid_cond)(
            wdata(data),
            wvalid(1),
            wlast(last),
            pack_count.inc()
        )
        fsm.If(pack_count > 0, stay_cond)(
            wdata(wdata >> ram_datawidth),
            wvalid(1),
            pack_count.inc()
        )
        fsm.If(pack_count == pack_size - 1)(
            pack_count(0)
        )

        fsm.If(pack_count == 0, valid_cond)(
            rest_size.dec()
        )

        fsm.If(pack_count == pack_size - 1, 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()
Пример #8
0
    def _synthesize_read_fsm_fifo_wide(self, fifo, fifo_datawidth):
        """ axi.datawidth > fifo.datawidth """

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

        pack_size = self.datawidth // fifo_datawidth
        shamt = int(math.log(pack_size, 2))
        res = vtypes.Mux(
            vtypes.And(self.read_size, 2 ** shamt - 1) > 0, 1, 0)
        dma_size = (self.read_size >> shamt) + res

        actual_read_size = dma_size << shamt

        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_wide_fsms:
            """ new op """
            self.read_ops.append(op_id)

            fsm = self.read_wide_fsms[pack_size]
            pack_count = self.read_wide_pack_counts[pack_size]
            data = self.read_wide_data_wires[pack_size]
            valid = self.read_wide_valid_wires[pack_size]
            rest_size = self.read_wide_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)
            valid_cond = vtypes.Ands(valid, self.read_op_sel == op_id)
            stay_cond = self.read_op_sel == op_id

            fsm.Delay(1)(
                wvalid(0)
            )
            fsm.If(pack_count == 0, valid_cond)(
                wdata(data),
                wvalid(1),
                pack_count.inc()
            )
            fsm.If(pack_count > 0, stay_cond)(
                wdata(wdata >> fifo_datawidth),
                wvalid(1),
                pack_count.inc()
            )
            fsm.If(valid_cond)(
                rest_size.dec()
            )

            return

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

        self.read_ops.append(op_id)

        rest_size = self.m.Reg('_'.join(['', self.name,
                                         'read_wide', str(pack_size),
                                         'rest_size']),
                               self.addrwidth + 1, initval=0)
        self.read_wide_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_wide', str(pack_size),
                                          'pack_count']),
                                int(math.ceil(math.log(pack_size, 2))), initval=0)
        self.read_wide_pack_counts[pack_size] = pack_count

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

        cond = vtypes.Ands(fsm.here, pack_count == 0, read_cond)
        data, last, _id, user, dest, valid = self.read_data(cond=cond)
        self.read_wide_data_wires[pack_size] = data
        self.read_wide_valid_wires[pack_size] = valid

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

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

        ack, _ = fifo.enq_rtl(wdata, cond=wvalid)

        wlast = self.m.Reg('_'.join(['', self.name,
                                     'read_wide', str(pack_size),
                                     'wlast']),
                           initval=0)

        fsm.Delay(1)(
            wvalid(0)
        )
        fsm.If(pack_count == 0, valid_cond)(
            wdata(data),
            wvalid(1),
            wlast(last),
            pack_count.inc()
        )
        fsm.If(pack_count > 0, stay_cond)(
            wdata(wdata >> fifo_datawidth),
            wvalid(1),
            pack_count.inc()
        )
        fsm.If(pack_count == pack_size - 1)(
            pack_count(0)
        )

        fsm.If(pack_count == 0, valid_cond)(
            rest_size.dec()
        )

        fsm.If(pack_count == pack_size - 1, 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()