mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	sdc: error on unknown getters
This commit is contained in:
		
							parent
							
								
									0aa2a4c260
								
							
						
					
					
						commit
						91ff55a50c
					
				
					 4 changed files with 60 additions and 7 deletions
				
			
		|  | @ -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] | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										1
									
								
								tests/sdc/get_foo.sdc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/sdc/get_foo.sdc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| get_foo -bar 1 | ||||
							
								
								
									
										5
									
								
								tests/sdc/unknown-getter.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								tests/sdc/unknown-getter.sh
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| #!/usr/bin/env bash | ||||
| 
 | ||||
| set -euo pipefail | ||||
| 
 | ||||
| ! ../../yosys -p 'read_verilog alu_sub.v; proc; hierarchy -auto-top; sdc get_foo.sdc' 2>&1 | grep 'Unknown getter' | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue