mirror of https://github.com/llvm/circt.git
[PyCDE] Value naming enhancements (#1609)
Provide a name property on Value and use it to better name registers, array gets, and struct field gets.
This commit is contained in:
parent
14a7212050
commit
3d91752243
|
@ -11,6 +11,8 @@ from circt.dialects import hw, seq
|
|||
|
||||
import mlir.ir as ir
|
||||
|
||||
import re
|
||||
|
||||
|
||||
class Value:
|
||||
|
||||
|
@ -28,8 +30,40 @@ class Value:
|
|||
return StructValue(value, type)
|
||||
return RegularValue(value, type)
|
||||
|
||||
def reg(self, clk, rst=None):
|
||||
return seq.reg(self.value, clk, rst)
|
||||
_reg_name = re.compile(r"^(.*)__reg(\d+)$")
|
||||
|
||||
def reg(self, clk, rst=None, name=None):
|
||||
if name is None:
|
||||
name = self.name
|
||||
if name is not None:
|
||||
m = Value._reg_name.match(name)
|
||||
if m:
|
||||
basename = m.group(1)
|
||||
reg_num = m.group(2)
|
||||
name = f"{basename}__reg{int(reg_num)+1}"
|
||||
else:
|
||||
name = name + "__reg1"
|
||||
return Value.get(seq.reg(self.value, clock=clk, reset=rst, name=name))
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
owner = self.value.owner
|
||||
if hasattr(owner, "attributes") and "name" in owner.attributes:
|
||||
return ir.StringAttr(owner.attributes["name"]).value
|
||||
if isinstance(owner, ir.Block) and isinstance(owner.owner, hw.HWModuleOp):
|
||||
mod = owner.owner
|
||||
return ir.StringAttr(
|
||||
ir.ArrayAttr(mod.attributes["argNames"])[self.value.arg_number]).value
|
||||
if hasattr(self, "_name"):
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, new: str):
|
||||
owner = self.value.owner
|
||||
if hasattr(owner, "attributes"):
|
||||
owner.attributes["name"] = ir.StringAttr.get(new)
|
||||
else:
|
||||
self._name = new
|
||||
|
||||
|
||||
class RegularValue(Value):
|
||||
|
@ -57,7 +91,10 @@ class ListValue(Value):
|
|||
raise TypeError("Subscript on array must be either int or MLIR int"
|
||||
f" Value, not {type(sub)}.")
|
||||
with get_user_loc():
|
||||
return Value.get(hw.ArrayGetOp.create(self.value, idx))
|
||||
v = Value.get(hw.ArrayGetOp.create(self.value, idx))
|
||||
if self.name and isinstance(idx, int):
|
||||
v.name = self.name + f"__{idx}"
|
||||
return v
|
||||
|
||||
def __len__(self):
|
||||
return self.type.strip.size
|
||||
|
@ -81,5 +118,8 @@ class StructValue(Value):
|
|||
fields = ty.get_fields()
|
||||
if attr in [name for name, _ in fields]:
|
||||
with get_user_loc():
|
||||
return Value.get(hw.StructExtractOp.create(self.value, attr))
|
||||
v = Value.get(hw.StructExtractOp.create(self.value, attr))
|
||||
if self.name:
|
||||
v.name = f"{self.name}__{attr}"
|
||||
return v
|
||||
raise AttributeError(f"'Value' object has no attribute '{attr}'")
|
||||
|
|
|
@ -52,7 +52,7 @@ class ComplexPorts:
|
|||
def build(mod):
|
||||
assert len(mod.data_in) == 3
|
||||
return {
|
||||
'a': mod.data_in[0].reg(mod.clk),
|
||||
'a': mod.data_in[0].reg(mod.clk).reg(mod.clk),
|
||||
'b': mod.data_in[mod.sel],
|
||||
'c': mod.struct_data_in.foo
|
||||
}
|
||||
|
@ -84,8 +84,11 @@ sys.generate()
|
|||
sys.print()
|
||||
# CHECK: hw.module @pycde.Comple_Ports(%clk: i1, %data_in: !hw.array<3xi32>, %sel: i2, %struct_data_in: !hw.struct<foo: i32>) -> (%a: i32, %b: i32, %c: i32) {
|
||||
# CHECK: %c0_i2 = hw.constant 0 : i2
|
||||
# CHECK: [[REG0:%.+]] = hw.array_get %data_in[%c0_i2] : !hw.array<3xi32>
|
||||
# CHECK: [[REGR:%.+]] = seq.compreg [[REG0]], %clk : i32
|
||||
# CHECK: [[REG0:%.+]] = hw.array_get %data_in[%c0_i2] {name = "data_in__0"} : !hw.array<3xi32>
|
||||
# CHECK: [[REGR1:%.+]] = seq.compreg [[REG0]], %clk {name = "data_in__0__reg1"} : i32
|
||||
# CHECK: [[REGR2:%.+]] = seq.compreg [[REGR1]], %clk {name = "data_in__0__reg2"} : i32
|
||||
# CHECK: [[REG1:%.+]] = hw.array_get %data_in[%sel] : !hw.array<3xi32>
|
||||
# CHECK: [[REG2:%.+]] = hw.struct_extract %struct_data_in["foo"] : !hw.struct<foo: i32>
|
||||
# CHECK: hw.output [[REGR]], [[REG1]], [[REG2]] : i32, i32, i32
|
||||
# CHECK: [[REG2:%.+]] = hw.struct_extract %struct_data_in["foo"] {name = "struct_data_in__foo"} : !hw.struct<foo: i32>
|
||||
# CHECK: hw.output [[REGR2]], [[REG1]], [[REG2]] : i32, i32, i32
|
||||
|
||||
sys.print_verilog()
|
||||
|
|
Loading…
Reference in New Issue