Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions auto_generated/netlist_files/get_clocks_netlist.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Command: get_clocks
Description:
-Returns a list of clocks matching patterns

SDC Example:
get_clocks clk1
get_clocks -quiet clk1098
*/

//Main module
module get_clocks(
input wire clk1,
input wire clk2,
input wire clk_gen,
input wire clock,
output reg dummy_out
);
initial dummy_out = 1'b1;

always @(posedge clk1 or posedge clk2 or posedge clk_gen or posedge clock) begin
dummy_out <= ~dummy_out;
end

endmodule

35 changes: 35 additions & 0 deletions auto_generated/netlist_files/get_pins_netlist.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Command: get_pins
Description:
-Returns a list of all instance pins matching patterns

SDC Example:
get_pins -regexp u1/D
get_pins u1/D
*/

//Main module
module get_pins(
input wire clk,
input wire data_in,
output reg [1:0] data_out
);
wire u1_out, u2_out;

//Datapath
DFF u1(.clk(clk), .D(data_in), .Q(u1_out));
DFF u2(.clk(clk), .D(~data_in), .Q(u2_out));

assign data_out = {u1_out, u2_out};

endmodule

module DFF(
input wire clk,
input wire D,
output reg Q
);
always @(posedge clk) begin
Q <= D;
end
endmodule
32 changes: 32 additions & 0 deletions auto_generated/netlist_files/get_ports_netlist.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Command: get_ports
Description:
-Returns a list of all top level ports that match patterns

SDC Example:
get_ports data*
get_ports -regexp rst
*/

module get_ports(
input wire clk,
input wire rst,
input wire data1_in,
input wire data2_in,
input wire valid_in,
output reg result_out,
output wire ready_out
);
//ready_out is always 1 for this simple module
assign ready_out = 1'b1;

always @(posedge clk or posedge rst) begin
if (rst) begin
result_out <= 1'b0;
end
else if (valid_in) begin
result_out <= data1_in + data2_in;
end
end

endmodule
Binary file added docs/images/Synopsys-Design-Constraints.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/Syntax-Suite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/Timing-Suite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 36 additions & 68 deletions scripts/generate_sdc.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@

'''
PATTERNS = {
"clock": ["clk*", "*clk*", "clk[0-9]*", "clock_*"],
"port": ["*_in", "*_out", "data*", "port*"],
"pin": ["pin*", "*/Q", "*/D", "*/CLK"],
"clock": ["clk*", "clk_gen", "clock", "clk1"],
"port": ["data*", "*in", "*out", "valid_in"],
"pin": ["u1/*", "*/Q", "u2/D", "*/clk"],
"cell": ["inst*", "reg_*", "*_buffer"],
"net": ["net*", "n[0-9]*", "*_data"]
}
Comment on lines +103 to 108
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Ensure patterns match the selected mode (glob vs -regexp)

PATTERNS now feeds both plain mode and -regexp mode. Several entries (e.g., clk*, *in, */Q) look like glob patterns; under -regexp they may be invalid or at least semantically different than intended depending on the SDC implementation. Consider maintaining separate pattern banks (glob vs regex) or translating when -regexp is present.

 PATTERNS = {
-    "clock": ["clk*", "clk_gen", "clock", "clk1"],
-    "port": ["data*", "*in", "*out", "valid_in"],
-    "pin": ["u1/*", "*/Q", "u2/D", "*/clk"],
+    # Consider splitting into "glob" vs "regex" banks if -regexp is used.
+    "clock": ["clk*", "clk_gen", "clock", "clk1"],
+    "port": ["data*", "*in", "*out", "valid_in"],
+    "pin": ["u1/*", "*/Q", "u2/D", "*/clk"],
     "cell": ["inst*", "reg_*", "*_buffer"],
     "net": ["net*", "n[0-9]*", "*_data"]
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"clock": ["clk*", "clk_gen", "clock", "clk1"],
"port": ["data*", "*in", "*out", "valid_in"],
"pin": ["u1/*", "*/Q", "u2/D", "*/clk"],
"cell": ["inst*", "reg_*", "*_buffer"],
"net": ["net*", "n[0-9]*", "*_data"]
}
PATTERNS = {
# Consider splitting into "glob" vs "regex" banks if -regexp is used.
"clock": ["clk*", "clk_gen", "clock", "clk1"],
"port": ["data*", "*in", "*out", "valid_in"],
"pin": ["u1/*", "*/Q", "u2/D", "*/clk"],
"cell": ["inst*", "reg_*", "*_buffer"],
"net": ["net*", "n[0-9]*", "*_data"]
}
🤖 Prompt for AI Agents
In scripts/generate_sdc.py around lines 103 to 108, PATTERNS currently contains
glob-style entries that are being used regardless of whether the SDC engine is
invoked in plain (glob) or -regexp mode; this can produce incorrect or invalid
matches. Fix by branching on the selected mode: if mode == "regexp" either (a)
maintain a separate PATTERNS_REGEXP mapping with proper regular expressions for
each key, or (b) programmatically translate glob patterns to equivalent regex
(escaping as needed and converting * -> .* and ? -> .) before emitting them;
validate converted patterns (e.g., compile them) and use the appropriate bank
when generating the SDC output.

Expand Down Expand Up @@ -235,11 +235,11 @@ def generate_create_clock():

def generate_get_ports():
'''
Optional: -filter, -regexp, -nocase(Legal only with -regexp), -quiet, -of_objects, patterns
Optional: -regexp, -nocase(Legal only with -regexp), -quiet
'''
commands = [] #List containing all possible combinations of options

optional_options = ["-filter", "-regexp", "-nocase", "-quiet", "-of_objects", "patterns"]
optional_options = ["-regexp", "-nocase", "-quiet"]

for i in range(len(optional_options) + 1):
for option_combination in combinations(optional_options, i):
Expand All @@ -249,12 +249,6 @@ def generate_get_ports():
continue

pieces = ["get_ports"]

if "-filter" in option_combination:
#FIXME: Random filter type
filter_type = choose_filter_type()
expr = generate_filter(filter_type, "port")
pieces.append(f"-filter {expr}")

if "-regexp" in option_combination:
pieces.append("-regexp")
Expand All @@ -264,30 +258,25 @@ def generate_get_ports():

if "-quiet" in option_combination:
pieces.append("-quiet")

if "-of_objects" in option_combination:
#FIXME: Do not make this random.
#The name of net or list of nets
net_list = random.choice(NETS)
pieces.append(f"-of_objects {net_list}")

if "patterns" in option_combination:
#FIXME: Do not make this random.
#A list of port name patterns
pattern = generate_pattern("port")
pieces.append(pattern)

commands.append(" ".join(pieces))
#A list of port name patterns
pattern = generate_pattern("port")
pieces.append(pattern)

#Join the options to create a proper command
pieces = " ".join(pieces)
#Add create_clock prerequisites
pieces = ("create_clock -period 10 -name clk [get_ports clk]\n" + pieces)
commands.append(pieces)

return commands

def generate_get_clocks():
'''
Required:
Optional: -filter, -regexp, -nocase(Legal only with -regexp), -quiet, patterns
Optional: -regexp, -nocase(Legal only with -regexp), -quiet
'''
commands = [] #List containing all possible combinations of options
optional_options = ["-filter", "-regexp", "-nocase", "-quiet", "patterns"]
optional_options = ["-regexp", "-nocase", "-quiet"]

for i in range(len(optional_options) + 1):
for option_combination in combinations(optional_options, i):
Expand All @@ -298,12 +287,6 @@ def generate_get_clocks():

pieces = ["get_clocks"]

if "-filter" in option_combination:
#Filter expression with object type "clock"
filter_type = choose_filter_type()
expr = generate_filter(filter_type, "clock")
pieces.append(f"-filter {expr}")

if "-regexp" in option_combination:
pieces.append("-regexp")

Expand All @@ -313,12 +296,18 @@ def generate_get_clocks():
if "-quiet" in option_combination:
pieces.append("-quiet")

if "patterns" in option_combination:
#FIXME: Do not make this random.
pattern = generate_pattern("clock")
pieces.append(pattern)

commands.append(" ".join(pieces))
pattern = generate_pattern("clock")
pieces.append(pattern)

#Join the options to create a proper command
pieces = " ".join(pieces)
#Add create_clock prerequisites
pieces = ("create_clock -period 10 -name clk1 [get_ports clk1]\n" +
"create_clock -period 10 -name clk2 [get_ports clk2]\n" +
"create_clock -period 10 -name clk_gen [get_ports clk_gen]\n" +
"create_clock -period 10 -name clock [get_ports clock]\n" +
pieces)
commands.append(pieces)

return commands

Expand All @@ -338,26 +327,8 @@ def generate_get_pins():
if "-nocase" in option_combination and "-regexp" not in option_combination:
continue #Skip this invalid combination

#Constraint 2: -hierarchical cannot be used with -of_objects
if "-hierarchical" in option_combination and "-of_objects" in option_combination:
continue #Skip this invalid combination

pieces = ["get_pins"]

if "-hierarchical" in option_combination:
pieces.append("-hierarchical")

if "-hsc" in option_combination:
#FIXME: Do not make this random.
separator = random.choice(SEPARATOR)
pieces.append(f"-hsc {separator}")

if "-filter" in option_combination:
#Filter expression with object type "pin"
filter_type = choose_filter_type()
expr = generate_filter(filter_type, "pin")
pieces.append(f"-filter {expr}")

if "-regexp" in option_combination:
pieces.append("-regexp")

Expand All @@ -367,18 +338,15 @@ def generate_get_pins():
if "-quiet" in option_combination:
pieces.append("-quiet")

if "-of_objects" in option_combination:
#FIXME: Do not make this random.
#The name or list of nets or instances.
net_inst_list = random.choice(NETS + INSTANCES)
pieces.append(f"-of_objects {net_inst_list}")

if "patterns" in option_combination:
#A list of pin name patterns
pattern = generate_pattern("pin")
pieces.append(pattern)
pattern = generate_pattern("pin")
pieces.append(pattern)

commands.append(" ".join(pieces))

#Join the options to create a proper command
pieces = " ".join(pieces)
#Add create_clock prerequisites
pieces = ("create_clock -period 10 -name clk [get_ports clk]\n" + pieces)
commands.append(pieces)

return commands

Expand Down