Esempio n. 1
0
    def __init__(self, *nodes, **opts):
        # ID for manager reuse and merge
        global _dataflow_counter
        self.object_id = _dataflow_counter
        _dataflow_counter += 1

        self.nodes = set(nodes)
        self.max_stage = 0
        self.last_input = None
        self.last_output = None

        self.module = opts['module'] if 'module' in opts else None
        self.clock = opts['clock'] if 'clock' in opts else None
        self.reset = opts['reset'] if 'reset' in opts else None

        self.aswire = opts['aswire'] if 'aswire' in opts else True

        self.seq = None

        if (self.module is not None and self.clock is not None
                and self.reset is not None):

            no_hook = opts['no_hook'] if 'no_hook' in opts else False
            if not no_hook:
                self.module.add_hook(self.implement)

            seq_name = (opts['seq_name'] if 'seq_name' in opts else
                        '_dataflow_seq_%d' % self.object_id)
            self.seq = Seq(self.module, seq_name, self.clock, self.reset)
Esempio n. 2
0
    def __init__(self, *nodes, **opts):
        # ID for manager reuse and merge
        global _stream_counter
        self.object_id = _stream_counter
        _stream_counter += 1

        self.nodes = set()
        self.named_numerics = OrderedDict()

        self.add(*nodes)

        self.max_stage = 0
        self.last_input = None
        self.last_output = None

        self.module = opts['module'] if 'module' in opts else None
        self.clock = opts['clock'] if 'clock' in opts else None
        self.reset = opts['reset'] if 'reset' in opts else None

        self.ivalid = opts['ivalid'] if 'ivalid' in opts else None
        self.iready = opts['iready'] if 'iready' in opts else None
        self.ovalid = opts['ovalid'] if 'ovalid' in opts else None
        self.oready = opts['oready'] if 'oready' in opts else None

        self.aswire = opts['aswire'] if 'aswire' in opts else True
        self.dump = opts['dump'] if 'dump' in opts else False
        self.dump_base = opts['dump_base'] if 'dump_base' in opts else 10
        self.dump_mode = opts['dump_mode'] if 'dump_mode' in opts else 'all'

        self.seq = None
        self.has_control = False

        self.implemented = False

        if (self.module is not None and
                self.clock is not None and self.reset is not None):

            no_hook = opts['no_hook'] if 'no_hook' in opts else False
            if not no_hook:
                self.module.add_hook(self.implement)

            seq_name = (opts['seq_name'] if 'seq_name' in opts else
                        '_stream_seq_%d' % self.object_id)
            self.seq = Seq(self.module, seq_name, self.clock, self.reset)

        if self.dump:
            dump_enable_name = '_stream_dump_enable_%d' % self.object_id
            dump_enable = self.module.Reg(dump_enable_name, initval=0)
            dump_mask_name = '_stream_dump_mask_%d' % self.object_id
            dump_mask = self.module.Reg(dump_mask_name, initval=0)
            dump_step_name = '_stream_dump_step_%d' % self.object_id
            dump_step = self.module.Reg(dump_step_name, 32, initval=0)

            self.dump_enable = dump_enable
            self.dump_mask = dump_mask
            self.dump_step = dump_step

            if self.seq:
                self.seq.add_reset(self.dump_enable)
                self.seq.add_reset(self.dump_mask)
Esempio n. 3
0
    def write(self, fsm, value, *part):
        if self.seq is None:
            m = fsm.m
            clk = fsm.clk
            rst = fsm.rst
            name = self._value.name
            self.seq = Seq(m, '_'.join(['seq', name]), clk, rst)

        cond = fsm.state == fsm.current

        def getval(v, p):
            if isinstance(p, (tuple, list)):
                return v[p[0], p[1]]
            return v[p]

        if len(part) == 0:
            targ = self._value
        elif len(part) == 1:
            targ = getval(self._value, part[0])
        elif len(part) == 2:
            targ = getval(getval(self._value, part[0]), part[1])
        else:
            raise TypeError('unsupported type')

        self.seq.If(cond)(targ(value))

        fsm.goto_next()
        return 0
Esempio n. 4
0
    def __init__(self,
                 m,
                 name,
                 clk,
                 rst,
                 datawidth=32,
                 addrwidth=10,
                 numports=1,
                 nodataflow=False):

        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst
        self.datawidth = datawidth
        self.addrwidth = addrwidth
        self.interfaces = [
            RAMInterface(m, name + '_%d' % i, datawidth, addrwidth)
            for i in range(numports)
        ]

        self.definition = mkRAMDefinition(name, datawidth, addrwidth, numports)
        self.inst = self.m.Instance(self.definition,
                                    'inst_' + name,
                                    ports=m.connect_ports(self.definition))

        self.seq = Seq(m, name, clk, rst)

        if nodataflow:
            self.df = None
        else:
            self.df = DataflowManager(self.m, self.clk, self.rst)

        self._write_disabled = [False for i in range(numports)]
Esempio n. 5
0
    def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=32,
                 nodataflow=False):

        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst
        self.datawidth = datawidth
        self.addrwidth = addrwidth

        self.waddr = AxiSlaveWriteAddress(m, name, datawidth, addrwidth)
        self.wdata = AxiSlaveWriteData(m, name, datawidth, addrwidth)
        self.raddr = AxiSlaveReadAddress(m, name, datawidth, addrwidth)
        self.rdata = AxiSlaveReadData(m, name, datawidth, addrwidth)

        self.seq = Seq(m, name, clk, rst)

        self.write_counters = []
        self.read_counters = []

        if nodataflow:
            self.df = None
        else:
            self.df = DataflowManager(self.m, self.clk, self.rst)

        self._write_disabled = False
        self._read_disabled = False
Esempio n. 6
0
    def __init__(self, m, name, clk, rst, func):
        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst
        self.func = func

        self.df = DataflowManager(self.m, self.clk, self.rst)
        self.seq = Seq(self.m, 'name', self.clk, self.rst)
        self.start_cond = None
        self.done_flags = []
Esempio n. 7
0
    def __init__(self,
                 m,
                 clk,
                 rst,
                 thread_name,
                 thread_id,
                 id,
                 sub_id=None,
                 datawidth=32,
                 addrwidth=10,
                 numports=1):

        self.m = m
        self.clk = clk
        self.rst = rst
        self.thread_name = thread_name
        self.thread_id = thread_id
        self.id = id
        self.sub_id = sub_id
        self.name = '_'.join([thread_name, 'memory', str(id)])
        self.datawidth = datawidth
        self.addrwidth = addrwidth

        self.interfaces = []
        for i in range(numports):
            index = i if numports > 1 else None
            obj = CoramMemoryInterface(m,
                                       name=self.name,
                                       datawidth=datawidth,
                                       addrwidth=addrwidth,
                                       index=index)
            self.interfaces.append(obj)

        self.definition = get_coram_memory_definition(numports)

        params = []
        params.append(('CORAM_THREAD_NAME', self.thread_name))
        params.append(('CORAM_THREAD_ID', self.thread_id))
        params.append(('CORAM_ID', self.id))
        if self.sub_id is not None:
            params.append(('CORAM_SUB_ID', self.sub_id))
        params.append(('CORAM_ADDR_LEN', self.addrwidth))
        params.append(('CORAM_DATA_WIDTH', self.datawidth))

        ports = []
        ports.append(('CLK', self.clk))
        ports.extend(m.connect_ports(self.definition, prefix=self.name + '_'))

        self.inst = self.m.Instance(self.definition, 'inst_' + self.name,
                                    params, ports)

        self.seq = Seq(m, self.name, clk, rst)

        self._write_disabled = [False for i in range(numports)]
Esempio n. 8
0
    def __init__(self,
                 m,
                 clk,
                 rst,
                 thread_name,
                 thread_id,
                 id,
                 sub_id=None,
                 datawidth=32,
                 addrwidth=4):

        self.m = m
        self.clk = clk
        self.rst = rst
        self.thread_name = thread_name
        self.thread_id = thread_id
        self.id = id
        self.sub_id = sub_id
        self.name = '_'.join([thread_name, 'channel', str(id)])
        self.datawidth = datawidth
        self.addrwidth = addrwidth
        self.wif = CoramChannelWriteInterface(self.m, self.name, datawidth)
        self.rif = CoramChannelReadInterface(self.m, self.name, datawidth)
        self.definition = get_coram_channel_definition()

        params = []
        params.append(('CORAM_THREAD_NAME', self.thread_name))
        params.append(('CORAM_THREAD_ID', self.thread_id))
        params.append(('CORAM_ID', self.id))
        if self.sub_id is not None:
            params.append(('CORAM_SUB_ID', self.sub_id))
        params.append(('CORAM_ADDR_LEN', self.addrwidth))
        params.append(('CORAM_DATA_WIDTH', self.datawidth))

        ports = []
        ports.append(('CLK', self.clk))
        ports.append(('RST', self.rst))
        ports.extend(m.connect_ports(self.definition, prefix=self.name + '_'))

        self.inst = self.m.Instance(self.definition, 'inst_' + self.name,
                                    params, ports)

        self.seq = Seq(m, self.name, clk, rst)

        self._max_size = (2**self.addrwidth - 1 if isinstance(
            self.addrwidth, int) else vtypes.Int(2)**self.addrwidth - 1)

        self._count = 0

        self._enq_disabled = False
        self._deq_disabled = False
Esempio n. 9
0
    def __init__(self,
                 m,
                 name,
                 clk,
                 rst,
                 width=32,
                 initname='init',
                 nohook=False,
                 as_module=False):
        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst
        self.width = width
        self.state_count = 0
        self.state = self.m.Reg(name, width)  # set initval later

        self.mark = collections.OrderedDict()  # key:index
        self._set_mark(0, self.name + '_' + initname)
        self.state.initval = self._get_mark(0)

        self.body = collections.defaultdict(list)
        self.jump = collections.defaultdict(list)

        self.delay_amount = 0
        self.delayed_state = collections.OrderedDict()  # key:delay
        self.delayed_body = collections.defaultdict(
            functools.partial(collections.defaultdict, list))  # key:delay
        self.delayed_cond = collections.OrderedDict()  # key:name
        self.tmp_count = 0

        self.dst_var = collections.OrderedDict()
        self.dst_visitor = SubstDstVisitor()
        self.reset_visitor = ResetVisitor()

        self.seq = Seq(self.m, self.name + '_par', clk, rst, nohook=True)

        self.done = False

        self.last_cond = []
        self.last_kwargs = {}
        self.last_if_statement = None
        self.elif_cond = None
        self.next_kwargs = {}

        self.as_module = as_module

        if not nohook:
            self.m.add_hook(self.implement)
Esempio n. 10
0
    def __init__(self, m, name, clk, rst, width=32):
        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst
        self.width = width

        self.tmp_count = 0
        self.max_stage_id = 0
        self.vars = []

        self.seq = Seq(self.m, self.name, clk, rst, nohook=True)
        self.data_visitor = DataVisitor(self)

        self.done = False
Esempio n. 11
0
    def __init__(self, m, name, clk, rst, width=32):

        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst
        self.width = width

        self.seq = Seq(self.m, self.name, self.clk, self.rst)

        self.lock_reg = self.m.Reg('_'.join(['', self.name, 'lock_reg']),
                                   initval=0)
        self.lock_id = self.m.Reg('_'.join(['', self.name, 'lock_id']),
                                  self.width,
                                  initval=0)

        self.id_map = {}
        self.id_map_count = 0
Esempio n. 12
0
def mkFifoDefinition(name, datawidth=32, addrwidth=4):
    m = module.Module(name)
    clk = m.Input('CLK')
    rst = m.Input('RST')

    wif = FifoWriteSlaveInterface(m, name, datawidth)
    rif = FifoReadSlaveInterface(m, name, datawidth)

    mem = m.Reg('mem', datawidth, 2**addrwidth)
    head = m.Reg('head', addrwidth, initval=0)
    tail = m.Reg('tail', addrwidth, initval=0)

    is_empty = m.Wire('is_empty')
    is_almost_empty = m.Wire('is_almost_empty')
    is_full = m.Wire('is_full')
    is_almost_full = m.Wire('is_almost_full')

    mask = (2**addrwidth) - 1

    is_empty.assign(head == tail)
    is_almost_empty.assign(head == ((tail + 1) & mask))
    is_full.assign(((head + 1) & mask) == tail)
    is_almost_full.assign(((head + 2) & mask) == tail)

    rdata = m.Reg('rdata_reg', datawidth, initval=0)

    wif.full.assign(is_full)
    wif.almost_full.assign(vtypes.Ors(is_almost_full, is_full))
    rif.empty.assign(is_empty)
    rif.almost_empty.assign(vtypes.Ors(is_almost_empty, is_empty))

    seq = Seq(m, '', clk, rst)

    seq.If(vtypes.Ands(wif.enq, vtypes.Not(is_full)))(mem[head](wif.wdata),
                                                      head.inc())

    seq.If(vtypes.Ands(rif.deq, vtypes.Not(is_empty)))(rdata(mem[tail]),
                                                       tail.inc())

    rif.rdata.assign(rdata)

    seq.make_always()

    return m
Esempio n. 13
0
    def __init__(self, m, name, clk, rst, datawidth=32, addrwidth=4):

        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst

        self.datawidth = datawidth
        self.addrwidth = addrwidth

        self.wif = FifoWriteInterface(self.m, name, datawidth)
        self.rif = FifoReadInterface(self.m, name, datawidth)

        self.definition = mkFifoDefinition(name, datawidth, addrwidth)

        self.inst = self.m.Instance(self.definition, 'inst_' + name,
                                    ports=m.connect_ports(self.definition))

        self.seq = Seq(m, name, clk, rst)

        # entry counter
        self._max_size = (2 ** self.addrwidth - 1 if isinstance(self.addrwidth, int) else
                          vtypes.Int(2) ** self.addrwidth - 1)

        self._count = self.m.Reg(
            'count_' + name, self.addrwidth + 1, initval=0)

        self.seq.If(
            vtypes.Ands(vtypes.Ands(self.wif.enq, vtypes.Not(self.wif.full)),
                        vtypes.Ands(self.rif.deq, vtypes.Not(self.rif.empty))))(
            self._count(self._count)
        ).Elif(vtypes.Ands(self.wif.enq, vtypes.Not(self.wif.full)))(
            self._count.inc()
        ).Elif(vtypes.Ands(self.rif.deq, vtypes.Not(self.rif.empty)))(
            self._count.dec()
        )

        self._enq_disabled = False
        self._deq_disabled = False

        self.mutex = None
Esempio n. 14
0
    def __init__(self, *nodes, **opts):
        # ID for manager reuse and merge
        global _stream_counter
        self.object_id = _stream_counter
        _stream_counter += 1

        self.nodes = set()
        self.named_numerics = OrderedDict()

        self.add(*nodes)

        self.max_stage = 0
        self.last_input = None
        self.last_output = None

        self.module = opts['module'] if 'module' in opts else None
        self.clock = opts['clock'] if 'clock' in opts else None
        self.reset = opts['reset'] if 'reset' in opts else None

        self.ivalid = opts['ivalid'] if 'ivalid' in opts else None
        self.iready = opts['iready'] if 'iready' in opts else None
        self.ovalid = opts['ovalid'] if 'ovalid' in opts else None
        self.oready = opts['oready'] if 'oready' in opts else None

        self.aswire = opts['aswire'] if 'aswire' in opts else True

        self.seq = None
        self.has_control = False

        self.implemented = False

        if (self.module is not None and self.clock is not None
                and self.reset is not None):

            no_hook = opts['no_hook'] if 'no_hook' in opts else False
            if not no_hook:
                self.module.add_hook(self.implement)

            seq_name = (opts['seq_name'] if 'seq_name' in opts else
                        '_stream_seq_%d' % self.object_id)
            self.seq = Seq(self.module, seq_name, self.clock, self.reset)
Esempio n. 15
0
    def __init__(self, m, name, clk, rst, numparties):

        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst
        self.numparties = numparties
        self.width = int(math.ceil(math.log(self.numparties, 2))) + 1

        self.seq = Seq(self.m, self.name, self.clk, self.rst)

        self.count = self.m.Reg('_'.join(['', self.name, 'barrier_count']),
                                self.width,
                                initval=0)
        self.done = self.m.Reg('_'.join(['', self.name, 'barrier_done']),
                               initval=0)
        self.mutex = Mutex(self.m, '_'.join(['', self.name, 'barrier_mutex']),
                           self.clk, self.rst)

        # reset condition
        self.seq(self.done(0))
        self.seq.If(self.count == self.numparties)(self.count(0), self.done(1))
Esempio n. 16
0
    def implement(self, m=None, clock=None, reset=None, aswire=None, seq_name=None):
        """ implemente actual registers and operations in Verilog """

        if self.implemented:
            if m is None:
                return self.module
            raise ValueError('already implemented.')

        self.implemented = True

        if m is None:
            m = self.module

        if self.module is None:
            self.module = m

        if clock is None:
            clock = self.clock

        if reset is None:
            reset = self.reset

        if self.seq is None:
            if seq_name is None:
                seq_name = '_stream_seq_%d' % self.object_id
            seq = Seq(m, seq_name, clock, reset)
        else:
            seq = self.seq

        if aswire is None:
            aswire = self.aswire

        self.add_control(aswire=aswire)
        self.has_control = True

        # for mult and div
        m._clock = clock
        m._reset = reset

        stream_nodes = self.nodes

        input_visitor = visitor.InputVisitor()
        input_vars = set()
        for node in sorted(stream_nodes, key=lambda x: x.object_id):
            input_vars.update(input_visitor.visit(node))

        output_visitor = visitor.OutputVisitor()
        output_vars = set()
        for node in sorted(stream_nodes, key=lambda x: x.object_id):
            output_vars.update(output_visitor.visit(node))

        # add input ports
        for input_var in sorted(input_vars, key=lambda x: x.object_id):
            input_var._implement_input(m, seq, aswire)

        # schedule
        sched = scheduler.ASAPScheduler()
        sched.schedule(output_vars)

        # balance output stage depth
        max_stage = 0
        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            max_stage = stypes._max(max_stage, output_var.end_stage)
        self.max_stage = max_stage

        output_vars = sched.balance_output(output_vars, max_stage)

        # get all vars
        all_visitor = visitor.AllVisitor()
        all_vars = set()
        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            all_vars.update(all_visitor.visit(output_var))

        # control (valid and ready)
        if not self.has_control:
            self.add_control(aswire)

        self.implement_control(seq)

        # allocate (implement signals)
        alloc = allocator.Allocator()
        alloc.allocate(m, seq, all_vars, self.valid_list, self.senable)

        # set default module information
        for var in sorted(all_vars, key=lambda x: x.object_id):
            var._set_module(m)
            var._set_strm(self)

            if var.seq is not None:
                seq.update(var.seq)

            var._set_seq(seq)

        # add output ports
        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            output_var._implement_output(m, seq, aswire)

        # save schedule result
        self.last_input = input_vars
        self.last_output = output_vars

        if self.dump:
            self.add_dump(m, seq, input_vars, output_vars, all_vars)

        return m
Esempio n. 17
0
    def implement(self,
                  m=None,
                  clock=None,
                  reset=None,
                  aswire=None,
                  seq_name=None):
        """ implemente actual registers and operations in Verilog """

        if m is None:
            m = self.module

        if clock is None:
            clock = self.clock

        if reset is None:
            reset = self.reset

        if self.seq is None or self.seq.done:
            if seq_name is None:
                seq_name = '_dataflow_seq_%d' % self.object_id
            seq = Seq(m, seq_name, clock, reset)
        else:
            seq = self.seq

        if aswire is None:
            aswire = self.aswire

        # for mult and div
        m._clock = clock
        m._reset = reset

        dataflow_nodes = self.nodes

        input_visitor = visitor.InputVisitor()
        input_vars = set()
        for node in sorted(dataflow_nodes, key=lambda x: x.object_id):
            input_vars.update(input_visitor.visit(node))

        output_visitor = visitor.OutputVisitor()
        output_vars = set()
        for node in sorted(dataflow_nodes, key=lambda x: x.object_id):
            output_vars.update(output_visitor.visit(node))

        # add input ports
        for input_var in sorted(input_vars, key=lambda x: x.object_id):
            input_var._implement_input(m, seq, aswire)

        # schedule
        sched = scheduler.ASAPScheduler()
        sched.schedule(output_vars)

        # balance output stage depth
        max_stage = 0
        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            max_stage = dtypes._max(max_stage, output_var.end_stage)
        self.max_stage = max_stage

        output_vars = sched.balance_output(output_vars, max_stage)

        # get all vars
        all_visitor = visitor.AllVisitor()
        all_vars = set()
        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            all_vars.update(all_visitor.visit(output_var))

        # allocate (implement signals)
        alloc = allocator.Allocator()
        alloc.allocate(m, seq, all_vars)

        # set default module information
        for var in sorted(all_vars, key=lambda x: x.object_id):
            var._set_module(m)
            var._set_df(self)

            if var.seq is not None:
                seq.update(var.seq)

            var._set_seq(seq)

        # add output ports
        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            output_var._implement_output(m, seq, aswire)

        # save schedule result
        self.last_input = input_vars
        self.last_output = output_vars

        return m