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 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
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, ))
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
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()))
def visit_Sens(self, node): if node.type == 'posedge': sig = self.visit(node.sig) return vtypes.Posedge(sig) if node.type == 'negedge': sig = self.visit(node.sig) return vtypes.Negedge(sig) if node.type == 'all': return vtypes.SensitiveAll() if node.type == 'level': sig = self.visit(node.sig) return sig raise TypeError("Unsupported sensitivity type '%s'" % node.type)
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
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
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
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
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 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 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
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
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 = 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))
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)
def next_clock(clk): return (vtypes.Event(vtypes.Posedge(clk)), vtypes.Delay(1))
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
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 = 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,
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, ))