コード例 #1
0
ファイル: stream.py プロジェクト: gwsu/veriloggen
    def write_sequential(self,
                         obj,
                         start_addr,
                         size,
                         value,
                         when=None,
                         port=0):
        flag = self.m.Reg(compiler._tmp_name('_'.join(['', self.name,
                                                       'flag'])),
                          initval=0)
        self.done_flags.append(flag)

        fsm = FSM(self.m, compiler._tmp_name('_'.join(['', self.name, 'fsm'])),
                  self.clk, self.rst)
        fsm.If(self.start_cond)(flag(0))
        fsm.If(self.start_cond).goto_next()

        done = obj.write_dataflow(port,
                                  start_addr,
                                  value,
                                  size,
                                  cond=fsm,
                                  when=when)
        fsm.goto_next()

        fsm.If(done)(flag(1))

        fsm.If(done).goto_init()

        return 0
コード例 #2
0
    def run(self, fsm, *args, **kwargs):
        """ start as a child thread """

        if not self.is_child and self.end_state is not None:
            raise ValueError('already started.')

        self.fsm = FSM(self.m, self.name, self.clk, self.rst)
        self.is_child = True

        if self.start_state is None:
            self.start_state = self.fsm.current

        start_flag = (fsm.state == fsm.current)
        self.fsm.goto_from(self.start_state, self.start_state + 1, start_flag)

        self.fsm._set_index(self.start_state + 1)

        if self.end_state is not None:
            return 0

        self._synthesize_fsm(self.fsm, args, kwargs)

        if self.end_state is None:
            self.end_state = self.fsm.current

        return 0
コード例 #3
0
    def write_pattern(self, obj, addr, value, pattern, when=None, port=0):

        flag = self.m.Reg(compiler._tmp_name('_'.join(['', self.name,
                                                       'flag'])),
                          initval=0)
        self.done_flags.append(flag)

        fsm = FSM(self.m, compiler._tmp_name('_'.join(['', self.name, 'fsm'])),
                  self.clk, self.rst)
        fsm.If(self.start_cond)(flag(0))
        fsm.If(self.start_cond).goto_next()

        if hasattr(obj, 'write_dataflow_pattern_interleave'):
            done = obj.write_dataflow_pattern_interleave(port,
                                                         addr,
                                                         value,
                                                         pattern,
                                                         cond=fsm,
                                                         when=when)
        else:
            done = obj.write_dataflow_pattern(port,
                                              addr,
                                              value,
                                              pattern,
                                              cond=fsm,
                                              when=when)

        fsm.goto_next()

        fsm.If(done)(flag(1))

        fsm.If(done).goto_init()

        return 0
コード例 #4
0
ファイル: stream.py プロジェクト: gwsu/veriloggen
    def read_sequential(self,
                        obj,
                        start_addr,
                        size,
                        point=0,
                        signed=False,
                        port=0,
                        with_last=False):
        flag = self.m.Reg(compiler._tmp_name('_'.join(['', self.name,
                                                       'flag'])),
                          initval=0)
        self.done_flags.append(flag)

        fsm = FSM(self.m, compiler._tmp_name('_'.join(['', self.name, 'fsm'])),
                  self.clk, self.rst)
        fsm.If(self.start_cond)(flag(0))
        fsm.If(self.start_cond).goto_next()

        rdata, rlast, done = obj.read_dataflow(port,
                                               start_addr,
                                               size,
                                               cond=fsm,
                                               point=point,
                                               signed=signed)
        fsm.goto_next()

        fsm.If(done)(flag(1))

        fsm.If(done).goto_init()

        if with_last:
            return rdata, rlast

        return rdata
コード例 #5
0
    def run(self, fsm, *args, **kwargs):
        """ start as a child thread """

        if not self.is_child and self.end_state is not None:
            raise ValueError('already started')

        if self.fsm is None:
            self.fsm = FSM(self.m,
                           self.name,
                           self.clk,
                           self.rst,
                           as_module=self.fsm_as_module)

        self.is_child = True

        if self.start_state is not None:
            self.fsm._set_index(self.start_state)
        else:
            self.start_state = self.fsm.current

        self._synthesize_run_fsm(fsm, args, kwargs)

        if self.end_state is None:
            self.end_state = self.fsm.current

        start_flag = (self.fsm.state == self.start_state)

        return start_flag
コード例 #6
0
    def read_reuse_pattern(self,
                           obj,
                           addr,
                           pattern,
                           reuse_size=1,
                           num_outputs=1,
                           point=0,
                           signed=False,
                           port=0,
                           with_last=False):

        flag = self.m.Reg(compiler._tmp_name('_'.join(['', self.name,
                                                       'flag'])),
                          initval=0)
        self.done_flags.append(flag)

        fsm = FSM(self.m, compiler._tmp_name('_'.join(['', self.name, 'fsm'])),
                  self.clk, self.rst)
        fsm.If(self.start_cond)(flag(0))
        fsm.If(self.start_cond).goto_next()

        if hasattr(obj, 'read_dataflow_reuse_pattern_interleave'):
            ret = obj.read_dataflow_reuse_pattern_interleave(port,
                                                             addr,
                                                             pattern,
                                                             reuse_size,
                                                             num_outputs,
                                                             cond=fsm,
                                                             point=point,
                                                             signed=signed)
        else:
            ret = obj.read_dataflow_reuse_pattern(port,
                                                  addr,
                                                  pattern,
                                                  reuse_size,
                                                  num_outputs,
                                                  cond=fsm,
                                                  point=point,
                                                  signed=signed)

        rdata = ret[:-2]
        done = ret[-1]
        rlast = ret[-2]

        fsm.goto_next()

        fsm.If(done)(flag(1))

        fsm.If(done).goto_init()

        if with_last:
            return tuple(rdata + [rlast])

        if len(rdata) == 1:
            rdata = rdata[0]
        else:
            rdata = tuple(rdata)

        return rdata
コード例 #7
0
ファイル: ttypes.py プロジェクト: howardyan93/veriloggen
    def _setup_register_lite_fsm(self):
        fsm = FSM(self.m, '_'.join(['', self.name, 'register_fsm']), self.clk,
                  self.rst)

        # request
        addr, readvalid, writevalid = self.pull_request(cond=fsm)

        maskaddr = self.m.TmpReg(self.maskwidth)
        fsm.If(vtypes.Ors(readvalid, writevalid))(maskaddr((addr >> self.shift)
                                                           & self.mask), )

        init_state = fsm.current

        # read
        read_state = fsm.current + 1
        fsm.If(readvalid).goto_from(init_state, read_state)
        fsm.set_index(read_state)

        rdata = self.m.TmpWire(self.datawidth)
        pat = [(maskaddr == i, r) for i, r in enumerate(self.register)]
        pat.append((None, vtypes.IntX()))
        rval = vtypes.PatternMux(pat)
        rdata.assign(rval)

        flag = self.m.TmpWire()
        pat = [(maskaddr == i, r) for i, r in enumerate(self.flag)]
        pat.append((None, vtypes.IntX()))
        rval = vtypes.PatternMux(pat)
        flag.assign(rval)

        resetval = self.m.TmpWire(self.datawidth)
        pat = [(maskaddr == i, r) for i, r in enumerate(self.resetval)]
        pat.append((None, vtypes.IntX()))
        rval = vtypes.PatternMux(pat)
        resetval.assign(rval)

        ack = self.push_read_data(rdata, cond=fsm)

        # flag reset
        state_cond = fsm.state == fsm.current
        for i, r in enumerate(self.register):
            self.seq.If(state_cond, ack, flag,
                        maskaddr == i)(self.register[i](resetval),
                                       self.flag[i](0))

        fsm.If(ack).goto_init()

        # write
        write_state = fsm.current + 1
        fsm.If(writevalid).goto_from(init_state, write_state)
        fsm.set_index(write_state)

        data, mask, valid = self.pull_write_data(cond=fsm)

        state_cond = fsm.state == fsm.current
        for i, r in enumerate(self.register):
            self.seq.If(state_cond, valid,
                        maskaddr == i)(self.register[i](data))
        fsm.goto_init()
コード例 #8
0
ファイル: stream.py プロジェクト: IanMadlenya/veriloggen
    def __init__(self, m, name, clk, rst,
                 datawidth=32, addrwidth=32,
                 max_pattern_length=4, ram_sel_width=8,
                 fsm_as_module=False):

        BaseStream.__init__(self, module=m, clock=clk, reset=rst,
                            no_hook=True)

        self.name = name
        self.datawidth = datawidth
        self.addrwidth = addrwidth

        self.max_pattern_length = max_pattern_length
        self.ram_sel_width = ram_sel_width

        self.fsm_as_module = fsm_as_module

        self.stream_synthesized = False
        self.fsm_synthesized = False

        self.fsm = FSM(self.module, '_%s_fsm' %
                       self.name, self.clock, self.reset,
                       as_module=self.fsm_as_module)
        self.start_flag = self.module.Wire(
            '_'.join(['', self.name, 'start_flag']))
        self.start = self.module.Reg(
            '_'.join(['', self.name, 'start']), initval=0)
        self.busy = self.module.Reg(
            '_'.join(['', self.name, 'busy']), initval=0)

        self.reduce_reset = None
        self.reduce_reset_var = None

        self.sources = OrderedDict()
        self.sinks = OrderedDict()
        self.constants = OrderedDict()
        self.substreams = []

        self.var_name_map = OrderedDict()
        self.var_id_map = OrderedDict()
        self.var_id_name_map = OrderedDict()
        self.var_name_id_map = OrderedDict()
        self.var_id_count = 0

        self.source_idle_map = OrderedDict()
        self.sink_when_map = OrderedDict()

        self.ram_id_count = 1  # '0' is reserved for idle
        self.ram_id_map = OrderedDict()  # key: ran._id(), value: count

        self.fsm_id_count = 0

        self.ram_delay = 4
コード例 #9
0
ファイル: stream.py プロジェクト: IanMadlenya/veriloggen
    def _synthesize_set_sink(self, var, name):
        if var.sink_fsm is not None:
            return

        sink_start = vtypes.Ands(self.start, var.sink_mode == 0,
                                 var.sink_size > 0)

        fsm_id = self.fsm_id_count
        self.fsm_id_count += 1

        prefix = self._prefix(name)

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

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

        var.sink_fsm.If(sink_start).goto_next()

        self.seq.If(var.sink_fsm.here)(
            var.sink_ram_waddr(var.sink_offset - var.sink_stride),
            var.sink_count(var.sink_size)
        )

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

        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_fsm.here)(
            var.sink_ram_wenable(0)
        )
        self.seq.If(var.sink_fsm.here, wcond)(
            var.sink_ram_waddr.add(var.sink_stride),
            var.sink_ram_wdata(rdata),
            var.sink_ram_wenable(1),
            var.sink_count.dec()
        )

        var.sink_fsm.If(wcond, var.sink_count == 1).goto_init()
コード例 #10
0
    def read_multidim(self,
                      obj,
                      addr,
                      shape,
                      order=None,
                      point=0,
                      signed=False,
                      port=0,
                      with_last=False):

        flag = self.m.Reg(compiler._tmp_name('_'.join(['', self.name,
                                                       'flag'])),
                          initval=0)
        self.done_flags.append(flag)

        fsm = FSM(self.m, compiler._tmp_name('_'.join(['', self.name, 'fsm'])),
                  self.clk, self.rst)
        fsm.If(self.start_cond)(flag(0))
        fsm.If(self.start_cond).goto_next()

        if hasattr(obj, 'read_dataflow_multidim_interleave'):
            rdata, rlast, done = obj.read_dataflow_multidim_interleave(
                port,
                addr,
                shape,
                order=order,
                cond=fsm,
                point=point,
                signed=signed)
        else:
            rdata, rlast, done = obj.read_dataflow_multidim(port,
                                                            addr,
                                                            shape,
                                                            order=order,
                                                            cond=fsm,
                                                            point=point,
                                                            signed=signed)

        fsm.goto_next()

        fsm.If(done)(flag(1))

        fsm.If(done).goto_init()

        if with_last:
            return rdata, rlast

        return rdata
コード例 #11
0
ファイル: stream.py プロジェクト: IanMadlenya/veriloggen
    def _synthesize_set_source(self, var, name):
        if var.source_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 == 0,
                                   var.source_size > 0)

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

        fsm_id = self.fsm_id_count
        self.fsm_id_count += 1

        prefix = self._prefix(name)

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

        var.source_fsm.If(source_start).goto_next()

        self.seq.If(var.source_fsm.here)(
            var.source_ram_raddr(var.source_offset),
            var.source_ram_renable(1),
            var.source_count(var.source_size)
        )

        var.source_fsm.goto_next()

        self.seq.If(var.source_fsm.here)(
            var.source_ram_raddr.add(var.source_stride),
            var.source_ram_renable(1),
            var.source_count.dec()
        )
        self.seq.If(var.source_fsm.here, var.source_count == 1)(
            var.source_ram_renable(0),
            var.source_idle(1)
        )

        var.source_fsm.If(var.source_count == 1).goto_init()
コード例 #12
0
ファイル: thread.py プロジェクト: yongfu-li/veriloggen
    def start(self, *args, **kwargs):
        """ build up a new FSM based on the arguments """

        if self.is_child:
            raise ValueError('already started as a child thread')

        if self.end_state is not None:
            raise ValueError('already started')

        frame = inspect.currentframe()
        self.start_frame = frame.f_back

        self.fsm = FSM(self.m, self.name, self.clk, self.rst)

        self.start_state = self.fsm.current
        self._synthesize_start_fsm(args, kwargs)
        self.end_state = self.fsm.current

        return self.fsm
コード例 #13
0
ファイル: pool.py プロジェクト: yinxx/veriloggen
    def run(self, fsm, tid, *args, **kwargs):
        """ start as a child thread """

        fsm(self.start[tid](1))
        fsm.goto_next()

        for thread in self.threads:
            start_cond = self.start[thread.tid]

            if not thread.is_child and thread.end_state is not None:
                raise ValueError('thread %d already started' % thread.tid)

            if thread.fsm is None:
                thread.fsm = FSM(thread.m,
                                 thread.name,
                                 thread.clk,
                                 thread.rst,
                                 as_module=thread.fsm_as_module)

            thread.is_child = True

            if thread.start_state is not None:
                thread.fsm._set_index(thread.start_state)
            else:
                thread.start_state = thread.fsm.current

        fsm_start = fsm.current

        for thread in self.threads:
            start_cond = self.start[thread.tid]

            fsm._set_index(fsm_start)

            thread._synthesize_run_fsm(fsm, args, kwargs, cond=start_cond)

            if thread.end_state is None:
                thread.end_state = thread.fsm.current

        fsm(self.start[tid](0))
        fsm.goto_next()

        return 0
コード例 #14
0
ファイル: stream.py プロジェクト: minhson/veriloggen
    def __init__(self, m, name, clk, rst, datawidth=32, fsm_sel_width=16):
        BaseStream.__init__(self, module=m, clock=clk, reset=rst,
                            no_hook=True)

        self.name = name
        self.datawidth = datawidth
        self.fsm_sel_width = fsm_sel_width
        self.stream_synthesized = False
        self.fsm_synthesized = False

        self.fsm = FSM(self.module, '_%s_fsm' %
                       self.name, self.clock, self.reset)
        self.start = self.module.Reg(
            '_'.join(['', self.name, 'start']), initval=0)
        self.busy = self.module.Reg(
            '_'.join(['', self.name, 'busy']), initval=0)

        self.reduce_reset = None
        self.reduce_reset_var = None

        self.sources = OrderedDict()
        self.sinks = OrderedDict()
        self.constants = OrderedDict()
        self.substreams = []

        self.var_name_map = OrderedDict()
        self.var_id_map = OrderedDict()
        self.var_id_name_map = OrderedDict()
        self.var_name_id_map = OrderedDict()
        self.var_id_count = 0
        self.source_idle_map = OrderedDict()
        self.sink_when_map = OrderedDict()

        self.fsm_id_map = OrderedDict()
        self.fsm_id_count = 1  # '0' is reserved for idle
        self.var_id_fsm_sel_map = OrderedDict()  # key: var_id, value: fsm_id reg

        self.ram_delay = 4
コード例 #15
0
    def start(self, *args, **kwargs):
        """ build up a new FSM based on the arguments """

        if self.is_child:
            raise ValueError('already started as a child thread')

        if self.end_state is not None:
            raise ValueError('already started')

        frame = inspect.currentframe()
        _locals = frame.f_back.f_locals

        self.local_objects = OrderedDict()
        for key, value in _locals.items():
            self.local_objects[key] = value

        self.fsm = FSM(self.m, self.name, self.clk, self.rst)

        self.start_state = self.fsm.current
        self._synthesize_start_fsm(args, kwargs)
        self.end_state = self.fsm.current

        return self.fsm
コード例 #16
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
コード例 #17
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
コード例 #18
0
    def _synthesize_read_fsm_fifo_same(self, fifo, fifo_datawidth):

        op_id = self._get_read_op_id_fifo(fifo)

        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)
            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)

            ack, _ = fifo.enq_rtl(data, cond=valid_cond)

            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
        cond = vtypes.Ands(self.read_start, self.read_op_sel == op_id)

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

        # state 1
        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_data_wire = data
        self.read_valid_wire = valid

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

        ack, _ = fifo.enq_rtl(data, cond=valid_cond)

        fsm.If(valid_cond)(
            rest_size.dec()
        )

        fsm.If(valid, rest_size <= 1).goto_next()

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

        fsm.goto_init()
コード例 #19
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()
コード例 #20
0
    def _synthesize_write_fsm(self):

        op_id = 1

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

        if self.write_fsm is not None:
            """ new op """
            self.write_ops.append(op_id)
            return

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

        self.write_ops.append(op_id)

        cur_global_addr = self.m.Reg('_'.join(['', self.name, 'write_cur_global_addr']),
                                     self.addrwidth, initval=0)
        cur_size = self.m.Reg('_'.join(['', self.name, 'write_cur_size']),
                              self.addrwidth + 1, initval=0)
        rest_size = self.m.Reg('_'.join(['', self.name, 'write_rest_size']),
                               self.addrwidth + 1, initval=0)
        max_burstlen = 2 ** self.burst_size_width

        # state 0
        if not self.use_global_base_addr:
            gaddr = self.write_global_addr
        else:
            gaddr = self.write_global_addr + self.global_base_addr

        fsm.If(self.write_start)(
            cur_global_addr(self.mask_addr(gaddr)),
            rest_size(self.write_size)
        )
        fsm.If(self.write_start).goto_next()

        # state 1
        check_state = fsm.current
        self._check_4KB_boundary(fsm, max_burstlen,
                                 cur_global_addr, cur_size, rest_size)

        # state 2
        ack, counter = self.write_request_counter(cur_global_addr, cur_size, cond=fsm)
        self.write_data_counter = counter
        fsm.If(ack).goto_next()

        # state 3
        cond = fsm.here
        data, last, _id, user, dest, done = self.in_streamout.read_dataflow(cond=cond)
        done_out = self.write_dataflow(data, counter, cond=cond)
        self.write_data_done.assign(done_out)

        fsm.If(self.write_data_done)(
            cur_global_addr.add(optimize(cur_size * (self.datawidth // 8)))
        )
        fsm.If(self.write_data_done, rest_size > 0).goto(check_state)
        fsm.If(self.write_data_done, rest_size == 0).goto_next()

        # state 4
        set_idle = self._set_flag(fsm)
        self.seq.If(set_idle)(
            self.write_idle(1)
        )

        fsm.goto_init()
コード例 #21
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()
コード例 #22
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()
コード例 #23
0
    def _synthesize_read_fsm(self):

        op_id = 1

        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)
            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)

        cur_global_addr = self.m.Reg('_'.join(['', self.name, 'read_cur_global_addr']),
                                     self.addrwidth, initval=0)
        cur_size = self.m.Reg('_'.join(['', self.name, 'read_cur_size']),
                              self.addrwidth + 1, initval=0)
        rest_size = self.m.Reg('_'.join(['', self.name, 'read_rest_size']),
                               self.addrwidth + 1, initval=0)
        max_burstlen = 2 ** self.burst_size_width

        # state 0
        if not self.use_global_base_addr:
            gaddr = self.read_global_addr
        else:
            gaddr = self.read_global_addr + self.global_base_addr

        fsm.If(self.read_start)(
            cur_global_addr(self.mask_addr(gaddr)),
            rest_size(self.read_size)
        )
        fsm.If(self.read_start).goto_next()

        # state 1
        check_state = fsm.current
        self._check_4KB_boundary(fsm, max_burstlen,
                                 cur_global_addr, cur_size, rest_size)

        # state 2
        ack = self.read_request(cur_global_addr, cur_size, cond=fsm)
        fsm.If(ack).goto_next()

        accept = vtypes.Ands(self.raddr.arvalid, self.raddr.arready)
        fsm.If(accept)(
            cur_global_addr.add(optimize(cur_size * (self.datawidth // 8)))
        )
        fsm.If(accept, rest_size > 0).goto(check_state)
        fsm.If(accept, rest_size == 0).goto_next()

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

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

        fsm.goto_init()
コード例 #24
0
ファイル: stream.py プロジェクト: IanMadlenya/veriloggen
    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()
コード例 #25
0
ファイル: stream.py プロジェクト: minhson/veriloggen
    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()
コード例 #26
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()
コード例 #27
0
ファイル: stream.py プロジェクト: IanMadlenya/veriloggen
    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()
コード例 #28
0
ファイル: stream.py プロジェクト: minhson/veriloggen
    def set_source(self, fsm, name, ram, offset, size, stride=1, port=0):
        """ intrinsic method to assign RAM property to a source 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.sources:
            raise NameError("No such stream '%s'" % name)

        prefix = self._prefix(name)

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

        source_idle = self.source_idle_map[name]
        source_offset = self.module.Reg('_%s_offset_%d' % (prefix, fsm_id),
                                        ram.addrwidth, initval=0)
        source_size = self.module.Reg('_%s_size_%d' % (prefix, fsm_id),
                                      ram.addrwidth + 1, initval=0)
        source_stride = self.module.Reg('_%s_stride_%d' % (prefix, fsm_id),
                                        ram.addrwidth, initval=0)
        source_count = self.module.Reg('_%s_count_%d' % (prefix, fsm_id),
                                       ram.addrwidth + 1, initval=0)

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

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

        source_fsm.If(set_cond)(
            source_offset(offset),
            source_size(size),
            source_stride(stride)
        )
        self.seq.If(set_cond)(
            fsm_sel(fsm_id)
        )

        self.seq.If(self.start)(
            source_idle(0)
        )

        source_start = vtypes.Ands(
            self.start, fsm_sel == fsm_id, source_size > 0)

        source_fsm.If(source_start)(
            source_count(source_size)
        )
        source_fsm.If(source_start).goto_next()

        raddr = self.module.Reg('_%s_raddr_%d' % (prefix, fsm_id),
                                ram.addrwidth, initval=0)
        renable = self.module.Reg('_%s_renable_%d' % (prefix, fsm_id),
                                  initval=0)

        rdata, rvalid = ram.read_rtl(raddr, port=port, cond=renable)

        wdata = rdata
        wenable = rvalid
        var.write(wdata, wenable)

        source_fsm(
            raddr(source_offset),
            renable(1),
            source_count.dec()
        )
        source_fsm.Delay(1)(
            renable(0)
        )
        self.seq.If(source_fsm.state == source_fsm.current,
                    source_count == 1)(
            source_idle(1)
        )
        source_fsm.If(source_count == 1).goto_init()
        source_fsm.If(source_count > 1).goto_next()

        source_fsm(
            raddr.add(source_stride),
            renable(1),
            source_count.dec()
        )
        source_fsm.Delay(1)(
            renable(0)
        )
        source_fsm.If(source_count == 1).goto_init()

        self.seq.If(source_fsm.state == source_fsm.current,
                    source_count == 1)(
            source_idle(1)
        )

        source_fsm._set_index(0)

        fsm.goto_next()
コード例 #29
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()
コード例 #30
0
ファイル: stream.py プロジェクト: minhson/veriloggen
    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)

        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_size = self.module.Reg('_%s_size_%d' % (prefix, fsm_id),
                                    ram.addrwidth + 1, initval=0)
        sink_stride = self.module.Reg('_%s_stride_%d' % (prefix, fsm_id),
                                      ram.addrwidth, initval=0)
        sink_count = self.module.Reg('_%s_count_%d' % (prefix, fsm_id),
                                     ram.addrwidth + 1, initval=0)

        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),
            sink_size(size),
            sink_stride(stride)
        )
        self.seq.If(set_cond)(
            fsm_sel(fsm_id)
        )

        sink_start = vtypes.Ands(
            self.start, fsm_sel == fsm_id, sink_size > 0)

        sink_fsm.If(sink_start)(
            sink_count(sink_size)
        )
        sink_fsm.If(sink_start).goto_next()

        num_wdelay = self._write_delay()

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

        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_offset),
            wdata(rdata),
            wenable(1),
            sink_count.dec()
        )
        sink_fsm.Delay(1)(
            wenable(0)
        )
        sink_fsm.If(wcond, sink_count == 1).goto_init()
        sink_fsm.If(wcond, sink_count > 1).goto_next()

        sink_fsm.If(wcond)(
            waddr.add(sink_stride),
            wdata(rdata),
            wenable(1),
            sink_count.dec()
        )
        sink_fsm.Delay(1)(
            wenable(0)
        )
        sink_fsm.If(wcond, sink_count == 1).goto_init()

        sink_fsm._set_index(0)

        fsm.goto_next()