Is there a way to specify multiple clocks with the...
# openlane
m
Is there a way to specify multiple clocks with their own max frequencies in openlane? So it would generate 2 clock trees and be able to do sta on both clock domains?
m
I've seen this before and the answer was no
πŸ‘ 2
m
Can you confirm this is still the case @Manar Abdelatty?
πŸ‘ 1
m
@Matt Venn Yes, openlane will create the timing report for one clock but for CTS you can set
CLOCK_NET
to a list of clocks and TritonCTS will create a tree for each
m
How do we specify different clock speed requirements?
j
The clock speeds are only relevant for STA so you would specify them in an .SDC file. Something like this.
Copy code
create_clock [get_ports wb_clk_i]  -name wb_clk_i  -period 10
create_clock [get_ports user_clock2]  -name user_clock2  -period 20
set_clock_groups -asynchronous \
   -group [get_clocks {wb_clk_i}] \
   -group [get_clocks {user_clock2}]
m
@Amogh Lonkar ^^
This explains the different between the clock port and net. I've wondered
j
It took a while for me to figure it out for MPW-1
m
@Manar Abdelatty tritonCTS doesn't match insertion delay of the multiple clocks, right? They are just independent?
j
In theory. correct. In practice, I think so.
@Manar Abdelatty In MPW-1 I was getting a static timing report for each independent clock. Two, in that case.
a
While generating a macro with two clock ports, is there a way to specify multiple
CLOCK_PORT
? With a similar custom .sdc file like above, it will create the macro but skip CTS and STA because no clock ports are declared.
m
@Amogh Lonkar No, only one port which is used to configure STA. You can specify multiple nets which is used to run clock tree synthesis on each one.
But if you rewrite your own .sdc file we could configure multiple clock ports
I think there was an option to specify a custom sdc file
j
Copy code
set ::env(BASE_SDC_FILE) "$script_dir/../../verilog/rtl/user_proj_example.sdc"
@Amogh Lonkar In MPW-ONE,
Copy code
set ::env(CLOCK_PORT) "wb_clk_i"
set ::env(CLOCK_NET) "wb_clk_i user_clock2"
set ::env(BASE_SDC_FILE) "$script_dir/../../verilog/rtl/user_proj_example.sdc"
Combined with sdc file
Copy code
create_clock [get_ports wb_clk_i]  -name wb_clk_i  -period 10
create_clock [get_ports user_clock2]  -name user_clock2  -period 20
set_clock_groups -asynchronous \
   -group [get_clocks {wb_clk_i}] \
   -group [get_clocks {user_clock2}]
CTS generated 2 independent clock trees and I'm pretty sure I got slack and slew reports for each clock domain indepedently. Even if only one clock was specified in CLOCK_PORT.
πŸ‘ 2
@Matt Venn Beware of clock domain crossings. They require special attention. πŸ‘€
m
Yeah, fascinating topic
Personally I avoid at all costs
But in the end your clock domain stops somewhere and then you have to deal with it....
Best I've read on this topic was the sunburst paper, got any other recommended resources?
j
Avoid if you can, but usually necessary at some point in multi-clock designs. Sunburst goes into great detail, but usually 2 flip flops will do! Three if you're paranoid. πŸ˜›
πŸ˜‚ 1
πŸ‘ 1
πŸ™ƒ 1
t
@Jean What is the best strategy in a scenario where I derive a slow clock from wb_clk_i, say with a period of 40. I use wishbone slave as a configuration bus in my user area, and the slow clock to run everything there.
j
I don't think it matters if you are deriving a slower clock by dividing another. In that case the clocks would be synchronous and timing contraints simply analyzed.
m
@Jean Do the CLOCK_NETs have to be inputs to the verilog module or can they be derived inside the macro?
I create a very low-speed clock that is the OR of either an off-chip GPIO or the LA for testing purposes. I get this error: [INFO]: Configuring cts characterization... [INFO]: Performing clock tree synthesis... [INFO]: Looking for the following net(s): clk sram_clk [INFO]: Running Clock Tree Synthesis... [ERROR UKN-0000] Error when finding -clk_nets in DB! Error: or_cts.tcl, 57 UKN-0000
Was able to figure this out. Yosys was buffering my clock net and in the process changed its name, so that it wasn't in the DEF file given to TritonCTS
j
I'm curious. What was your solution?
m
I'm moving some stuff to a different level of hierarchy so that there is only one clock domain per level of hierarchy
j
Ah, I read from another thread that CTS gets its clocks from STA which gets them from SDC. So far so good. I've never seen a create_clock SDC command bound to anything other than a port. I was going to suggest you encapsulate your OR gate in a module and designate its output port as a clock. You'd have to use hierarchical module notation to identify the port.
m
create_clock can be applied to pins as well (even in OpenRoad). I just need to figure out how to get the output pin. I've been able to get the fanin gates: set clkin [get_fanin -levels 1 -to "clk"] But this gets the fanin pins including the inputs of the driving gate. I'm not sure how to isolate the driving pin.
The OpenLane script, however, is tied to ports in the base.sdc: create_clock [get_port $::env(CLOCK_PORT)] -name $::env(CLOCK_PORT) -period $::env(CLOCK_PERIOD)
The get_port will fail to find a net
But you could make your own SDC
j
Doesn't
set ::env(BASE_SDC_FILE) "$script_dir/../../verilog/rtl/user_proj_example.sdc"
override the OpenLane script setting? Yes, ports and pins are valid. Would something like
create_clock [get_ports *.ORModuleOutputPort] ...
work?
m
Yes, that overrides it. I haven't tested if it can be a port of a submodule, but maybe?
j
For example:
module top(
input  wire fastclk,
input  wire slowclk,
input  wire la,
output wire someoutput,
output wire otheroutput
);
assign otheroutput = fastclk;
ORModule ormod(
.slowclk(slowclk),
.la(la),
.orout(someoutput));
endmodule
module ORModule(
input  wire slowclk,
input  wire la,
output wire orout
);
assign orout = slowclk | la;
endmodule
With this SDC works in Synopsys
create_clock [get_ports fastclk]  -name fastclk  -period 10
create_clock [get_nets {ormod|orout}] -name slowclk  -period 333
set_clock_groups -asynchronous \
-group [get_clocks {fastclk}] \
-group [get_clocks {slowclk}]
m
The second line doesn't work in OpenRoad. I tried it..
It complains that it isn't a port or pin