def construct(s, nports, nbits): s.in_ = [InPort(mk_bits(nbits)) for _ in range(nports)] s.out = [OutPort(mk_bits(nbits)) for _ in range(nports)] s.set_metadata(VerilogPlaceholderPass.params, { 'num_ports': nports, 'bitwidth': nbits, })
def construct(s, data_width, num_entries, count_width): s.count = OutPort(mk_bits(count_width)) s.deq_en = InPort(Bits1) s.deq_rdy = OutPort(Bits1) s.deq_msg = OutPort(mk_bits(data_width)) s.enq_en = InPort(Bits1) s.enq_rdy = OutPort(Bits1) s.enq_msg = InPort(mk_bits(data_width))
def construct( s, data_width, num_entries, count_width ): s.count = OutPort( mk_bits( count_width ) ) s.deq_en = InPort( Bits1 ) s.deq_rdy = OutPort( Bits1 ) s.deq_msg = OutPort( mk_bits( data_width ) ) s.enq_en = InPort( Bits1 ) s.enq_rdy = OutPort( Bits1 ) s.enq_msg = InPort( mk_bits( data_width ) ) s.set_metadata( VerilogTranslationImportPass.enable, True )
def construct(s, data_width, num_entries, count_width): s.count = OutPort(mk_bits(count_width)) s.deq_en = InPort(Bits1) s.deq_rdy = OutPort(Bits1) s.deq_msg = OutPort(mk_bits(data_width)) s.enq_en = InPort(Bits1) s.enq_rdy = OutPort(Bits1) s.enq_msg = InPort(mk_bits(data_width)) s.sverilog_import = ImportConfigs(vl_src=get_dir(__file__) + 'VQueue.sv')
def construct(s, data_width, num_entries, count_width): s.count = OutPort(mk_bits(count_width)) s.deq_en = InPort(Bits1) s.deq_rdy = OutPort(Bits1) s.deq_msg = OutPort(mk_bits(data_width)) s.enq_en = InPort(Bits1) s.enq_rdy = OutPort(Bits1) s.enq_msg = InPort(mk_bits(data_width)) s.config_placeholder = VerilogPlaceholderConfigs( src_file=dirname(__file__) + '/VQueue.v', ) s.verilog_translate_import = True
def construct(s, nports, nbits): s.in_ = [InPort(mk_bits(nbits)) for _ in range(nports)] s.out = [OutPort(mk_bits(nbits)) for _ in range(nports)] s.config_placeholder = VerilogPlaceholderConfigs( src_file=dirname(__file__) + '/VPassThrough.v', params={ 'num_ports': nports, 'bitwidth': nbits, }, has_clk=False, has_reset=False, ) s.verilog_translate_import = True
def _get_arg_str(name, obj): # Support common python types and Bits/BitStruct if isinstance(obj, (int, bool, str)): return str(obj) elif obj == None: return 'None' elif isinstance(obj, Bits): nbits = obj.nbits value = int(obj) Bits_name = f"Bits{nbits}" Bits_arg_str = f"{Bits_name}( {value} )" if Bits_name not in symbols and nbits >= 256: Bits_class = mk_bits(nbits) symbols.update({Bits_name: Bits_class}) return Bits_arg_str elif is_bitstruct_inst(obj): raise TypeError( "Do you really want to pass in an instance of " "a BitStruct? Contact PyMTL developers!") # This is hacky: we don't know how to construct an object that # is the same as `obj`, but we do have the object itself. If we # add `obj` to the namespace of `construct` everything works fine # but the user cannot tell what object is passed to the constructor # just from the code. # Do not use a double underscore prefix because that will be # interpreted differently by the Python interpreter # bs_name = ("_" if name[0] != "_" else "") + name + "_obj" # if bs_name not in symbols: # symbols.update( { bs_name : obj } ) # return bs_name elif isinstance(obj, type) and issubclass(obj, Bits): nbits = obj.nbits Bits_name = f"Bits{nbits}" if Bits_name not in symbols and nbits >= 256: Bits_class = mk_bits(nbits) symbols.update({Bits_name: Bits_class}) return Bits_name elif is_bitstruct_class(obj): BitStruct_name = obj.__name__ if BitStruct_name not in symbols: symbols.update({BitStruct_name: obj}) return BitStruct_name # FIXME formalize this elif isinstance(obj, type) and hasattr( obj, 'req') and hasattr(obj, 'resp'): symbols.update({obj.__name__: obj}) return obj.__name__ raise TypeError( f"Interface constructor argument {obj} is not an int/Bits/BitStruct/TypeTuple!" )
def __getitem__(s, idx): # Turn index into a slice if isinstance(idx, int): sl = slice(idx, idx + 1) elif isinstance(idx, slice): sl = idx else: assert False, "What the hell?" sl_tuple = (sl.start, sl.stop) if sl_tuple not in s.__dict__: x = s.__class__(mk_bits(sl.stop - sl.start)) x._dsl.parent_obj = s x._dsl.top_level_signal = s x._dsl.elaborate_top = s._dsl.elaborate_top sl_str = "[{}:{}]".format(sl.start, sl.stop) x._dsl.my_name = s._dsl.my_name + sl_str x._dsl.full_name = s._dsl.full_name + sl_str x._dsl.slice = sl s.__dict__[sl_tuple] = s._dsl.slices[sl_tuple] = x return s.__dict__[sl_tuple]
def construct( s, Type, n_ports ): s.in_ = [ InPort( Type ) for _ in range(n_ports) ] s.sel = InPort( mk_bits( clog2(n_ports) ) ) s.out = OutPort( Type ) @s.update def add_upblk(): s.out = s.in_[ s.sel ]
def test_interface_parameter_long_vector(do_test): class Ifc(Interface): def construct(s, Type, nbits_val, nbits_rdy): s.msg = InPort(Type) s.val = InPort(mk_bits(nbits_val)) # Added support for BitsN values in case someone wants to do # tricky things like this. s.rdy = OutPort(mk_bits(nbits_rdy.nbits)) class A(Component): def construct(s): Bits322 = mk_bits(322) s.ifc = Ifc(Bits322, 1, Bits322(1)) a = A() a._ref_symbols = {'Ifc': Ifc, 'Bits322': mk_bits(322)} a._ref_decls = ["s.ifc = Ifc( Bits322, 1, Bits322( 1 ) )"] a._ref_conns = [ "connect( s.clk, s.mangled__clk[0:1] )", "connect( s.reset, s.mangled__reset[0:1] )", "connect( s.ifc.msg, s.mangled__ifc___05Fmsg[0:322] )", "connect( s.ifc.rdy, s.mangled__ifc___05Frdy[0:322] )", "connect( s.ifc.val, s.mangled__ifc___05Fval[0:1] )", ] a._ref_conns_yosys = [ "connect( s.clk, s.mangled__clk )", "connect( s.reset, s.mangled__reset )", "connect( s.ifc.msg, s.mangled__ifc___05Fmsg )", "connect( s.ifc.rdy, s.mangled__ifc___05Frdy )", "connect( s.ifc.val, s.mangled__ifc___05Fval )", ] do_test(a)
def __getitem__(s, idx): assert issubclass(s._dsl.Type, Bits) # Turn index into a slice if isinstance(idx, int): sl = slice(idx, idx + 1) elif isinstance(idx, slice): sl = idx else: assert False, "What the hell?" sl_tuple = (sl.start, sl.stop) if sl_tuple not in s.__dict__: assert 0 <= sl.start < sl.stop <= s._dsl.Type.nbits x = s.__class__(mk_bits(sl.stop - sl.start)) sd = s._dsl xd = x._dsl xd.parent_obj = s xd.top_level_signal = sd.top_level_signal xd.elaborate_top = sd.elaborate_top sl_str = f"[{sl.start}:{sl.stop}]" xd.my_name = f"{sd.my_name}{sl_str}" xd.full_name = f"{sd.full_name}{sl_str}" xd.slice = sl s.__dict__[sl_tuple] = sd.slices[sl_tuple] = x return s.__dict__[sl_tuple]
def construct(s, Type, ninputs): s.in_ = [InPort(Type) for _ in range(ninputs)] s.sel = InPort(mk_bits(clog2(ninputs))) s.out = OutPort(Type) @update def up_mux(): s.out @= s.in_[s.sel]
def construct(s, nbits, nelems, nbits_cnt): s.count = OutPort(mk_bits(nbits_cnt)) s.deq_en = InPort(Bits1) s.deq_rdy = OutPort(Bits1) s.deq_msg = OutPort(mk_bits(nbits)) s.enq_en = InPort(Bits1) s.enq_rdy = OutPort(Bits1) s.enq_msg = InPort(mk_bits(nbits)) s.set_metadata(VerilogPlaceholderPass.src_file, dirname(__file__) + '/VQueue.v') s.set_metadata(VerilogPlaceholderPass.top_module, 'VQueue') s.set_metadata( VerilogPlaceholderPass.params, { 'data_width': nbits, 'num_entries': nelems, 'count_width': nbits_cnt, })
def construct(s, nbits): nbitsX2 = nbits * 2 s.x = Wire(mk_bits(nbits * 2)) @s.update def upA(): print(s.x[nbits]) print(s.x[0:nbits]) print(s.x[nbits:nbitsX2])
def construct(s, nbits, nelems, nbits_cnt): s.count = OutPort(mk_bits(nbits_cnt)) s.deq_en = InPort(Bits1) s.deq_rdy = OutPort(Bits1) s.deq_msg = OutPort(mk_bits(nbits)) s.enq_en = InPort(Bits1) s.enq_rdy = OutPort(Bits1) s.enq_msg = InPort(mk_bits(nbits)) s.config_placeholder = VerilogPlaceholderConfigs( src_file=dirname(__file__) + '/VQueue.v', top_module='VQueue', params={ 'data_width': nbits, 'num_entries': nelems, 'count_width': nbits_cnt, }, ) s.verilog_translate_import = True
def test_port_single(do_test): class A(Component): def construct(s): s.in_ = InPort(mk_bits(322)) a = A() a._ref_symbols = {'Bits322': mk_bits(322)} a._ref_decls = [ "s.in_ = InPort( Bits322 )", ] do_test(a)
def run_test(cls, args, test_vectors): m = cls(*args) BitsN = mk_bits(args[0]) def tv_in(model, test_vector): model.reqs = BitsN(test_vector[0]) def tv_out(model, test_vector): assert model.grants == BitsN(test_vector[1]) m._test_vectors = test_vectors m._tv_in, m._tv_out = tv_in, tv_out do_test(m)
def _get_arg_str(name, obj): if isinstance(obj, int): return str(obj) elif isinstance(obj, Bits): nbits = obj.nbits value = obj.value Bits_name = "Bits{nbits}".format(**locals()) Bits_arg_str = "{Bits_name}( {value} )".format( **locals()) if Bits_name not in symbols and nbits >= 256: Bits_class = mk_bits(nbits) symbols.update({Bits_name: Bits_class}) return Bits_arg_str elif isinstance(obj, BitStruct): # This is hacky: we don't know how to construct an object that # is the same as `obj`, but we do have the object itself. If we # add `obj` to the namespace of `construct` everything works fine # but the user cannot tell what object is passed to the constructor # just from the code. bs_name = "_" + name + "_obj" if bs_name not in symbols: symbols.update({bs_name: obj}) return bs_name elif isinstance(obj, type) and issubclass(obj, Bits): nbits = obj.nbits Bits_name = "Bits{nbits}".format(**locals()) if Bits_name not in symbols and nbits >= 256: Bits_class = mk_bits(nbits) symbols.update({Bits_name: Bits_class}) return Bits_name elif isinstance(obj, type) and issubclass(obj, BitStruct): BitStruct_name = obj.__name__ if BitStruct_name not in symbols: symbols.update({BitStruct_name: obj}) return BitStruct_name else: assert False, \ "Interface constructor argument {} is not an int/Bits/BitStruct!". \ format( obj )
def visit_FreeVar( s, node ): if node.name not in s.freevars: s.freevars[ node.name ] = node.obj try: t = rt.get_rtlir( node.obj ) except RTLIRConversionError as e: raise PyMTLTypeError(s.blk, node.ast, f'{node.name} cannot be converted into a valid RTLIR object!' ) if isinstance( t, rt.Const ) and isinstance( t.get_dtype(), rdt.Vector ): node._value = mk_bits( t.get_dtype().get_length() )( node.obj ) node.Type = t
def __init__( s, Type=Bits1 ): if isinstance( Type, int ): Type = mk_bits(Type) else: assert isinstance( Type, type ) and ( issubclass( Type, Bits ) or is_bitstruct_class(Type) ), \ f"RTL signal can only be of Bits type or bitstruct type, not {Type}.\n" \ f"Note: an integer is also accepted: Wire(32) is equivalent to Wire(Bits32))" s._dsl.Type = Type s._dsl.type_instance = None s._dsl.slice = None # None -- not a slice of some wire by default s._dsl.slices = {} s._dsl.top_level_signal = s s._dsl.needs_double_buffer = False
def gen_dtype_str(symbols, dtype): if isinstance(dtype, rdt.Vector): nbits = dtype.get_length() Bits_name = f"Bits{nbits}" if Bits_name not in symbols and nbits >= 256: Bits_class = mk_bits(nbits) symbols.update({Bits_name: Bits_class}) return f'Bits{dtype.get_length()}' elif isinstance(dtype, rdt.Struct): # It is possible to reuse the existing struct class because its __init__ # can be called without arguments. name, cls = dtype.get_name(), dtype.get_class() if name not in symbols: symbols.update({name: cls}) return name else: assert False, f"unrecognized data type {dtype}!"
def __getitem__(s, idx): if not issubclass(s._dsl.Type, Bits): raise InvalidConnectionError( "We don't allow slicing on non-Bits signals.") # Turn index into a slice if isinstance(idx, int): start, stop = idx, idx + 1 elif isinstance(idx, slice): start, stop = idx.start, idx.stop else: assert False, f"The slice {idx} is invalid" if s._dsl.slice is None: assert 0 <= start < stop <= s._dsl.Type.nbits, f"[{start}:{stop}] slice, check "\ f"0 <= {start} < {stop} <= {s._dsl.Type.nbits}" top_signal = s else: outer_start, outer_stop = s._dsl.slice.start, s._dsl.slice.stop # slicing over sliced signals assert 0 <= start < stop <= (outer_stop - outer_start), f"[{start}:{stop}] slice, check "\ f"0 <= {start} < {stop} <= {outer_stop - outer_start}" start += outer_start stop += outer_start top_signal = s._dsl.parent_obj sl_tuple = (start, stop) if sl_tuple not in top_signal.__dict__: x = top_signal.__class__(mk_bits(stop - start)) sd = top_signal._dsl xd = x._dsl xd.parent_obj = top_signal xd.top_level_signal = sd.top_level_signal xd.elaborate_top = sd.elaborate_top sl_str = f"[{start}:{stop}]" xd.my_name = f"{sd.my_name}{sl_str}" xd.full_name = f"{sd.full_name}{sl_str}" xd.slice = slice(start, stop) top_signal.__dict__[sl_tuple] = sd.slices[sl_tuple] = x return top_signal.__dict__[sl_tuple]
def test_interface_parameter_long_vector(do_test): class Ifc(Interface): def construct(s, Type, nbits_val, nbits_rdy): s.msg = InPort(Type) s.val = InPort(mk_bits(nbits_val)) # Added support for BitsN values in case someone wants to do # tricky things like this. s.rdy = OutPort(mk_bits(nbits_rdy.nbits)) class A(Component): def construct(s): Bits322 = mk_bits(322) s.ifc = Ifc(Bits322, 1, Bits322(1)) a = A() a._ref_symbols = {'Ifc': Ifc, 'Bits322': mk_bits(322)} a._ref_decls = ["s.ifc = Ifc( Bits322, 1, Bits322( 1 ) )"] do_test(a)
def run_test(cls, args, test_vectors): m = cls(*args) T = args[1] Tsel = mk_bits(clog2(args[0])) def tv_in(model, test_vector): n = len(model.in_) for i in range(n): model.in_[i] = T(test_vector[i]) model.sel[i] = Tsel(test_vector[n + i]) def tv_out(model, test_vector): n = len(model.in_) for i in range(n): assert model.out[i] == T(test_vector[n * 2 + i]) m._test_vectors = test_vectors m._tv_in, m._tv_out = tv_in, tv_out do_test(m)
def test_port_single(do_test): class A(Component): def construct(s): s.in_ = InPort(mk_bits(322)) a = A() a._ref_symbols = {'Bits322': mk_bits(322)} a._ref_decls = [ "s.in_ = InPort( Bits322 )", ] a._ref_conns = [ "connect( s.clk, s.mangled__clk[0:1] )", "connect( s.in_, s.mangled__in_[0:322] )", "connect( s.reset, s.mangled__reset[0:1] )" ] a._ref_conns_yosys = [ "connect( s.clk, s.mangled__clk )", "connect( s.in_, s.mangled__in_ )", "connect( s.reset, s.mangled__reset )" ] do_test(a)
def construct(s): s.in_ = InPort(mk_bits(322))
def construct(s, Type, nbits_val, nbits_rdy): s.msg = InPort(Type) s.val = InPort(mk_bits(nbits_val)) # Added support for BitsN values in case someone wants to do # tricky things like this. s.rdy = OutPort(mk_bits(nbits_rdy.nbits))
def construct(s): Bits322 = mk_bits(322) s.ifc = Ifc(Bits322, 1, Bits322(1))
def VectorInitData(dtype): nbits = dtype.get_length() min_val, max_val = -(2**(nbits - 1)), 2**(nbits - 1) - 1 value = 0 return mk_bits(nbits)(value)
def VectorDataStrategy(draw, dtype): nbits = dtype.get_length() min_val, max_val = -(2**(nbits - 1)), 2**(nbits - 1) - 1 value = draw(st.integers(min_val, max_val)) return mk_bits(nbits)(value)