[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:
John Demme 2021-08-19 23:49:13 -07:00 committed by GitHub
parent 14a7212050
commit 3d91752243
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 9 deletions

View File

@ -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}'")

View File

@ -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()