# Create a max skew constraint that includes input and output delays
# as well as the default data arrivals, clock arrivals and clock uncertainty
set_max_skew -from [get_keepers inst1|*] -to [get_keepers inst2|*] 0.200 \
-include { input_delay output_delay }
entity pwm_example is
port (
pwmA_in : in std_logic;
pwmB_in : in std_logic;
pwmA_out : out std_logic;
pwmB_out : out std_logic;
pwm_en : in std_logic
);
end pwm_example;
architecture rtl of pwm_example is
-- no declarations!
begin
pwmA_out <= pwmA_in when (pwm_en='1') else '0';
pwmB_out <= pwmB_in when (pwm_en='1') else '0';
end rtl;
FPGAs are meant for synchronous design and its timing targets clocked signals. So in principle you cannot control your signals by defining delays through constraints which will vary anyway from build to build.In a design I'm working on, I have two PWM signals generated by a switchmode power supply controller. The two signals are "mostly" complementary with a small amount of dead time tdead inserted where both signals must be low. For my application, tdead is around 5ns.
View attachment 173551
I want to use an FPGA to gate both these signals, but want to ensure skew is limited so tdead is not significantly altered.
I'm fairly new to SDC. I am aware of the set_max_skew command, but all the guidance I see on its usage refer to clocks or signals launched by clocks, whereas in my case my signals are totally asynchronous. And I want to consider skew all the way from the input pin to the output pin (including io delays), but most of the examples only consider pins to registers, or registers to pins.
The example I've found that seems most relevant is this:
But I don't really see how to adopt this to my needs. Let's assume my code looks like this:
Code:entity pwm_example is port ( pwmA_in : in std_logic; pwmB_in : in std_logic; pwmA_out : out std_logic; pwmB_out : out std_logic; pwm_en : in std_logic ); end pwm_example; architecture rtl of pwm_example is -- no declarations! begin pwmA_out <= pwmA_in when (pwm_en='1') else '0'; pwmB_out <= pwmB_in when (pwm_en='1') else '0'; end rtl;
So I want to constrain skew between the in > out paths (skew from the pwm_en signal isn't a concern).
Not sure what you mean by "vary from build to build". Surely the timing analyzer is capable of checking the total delays along paths through combinational logic and IO. In principle, all I want is to do that, then take the difference between different paths, and report a timing error if it's above a max skew or not.FPGAs are meant for synchronous design and its timing targets clocked signals. So in principle you cannot control your signals by defining delays through constraints which will vary anyway from build to build.
The dead time is around 5ns, but the timing resolution of the edges is actually <0.2ns, so I would need a >5GHz clock to avoid degrading the timing resolution (which is critical in my application). Far beyond the specs of my FPGA.Why don't you try a clock at say 200 MHz for 5 ns resolution then you can control both the dead and the live sections of your signals.
My understanding of Quartus/Vivado STA and their sdc processing is that if there is no clock there is no timing path to report. If there is clock the tool targets passing tSU/tH relevant to that clock and once achieved it stops there. So the primary question raised is "can" or "how" a design can be constrained in an FPGA without any clock, and especially so for delays such as 0.5ns. I can imagine that is possible in ASIC.Although SDC is focussed on synchronous design, it can constrain purely asynchronous paths without registers. According to documentation, set_minimum_delay and set_maximum_delay is suited for port to port delay. There's probably no relative (skew) constraint.
Well without a clock there certainly aren't any tsu or th to report, but there still is delay. From what I understand, report_path just reports delays, not slack or tsu/th. Maybe as a first step I should just have my tcl report the delays for each pwm signal.My understanding of Quartus/Vivado STA and their sdc processing is that if there is no clock there is no timing path to report.
I think I understand where you are coming from. In general, meeting tsh/th (plus removal/recovery) is the only objective. But then what it the intended purpose of set_max_skew?If there is clock the tool targets passing tSU/tH relevant to that clock and once achieved it stops there. So the primary question raised is "can" or "how" a design can be constrained in an FPGA without any clock, and especially so for delays such as 0.5ns. I can imagine that is possible in ASIC. The set_min_delay/set_max_delay are meant for clock as alternative to tH, tSU, or multicycle paths as well as for ports instead of set_input_delay/set_output_delay.
So again, what is set_max_skew for? Maybe the definition of "skew" it's referring to is completely different from what I'm interested in?Although SDC is focussed on synchronous design, it can constrain purely asynchronous paths without registers. According to documentation, set_minimum_delay and set_maximum_delay is suited for port to port delay. There's probably no relative (skew) constraint.
library ieee;
use ieee.std_logic_1164.all;
entity async is
port
(
a : in std_logic;
b : in std_logic;
en : in std_logic;
qa : out std_logic;
qb : out std_logic
);
end async;
architecture rtl of async is
attribute altera_attribute : string;
attribute altera_attribute of rtl : architecture is
"-name sdc_statement ""set_false_path -from [get_ports {en}]"";" &
"-name sdc_statement ""set_max_skew 0.65 -from [get_ports {a b}] -to [get_ports {qa qb}]""";
begin
qa <= a and en;
qb <= b and en;
end rtl;
So skew refers to the difference in delay of a single clock along multiple paths to different registers? I suppose that's a valid use of the term, but not relevant in my case.set_max_skew is meant for multiple registers/nodes such as a data bus with 2 bits or more
This is what I was anticipating. I'm not expecting anyone here to promise me a working solution.My main concern is that if we divert from intended methodology of synchronous design then it becomes a case of experimenting that may or may not succeed.
Yes, locking down the synthesis of this logic sounds worthwhile, but that's another thing I've never done before. I assume it's very tool-dependent (I'm using quartus). I'll probably come back asking about that if the skew turns out to be significant.@mtwieg you should probably consider specifying placement constraints for the input/output/gating logic for these "gated" signals. Co-located input/output for each of the signals, replicate the same relative placement on another set of pins, use information from the FPGA manufacturer on the package delay for pin pairs you want to use to ensure the skew is the same for both paths.
Doing the above you won't even need to add constraints other than to verify the place and route tools didn't screw up and ignore the placement or routes the signal across the die for some reason.
If you've already got a poor placement of I/O pins then you will have to live with any skew issues unless you take advantage of any skew compensation logic in the I/O that you device might have (it's the logic that is used to run DDRx memory interfaces). That would have to tuned in after you've implemented the design and locked down the placement/routing of the poorly placed logic.
Interesting, I've never seen sdc commands in source code before. Does this change how compilation/synthesis/timing analysis work vs putting everything in the sdc file?Other than assumed, set_max_skew also works for asynchronous paths. SDC commands are conveniently embedded in VHDL.
As mentioned by ads-ee, it's essential to place the port pins appropriately and to avoid pins that involve extra delay or delay skew.
Code:library ieee; use ieee.std_logic_1164.all; entity async is port ( a : in std_logic; b : in std_logic; en : in std_logic; qa : out std_logic; qb : out std_logic ); end async; architecture rtl of async is attribute altera_attribute : string; attribute altera_attribute of rtl : architecture is "-name sdc_statement ""set_false_path -from [get_ports {en}]"";" & "-name sdc_statement ""set_max_skew 0.65 -from [get_ports {a b}] -to [get_ports {qa qb}]"""; begin qa <= a and en; qb <= b and en; end rtl;
skew affects data path so it can be applied to your inputs. clock paths are kept clean untouched. I view skew purpose as follows:So skew refers to the difference in delay of a single clock along multiple paths to different registers? I suppose that's a valid use of the term, but not relevant in my case.
Embedded SDC commands are evaluated before the global SDC file. In the present case, skew analysis is referring to design ports, respectively it should use top level pin names. That's not the typical usage of embedded SDC commands. We normally use it to constrain modules, e.g. cut the path in a synchronizer. To generate valid hierarchical names, we have wildcards for the hierachy and a combination of module and signal names to identify source and target.Interesting, I've never seen sdc commands in source code before. Does this change how compilation/synthesis/timing analysis work vs putting everything in the sdc file?
Does this work if this entity/component is buried in deeper in a hierarchical design? I'm assuming it would only consider skew due to logic external to the component?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?