Beispiel #1
0
    def Elif(self, *cond):
        if len(self.last_cond) == 0:
            raise ValueError("No previous condition for Else.")

        cond = make_condition(*cond)

        old = self.last_cond.pop()
        self.last_cond.append(vtypes.Not(old))
        self.last_cond.append(cond)

        # if the true-statement has delay attributes, Else statement is
        # separated.
        if 'delay' in self.last_kwargs and self.last_kwargs['delay'] > 0:
            prev_cond = self.last_cond
            ret = self.Then()
            self.last_cond = prev_cond
            return ret

        if not isinstance(self.last_if_statement, vtypes.If):
            raise ValueError("Last if-statement is not If")

        self.elif_cond = cond

        cond = self._make_cond(self.last_cond)
        self.next_kwargs['cond'] = cond

        return self
Beispiel #2
0
    def done(self, fsm):
        done = None

        for flag in self.done_flags:
            done = make_condition(done, flag)

        return done
Beispiel #3
0
    def Elif(self, *cond):
        if len(self.last_cond) == 0:
            raise ValueError("No previous condition for Else.")

        cond = make_condition(*cond)

        old = self.last_cond.pop()
        self.last_cond.append(vtypes.Not(old))
        self.last_cond.append(cond)

        # if the true-statement has delay attributes, Else statement is
        # separated.
        if 'delay' in self.last_kwargs and self.last_kwargs['delay'] > 0:
            prev_cond = self.last_cond
            ret = self.Then()
            self.last_cond = prev_cond
            return ret

        if not isinstance(self.last_if_statement, vtypes.If):
            raise ValueError("Last if-statement is not If")

        self.elif_cond = cond

        cond = self._make_cond(self.last_cond)
        self.next_kwargs['cond'] = cond

        return self
Beispiel #4
0
    def join(self, fsm):
        done = None

        for flag in self.done_flags:
            done = make_condition(done, flag)

        fsm.If(done).goto_next()
        return 0
Beispiel #5
0
    def _add_statement(self, statement, index=None, keep=None, delay=None, cond=None,
                       lazy_cond=False, eager_val=False, no_delay_cond=False):

        cond = make_condition(cond)
        index = self._to_index(index) if index is not None else self.current

        if keep is not None:
            for i in range(keep):
                new_delay = i if delay is None else delay + i
                self._add_statement(statement, index=index,
                                    keep=None, delay=new_delay, cond=cond,
                                    lazy_cond=lazy_cond, eager_val=eager_val,
                                    no_delay_cond=no_delay_cond)
            return self

        if delay is not None and delay > 0:
            self._add_delayed_state(delay)

            if eager_val:
                statement = [self._add_delayed_subst(s, index, delay)
                             for s in statement]

            if not no_delay_cond:
                if cond is None:
                    cond = 1

                if not lazy_cond:
                    cond = self._add_delayed_cond(cond, index, delay)

                else:  # lazy condition
                    t = self._add_delayed_cond(1, index, delay)
                    if isinstance(cond, int) and cond == 1:
                        cond = t
                    else:
                        cond = vtypes.Ands(t, cond)

                statement = [vtypes.If(cond)(*statement)]

            self.delayed_body[delay][index].extend(statement)
            self._add_dst_var(statement)

            return self

        if cond is not None:
            statement = [vtypes.If(cond)(*statement)]
            self.last_if_statement = statement[0]

        self.body[index].extend(statement)
        self._add_dst_var(statement)

        return self
Beispiel #6
0
    def If(self, *cond):
        self._clear_elif_cond()

        cond = make_condition(*cond)

        if cond is None:
            return self

        if 'cond' not in self.next_kwargs:
            self.next_kwargs['cond'] = cond
        else:
            self.next_kwargs['cond'] = vtypes.Ands(self.next_kwargs['cond'],
                                                   cond)

        self.last_cond = [self.next_kwargs['cond']]

        return self
Beispiel #7
0
    def If(self, *cond):
        self._clear_elif_cond()

        cond = make_condition(*cond)

        if cond is None:
            return self

        if 'cond' not in self.next_kwargs:
            self.next_kwargs['cond'] = cond
        else:
            self.next_kwargs['cond'] = vtypes.Ands(
                self.next_kwargs['cond'], cond)

        self.last_cond = [self.next_kwargs['cond']]

        return self
Beispiel #8
0
    def deq_rtl(self, cond=None):
        """ Deque """

        if self._deq_disabled:
            raise TypeError('Deq disabled.')

        cond = make_condition(cond)
        ready = vtypes.Not(self.rif.empty)

        if cond is not None:
            deq_cond = vtypes.Ands(cond, ready)
        else:
            deq_cond = ready

        util.add_enable_cond(self.rif.deq, deq_cond, 1)

        data = self.rif.rdata
        valid = self.seq.Prev(deq_cond, 1)

        return data, valid, ready
Beispiel #9
0
    def enq_rtl(self, wdata, cond=None):
        """ Enque """

        if self._enq_disabled:
            raise TypeError('Enq disabled.')

        cond = make_condition(cond)
        ready = vtypes.Not(self.wif.almost_full)

        if cond is not None:
            enq_cond = vtypes.Ands(cond, ready)
            enable = cond
        else:
            enq_cond = ready
            enable = vtypes.Int(1, 1)

        util.add_mux(self.wif.wdata, enable, wdata)
        util.add_enable_cond(self.wif.enq, enable, enq_cond)

        ack = self.seq.Prev(ready, 1)

        return ack, ready
Beispiel #10
0
    def _synthesize_set_sink_pattern(self, var, name):
        if var.sink_pat_fsm is not None:
            return

        sink_start = vtypes.Ands(self.start, var.sink_mode == 1)
        for sink_pat_size in var.sink_pat_sizes:
            sink_start = vtypes.Ands(sink_start, sink_pat_size > 0)

        fsm_id = self.fsm_id_count
        self.fsm_id_count += 1

        prefix = self._prefix(name)

        fsm_name = '_%s_sink_pat_fsm_%d' % (prefix, fsm_id)
        var.sink_pat_fsm = FSM(self.module, fsm_name,
                               self.clock, self.reset,
                               as_module=self.fsm_as_module)

        self.seq.If(var.sink_pat_fsm.here)(
            var.sink_ram_wenable(0)
        )

        var.sink_pat_fsm.If(sink_start).goto_next()

        self.seq.If(var.sink_pat_fsm.here)(
            var.sink_ram_waddr(var.sink_offset - var.sink_stride)
        )

        for sink_pat_offset in var.sink_pat_offsets:
            self.seq.If(var.sink_pat_fsm.here)(
                sink_pat_offset(0)
            )

        for (sink_pat_size, sink_pat_count) in zip(
                var.sink_pat_sizes, var.sink_pat_counts):
            self.seq.If(var.sink_pat_fsm.here)(
                sink_pat_count(sink_pat_size - 1)
            )

        num_wdelay = self._write_delay()
        for _ in range(num_wdelay):
            var.sink_pat_fsm.goto_next()

        if name in self.sink_when_map:
            when = self.sink_when_map[name]
            wcond = when.read()
        else:
            wcond = None

        sink_all_offset = self.module.Wire('_%s_sink_pat_all_offset' % prefix,
                                           self.addrwidth)
        sink_all_offset_val = var.sink_offset
        for sink_pat_offset in var.sink_pat_offsets:
            sink_all_offset_val += sink_pat_offset
        sink_all_offset.assign(sink_all_offset_val)

        if name in self.sink_when_map:
            when = self.sink_when_map[name]
            wcond = when.read()
        else:
            wcond = None

        rdata = var.read()

        self.seq.If(var.sink_pat_fsm.here)(
            var.sink_ram_wenable(0)
        )
        self.seq.If(var.sink_pat_fsm.here, wcond)(
            var.sink_ram_waddr(sink_all_offset),
            var.sink_ram_wdata(rdata),
            var.sink_ram_wenable(1)
        )

        upcond = None

        for (sink_pat_offset, sink_pat_size,
             sink_pat_stride, sink_pat_count) in zip(
                 var.sink_pat_offsets, var.sink_pat_sizes,
                 var.sink_pat_strides, var.sink_pat_counts):

            self.seq.If(var.sink_pat_fsm.here, upcond)(
                sink_pat_offset.add(sink_pat_stride),
                sink_pat_count.dec()
            )

            reset_cond = sink_pat_count == 0
            self.seq.If(var.sink_pat_fsm.here, upcond, reset_cond)(
                sink_pat_offset(0),
                sink_pat_count(sink_pat_size - 1)
            )
            upcond = make_condition(upcond, reset_cond)

        fin_cond = upcond

        var.sink_pat_fsm.If(fin_cond).goto_init()
Beispiel #11
0
    def _synthesize_set_source_pattern(self, var, name):
        if var.source_pat_fsm is not None:
            return

        wdata = var.source_ram_rdata
        wenable = var.source_ram_rvalid
        var.write(wdata, wenable)

        source_start = vtypes.Ands(self.start, var.source_mode == 1)
        for source_pat_size in var.source_pat_sizes:
            source_start = vtypes.Ands(source_start, source_pat_size > 0)

        self.seq.If(source_start)(
            var.source_idle(0)
        )

        for source_pat_offset in var.source_pat_offsets:
            self.seq.If(source_start)(
                source_pat_offset(0)
            )

        for (source_pat_size, source_pat_count) in zip(
                var.source_pat_sizes, var.source_pat_counts):
            self.seq.If(source_start)(
                source_pat_count(source_pat_size - 1)
            )

        fsm_id = self.fsm_id_count
        self.fsm_id_count += 1

        prefix = self._prefix(name)

        fsm_name = '_%s_source_pat_fsm_%d' % (prefix, fsm_id)
        var.source_pat_fsm = FSM(self.module, fsm_name,
                                 self.clock, self.reset,
                                 as_module=self.fsm_as_module)

        var.source_pat_fsm.If(source_start).goto_next()

        source_all_offset = self.module.Wire('_%s_source_pat_all_offset' % prefix,
                                             self.addrwidth)
        source_all_offset_val = var.source_offset
        for source_pat_offset in var.source_pat_offsets:
            source_all_offset_val += source_pat_offset
        source_all_offset.assign(source_all_offset_val)

        self.seq.If(var.source_pat_fsm.here)(
            var.source_ram_raddr(source_all_offset),
            var.source_ram_renable(1)
        )

        upcond = None

        for (source_pat_offset, source_pat_size,
             source_pat_stride, source_pat_count) in zip(
                 var.source_pat_offsets, var.source_pat_sizes,
                 var.source_pat_strides, var.source_pat_counts):

            self.seq.If(var.source_pat_fsm.here, upcond)(
                source_pat_offset.add(source_pat_stride),
                source_pat_count.dec()
            )

            reset_cond = source_pat_count == 0
            self.seq.If(var.source_pat_fsm.here, upcond, reset_cond)(
                source_pat_offset(0),
                source_pat_count(source_pat_size - 1)
            )
            upcond = make_condition(upcond, reset_cond)

        fin_cond = upcond

        var.source_pat_fsm.If(fin_cond).goto_next()

        self.seq.If(var.source_pat_fsm.here)(
            var.source_ram_renable(0),
            var.source_idle(1)
        )

        var.source_pat_fsm.goto_init()
Beispiel #12
0
    def run(self, fsm):
        # entry point
        self.fsm._set_index(0)

        #cond = fsm.here
        cond = self._set_flag(fsm)
        add_mux(self.start_flag, cond, 1)

        # after started
        if self.fsm_synthesized:
            fsm.goto_next()
            fsm.goto_next()
            return

        self.fsm_synthesized = True

        num_wdelay = self._write_delay()

        self.fsm.If(self.start_flag)(
            self.start(1),
            self.busy(1)
        )

        if self.reduce_reset is not None:
            self.fsm.seq.If(self.seq.Prev(self.start_flag, self.ram_delay + 1))(
                self.reduce_reset(0)
            )

        substreams = self._collect_substreams()

        for sub in substreams:
            reset_delay = self.ram_delay + 1 + sub.start_stage + sub.reset_delay
            sub_fsm = sub.substrm.fsm
            sub_fsm._set_index(0)

            if sub.substrm.reduce_reset is not None:
                sub_fsm.seq.If(self.seq.Prev(self.start_flag, reset_delay))(
                    sub.substrm.reduce_reset(0)
                )

            for cond in sub.conds.values():
                sub_fsm.If(self.start_flag)(
                    cond(1)
                )

        self.fsm.If(self.start_flag).goto_next()

        self.fsm(
            self.start(0)
        )
        self.fsm.goto_next()

        done_cond = None
        for key, source_idle in sorted(self.source_idle_map.items(),
                                       key=lambda x: x[0]):
            done_cond = make_condition(done_cond, source_idle)

        done = self.module.Wire('_%s_done' % self.name)
        done.assign(done_cond)

        self.fsm.If(done).goto_next()

        depth = self.pipeline_depth()
        for _ in range(depth):
            self.fsm.goto_next()

        self.fsm.goto_next()

        # reset accumulate pipelines
        if self.reduce_reset is not None:
            self.fsm(
                self.reduce_reset(1)
            )

        end_flag = self.fsm.here

        for sub in substreams:
            sub_fsm = sub.substrm.fsm
            sub_fsm._set_index(0)
            if sub.substrm.reduce_reset is not None:
                sub_fsm.If(end_flag)(
                    sub.substrm.reduce_reset(1)
                )

            for cond in sub.conds.values():
                sub_fsm.If(end_flag)(
                    cond(0)
                )

        self.fsm.goto_next()

        self.fsm(
            self.busy(0)
        )

        self.fsm.goto_init()

        fsm.goto_next()
        fsm.goto_next()

        return 0
Beispiel #13
0
    def run(self, fsm):
        # entry point
        self.fsm._set_index(0)

        start_flag = (fsm.state == fsm.current)

        self.fsm.If(start_flag)(
            self.start(1),
            self.busy(1)
        )
        self.fsm.If(start_flag).Delay(1)(
            self.start(0)
        )

        if self.reduce_reset is not None:
            self.fsm.If(start_flag).Delay(self.ram_delay + 1)(
                self.reduce_reset(0)
            )

        substreams = self._collect_substreams()

        for sub in substreams:
            reset_delay = self.ram_delay + 1 + sub.start_stage
            if sub.substrm.reduce_reset is not None:
                self.fsm.If(start_flag).Delay(reset_delay)(
                    sub.substrm.reduce_reset(0)
                )

            for cond in sub.conds.values():
                self.fsm.If(start_flag)(
                    cond(1)
                )

        self.fsm.If(start_flag).goto_next()

        # after started
        if self.fsm_synthesized:
            fsm.goto_next()
            return

        self.fsm_synthesized = True

        self.fsm.goto_next()

        done_cond = None
        for key, source_idle in sorted(self.source_idle_map.items(),
                                       key=lambda x: x[0]):
            done_cond = make_condition(done_cond, source_idle)

        done = self.module.Wire('_%s_done' % self.name)
        done.assign(done_cond)
        self.fsm.If(done).goto_next()

        depth = self.pipeline_depth()
        num_wdelay = self._write_delay()

        # pipeline delay
        for i in range(depth):
            self.fsm.goto_next()

        self.fsm.goto_next()

        # reset accumulate pipelines
        if self.reduce_reset is not None:
            self.fsm(
                self.reduce_reset(1)
            )

        for sub in substreams:
            reset_delay = sub.start_stage
            if sub.substrm.reduce_reset is not None:
                self.fsm(
                    sub.substrm.reduce_reset(1)
                )

            for cond in sub.conds.values():
                self.fsm(
                    cond(0)
                )

        for i in range(num_wdelay - depth - 1):
            self.fsm.goto_next()

        # finish
        self.fsm(
            self.busy(0)
        )

        self.fsm.goto_init()

        fsm.goto_next()

        return 0
Beispiel #14
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,)

        prefix = self._prefix(name)

        fsm_id = self.fsm_id_count
        fsm_name = '_%s_fsm_%d' % (prefix, fsm_id)
        sink_fsm = FSM(self.module, fsm_name, self.clock, self.reset)
        self.fsm_id_map[fsm_id] = sink_fsm
        self.fsm_id_count += 1

        sink_offset = self.module.Reg('_%s_offset_%d' % (prefix, fsm_id),
                                      ram.addrwidth, initval=0)
        sink_pat_offsets = [self.module.Reg('_%s_pat_offset_%d_%d' % (prefix, fsm_id, i),
                                            ram.addrwidth, initval=0)
                            for i, _ in enumerate(pattern)]
        sink_pat_sizes = [self.module.Reg('_%s_pat_size_%d_%d' % (prefix, fsm_id, i),
                                          ram.addrwidth + 1, initval=0)
                          for i, _ in enumerate(pattern)]
        sink_pat_strides = [self.module.Reg('_%s_pat_stride_%d_%d' % (prefix, fsm_id, i),
                                            ram.addrwidth, initval=0)
                            for i, _ in enumerate(pattern)]
        sink_pat_counts = [self.module.Reg('_%s_pat_count_%d_%d' % (prefix, fsm_id, i),
                                           ram.addrwidth + 1, initval=0)
                           for i, _ in enumerate(pattern)]

        var_id = self.var_name_id_map[name]
        fsm_sel = self.var_id_fsm_sel_map[var_id]

        set_cond = (fsm.state == fsm.current)

        sink_fsm.If(set_cond)(
            sink_offset(offset)
        )
        self.seq.If(set_cond)(
            fsm_sel(fsm_id)
        )

        for sink_pat_offset in sink_pat_offsets:
            sink_fsm.If(set_cond)(
                sink_pat_offset(0)
            )

        for (sink_pat_size, sink_pat_stride, (size, stride)) in zip(
                sink_pat_sizes, sink_pat_strides, pattern):
            sink_fsm.If(set_cond)(
                sink_pat_size(size),
                sink_pat_stride(stride)
            )

        sink_start = vtypes.Ands(self.start, fsm_sel == fsm_id)
        for sink_pat_size in sink_pat_sizes:
            sink_start = vtypes.Ands(sink_start, sink_pat_size > 0)

        for (sink_pat_size, sink_pat_count) in zip(
                sink_pat_sizes, sink_pat_counts):
            sink_fsm.If(sink_start)(
                sink_pat_count(sink_pat_size - 1)
            )

        sink_fsm.If(sink_start).goto_next()

        num_wdelay = self._write_delay()

        for i in range(num_wdelay):
            sink_fsm.goto_next()

        sink_all_offset = self.module.Wire('_%s_all_offset_%d' % (prefix, fsm_id),
                                           ram.addrwidth)
        sink_all_offset_val = sink_offset
        for sink_pat_offset in sink_pat_offsets:
            sink_all_offset_val += sink_pat_offset
        sink_all_offset.assign(sink_all_offset_val)

        waddr = self.module.Reg('_%s_waddr_%d' % (prefix, fsm_id),
                                ram.addrwidth, initval=0)
        wenable = self.module.Reg('_%s_wenable_%d' % (prefix, fsm_id),
                                  initval=0)
        wdata = self.module.Reg('_%s_wdata_%d' % (prefix, fsm_id),
                                ram.datawidth, initval=0, signed=True)
        rdata = var.read()

        ram.write_rtl(waddr, wdata, port=port, cond=wenable)

        if name in self.sink_when_map:
            when = self.sink_when_map[name]
            wcond = when.read()
        else:
            wcond = None

        sink_fsm.If(wcond)(
            waddr(sink_all_offset),
            wdata(rdata),
            wenable(1)
        )
        sink_fsm.Delay(1)(
            wenable(0)
        )

        upcond = None

        for (sink_pat_offset, sink_pat_size,
             sink_pat_stride, sink_pat_count) in zip(
                 sink_pat_offsets, sink_pat_sizes,
                 sink_pat_strides, sink_pat_counts):
            sink_fsm.If(upcond)(
                sink_pat_offset.add(sink_pat_stride),
                sink_pat_count.dec()
            )
            reset_cond = sink_pat_count == 0
            sink_fsm.If(upcond, reset_cond)(
                sink_pat_offset(0),
                sink_pat_count(sink_pat_size - 1)
            )
            upcond = make_condition(upcond, reset_cond)

        fin_cond = upcond

        sink_fsm.If(fin_cond).goto_init()

        sink_fsm._set_index(0)

        fsm.goto_next()