예제 #1
0
    def __init__(self,
                 module,
                 name,
                 input_port_mapping,
                 *,
                 results=None,
                 parameters={},
                 sym_name=None,
                 loc=None,
                 ip=None):
        self.module = module
        instance_name = StringAttr.get(name)
        module_name = FlatSymbolRefAttr.get(StringAttr(module.name).value)
        inst_param_array = create_parameters(parameters, module)
        if sym_name:
            sym_name = StringAttr.get(sym_name)
        pre_args = [instance_name, module_name]
        post_args = [
            ArrayAttr.get([StringAttr.get(x) for x in self.operand_names()]),
            ArrayAttr.get([StringAttr.get(x) for x in self.result_names()]),
            ArrayAttr.get(inst_param_array), sym_name
        ]
        if results is None:
            results = module.type.results

        if not isinstance(module, hw.HWModuleExternOp):
            input_name_type_lookup = {
                name: support.type_to_pytype(ty)
                for name, ty in zip(self.operand_names(), module.type.inputs)
            }
            for input_name, input_value in input_port_mapping.items():
                if input_name not in input_name_type_lookup:
                    continue  # This error gets caught and raised later.
                mod_input_type = input_name_type_lookup[input_name]
                if support.type_to_pytype(input_value.type) != mod_input_type:
                    raise TypeError(
                        f"Input '{input_name}' has type '{input_value.type}' "
                        f"but expected '{mod_input_type}'")

        super().__init__(hw.InstanceOp,
                         results,
                         input_port_mapping,
                         pre_args,
                         post_args,
                         needs_result_type=True,
                         loc=loc,
                         ip=ip)
예제 #2
0
def create_type_string(ty):
    from .dialects import hw
    ty = support.type_to_pytype(ty)
    if isinstance(ty, hw.TypeAliasType):
        return ty.name
    if isinstance(ty, hw.ArrayType):
        return f"{ty.size}x" + create_type_string(ty.element_type)
    return str(ty)
예제 #3
0
 def set_guard(self, guard_fn):
     """Executes a function to generate a guard for the transition.
 The function is executed within the guard region of this operation."""
     guard_block = _get_or_add_single_block(self.guard)
     with InsertionPoint(guard_block):
         guard = guard_fn()
         guard_type = support.type_to_pytype(guard.type)
         if guard_type.width != 1:
             raise ValueError('The guard must be a single bit')
         fsm.ReturnOp(operand=guard.value)
예제 #4
0
def _validate_idx(size: int, idx: Union[int, BitVectorValue]):
    """Validate that `idx` is a valid index into a bitvector or array."""
    if isinstance(idx, int):
        if idx >= size:
            raise ValueError("Subscript out-of-bounds")
    else:
        idx = support.get_value(idx)
        if idx is None or not isinstance(support.type_to_pytype(idx.type),
                                         ir.IntegerType):
            raise TypeError("Subscript on array must be either int or MLIR int"
                            f" Value, not {type(idx)}.")
예제 #5
0
 def __getitem__(self, sub):
   if isinstance(sub, int):
     idx = int(sub)
     if idx >= self.type.size:
       raise ValueError("Subscript out-of-bounds")
   else:
     idx = support.get_value(sub)
     if idx is None or not isinstance(support.type_to_pytype(idx.type),
                                      ir.IntegerType):
       raise TypeError("Subscript on array must be either int or MLIR int"
                       f" Value, not {type(sub)}.")
   from .dialects import hw
   with get_user_loc():
     v = hw.ArrayGetOp(self.value, idx)
     if self.name and isinstance(idx, int):
       v.name = self.name + f"__{idx}"
     return v
예제 #6
0
    def create(*sub_arrays):
        vals = []
        types = []
        element_type = None
        for array in sub_arrays:
            array_value = support.get_value(array)
            array_type = support.type_to_pytype(array_value.type)
            if array_value is None or not isinstance(array_type, hw.ArrayType):
                raise TypeError(f"Cannot concatenate {array_value}")
            if element_type is None:
                element_type = array_type.element_type
            elif element_type != array_type.element_type:
                raise TypeError(
                    "All arguments must be the same type to concatenate arrays"
                )
            vals.append(array_value)
            types.append(array_type)

        size = sum(t.size for t in types)
        combined_type = hw.ArrayType.get(element_type, size)
        return hw.ArrayConcatOp(combined_type, vals)
예제 #7
0
  def create(*sub_arrays):
    vals = []
    types = []
    element_type = None
    for i, array in enumerate(sub_arrays):
      array_value = support.get_value(array)
      array_type = support.type_to_pytype(array_value.type)
      if array_value is None or not isinstance(array_type, hw.ArrayType):
        raise TypeError(f"Cannot concatenate {array_value}")
      if element_type is None:
        element_type = array_type.element_type
      elif element_type != array_type.element_type:
        raise TypeError(
            f"Argument {i} has a different element type ({element_type}) than the element type of the array ({array_type.element_type})"
        )

      vals.append(array_value)
      types.append(array_type)

    size = sum(t.size for t in types)
    combined_type = hw.ArrayType.get(element_type, size)
    return hw.ArrayConcatOp(combined_type, vals)