01-25-2021 11:23 AM - edited 01-28-2021 03:45 PM
If a bit file is created already and we program the FPGA once , then power off , and write the bit file again, Will the logic be in the same location(Same Slices and CLB) on the FPGA as the first time?
I'm trying to create a Ring Oscillator based PUF. And first I'm analyzing of the ring oscillator.
It should be a value (between 180MHz-400MHz ) with very small standard deviation with previous readings.
Since the frequency of a ring oscillator is determined by the placement and routing, but also by the Process/Voltage/Temperature (PVT). For process, this means that even if two different FPGAs are programmed with the same bitstream, since they can have different process, they will result in different frequencies.
But my readings are :
I read the frequency 10 time , after each 500us
Even I constrained the Ring Oscillator in pblock, each time I reprogram the fpga, the frequency is very very different and very high (in GHz) on the same FPGA using the same bitstream.
My design is as follows:
02-02-2021 04:08 AM
Just a thought,
why is the clk signal in red on the simulation display ?
red normally indicates un defined,
02-02-2021 07:29 AM
The ring oscillator is inside Datapath, the ring oscillator clock (output) driving 32 flip flops for keeping cycles count,
Well, not really. The ring oscillator is generating a clock. This clock is driving some "synchronous-ish" logic - at the minimum a counter and a state machine. While you can argue wither the counter and state machine are datapath or not, the clock certainly isn't...
As a result, you have two clock domains in your system - the output of the ring oscillator must be treated as a clock domain.
First of all, is the output of the ring oscillator put on a clock buffer? It pretty much has to be - a BUFH would probably be the best choice (assuming this is a 7 series family).
Second, the logic on the ring oscillator needs to be constrained; this should be done with a create_clock on the output of the ring oscillator. This is probably one of the only cases where you would put a create_clock on an internal node (since this is the only way of generating a clock inside the FPGA that is not dependent on some other clock). For the frequency of the clock you should use something faster than the fastest you expect the ring counter to be able to run.
Third, you need proper clock domain crossing techniques for all signals that cross the boundary. The mechanism you have of only sampling the counter values when the clock is stopped is acceptable for these paths, but (after creating a clock for the ring oscillator) you will need an exception on this path - a set_max_delay -datapath_only will be acceptable here.
For the enable signal going from the stable domain to the ring domain you will need a metastability reduction circuit - several back to back flip-flops on the ring oscillator clock domain with the ASYNC_REG property set on them - I would use 3 or 4 flip-flops due to the frequency of the clock. You will also need an exception on the enable signal between the last clock on the stable domain and the first clock of the synchronizer - again a set_max_delay -datapath_only is appropriate.
You will also need a similar synchronizer going back for the signal that tells the main domain that the state machine is in the "STOP" state. The stop signal must come directly from a flop (and not be decoded from the state vector of the state machine) and should go through back to back flip-flops in the stable domain with the ASYNC_REG property set.
Without all of this, you run the risk of corrupting your system.
02-02-2021 11:05 AM
I realize that something I said here is clearly impossible - that you need to synchronize the enable signal to the ring oscillator clock. Obviously that can't be done since your synchronizer would run on the ring oscillator clock which is turned off by the enable - there would be no way to reenable it.
But the enable signal to start your counter clearly must be synchronized.
So clearly you need two enables; clock_enable and counter_enable. The clock_enable would go directly to the ring oscillator, and, by definition, cannot be synchronized. Since there are no flip-flops in this logic, there is no real problem with metastability (at least not due to the clock crossing - ring oscillators have their own potential metastability issues - I will come back to that later).
The counter_enable, though, does need to be synchronized to the ring oscillator domain. In fact, it is more of a "reset" than an enable; when clear, the counter holds the 0 value, and when set to 1, the counter starts counting.
Your whole sequence (from the point of view of the controller on the stable clock) would then need to be
This won't have your "STOP" signal - but there isn't really a mechanism of generating this in a safe way - waiting "long enough" on your stable domain will have to do.
Now for ring oscillator metastability. Ring oscillators are, by definition unstable - that is in fact the characteristic we desire - they do not end up in a stable state; they oscillate. But there is more than one potential unstable state. For example lets take the example of an oscillator with 4 buffers and one inverter. We expect it to go through the following "sequence" (where each line is a "gate delay")
But consider the possibility that the initial state somehow gets to be 00100. Now lets look at the sequence
This is also at least somewhat repeating. It is more unstable than the previous sequence, so may, after some number of iterations fall into the other patten (the isolated "other value" may decay), but it could persist for some time. The result of this would be a frequency that is some multiple (2x?) of what you expect.
In fact, taken to an extreme this could result in a truly metastable state, where none of the nodes are logic 0 nor logic one, but where they are all at some intermediate voltage that is metastable in the analog domain. Again, this would not be likely to persist for long, and would likely decay to one of the less unstable states, but it is possible.
All this to say, it is probably a good idea to wait for your ring oscillator to stabilize before using it.
Alternatively, don't actually turn off the ring oscillator - just gate the output with the clock_enable before using it as the clock for the rest of your stuff on the ring oscillator domain. This way the metastability state of the ring oscillator only needs to resolve once - at power up (well really the end of the configuration cycle). You could even use the CE on the BUFHCE to do this gating...