Electronics > FPGA

Clock Enable and timing constants

(1/5) > >>

Rainwater:
I have avoided using all but clock speed timing constants. But now I want to use a `clock enable` pin to do some more complex logic that just cant be done in one clock cycle.
So now I have a lot of red setup violation in my timing report(103) and want to know if there is an easier way to write these constants.
really simple, my external clock is 27mhz, feeds a rpll with a 200.6 mhz output(clk_200)
attached to clk_200 is a counter and register, for every 8 'clk_200' ticks, I get one tick on 'ce_25mhz'

My first attempt was to write
--- Code: ---set_multicycle_path -through [get_nets {ce_25mhz}] -setup -end 8
set_multicycle_path -through [get_nets {ce_25mhz}] -hold-end 7
--- End code ---
My thinking is, the toolchain will see the constrant on the ce_25mhz and it will carry through into the modules using it.
this didn't work. the violation count went to 99.

So my next step was to breakout the pen and paper, and go through all the verilog using CE and record the registers that are clocked on CE.
after writing a constant containing 35 registers, I now pass timing.

This can not be the proper way. this process would be worth automating. surely I'm mucking it up.
Any advice would greatly appreciated.

BrianHG:
I'm not an expert, but, making a clock enable input have a 7 to 8 cycle clock delay from your 27m reference would be nearly impossible to properly timing fit in your design since the 7-8x slower than 27mhz delay window would need to be achieved in async logic or IO pin delay on the FPGA fabric.  This is a huge delay.  For multicycle, the most I've used in the past was 2-1 for transferring data from a 400mhz domain to a 300 or 200 mhz domain.

What I would do is have a single 'DFF' running at your high MHZ system speed clock in/sample your CE pin at your 200.6 mhz, then the output of that DFF is used to enable you 200.6mhz code.

The only timing .sdc entry should be the input pin's relative setup & hold with reference to your 200.6mhz clock.

Then, I would make a 'falsepath' from the input pin to the 27mhz clock so that the compiler ignores attempting to time constraint that input with the clock going into my PLL source.

Note that this is how I would approach this issue.

nctnico:

--- Quote from: Rainwater on May 25, 2024, 10:45:29 pm ---I have avoided using all but clock speed timing constants. But now I want to use a `clock enable` pin to do some more complex logic that just cant be done in one clock cycle.
So now I have a lot of red setup violation in my timing report(103) and want to know if there is an easier way to write these constants.
really simple, my external clock is 27mhz, feeds a rpll with a 200.6 mhz output(clk_200)
attached to clk_200 is a counter and register, for every 8 'clk_200' ticks, I get one tick on 'ce_25mhz'

My first attempt was to write
--- Code: ---set_multicycle_path -through [get_nets {ce_25mhz}] -setup -end 8
set_multicycle_path -through [get_nets {ce_25mhz}] -hold-end 7
--- End code ---
My thinking is, the toolchain will see the constrant on the ce_25mhz and it will carry through into the modules using it.
this didn't work. the violation count went to 99.

So my next step was to breakout the pen and paper, and go through all the verilog using CE and record the registers that are clocked on CE.
after writing a constant containing 35 registers, I now pass timing.

This can not be the proper way. this process would be worth automating. surely I'm mucking it up.

--- End quote ---
I don't think you are mucking things up. I don't recognise the timing constraint syntax you are using but it might be possible to group all the registers enabled by the CE line and have a single constraint. An alternative approach is to create a lower frequency clock from the PLL and use that to clock the lower speed logic. Typically the constraints will be generated automatically because the routing software now knows the relationships between the clocks by looking at the PLL configuration. Or at least you can create a constraint for the lower speed clock. The advantage of this approach is that you can add / remove logic from the low speed clock domain without needing to change the constraints. The CE line becomes a strobe to kick the lower speed logic into action.

Rainwater:
my apologies for not explaining this better. The external clock is only being used to drive the pll. everything else is coming from the 200mhz pll output. this output is how im generating a 25mhz CE pin. the external clock is not being used for any logic. just the pll

I have a clk_200 domain, which runs a few modules. (sram,  external input synchronizers, and soon some dsp's)
I want to use a clock enable pins( CE pin ) to drive other logic that doesn't need that high speed. such as a UART, some 2Khz PWM and a few SPI interfaces that max out at 2Mhz.

All the reading I have done says there are two solutions to this problem. #1 is to generate another clock domain, and #2 is to use a CE pin.
There are pros and cons to each solution. Solution #2 is better suited to my needs and design.
My device does not have dual port ram.
Solution #1 would complicate access to/from the FIFO's from the slow clk to the fast clk, access to the read or write enable pin of the fifo would span multiple fast_clock ticks, resulting in multiple reads/writes with each slow clock access. and requires a complex setup to solve(edge detection) and over complicates burst writes/reads from the slow clock domain.

Solution #2 does not have this problem, I can toggle pins as fast as my clk speed at the cost of routing resources for an addition CE pin with a high fanout

When I say pins, I am not talking about external pins, but ports within the verilog modules.

I have been able to greatly simplify the constant, by adding a prefix to the registers used in the multi-cycle path, then using wildcards to search for these nets and apply the MCP.
https://cdn.gowinsemi.com.cn/SUG940E.pdf is the timing constraint users guide for my device.

BrianHG:
If the CE pin is just a system enable, not a logic timing critical point which must meet the 5ns 200Mhz timing at every endpoint in your desing, then just use the 'set_false_path' for that net.  Your compiler will make everything else routed as timing critical and just route the CE so that it just gets there whenever.

This means it will be easier for you compiler to focus on the important timing elsewhere.

Looking at one of my .sdc files here:
BrianHG_DDR3_DECA.sdc (Scroll down to the  'set_false_path' section...)

You can see I even use 'set_false_path' between my Max 10's 50mhz clock input pin to the PLL source input and all my core DDDR3 core clocks and VGA clocks.  Without this exclusion, the Quartus compiler would try to not only sync the PLL core clock with it's driven IOs, but also with the reference source 50mhz input pin and my VGA clock source and it's PLL.  Cutting these paths means I dont care about the PLL's timing and uncertainty between it's input and core with IO, I only care about the PLL's core outputs and it's driven IOs making it easier for Quartus to not have to route around an additional timing constraint of the 50MHz source which I only use as a reference for the system PLL.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod