First NCL FPGA Test

Last week, I took the NCL 2-rail register and tweaked it to work with the FPGA development environment I have access to at my university. Specifically, I put it into Xilinx Vivado 2018.3 as a RTL module in a block design.

Setup

I used a single 2-rail bit configuration and started with just one register. I tied the inputs to switches and the outputs to LEDs. One thing to note is that the from_next signal used to control the forward propagation of wavefronts was attached to the switch through an RC lowpass filter to de-bounce it.

I had to make some changes to the register component due to Vivado’s restrictions. I wanted to use a block design, so I had to make all the ports std_logic​ or std_logic_vector. I had been using a custom record type (ncl_pair) to group the DATA0 and DATA1 lines. For now, I just split them apart into two std_logic_vector(0 to 0) lines.

Aside on switch bouncing: Normally when a switch is flipped, there is a small amount of ‘bounce’ where the contact opens and closes rapidly for a short time (as the contacts get very close). By running the output of the switch through a lowpass filter, the fast on/off cycles are somewhat flattened, so that the output is only rising, or only falling when the switch is flipped. Otherwise, the register would have tried to pass several wavefronts before I could see it. For anyone duplicating this, I used a time constant of about 50 ms.

Testing

The register behaved as I expected it to from simulation. initially, the data outputs were all off (NULL) with the to_prev signal asserted (requesting data). When I activated one of the switches (the bounce would have technically made it toggle between DATA to NULL for a bit, but when NULL, all inputs would be NULL, so it didn’t break anything). As I was still requesting NULL from the register (the from_next switch was left de-asserted) the output from the register was still NULL and it was requesting DATA. When I toggled the from_next input to the register to a request for DATA, it outputted the value I had inputted (DATA0 or DATA1 depending on the test case) and switched to requesting NULL. I de-asserted the data line input and set the from_next request to NULL causing the outputs to switch to NULL.

Extension

With this success, I wanted to see if a slightly more complex test would work as well. I added 4 more registers (5 total). The design was still using one 2-rail bit, but now had the capacity to ‘store’ some wavefronts internally. Remember that a sequence of NCL registers can pass a NULL/DATA wave all the way through or can have several stored (approximately N/2) while they wait to pass them on. This held up in testing.

All the same inputs/outputs were used, but the from_next switch was going into the last register, the to_prev LED cam out of the first register, and the data inputs/outputs were connected to the first/last register. I used the following test pattern with NULL waves between each:

DATA0, DATA1, DATA0, DATA0, DATA1, DATA1

I ran this several times with different orders of adding and removing data from the pipeline. E.g. the first time, I kept adding DATA/NULL at the input as long as the to_prev line kept toggling and removed DATA by toggling the from_next line when the pipeline was full. In the next run, I first added 2 DATA waves, then extracted 2 DATA waves, and so on.

I was able to get the same behavior I saw in simulation, which was very exciting.

Moving Forward

This test has given me some confidence that I can successfully map the NCL components to an FPGA. I plan to move forward by building a Vivado IP library. As I go, I will be making a VHDL library for 2-rail NCL. During my long break from working on this, I took a course that gave me experience with these tools designing hardware modules and using FPGAs to implement systems. During that class, I learned that implementing components structurally has its place, but is often a very slow way to design. I will be working on making a more expressive VHDL library than what I have been working with in previous posts (entirely structural). I will be discussing this more in future posts.

To summarize, I have two sub-projects to work on that are highly connected:

  1. Building an expressive VHDL library for Null Convention Logic
  2. Creating a Vivado IP Library for the components from (1).

The git repository is currently in a somewhat inconsistent state as I am re-doing the library and many components need to be re-done.

A Fun Little Embedded Project

Background: My roommates and I have been playing a game called Earth Defense Force 5 on PS4 together. The gameplay centers around destroying giant bugs (ants, spiders, etc.) and invading aliens. All of the equipment is obtained through random drops from enemies, including persistent armor boosts. I usually play as a character called an Air Raider who can call in air strikes and place auto-turrets.

One of my roommates and I were working on farming the armor boosts and weapons on a level where the enemies’ only attack is to roll at you, knocking you over and doing some damage. Individually, these enemies are really easy, just shoot them to knock them out of their roll, but when facing a group, the only way to stay on your feet is to get inside a building where they can’t reach, but you can shoot out. As an Air Raider, I usually sit near the entrance and throw turrets out the door.

The Problem: Throwing turrets out the door of a parking garage is very effective, and leaves you with a lot of extra time, but you have to replace the turrets every minute or so, so you can’t leave.

The Solution: Attach a micro-servo controlled by an arduino to the front of the controller. Have the servo deploy the turrets every 75 seconds and go do something else for a few hours while the loot piles up.

ControllerActuator[edit].jpg

Details: In EDF5, the fire/activate button can be held between reloads, and the weapon will fire/activate whenever possible (at least for some weapons, including turrets). I used a rubber band to hold down the fire button continuously. For turrets, the left bumper must be pressed separately each time to deploy them (the fire button throws a suitcase-looking thing out and the L1 button makes it unpack into a turret). I use the following code to move the servo:

#include <Servo.h>

Servo L1;

void setup() {
  L1.attach(3, 500, 2500);
}

void loop() {
  L1.write(10);
  delay(500);
  L1.write(0);
  delay( (75l * 1000l) - 500l);
}

The 75 is the number of seconds between attempted activation. Initially, I had it set to 10 seconds, but the servo was making noise while we were watching a movie, so I changed it to just larger than the time the turrets are alive + the time required to reload and throw them out the door.

As for the mechanical mount, I just cut the string off of a couple extra lanyards we had lying around. I was able to get it so that the controller can be used normally with the servo unplugged from the Arduino. This lets us get set up in the building before farming.

Summary: This project took about 1 hour for the first functioning prototype, though some tuning was done after. Most of that time was spent trying to get my instance of Code Composer Studio to work with the MSP432 Launchpad I had on hand (which I hadn’t used in a while). I then switched to another arduino which I believe has an electrical fault, and finally settled on the Arduino Uno. Getting everything working on the Uni took 20 minutes