Exemplo n.º 1
0
def mkMultiplier(name,
                 lsigned=True,
                 rsigned=True,
                 depth=6,
                 with_update=True,
                 with_enable=True):

    mult = mkMultiplierCore(name, lsigned, rsigned, depth, with_update)

    m = module.Module(name)

    lwidth = m.Parameter('lwidth', 32)
    rwidth = m.Parameter('rwidth', 32)
    retwidth = lwidth + rwidth

    clk = m.Input('CLK')
    rst = m.Input('RST')

    if with_update:
        update = m.Input('update')

    if with_enable:
        enable = m.Input('enable')
    else:
        enable = 1

    if with_enable:
        valid = m.Output('valid')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    if with_enable:
        valid_reg = [m.Reg('valid_reg%d' % i) for i in range(depth)]

        m.Assign(valid(valid_reg[depth - 1]))

        body = (valid_reg[0](enable),
                [valid_reg[i](valid_reg[i - 1]) for i in range(1, depth)])

        if with_update:
            body = vtypes.If(update)(body)

        m.Always(vtypes.Posedge(clk))(
            vtypes.If(rst)([valid_reg[i](0) for i in range(depth)]).Else(body))

    params = [('lwidth', lwidth), ('rwidth', rwidth)]

    ports = [('CLK', clk)]
    if with_update:
        ports.append(('update', update))

    ports.extend([('a', a), ('b', b), ('c', c)])

    m.Instance(mult, 'mult', params=params, ports=ports)

    return m
Exemplo n.º 2
0
    def _add_statement(self,
                       statement,
                       keep=None,
                       delay=None,
                       cond=None,
                       lazy_cond=False,
                       eager_val=False,
                       no_delay_cond=False):

        cond = make_condition(cond)

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

        if delay is not None and delay > 0:
            if eager_val:
                statement = [
                    self._add_delayed_subst(s, delay) for s in statement
                ]

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

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

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

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

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

            return self

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

        self.body.extend(statement)
        self._add_dst_var(statement)

        return self
Exemplo n.º 3
0
def mkROMDefinition(name,
                    values,
                    size,
                    datawidth,
                    sync=False,
                    with_enable=False):
    if not sync and with_enable:
        raise ValueError('Async ROM cannot have enable signals')

    m = Module(name)

    clk = m.Input('CLK') if sync else None
    addr = m.Input('addr', size)
    if with_enable:
        enable = m.Input('enable')
    val = m.OutputReg('val', datawidth)

    if clk is not None:
        alw = m.Always(vtypes.Posedge(clk))
    else:
        alw = m.Always()

    patterns = [
        vtypes.When(i)(val(v, blk=not sync)) for i, v in enumerate(values)
    ]

    body = vtypes.Case(addr)(*patterns)

    if with_enable:
        body = vtypes.If(enable)(body)

    alw(body)

    return m
Exemplo n.º 4
0
def mkCoramMemoryDefinition(numports):
    name = 'CoramMemory%dP' % numports
    m = module.Module(name)

    coram_thread_name = m.Parameter('CORAM_THREAD_NAME', 'none')
    coram_thread_id = m.Parameter('CORAM_THREAD_ID', 0)
    coram_id = m.Parameter('CORAM_ID', 0)
    coram_sub_id = m.Parameter('CORAM_SUB_ID', 0)
    coram_addr_len = m.Parameter('CORAM_ADDR_LEN', 10)
    coram_data_width = m.Parameter('CORAM_DATA_WIDTH', 32)

    clk = m.Input('CLK')

    interfaces = []

    for i in range(numports):
        index = i if numports > 1 else None
        interface = CoramMemorySlaveInterface(m,
                                              datawidth=coram_data_width,
                                              addrwidth=coram_addr_len,
                                              index=index)
        delay_addr_name = 'D_ADDR%d' % i if numports > 1 else 'D_ADDR'
        interface.delay_addr = m.Reg(delay_addr_name, coram_addr_len)
        interfaces.append(interface)

    mem = m.Reg('mem', coram_data_width, length=vtypes.Int(2)**coram_addr_len)

    for interface in interfaces:
        m.Always(vtypes.Posedge(clk))(vtypes.If(interface.wenable)(
            mem[interface.addr](interface.wdata)),
                                      interface.delay_addr(interface.addr))
        m.Assign(interface.rdata(mem[interface.delay_addr]))

    return m
Exemplo n.º 5
0
 def _get_if_statement(self, index):
     body = []
     body.extend(self.body[index])
     for dst, cond, else_dst in self.jump[index]:
         self._add_mark(dst)
         if else_dst is not None:
             self._add_mark(else_dst)
         body.append(self._to_state_assign(dst, cond, else_dst))
     return vtypes.If(self._cond_if(index))(*body)
Exemplo n.º 6
0
 def _to_state_assign(self, dst, cond=None, else_dst=None):
     dst_mark = self._get_mark(dst)
     value = self.state(dst_mark)
     if cond is not None:
         value = vtypes.If(cond)(value)
         if else_dst is not None:
             else_dst_mark = self._get_mark(else_dst)
             value = value.Else(self.state(else_dst_mark))
     return value
Exemplo n.º 7
0
def mkMultiplier(index,
                 lwidth=32,
                 rwidth=32,
                 lsigned=True,
                 rsigned=True,
                 depth=6):
    if lwidth <= 0:
        raise ValueError("data width must be greater than 0.")
    if rwidth <= 0:
        raise ValueError("data width must be greater than 0.")
    if depth < 2:
        raise ValueError("depth must be greater than 1.")

    retwidth = lwidth + rwidth

    mult = mkMultiplierCore(index, lwidth, rwidth, lsigned, rsigned, depth)

    m = module.Module('multiplier_%d' % index)

    clk = m.Input('CLK')
    rst = m.Input('RST')

    update = m.Input('update')
    enable = m.Input('enable')
    valid = m.Output('valid')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    valid_reg = [m.Reg('valid_reg%d' % i) for i in range(depth)]

    m.Assign(valid(valid_reg[depth - 1]))

    m.Always(vtypes.Posedge(clk))(
        vtypes.If(rst)([valid_reg[i](0) for i in range(depth)]).Else(
            vtypes.If(update)(
                valid_reg[0](enable),
                [valid_reg[i](valid_reg[i - 1]) for i in range(1, depth)])))

    ports = [('CLK', clk), ('update', update), ('a', a), ('b', b), ('c', c)]
    m.Instance(mult, 'mult', ports=ports)

    return m
Exemplo n.º 8
0
def mkRAMDefinition(name,
                    datawidth=32,
                    addrwidth=10,
                    numports=2,
                    sync=True,
                    with_enable=False):
    m = Module(name)
    clk = m.Input('CLK')

    interfaces = []

    for i in range(numports):
        interface = RAMSlaveInterface(m,
                                      name + '_%d' % i,
                                      datawidth,
                                      addrwidth,
                                      with_enable=with_enable)
        if sync:
            interface.delay_addr = m.Reg(name + '_%d_daddr' % i, addrwidth)

        interfaces.append(interface)

    mem = m.Reg('mem', datawidth, length=2**addrwidth)

    for interface in interfaces:
        body = [
            vtypes.If(interface.wenable)(mem[interface.addr](interface.wdata))
        ]

        if sync:
            body.append(interface.delay_addr(interface.addr))

        if with_enable:
            body = vtypes.If(interface.enable)(*body)

        m.Always(vtypes.Posedge(clk))(body)

        if sync:
            m.Assign(interface.rdata(mem[interface.delay_addr]))
        else:
            m.Assign(interface.rdata(mem[interface.addr]))

    return m
Exemplo n.º 9
0
    def make_always(self, reset=(), body=()):
        if self.done:
            raise ValueError('make_always() has been already called.')
        self.done = True

        for var in self.vars:
            if var.output_vars is not None:
                var.make_output()

        self.m.Always(vtypes.Posedge(self.clk))(vtypes.If(self.rst)(
            reset, self.make_reset())(body, self.make_code()))
Exemplo n.º 10
0
    def visit_If(self, node):
        condition = self.visit(node.condition)
        true_statement = self.visit(node.true_statement)
        if node.false_statement is not None:
            false_statement = self.visit(node.false_statement)
        else:
            false_statement = None

        ret = vtypes.If(condition)
        ret.true_statement = true_statement
        ret.false_statement = false_statement
        return ret
Exemplo n.º 11
0
def mkMultiplierCore(name,
                     lsigned=True,
                     rsigned=True,
                     depth=6,
                     with_update=True):

    m = module.Module(name + '_core')

    lwidth = m.Parameter('lwidth', 32)
    rwidth = m.Parameter('rwidth', 32)
    retwidth = lwidth + rwidth

    clk = m.Input('CLK')

    if with_update:
        update = m.Input('update')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    _a = m.Reg('_a', lwidth, signed=lsigned)
    _b = m.Reg('_b', rwidth, signed=rsigned)
    _mul = m.Wire('_mul', retwidth, signed=True)
    _pipe_mul = [
        m.Reg('_pipe_mul%d' % i, retwidth, signed=True)
        for i in range(depth - 1)
    ]

    __a = _a
    __b = _b
    if not lsigned:
        __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _a))
    if not rsigned:
        __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _b))

    m.Assign(_mul(__a * __b))
    m.Assign(c(_pipe_mul[depth - 2]))

    body = (_a(a), _b(b), _pipe_mul[0](_mul),
            [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)])

    if with_update:
        body = vtypes.If(update)(body)

    m.Always(vtypes.Posedge(clk))(body)

    return m
Exemplo n.º 12
0
def mkMaddCore(index, awidth=32, bwidth=32, cwidth=32,
               asigned=True, bsigned=True, csigned=True, depth=6):

    retwidth = max(awidth + bwidth, cwidth)

    m = module.Module('madd_core_%d' % index)

    clk = m.Input('CLK')
    update = m.Input('update')

    a = m.Input('a', awidth)
    b = m.Input('b', bwidth)
    c = m.Input('c', cwidth)
    d = m.Output('d', retwidth)

    _a = m.Reg('_a', awidth, signed=asigned)
    _b = m.Reg('_b', bwidth, signed=bsigned)
    _c = m.Reg('_c', cwidth, signed=csigned)
    _mul = m.Wire('_mul', retwidth, signed=True)
    _madd = m.Wire('_madd', retwidth, signed=True)
    _pipe_madd = [m.Reg('_pipe_madd%d' % i, retwidth, signed=True)
                  for i in range(depth - 1)]

    __a = _a
    __b = _b
    __c = _c
    if not asigned:
        __a = vtypes.SystemTask(
            'signed', vtypes.Cat(vtypes.Int(0, width=1), _a))
    if not bsigned:
        __b = vtypes.SystemTask(
            'signed', vtypes.Cat(vtypes.Int(0, width=1), _b))
    if not csigned:
        __c = vtypes.SystemTask(
            'signed', vtypes.Cat(vtypes.Int(0, width=1), _c))

    m.Assign(_mul(__a * __b))
    m.Assign(_madd(_mul + __c))
    m.Assign(d(_pipe_madd[depth - 2]))

    m.Always(vtypes.Posedge(clk))(
        vtypes.If(update)(
            _a(a),
            _b(b),
            _c(c),
            _pipe_madd[0](_madd),
            [_pipe_madd[i](_pipe_madd[i - 1]) for i in range(1, depth - 1)]
        ))

    return m
Exemplo n.º 13
0
def mkMultiplierCore(index,
                     lwidth=32,
                     rwidth=32,
                     lsigned=True,
                     rsigned=True,
                     depth=6):
    if lwidth <= 0:
        raise ValueError("data width must be greater than 0.")
    if rwidth <= 0:
        raise ValueError("data width must be greater than 0.")
    if depth < 2:
        raise ValueError("depth must be greater than 1.")

    retwidth = lwidth + rwidth

    m = module.Module('multiplier_core_%d' % index)

    clk = m.Input('CLK')
    update = m.Input('update')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    _a = m.Reg('_a', lwidth, signed=lsigned)
    _b = m.Reg('_b', rwidth, signed=rsigned)
    _mul = m.Wire('_mul', retwidth, signed=True)
    _pipe_mul = [
        m.Reg('_pipe_mul%d' % i, retwidth, signed=True)
        for i in range(depth - 1)
    ]

    __a = _a
    __b = _b
    if not lsigned:
        __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _a))
    if not rsigned:
        __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _b))

    m.Assign(_mul(__a * __b))
    m.Assign(c(_pipe_mul[depth - 2]))

    m.Always(vtypes.Posedge(clk))(vtypes.If(update)(
        _a(a), _b(b), _pipe_mul[0](_mul),
        [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)]))

    return m
Exemplo n.º 14
0
 def visit_IfStatement(self, node):
     if isinstance(self.m, (module.GenerateFor, module.GenerateIf)):
         return self._visit_GenerateIf(node)
     condition = self.visit(node.cond)
     true_statement = self.visit(node.true_statement)
     false_statement = (self.visit(node.false_statement)
                        if node.false_statement is not None else None)
     true_statement = to_tuple(true_statement)
     false_statement = (to_tuple(false_statement)
                        if false_statement is not None else None)
     _if = vtypes.If(condition)
     _if = _if(*true_statement)
     if false_statement is not None:
         _if = _if(*false_statement)
     return _if
Exemplo n.º 15
0
    def make_always(self, reset=(), body=()):
        if self.done:
            #raise ValueError('make_always() has been already called.')
            return

        self.done = True

        part_reset = list(reset) + list(self.make_reset())
        part_body = list(body) + list(self.make_code())

        if not part_reset and not part_body:
            pass
        elif not part_reset or self.rst is None:
            self.m.Always(vtypes.Posedge(self.clk))(part_body, )
        else:
            self.m.Always(vtypes.Posedge(self.clk))(vtypes.If(self.rst)(
                part_reset, )(part_body, ))
Exemplo n.º 16
0
def mkMultiplierCore(index,
                     lwidth=32,
                     rwidth=32,
                     lsigned=True,
                     rsigned=True,
                     depth=6):
    retwidth = lwidth + rwidth

    m = module.Module('multiplier_core_%d' % index)

    clk = m.Input('CLK')
    update = m.Input('update')

    a = m.Input('a', lwidth)
    b = m.Input('b', rwidth)
    c = m.Output('c', retwidth)

    _a = m.Reg('_a', lwidth, signed=lsigned)
    _b = m.Reg('_b', rwidth, signed=rsigned)
    tmpval = [
        m.Reg('_tmpval%d' % i, retwidth, signed=True) for i in range(depth - 1)
    ]
    rslt = m.Wire('rslt', retwidth, signed=True)

    __a = _a
    __b = _b
    if not lsigned:
        __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _a))
    if not rsigned:
        __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1),
                                                     _b))

    m.Assign(rslt(__a * __b))
    m.Assign(c(tmpval[depth - 2]))

    m.Always(vtypes.Posedge(clk))(vtypes.If(update)(
        _a(a), _b(b), tmpval[0](rslt),
        [tmpval[i](tmpval[i - 1]) for i in range(1, depth - 1)]))

    return m
Exemplo n.º 17
0
def mkRAMCore(name, datawidth=32, addrwidth=10, numports=2):
    m = Module(name)
    clk = m.Input('CLK')

    interfaces = []

    for i in range(numports):
        interface = RAMInterface(
            m, name + '_%d' % i, datawidth, addrwidth)
        interface.delay_addr = m.Reg(name + '_%d_daddr' % i, addrwidth)
        interfaces.append(interface)

    mem = m.Reg('mem', datawidth, length=2**addrwidth)

    for interface in interfaces:
        m.Always(vtypes.Posedge(clk))(
            vtypes.If(interface.wenable)(
                mem[interface.addr](interface.wdata)
            ),
            interface.delay_addr(interface.addr)
        )
        m.Assign(interface.rdata(mem[interface.delay_addr]))

    return m
Exemplo n.º 18
0
        body = [src_rename_visitor.visit(statement)
                for statement in body]

        reset = self.make_reset(reset)

        if not reset and not body:
            pass
        elif not reset or rst is None:
            m.Always(vtypes.Posedge(clk))(
                body,
            )
        else:
            m.Always(vtypes.Posedge(clk))(
                vtypes.If(rst)(
                    reset,
                )(
                    body,
                ))

        arg_params = [(name, param) for name, param in params.items()]

        arg_ports = [('CLK', self.clk)]
        if self.rst is not None:
            arg_ports.append(('RST', self.rst))

        arg_ports.extend([(name, port) for name, port in ports.items()])

        sub = Submodule(self.m, m, 'inst_' + m.name, '_%s_' % self.name,
                        arg_params=arg_params, arg_ports=arg_ports)

    # -------------------------------------------------------------------------
Exemplo n.º 19
0
    def make_module(self, reset=(), body=()):
        if self.done:
            #raise ValueError('make_always() has been already called.')
            return

        self.done = True

        m = Module(self.name)

        clk = m.Input('CLK')

        if self.rst is not None:
            rst = m.Input('RST')
        else:
            rst = None

        body = list(body) + list(self.make_code())
        dsts = self.dst_var.values()
        src_visitor = SubstSrcVisitor()

        # collect sources in destination variable definitions
        for dst in dsts:
            if isinstance(dst, (vtypes.Pointer, vtypes.Slice, vtypes.Cat)):
                raise ValueError(
                    'Partial assignment is not supported by as_module mode.')

            if isinstance(dst, vtypes._Variable):
                if dst.width is not None:
                    src_visitor.visit(dst.width)
                if dst.length is not None:
                    src_visitor.visit(dst.length)

        # collect sources in statements
        for statement in body:
            src_visitor.visit(statement)

        srcs = src_visitor.srcs.values()

        # collect sources in source variable definitions
        for src in srcs:
            if isinstance(src, vtypes._Variable):
                if src.width is not None:
                    src_visitor.visit(src.width)
                if src.length is not None:
                    src_visitor.visit(src.length)

        srcs = src_visitor.srcs.values()

        params = collections.OrderedDict()
        ports = collections.OrderedDict()
        src_rename_dict = collections.OrderedDict()

        # create parameter/localparam definitions
        for src in srcs:
            if isinstance(src, (vtypes.Parameter, vtypes.Localparam)):
                arg_name = src.name
                v = m.Parameter(arg_name, src.value, src.width, src.signed)
                src_rename_dict[src.name] = v
                params[arg_name] = src

        src_rename_visitor = SrcRenameVisitor(src_rename_dict)

        for src in srcs:
            if isinstance(src, (vtypes.Parameter, vtypes.Localparam)):
                continue

            arg_name = 'i_%s' % src.name

            if src.length is not None:
                width = src.bit_length()
                length = src.length
                pack_width = vtypes.Mul(width, length)
                out_line = self.m.TmpWire(
                    pack_width, prefix='_%s_%s' % (self.name, src.name))
                i = self.m.TmpGenvar(prefix='i')
                v = out_line[i * width:(i + 1) * width]
                g = self.m.GenerateFor(i(0), i < length, i(i + 1))
                p = g.Assign(v(src[i]))

                rep_width = (src_rename_visitor.visit(src.width)
                             if src.width is not None else None)
                rep_length = src_rename_visitor.visit(src.length)
                pack_width = (rep_length if rep_width is None else
                              vtypes.Mul(rep_length, rep_width))
                in_line = m.Input(arg_name + '_line', pack_width,
                                  signed=src.get_signed())
                in_array = m.Wire(arg_name, rep_width, rep_length,
                                  signed=src.get_signed())
                i = m.TmpGenvar(prefix='i')
                v = in_line[i * rep_width:(i + 1) * rep_width]
                g = m.GenerateFor(i(0), i < rep_length, i(i + 1))
                p = g.Assign(in_array[i](v))

                src_rename_dict[src.name] = in_array
                ports[in_line.name] = out_line

            else:
                rep_width = (src_rename_visitor.visit(src.width)
                             if src.width is not None else None)
                v = m.Input(arg_name, rep_width, signed=src.get_signed())

                src_rename_dict[src.name] = v
                ports[arg_name] = src

        for dst in dsts:
            arg_name = dst.name

            rep_width = (src_rename_visitor.visit(dst.width)
                         if dst.width is not None else None)
            out = m.OutputReg(arg_name, rep_width, signed=dst.get_signed())
            out_wire = self.m.TmpWire(rep_width, signed=dst.get_signed(),
                                      prefix='_%s_%s' % (self.name, arg_name))
            self.m.Always()(dst(out_wire, blk=True))
            ports[arg_name] = out_wire

        body = [src_rename_visitor.visit(statement)
                for statement in body]

        reset = list(reset) + list(self.make_reset())

        if not reset and not body:
            pass
        elif not reset or rst is None:
            m.Always(vtypes.Posedge(clk))(
                body,
            )
        else:
            m.Always(vtypes.Posedge(clk))(
                vtypes.If(rst)(
                    reset,
                )(
                    body,
                ))

        arg_params = [(name, param) for name, param in params.items()]

        arg_ports = [('CLK', self.clk)]
        if self.rst is not None:
            arg_ports.append(('RST', self.rst))

        arg_ports.extend([(name, port) for name, port in ports.items()])

        sub = Submodule(self.m, m, 'inst_' + m.name, '_%s_' % self.name,
                        arg_params=arg_params, arg_ports=arg_ports)
Exemplo n.º 20
0
def mkRAMDefinition(name,
                    datawidth=32,
                    addrwidth=10,
                    numports=2,
                    initvals=None,
                    sync=True,
                    with_enable=False,
                    nocheck_initvals=False,
                    ram_style=None):
    m = Module(name)
    clk = m.Input('CLK')

    interfaces = []

    for i in range(numports):
        interface = RAMSlaveInterface(m,
                                      name + '_%d' % i,
                                      datawidth,
                                      addrwidth,
                                      with_enable=with_enable)
        if sync:
            interface.delay_addr = m.Reg(name + '_%d_daddr' % i, addrwidth)

        interfaces.append(interface)

    if ram_style is not None:
        m.EmbeddedCode(ram_style)

    mem = m.Reg('mem', datawidth, 2**addrwidth)

    if initvals is not None:
        if not isinstance(initvals, (tuple, list)):
            raise TypeError("initvals must be tuple or list, not '%s" %
                            str(type(initvals)))

        base = 16

        if not nocheck_initvals:
            new_initvals = []
            for initval in initvals:
                if isinstance(initval, int):
                    new_initvals.append(vtypes.Int(initval, datawidth,
                                                   base=16))
                elif isinstance(initval, vtypes.Int) and isinstance(
                        initval.value, int):
                    v = copy.deepcopy(initval)
                    v.width = datawidth
                    v.base = base
                    new_initvals.append(v)
                elif isinstance(initval, vtypes.Int) and isinstance(
                        initval.value, str):
                    v = copy.deepcopy(initval)
                    v.width = datawidth
                    if v.base != 2 and v.base != 16:
                        raise ValueError('base must be 2 or 16')
                    base = v.base
                    new_initvals.append(v)
                else:
                    raise TypeError("values of initvals must be int, not '%s" %
                                    str(type(initval)))

            initvals = new_initvals

        if 2**addrwidth > len(initvals):
            initvals.extend([
                vtypes.Int(0, datawidth, base=base)
                for _ in range(2**addrwidth - len(initvals))
            ])

        m.Initial(*[mem[i](initval) for i, initval in enumerate(initvals)])

    for interface in interfaces:
        body = [
            vtypes.If(interface.wenable)(mem[interface.addr](interface.wdata))
        ]

        if sync:
            body.append(interface.delay_addr(interface.addr))

        if with_enable:
            body = vtypes.If(interface.enable)(*body)

        m.Always(vtypes.Posedge(clk))(body)

        if sync:
            m.Assign(interface.rdata(mem[interface.delay_addr]))
        else:
            m.Assign(interface.rdata(mem[interface.addr]))

    return m
Exemplo n.º 21
0
            out_wire = self.m.TmpWire(rep_width,
                                      signed=dst.get_signed(),
                                      prefix='_%s_%s' % (self.name, arg_name))
            self.m.Always()(dst(out_wire, blk=True))
            ports[arg_name] = out_wire

        body = [src_rename_visitor.visit(statement) for statement in body]

        reset = self.make_reset(reset)

        if not reset and not body:
            pass
        elif not reset or rst is None:
            m.Always(vtypes.Posedge(clk))(body, )
        else:
            m.Always(vtypes.Posedge(clk))(vtypes.If(rst)(reset, )(body, ))

        arg_params = [(name, param) for name, param in params.items()]

        arg_ports = [('CLK', self.clk)]
        if self.rst is not None:
            arg_ports.append(('RST', self.rst))

        arg_ports.extend([(name, port) for name, port in ports.items()])

        sub = Submodule(self.m,
                        m,
                        'inst_' + m.name,
                        '_%s_' % self.name,
                        arg_params=arg_params,
                        arg_ports=arg_ports)
Exemplo n.º 22
0
class FSM(vtypes.VeriloggenNode):
    """ Finite State Machine Generator """
    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)

    #-------------------------------------------------------------------------
    def goto(self, dst, cond=None, else_dst=None):
        if cond is None and 'cond' in self.next_kwargs:
            cond = self.next_kwargs['cond']
        self._clear_next_kwargs()
        self._clear_last_if_statement()
        self._clear_last_cond()

        src = self.current
        return self._go(src, dst, cond, else_dst)

    def goto_init(self, cond=None):
        if cond is None and 'cond' in self.next_kwargs:
            cond = self.next_kwargs['cond']
        self._clear_next_kwargs()
        self._clear_last_if_statement()
        self._clear_last_cond()

        src = self.current
        dst = 0
        return self._go(src, dst, cond)

    def goto_next(self, cond=None):
        if cond is None and 'cond' in self.next_kwargs:
            cond = self.next_kwargs['cond']
        self._clear_next_kwargs()
        self._clear_last_if_statement()
        self._clear_last_cond()

        src = self.current
        dst = self.current + 1
        ret = self._go(src, dst, cond=cond)
        self.inc()
        return ret

    def goto_from(self, src, dst, cond=None, else_dst=None):
        if cond is None and 'cond' in self.next_kwargs:
            cond = self.next_kwargs['cond']
        self._clear_next_kwargs()
        self._clear_last_if_statement()
        self._clear_last_cond()

        return self._go(src, dst, cond, else_dst)

    def inc(self):
        self._set_index(None)

    #-------------------------------------------------------------------------
    def add(self, *statement, **kwargs):
        """ add new assignments """
        kwargs.update(self.next_kwargs)
        self.last_kwargs = kwargs
        self._clear_next_kwargs()

        # if there is no attributes, Elif object is reused.
        has_args = not (len(kwargs) == 0 or  # has no args
                        (len(kwargs) == 1 and 'cond' in kwargs)
                        )  # has only 'cond'

        if self.elif_cond is not None and not has_args:
            next_call = self.last_if_statement.Elif(self.elif_cond)
            next_call(*statement)
            self.last_if_statement = next_call
            self._add_dst_var(statement)
            self._clear_elif_cond()
            return self

        self._clear_last_if_statement()
        return self._add_statement(statement, **kwargs)

    #-------------------------------------------------------------------------
    def Prev(self, var, delay, initval=0, cond=None, prefix=None):
        return self.seq.Prev(var, delay, initval, cond, prefix)

    #-------------------------------------------------------------------------
    def If(self, *cond):
        self._clear_elif_cond()

        cond = make_condition(*cond)

        if cond is None:
            return self

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

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

        return self

    def Else(self, *statement, **kwargs):
        self._clear_elif_cond()

        if len(self.last_cond) == 0:
            raise ValueError("No previous condition for Else.")

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

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

        # if there is additional attribute, Else statement is separated.
        has_args = not (len(self.next_kwargs) == 0 or  # has no args
                        (len(self.next_kwargs) == 1 and 'cond' in kwargs)
                        )  # has only 'cond'

        if has_args:
            prev_cond = self.last_cond
            ret = self.Then()(*statement)
            self.last_cond = prev_cond
            return ret

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

        self.last_if_statement.Else(*statement)
        self._add_dst_var(statement)

        return self

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

        cond = make_condition(*cond)

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

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

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

        self.elif_cond = cond

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

        return self

    def Delay(self, delay):
        self.next_kwargs['delay'] = delay
        return self

    def Keep(self, keep):
        self.next_kwargs['keep'] = keep
        return self

    def Then(self):
        cond = self._make_cond(self.last_cond)
        self._clear_last_cond()
        self.If(cond)
        return self

    def LazyCond(self, value=True):
        self.next_kwargs['lazy_cond'] = value
        return self

    def EagerVal(self, value=True):
        self.next_kwargs['eager_val'] = value
        return self

    def Clear(self):
        self._clear_next_kwargs()
        self._clear_last_if_statement()
        self._clear_last_cond()
        self._clear_elif_cond()
        return self

    #-------------------------------------------------------------------------
    @property
    def current(self):
        return self.state_count

    @property
    def next(self):
        return self.current + 1

    @property
    def current_delay(self):
        if 'delay' in self.next_kwargs:
            return self.next_kwargs['delay']
        return 0

    @property
    def last_delay(self):
        if 'delay' in self.last_kwargs:
            return self.last_kwargs['delay']
        return 0

    @property
    def current_condition(self):
        cond = self.next_kwargs['cond'] if 'cond' in self.next_kwargs else None
        if cond is not None:
            cond = vtypes.AndList(self.state == self.state_count, cond)
        else:
            cond = self.state == self.state_count
        return cond

    @property
    def last_condition(self):
        cond = self._make_cond(self.last_cond)
        if cond is not None:
            cond = vtypes.AndList(self.state == self.state_count, cond)
        else:
            cond = self.state == self.state_count
        return cond

    @property
    def then(self):
        return self.last_condition

    @property
    def here(self):
        return self.state == self.current

    #-------------------------------------------------------------------------
    def implement(self):
        if self.as_module:
            self.make_module()
            return

        self.make_always()

    #-------------------------------------------------------------------------
    def make_always(self, reset=(), body=(), case=True):
        if self.done:
            #raise ValueError('make_always() has been already called.')
            return

        self.done = True

        part_reset = self.make_reset(reset)
        part_body = list(body) + list(
            self.make_case() if case else self.make_if())
        self.m.Always(vtypes.Posedge(self.clk))(vtypes.If(self.rst)(
            part_reset, )(part_body, ))
Exemplo n.º 23
0
 def _get_delayed_if_statement(self, index, delay):
     return vtypes.If(self._delayed_cond_if(
         index, delay))(*self.delayed_body[delay][index])