mirror of https://github.com/llvm/circt.git
[PyCDE] Make Values easier to name
This commit is contained in:
parent
bb5e79b041
commit
3634b6c6e1
|
@ -216,14 +216,14 @@ def _module_base(cls, extern: bool, params={}):
|
|||
raise ConnectionError(
|
||||
"`no_connect` is only valid on extern module ports")
|
||||
else:
|
||||
value = hw.ConstantOp.create(types.i1, 0).result
|
||||
value = Value.get(hw.ConstantOp.create(types.i1, 0).result)
|
||||
else:
|
||||
value = obj_to_value(input, type)
|
||||
else:
|
||||
backedge = BackedgeBuilder.current().create(type, name, self, loc=loc)
|
||||
self.backedges[idx] = backedge
|
||||
value = backedge.result
|
||||
input_ports_values.append(value)
|
||||
value = Value.get(backedge.result)
|
||||
input_ports_values.append(value.value)
|
||||
|
||||
# Set up the op attributes.
|
||||
attributes: dict[str:mlir.ir.Attribute] = {}
|
||||
|
@ -465,7 +465,7 @@ class _Generate:
|
|||
unconnected_ports.append(name)
|
||||
outputs.append(None)
|
||||
else:
|
||||
val = obj_to_value(gen_ret[name], port_type)
|
||||
val = obj_to_value(gen_ret[name], port_type).value
|
||||
outputs.append(val)
|
||||
gen_ret.pop(name)
|
||||
if len(unconnected_ports) > 0:
|
||||
|
|
|
@ -18,7 +18,7 @@ class _Types:
|
|||
self.registered_aliases = OrderedDict()
|
||||
|
||||
def __getattr__(self, name: str) -> mlir.ir.Type:
|
||||
return mlir.ir.Type.parse(name)
|
||||
return self.wrap(mlir.ir.Type.parse(name))
|
||||
|
||||
def int(self, width: int, name: str = None):
|
||||
return self.wrap(mlir.ir.IntegerType.get_signless(width), name)
|
||||
|
@ -111,9 +111,12 @@ def PyCDEType(type):
|
|||
else:
|
||||
return self
|
||||
|
||||
def create(self, obj):
|
||||
def create(self, obj, name: str = None):
|
||||
"""Create a Value of this type from a python object."""
|
||||
from .support import obj_to_value
|
||||
return obj_to_value(obj, self, self)
|
||||
v = obj_to_value(obj, self, self)
|
||||
if name is not None:
|
||||
v.name = name
|
||||
return v
|
||||
|
||||
return _PyCDEType(type)
|
||||
|
|
|
@ -63,6 +63,7 @@ class OpOperandConnect(support.OpOperand):
|
|||
def obj_to_value(x, type, result_type=None):
|
||||
"""Convert a python object to a CIRCT value, given the CIRCT type."""
|
||||
assert x is not None
|
||||
from .value import Value
|
||||
|
||||
type = support.type_to_pytype(type)
|
||||
if isinstance(type, hw.TypeAliasType):
|
||||
|
@ -72,19 +73,19 @@ def obj_to_value(x, type, result_type=None):
|
|||
result_type = type
|
||||
else:
|
||||
result_type = support.type_to_pytype(result_type)
|
||||
assert isinstance(result_type, hw.TypeAliasType)
|
||||
assert isinstance(result_type, hw.TypeAliasType) or result_type == type
|
||||
|
||||
val = support.get_value(x)
|
||||
# If x is already a valid value, just return it.
|
||||
if val is not None:
|
||||
if val.type != result_type:
|
||||
raise ValueError(f"Expected {result_type}, got {val.type}")
|
||||
return val
|
||||
return Value.get(val)
|
||||
|
||||
if isinstance(x, int):
|
||||
if not isinstance(type, ir.IntegerType):
|
||||
raise ValueError(f"Int can only be converted to hw int, not '{type}'")
|
||||
return hw.ConstantOp.create(type, x).result
|
||||
return Value.get(hw.ConstantOp.create(type, x).result)
|
||||
|
||||
if isinstance(x, list):
|
||||
if not isinstance(type, hw.ArrayType):
|
||||
|
@ -95,7 +96,7 @@ def obj_to_value(x, type, result_type=None):
|
|||
f"{len(x)} vs {type.size}")
|
||||
list_of_vals = list(map(lambda x: obj_to_value(x, elemty), x))
|
||||
# CIRCT's ArrayCreate op takes the array in reverse order.
|
||||
return hw.ArrayCreateOp.create(reversed(list_of_vals)).result
|
||||
return Value.get(hw.ArrayCreateOp.create(reversed(list_of_vals)).result)
|
||||
|
||||
if isinstance(x, dict):
|
||||
if not isinstance(type, hw.StructType):
|
||||
|
@ -109,8 +110,9 @@ def obj_to_value(x, type, result_type=None):
|
|||
x.pop(fname)
|
||||
if len(x) > 0:
|
||||
raise ValueError(f"Extra fields specified: {x}")
|
||||
return hw.StructCreateOp.create(elem_name_values,
|
||||
result_type=result_type).result
|
||||
return Value.get(
|
||||
hw.StructCreateOp.create(elem_name_values,
|
||||
result_type=result_type).result)
|
||||
|
||||
raise ValueError(f"Unable to map object '{type(x)}' to MLIR Value")
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# RUN: %PYTHON% %s | FileCheck %s
|
||||
|
||||
from pycde import (Output, Input, module, generator, types, dim, System)
|
||||
|
||||
|
||||
@module
|
||||
class WireNames:
|
||||
clk = Input(types.i1)
|
||||
sel = Input(types.i2)
|
||||
data_in = Input(dim(32, 3))
|
||||
|
||||
a = Output(types.i32)
|
||||
b = Output(types.i32)
|
||||
|
||||
@generator
|
||||
def build(mod):
|
||||
foo = mod.data_in[0]
|
||||
foo.name = "foo"
|
||||
arr_data = dim(32, 4).create([1, 2, 3, 4], "arr_data")
|
||||
return {
|
||||
'a': foo.reg(mod.clk).reg(mod.clk),
|
||||
'b': arr_data[mod.sel],
|
||||
}
|
||||
|
||||
|
||||
sys = System([WireNames])
|
||||
sys.generate()
|
||||
sys.print()
|
||||
# CHECK: hw.module @pycde.WireNames(%clk: i1, %data_in: !hw.array<3xi32>, %sel: i2) -> (%a: i32, %b: i32) {
|
||||
# CHECK: %c0_i2 = hw.constant 0 : i2
|
||||
# CHECK: %0 = hw.array_get %data_in[%c0_i2] {name = "foo"} : !hw.array<3xi32>
|
||||
# CHECK: %c1_i32 = hw.constant 1 : i32
|
||||
# CHECK: %c2_i32 = hw.constant 2 : i32
|
||||
# CHECK: %c3_i32 = hw.constant 3 : i32
|
||||
# CHECK: %c4_i32 = hw.constant 4 : i32
|
||||
# CHECK: %1 = hw.array_create %c4_i32, %c3_i32, %c2_i32, %c1_i32 : i32
|
||||
# CHECK: %2 = seq.compreg %0, %clk {name = "foo__reg1"} : i32
|
||||
# CHECK: %3 = seq.compreg %2, %clk {name = "foo__reg2"} : i32
|
||||
# CHECK: %4 = hw.array_get %1[%sel] : !hw.array<4xi32>
|
||||
# CHECK: hw.output %3, %4 : i32, i32
|
||||
# CHECK: }
|
||||
|
||||
sys.print_verilog()
|
Loading…
Reference in New Issue