circt
circt copied to clipboard
[HGLDD] Emit HW struct and array types
The EmitHGLDD target can emit the necessary HGLDD JSON bits to encode arrays and structs when it sees dbg.array and dbg.struct operations, but it ignores dbg.variable ops with !hw.array and !hw.struct types. Supporting these native HW types and creating the corresponding JSON structures should be fairly straightforward.
Hello, I would be interested in giving this a shot.
That sounds great! You'll probably want to look at the part of HGLDD emission that handles the StructOp from the debug dialect, and do more or less the same thing for VariableOps that have an !hw.struct type.
Finally had a chance to look into it. Just make sure I understand it correctly, I would have to make a check like this here:
if (auto variableOp = dyn_cast<debug::VariableOp>(op)){
// Only tracked structs are considered here
if (isa<hw::StructType>(variableOp.getValue().getType())){
auto value= dyn_cast<hw::StructType>(variableOp.getValue());
auto name = variableOp.getName();
}
}
Or am I misunderstanding the VariableOp here?
@fabianschuiki Could you give me a hint how I can access the underlying hw.struct ? Using op.getValue() just returns a general mlir::Value and I can't figure out how to use that to access the fields.
You can use dedicated operations like hw.struct_extract to take that general Value and access a field of the struct. By looking at the struct type, you can get a list of all fields that you might want to extract and look at.
@fabianschuiki Thanks! But don't I need a builder to create the hw.struct_extract? At least, that is the only way I know of how you can do this, and there doesn't seem to be one in the EmitHGLDD.cpp file.
Ah that's a great point! Yeah you're right, because we're emitting an HGLDD JSON file here, and the SV file has already been generated, there is no way to generate any extract ops. So in case you see an hw::StructType, you'd have to go through the field names of the struct and fill those into the HGLDD JSON as separate fields, similar to how it's done for the dbg.struct op. But you don't have actual values to point to, but instead have to fill in a hierarchical name for the expressions of each field, something like {"op": ".", "operands": ["someStructValueName", "fieldName"]}.