cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
khaalidi
Participant
Participant
2,168 Views
Registered: ‎01-20-2021

Ring oscillator frequency is too high (GHz 😲) and much different with consecutive readings

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 :

  1. 16351469/0.5ms,
  2. 17275163 /0.5ms,
  3. 18198823/0.5ms,
  4. 19122602/0.5ms,
  5. 20046322/0.5ms,
  6. 20970099/0.5ms,
  7. 21926595/0.5ms,
  8. 22850271/0.5ms,
  9. 23774049/0.5ms,
  10. 24697803 /0.5ms

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:

IyF9s.pngQZcwR.png

 

 

 

 

❝Analogue by birth, Digital by design.❞
Tags (2)
0 Kudos
32 Replies
drjohnsmith
Teacher
Teacher
223 Views
Registered: ‎07-09-2009

Just a thought,

why is the clk signal in red on the simulation display ? 

 red normally indicates un defined, 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
avrumw
Guide
Guide
215 Views
Registered: ‎01-23-2009

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.

Avrum

avrumw
Guide
Guide
201 Views
Registered: ‎01-23-2009

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

  • Start with clock_enable=0 and count_enable=0
  • Set clock_enable to 1
  • WAIT for "some time" - long enough for the ring counter to stabilize (again, I will come back to this)
  • set count_enable to 1 to start the counter
  • Wait 0.5ms
  • Turn off clock_enable to stop the ring counter - effectively gating the clock
  • Wait "some time" for the count value to be stable
  • Read the count value 
  • Set count_enable to 0 (to reset the counter and prepare for the next pass)

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")

00000
10000
11000
11100
11110
11111
01111
00111
...

But consider the possibility that the initial state somehow gets to be 00100. Now lets look at the sequence

00100
10010
11001
01100
10110
11011
01101
00110
10011
01001
00100

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...

Avrum