Exemple #1
0
    def _get_read_op_id(self, ram, port, ram_method):

        ram_id = ram._id()
        port = vtypes.to_int(port)
        ram_method_name = (ram_method.func.__name__
                           if isinstance(ram_method, functools.partial) else
                           ram_method.__name__)
        op = (ram_id, port, ram_method_name)

        if op in self.read_op_id_map:
            op_id = self.read_op_id_map[op]
        else:
            op_id = self.read_op_id_count
            self.read_op_id_count += 1
            self.read_op_id_map[op] = op_id

        return op_id
Exemple #2
0
    def set_sink(self, fsm, name, ram, offset, size, stride=1, port=0):
        """ intrinsic method to assign RAM property to a sink stream """

        if not self.stream_synthesized:
            self._implement_stream()

        if isinstance(name, str):
            var = self.var_name_map[name]
        elif isinstance(name, vtypes.Str):
            name = name.value
            var = self.var_name_map[name]
        elif isinstance(name, int):
            var = self.var_id_map[name]
        elif isinstance(name, vtypes.Int):
            name = name.value
            var = self.var_id_map[name]
        else:
            raise TypeError('Unsupported index name')

        if name not in self.sinks:
            raise NameError("No such stream '%s'" % name)

        #set_cond = fsm.here
        set_cond = self._set_flag(fsm)

        self.seq.If(set_cond)(
            var.sink_mode(0),
            var.sink_offset(offset),
            var.sink_size(size),
            var.sink_stride(stride)
        )

        port = vtypes.to_int(port)
        self._setup_sink_ram(ram, var, port, set_cond)
        self._synthesize_set_sink(var, name)

        fsm.goto_next()
Exemple #3
0
    def set_sink_pattern(self, fsm, name, ram, offset, pattern, port=0):
        """ intrinsic method to assign RAM property to a sink stream """

        if not self.stream_synthesized:
            self._implement_stream()

        if isinstance(name, str):
            var = self.var_name_map[name]
        elif isinstance(name, vtypes.Str):
            name = name.value
            var = self.var_name_map[name]
        elif isinstance(name, int):
            var = self.var_id_map[name]
        elif isinstance(name, vtypes.Int):
            name = name.value
            var = self.var_id_map[name]
        else:
            raise TypeError('Unsupported index name')

        if name not in self.sinks:
            raise NameError("No such stream '%s'" % name)

        if not isinstance(pattern, (tuple, list)):
            raise TypeError('pattern must be list or tuple.')

        if not pattern:
            raise ValueError(
                'pattern must have one (size, stride) pair at least.')

        if not isinstance(pattern[0], (tuple, list)):
            pattern = (pattern,)

        pattern = tuple(pattern)

        if len(pattern) > self.max_pattern_length:
            raise ValueError(
                "'pattern' length exceeds maximum pattern length.")

        self._make_sink_pattern_vars(var, name)

        #set_cond = fsm.here
        set_cond = self._set_flag(fsm)

        self.seq.If(set_cond)(
            var.sink_mode(1),
            var.sink_offset(offset)
        )

        pad = tuple([(1, 0)
                     for _ in range(self.max_pattern_length - len(pattern))])

        for (sink_pat_size, sink_pat_stride,
             (size, stride)) in zip(var.sink_pat_sizes, var.sink_pat_strides,
                                    pattern + pad):
            self.seq.If(set_cond)(
                sink_pat_size(size),
                sink_pat_stride(stride)
            )

        port = vtypes.to_int(port)
        self._setup_sink_ram(ram, var, port, set_cond)
        self._synthesize_set_sink_pattern(var, name)

        fsm.goto_next()
Exemple #4
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()
Exemple #5
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()
Exemple #6
0
    def _synthesize_read_fsm_same(self, ram, port, ram_method, ram_datawidth):

        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 self.read_fsm is not None:
            """ new op """
            self.read_ops.append(op_id)

            fsm = self.read_fsm
            data = self.read_data_wire
            valid = self.read_valid_wire
            rest_size = self.read_rest_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(valid_cond)(
                wdata(data),
                wvalid(1)
            )
            fsm.If(valid_cond)(
                rest_size.dec()
            )

            return

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

        self.read_ops.append(op_id)

        rest_size = self.m.Reg('_'.join(['', self.name, 'read_rest_size']),
                               self.addrwidth + 1, initval=0)
        self.read_rest_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(self.read_size)
        )
        fsm.If(cond).goto_next()

        # state 1
        data, last, _id, user, dest, valid = self.read_data(cond=fsm)
        self.read_data_wire = data
        self.read_valid_wire = valid

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

        fsm.Delay(1)(
            wvalid(0)
        )
        fsm.If(valid_cond)(
            wdata(data),
            wvalid(1),
        )
        fsm.If(valid_cond)(
            rest_size.dec()
        )

        fsm.If(valid, rest_size <= 1).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()
Exemple #7
0
    def _set_read_request(self, ram, port, ram_method, start,
                          local_addr, size, local_stride):

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

        if op_id in self.read_reqs:
            (read_start, read_op_sel,
             read_local_addr_in,
             read_size_in, read_local_stride_in) = self.read_reqs[op_id]

            self.seq.If(start)(
                read_start(1),
                read_op_sel(op_id),
                read_local_addr_in(local_addr),
                read_size_in(size),
                read_local_stride_in(local_stride)
            )

            return

        port = str(vtypes.to_int(port))

        read_start = self.m.Reg(
            '_'.join(['', self.name, ram.name, port, 'read_start']),
            initval=0)
        read_op_sel = self.m.Reg(
            '_'.join(['', self.name, ram.name, port, 'read_op_sel']),
            self.op_sel_width, initval=0)
        read_local_addr = self.m.Reg(
            '_'.join(['', self.name, ram.name, port, 'read_local_addr']),
            self.addrwidth, initval=0)
        read_size = self.m.Reg(
            '_'.join(['', self.name, ram.name, port, 'read_size']),
            self.addrwidth + 1, initval=0)
        read_local_stride = self.m.Reg(
            '_'.join(['', self.name, ram.name, port, 'read_local_stride']),
            self.addrwidth, initval=0)

        self.seq(
            read_start(0)
        )
        self.seq.If(start)(
            read_start(1),
            read_op_sel(op_id),
            read_local_addr(local_addr),
            read_size(size),
            read_local_stride(local_stride)
        )

        self.read_reqs[op_id] = (read_start, read_op_sel,
                                 read_local_addr,
                                 read_size, read_local_stride)

        if self.num_cmd_delay > 0:
            read_start = self.seq.Prev(read_start, self.num_cmd_delay)
            read_op_sel = self.seq.Prev(read_op_sel, self.num_cmd_delay)
            read_local_addr = self.seq.Prev(
                read_local_addr, self.num_cmd_delay)
            read_size = self.seq.Prev(read_size, self.num_cmd_delay)
            read_local_stride = self.seq.Prev(
                read_local_stride, self.num_cmd_delay)

        self.seq.If(read_start)(
            self.read_idle(0)
        )

        self.seq.If(read_start)(
            self.read_start(1),
            self.read_op_sel(read_op_sel),
            self.read_local_addr(read_local_addr),
            self.read_size(read_size),
            self.read_local_stride(read_local_stride)
        )