Categories

[AmpeROSE] Field-Programmable Gate Amperose

Hello everyone,

In this post I’d like to elaborate on how AmpeROSE’s FPGA component will operate, in the configuration where it actively participates in the automatic calibration and data acquisition. You may also want to refer to my previous post on this subject.

Automatic Calibration

When we were performing SPICE simulations of our measurement circuit, we observed the following phenomenon that led us away from thinking of implementing the calibration logic as a synchronous state machine (namely, a bidirectional shift register):

  • If the frequency of the clock driving the state machine was too elevated (>1MHz), the output of any comparators going high would very often cause the state machine to go to the corresponding extreme measurement range, even when stopping at the middle range would be the correct thing to do. This, in turn, caused the other comparator output to go high, and the state machine would oscillate. The cause of this exagerated reaction was that the state machine performed the second change in calibration before the rest of the circuit had time to properly react to the first change, and reach a new burden voltage corresponding to the current measurement range.
  • On the other hand, if the clock frequency was reduced to allow for the reaction time of the circuit after a state change (according to our simulations, about 2.5 us on the worst case, owing to the capacitances of the switches in the shunt selector), then a sudden peak in burden voltage that happened to take place just after a rising clock edge would go untreated for a very long time.

There is actually a way to address these issues without abandoning the idea of a synchronous implementation: a state machine clocked at a high frequency, which allows for a short reaction time, associated with a down-counter. Whenever a state change occurs, the down-counter is loaded with a value proportional to the reaction time allowed to the circuit, and further state changes are blocked up until the counter reaches 0. This is the strategy that I followed for implementing our calibration logic in SystemVerilog.

In terms of what exactly is the “high frequency” that should be used to clock our state machine and the counter, we calculated that in most extreme situation that still falls in our expected operating conditions (up to 300 mA drawn by the device under test (DUT), which has a bulk capacitance of 500nF) the DUT’s bulk capacitance should be able to hold the drop in the DUT’s supply voltage under 1V for about 1.66us, so we should, at the very least, react faster than this. Fortunately, Quartus indicates that maximum clock frequency for the current version of the calibration circuit is 111MHz, so we should be able to even approach the reaction time of our hardware comparators (5ns) if this proves to be necessary.

Regarding how the clock will be supplied to the calibration state machine, one of the dedicated clock inputs for the FPGA is connected to a pin of the uC which can be configured as the master clock of a Serial Audio Interface. Such a master clock signal can receive the output of the uC’s PLLI2S phase-locked loop, which we are not otherwise using in our design. This affords us a great flexibility in terms of choosing the clock frequency.

Context bits and SPI

When our external ADC signals that a new measurement is available, the FPGA “takes a snapshot” of the calibration state, of the context bits and of a bit indicating whether the calibration changed since the last measurement (which is then reset), and places it in an 8-bit register.

The “data ready” signal from the ADC is also transported to the microcontroller (uC), which should begin a SPI read of 32 bits. For the first 24 bits, the FPGA simply transports the signals between the uC and the ADC, so the 24-bit voltage measurement can be read. For the last eight bits, on the other hand, the FPGA inserts the bits from the “snapshot” on the MISO line, one per cycle of the serial clock. Thus, the uC receives the complete set of 32 bits corresponding the measurement (24 for the voltage measurement, 5 for the context and 3 for the automatic calibration) by the end of the SPI read.

How to test it all

I put together a straightforward testbench using Verilator and systemC. This testbench has simple systemC threads and methods playing the role of the components of the system (ADC, uC, comparators) which communicate through signals between themselves and to a systemC model of our FPGA, generated by Verilator from the SystemVerilog code.

Periodically, the uC thread determines a 32-bit measurement that should be obtained, and communicates it to the other threads, which cooperate to create the conditions for it to be produced (the ADC thread signals that is has completed its measurement and sends the most significant 24 bits of the 32, the comparators method react to the switch outputs of the FPGA model as if the correct range to be reached is the one described by the two least significant bits of the 32, etc.).

When the adc thread signals that a measurement is ready, the uC thread performs a SPI read, where the FPGA model plays the role described in the previous section. If the 32 bit reading obtained from this transaction is different from what was expected, the simulation returns an error. This testbench is currently passed by the SystemVerilog code.

How to proceed from here

The next immediate steps would be to improve the testbench to make it more realistic, and then to test the SystemVerilog code using a real FPGA and a microcontroller, such as the DE1-SoC boards present in our lab and our development board, respectively. After we receive our PCB, we should strive test it with our actual uC and FPGA as soon as possible.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>