Beispiel #1
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
Beispiel #2
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
Beispiel #3
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
Beispiel #4
0
def mkROMDefinition(name, values, size, datawidth, sync=False):
    m = Module(name)

    clk = m.Input('CLK') if sync else None
    addr = m.Input('addr', size)
    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)
    ]

    alw(vtypes.Case(addr)(*patterns))

    return m
Beispiel #5
0
            if isinstance(src, (vtypes.Parameter, vtypes.Localparam)):
                if src.name in fsm_orig_labels:
                    fsm_labels[src.name] = m.Localparam(src.name, src.value)
                    continue

                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)

        state_width = src_rename_visitor.visit(self.state.width)
        state_initval = src_rename_visitor.visit(self.state.initval)
        state = m.OutputReg(self.state.name,
                            state_width,
                            initval=state_initval)
        out_state = self.m.TmpWire(state_width,
                                   prefix='_%s_out' % self.state.name)
        self.m.Always()(self.state(out_state, blk=True))
        ports[state.name] = out_state

        src_rename_dict[self.state.name] = state

        for delay, s in sorted(self.delayed_state.items(), key=lambda x: x[0]):
            s_width = src_rename_visitor.visit(s.width)
            s_initval = src_rename_visitor.visit(s.initval)
            d = m.OutputReg(s.name, s_width, initval=s_initval)
            out_d = self.m.TmpWire(s_width, prefix='_%s_out' % d.name)
            self.m.Always()(s(out_d, blk=True))
            ports[s.name] = out_d
Beispiel #6
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)