Categories

[SpiROSE] FPGA, the end is near

Hello everyone, I hadn’t posted since Christmas, so here I go ! Since the expedition (no pun intended) of the PCBs to the manufacturer, I kept mainly focused on FPGA development including source code and tests for various modules, which allowed us to correct many bugs we hadn’t seen so far. I will detail some features later on.

SPI slave

The SPI slave implementation is complete. The protocol for sending commands from the SBC to the FPGA is simple, we have a header command byte, followed by as many bytes of data as needed. Let’s have a quick summary of the different possible commands.

  • Enable/Disable the RGB module: we need to tell the RGB module, the one that writes into RAM the data the FPGA receives from the parallel RGB, to start or stop writing in RAM, since we only want to display relevant data. As the RGB module is the first module in the chain, this command starts everything.
  • Configuration command: change the configuration of the drivers. The command may be issued at every moment, the driver controller module can handle the reconfiguration even when it was streaming data to the drivers.
  • Request rotation information: The FPGA should be able to send its the rotation position (the slice we are at), as well as the speed of the motor.

But how can we get the position of the rotating part ? Let’s look at the Hall effect sensors !

Hall effect sensors

Since we finally use Hall effect sensors instead of the rotary encoder that was originally wanted, I did the module that tells the driver controller and the framebuffer when we enter a new slice, to begin displaying for the current slice.

The issue is that we have only two Hall sensors that are opposite one to another and 256 slices per turn. So we need to infer the slice we are at given only 2 positions, over the 256 for a turn, that we are absolutely sure of. Ideally, the synchronization signal is generated without knowing in advance the motor speed, so it must adapt in “real time” to it. An idea, since we have 128 slices per turn, is to estimate the slice positions of the current half-turn given the number of cycles that it took to make the previous half-turn. In a word, we constantly correct the duration of a half-turn to fit the speed variations of the motor.

The Hall effect sensors we chose are hysteresis sensors which, in their case, means that the output of the sensors is set low when the magnetic flux is beyond a certain threshold and is kept low until the flux reaches a second threshold that is lower than the first one. This provides an integrated anti-bounce mechanism. We thus only need to detect the negative edge of the sensor output to have a “top” to synchronize onto. Between the 2 tops of the opposite sensors, we count the number of cycles and we compute (right shift)  the duration for each slice for the following half-turn, sending the synchronization signal accordingly. To give a few figures, if we have 15 rotations per seconds, around 15600 clock cycles are elapsed between 2 slices.

 

For the upcoming week, while we are waiting for the components to be shipped and since all FPGA modules are complete, we will build end-to-end tests with all of them, hoping that all the tests we have implemented for each modules were thorough enough to spot all possible bugs, for it to be ready for a quick deployment on the actual board.

See you soon !

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

[AmpeROSE] Recalibrating our Architecture

Hello, everyone!

In this post, I’d like to discuss a final significant change that our architecture for AmpeROSE underwent in the end of December.

The calibration problem

As you may recall, a fundamental task for AmpeROSE is to perform “automatic calibration”, controlling in real time the value of its shunt resistance, which is used to convert the current drawn by the device under test (DUT) into a tension that is amplified and measured by an ADC. Each possible value for the shunt corresponds to a range of current values that may be effectively measured with it. Having an inadequate shunt value at a given time can cause the following negative consequences:

  1. If the current is too small for the shunt (there’s a larger available value for the shunt that we should be using), we lose precision.
  2. If the current is too big for the shunt (there’s a smaller available value for the shunt that we should be using), we lose measurements, as the reading will just be stuck at the maximum value for the measurement range corresponding to the current shunt. More importantly, we risk having a brownout on the DUT if the burden voltage becomes large and the situation persists for longer than the DUT’s power supply circuit can handle.

You may consult these two previous posts (1, 2) to review our process for arriving at the automatic calibration scheme we initially based our schematics and PCB design on. Here is a high-level view of it, with the calibration circuit in the center:

In this configuration, hardware comparators are used to generate signals that indicate whenever the amplified shunt voltage has surpassed the upper limit for the current measurement range (VIN>VON), or gone below its lower limit (VIN<VOFF). A third comparator determines whether the burden voltage (voltage on the shunts) has surpassed its maximum allowable value, its output being ALERT. These outputs are fed into a circuit composed of discrete ICS (NAND and NOT gates, SR latches and delay blocks) that implements the calibration logic and generated two outputs (SW1 and SW2) which contror transistor switches which may be used to connect and disconnect resistor in parallel with the shunt, thus changing its value.

In this configuration, it is the microcontoller’s job to read each mesurement from the ADC when it’s ready, through SPI, and sample values of the calibration outputs and of the context bits to associate with the measurement. It also determines the reference voltages for the comparators using its digital to analog converters and controlling a potentiometer.

In the course of the elaboration of our printed circuit board (PCB), this approach for the calibration circuit proved to be problematic, in particular the placing and routing of the different ICs, some of them containing several logic gates that would , not to mention the difficulty of reasoning about the timing of the logic signals. More importantly, the calibration logic would be locked into what is determined by the discrete ICs placed on the PCB, and would be impossible to correct if tests with the finished PCB revealed that corrections would be in order.

In view of these issues, our supervisors encouraged us to consider two alternative approaches that would grant us more flexibility and could be implemented more expediently:

Calibrate using a FPGA

This approach uses a small field-programmable gate array – FPGA (small in terms of package size/pin numbers, and in terms of number of interal logic cells) to implement the calibration logic and generate the SWx outputs. The calibration circuit would be described using a hardware description language such as SystemVerilog, which we have employed often in our embedded systems education, and could be corrected by reprogramming the FPGA through JTAG.

Additionally, we envision using the fpga to read the ADC measurement and the context bits, and prepare and transmit the complete measurement word to the microcontroller though SPI.

Calibrate using the microcontroller

In this approach the outputs of the comparators would be connected to microcontroller pins and would generate fast interrupts, whose service routines would implement the calibration logic and update the shunt control signals.

This design has the advantage of simplifying even more the PCB, and would take advantage of the relatively powerful microcontroller we’re using in our design. On the other hand, performing the calibration does represents a significant burden on microntroller if compared with the circuit with the FPGA, especially because it will also be managing an Ethernet connection.

And the winner is…

Neither! I mean, both! Our PCB will contain a MAX3000A fpga with 44 pins and 64 macrocells, but the components have been placed and routed in such a way that it will be possible to implement either of the designs present above in the PCB, just by reprogramming the microcontroller and the FPGA. The calibration using the FPGA will work essentially as described previously, while for the calibration using the microcontroller, the FPGA will be programmed to simply transmit signals transperantly between the microcontroller and other components in the board.

This strategy will allow us to evaluate the feasibility of both strategies, with the goal of determining which would be more interesting for a more mature version of AmpeROSE. I’m currently working on the SystemVerilog code for the calibration using FPGA, which should then be simulated and tested so we can be confident it’s likely to work when we receive our PCB.

[SpiROSE] Driving the LED Drivers with the FPGA

This week was dedicated to writing the SystemVerilog code for driving the TLC5957 LED drivers. The first issue was to get some SystemC tests ready to use. While the tests where being written by someone else, I started writing the SystemVerilog code. Now the code is ready and have been tested on the drivers, but the timings are not correctly set, so the drivers are being incorrectly driven and behave pretty randomly.

The FPGA development have been delayed in order to get the schematics ready quickly. During the same time a more precise analysis of the available encoders have been done, including the mechanical restrictions, connector, communication protocol, etc.

Next week will be dedicated to the shematics and datasheets reading.

[SpiROSE] Mechanical construction, various tests and FPGA design

This week was full of various little tests and tryouts: Power input, Motors, LEDs,  LED Drivers, etc. It was also a week used for designing the FPGA internal architecture and final adjustments for mechanical construction.

 

Mechanical construction

The mechanical design have been updated due to the lack of some materials in our distributor. The design have been checked and validated back with the mechanics, and the materials have been ordered. The mechanics will start the construction on next week. The motor and his controller have been ordered too.

The updated mechanical design is available here.

FPGA Design

The FPGA architecture have been finished, including clock domains, I/O count, main modules definition, RAM layout, data input specifications, synchronization constraints and drivers control logic. The chosen FPGA (Cyclone III with 40KLE) have been validated to work with this architecture and next week will be used for starting developing on it, to check the timing requirements. The rotative base station schematics can now start.

A note about RAM: last week a basic estimation was done to see if an FPGA could internally store a whole 3D image, but the calculus was erroneous, which leaded us to think that the Cyclone III FPGA was capable of it. The reality is that it can store up to 18 ‘slices’ (we call these micro-blocks), so synchronization is needed.

 

Various experiments

The LED drivers have been soldered on breakout board, as for the LEDs, and some motors we had have been tested. The goal was to validate our choice of components. Due to mechanical construction starting soon, we ordered the final motor and controller just after the tests in order to have it when the construction starts.

 

Now the schematics of the rotative base station are ready to start, and the FPGA code have to be written.

See you next week for more details!

[SpiROSE] Continuous integration and the FPGA story

This week, we put a conscientious effort in making the project eventually start its journey in a more peaceful way. We were quite pressured by the choice of the FPGA and SBC as it was impeding the rest of the project and its existence. Now it has been fixed, we can really start to think about the next tasks: developing software and tests.

Even if it is still not perfect, we spent some time in configuring the continuous integration, designing the different steps for each piece of our software. As I spent most of the week doing code review (and FH work about happiness at work, which made me happy about ROSE), I highlighted some points where it failed, like some commits accepted by the tests although some files were missing, or incorrect style not failing the CI, or that the file organization in some subprojects weren’t practical for the integration of tests.

Two things are still missing. On the first hand, we have to save the artifacts so as to show demo easily, but we need more code so that it is useful and easy-to-follow manuals about how to use these artifact (flashing, running configuration, etc.) We expect to have this quickly for the LCD screen and renderer demos. On the other hand, we still don’t have very precise tests on our software, but things are to change quickly as we are writing simulation code in SystemC for the FPGA.

The idea, given by our teachers, is to use Verilator, a SystemVerilog-to-C++-library compiler, to put our FPGA controller into an environment with a simulated SBC input and simulated drivers so as to produce an output image. We will be able to cross-check the protocol used by the drivers in poker mode and check timing constraints. The SBC will generate sample image in the future and we will be able to check that it is correctly rendered by the FPGA.

To use Verilator, we have to:

  • compile each .sv file into a library (or only source/header files)
  • create a top file in SystemC which integrates each piece that we connect to the FPGA
  • monitor the input and output of the FPGA through SystemC stub modules

Eventually, we have to find a way to do the same on the real FPGA so as to have host integration tests.

We received the LED and the driver on Friday, so we didn’t try another experiment of the POV effect, but it will come quickly this week.