3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-10-10 17:58:07 +00:00

sdc: error on unknown getters

This commit is contained in:
Emil J. Tywoniak 2025-10-09 20:55:15 +02:00
parent 0aa2a4c260
commit 91ff55a50c
4 changed files with 60 additions and 7 deletions

View file

@ -1,4 +1,21 @@
proc unknown {args} {
# Check if it's a getter
if {[llength $args] > 0} {
set first_arg [lindex $args 0]
if {[string match "get_*" $first_arg]} {
# It's a getter, has it been redirected from specialized C++ code?
if {[llength $args] > 1} {
set second_arg [lindex $args 1]
if {$second_arg ne "-getter-validated"} {
error "Unknown getter: $first_arg"
}
} else {
error "Unknown getter: $first_arg"
}
}
}
# TODO this safety feature could be optional via a global
global sdc_call_index
global sdc_calls
if {![info exists sdc_call_index]} {
@ -15,4 +32,11 @@ proc unknown {args} {
}
proc list {args} {
return [unknown "list" {*}$args]
}
}
proc get_clocks {args} {
# get_clocks isn't a design object getter
# because clocks aren't design objects, just aliases
# so the referred to clock pin already are being tracked
# as arguments of uninterpreted create_clock command or similar
return [unknown "get_clocks" "-getter-validated" {*}$args]
}

View file

@ -344,9 +344,32 @@ static std::pair<bool, BitSelection> matches(std::string name, const std::string
}
}
static int graph_node(TclCall call) {
// TODO is that it?
return redirect_unknown(call);
static int getter_graph_node(TclCall call) {
// Insert -getter-validated as first argument for passing to unknown
// to distinguish resolved and unknown getters.
// For example, if call is ["get_foo", "-bar"]
// then newCall is ["get_foo", "-getter-validated", "-bar"]
Tcl_Obj* validity_tag = Tcl_NewStringObj("-getter-validated", -1);
Tcl_IncrRefCount(validity_tag);
std::vector<Tcl_Obj*> newObjv(call.objc + 1);
log_assert(call.objc > 0);
newObjv[0] = call.objv[0];
newObjv[1] = validity_tag;
for (int i = 1; i < call.objc; ++i) {
newObjv[i + 1] = call.objv[i];
}
// Send the vector to the Tcl land
Tcl_Obj** allocatedObjv = new Tcl_Obj*[call.objc + 1];
for (int i = 0; i < call.objc + 1; ++i) {
allocatedObjv[i] = newObjv[i];
}
TclCall newCall {
.interp = call.interp,
.objc = call.objc + 1,
.objv = allocatedObjv
};
// Finally, redirect to unknown handler
return redirect_unknown(newCall);
}
static int redirect_unknown(TclCall call) {
@ -610,7 +633,7 @@ static int sdc_get_pins_cmd(ClientData data, Tcl_Interp *interp, int objc, Tcl_O
const auto& pins = objects->design_pins;
resolved = find_matching<SdcObjects::CellPin, decltype(pins)>(pins, config, opts.patterns, "pin");
return graph_node(TclCall{interp, objc, objv});
return getter_graph_node(TclCall{interp, objc, objv});
}
static int sdc_get_ports_cmd(ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj* const objv[])
@ -631,7 +654,7 @@ static int sdc_get_ports_cmd(ClientData data, Tcl_Interp *interp, int objc, Tcl_
merge_or_init(std::make_pair(name, wire), objects->constrained_ports, matching_bits);
}
return graph_node(TclCall{interp, objc, objv});
return getter_graph_node(TclCall{interp, objc, objv});
}
static int sdc_get_nets_cmd(ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj* const objv[])
@ -652,7 +675,7 @@ static int sdc_get_nets_cmd(ClientData data, Tcl_Interp *interp, int objc, Tcl_O
merge_or_init(std::make_pair(name, wire), objects->constrained_nets, matching_bits);
}
return graph_node(TclCall{interp, objc, objv});
return getter_graph_node(TclCall{interp, objc, objv});
}
class SDCInterpreter