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
def to_module(self, name, clock='CLK', reset='RST', aswire=False, seq_name=None): """ generate a Module definion """ m = Module(name) clk = m.Input(clock) rst = m.Input(reset) m = self.implement(m, clk, rst, aswire=aswire, seq_name=seq_name) return m
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
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
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
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
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
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
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, )) #------------------------------------------------------------------------- def make_module(self, reset=(), body=(), case=True): if self.done: #raise ValueError('make_always() has been already called.') return self.done = True m = Module('sub_%s' % 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_case() if case else self.make_if()) dst_var = self.seq.dst_var dst_var.update(self.dst_var) dsts = 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)):
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)