Skip to contentSkip to author details

Reversible Binary Counter on the Mojo FPGA

 FPGA  electronics  binary

After playing around with the Binary counter implementation from a previous post:
Implementing a simple binary counter in the Mojo FPGA IDE, I wanted to make the LEDs display a count down in response to a switch position. I decided to make a reversible slow counter that lets you choose which direction to count in (UP or DOWN).

When you set the direction to UP, the initial value of the counter is 0 and it counts up from there. When the direction is DOWN, the counter is initialized to 255 (MAX value possible with 8 LEDs) and it counts down.

Here is the lucid source code for the slowCounter module:

module slowCounter #(  
      DIRECTION = 1 : DIRECTION  1 || DIRECTION  0,
      RESET = 0 : RESET  0 || RESET  1
    )(
    input clk,  // clock
    input rst,  // reset
    output value[8]
  ) {

  .clk(clk), .rst(RESET) {
    counter slow(#SIZE(25));
  }

  counter ctr(#UP(DIRECTION), .rst(rst));

  always {
    ctr.clk = slow.value[24];
    value = ctr.value;
  }
}

To setup the circuit, I put a switch on a breadboard and connected one end to GND and another to pin 51.

Breadboard setup for reversible counter

I made pin 51 active low (PULLUP) but adding the following to a new Constraints (.ucf) file:

NET "switch1" LOC = P51 | IOSTANDARD = LVTTL | PULLUP;

As you can see, the switch is named switch1.

The developer in me first started out by using two separate counters and switching between them when the switch was toggled:

module mojo_top (  
    input clk,              // 50MHz clock
    input rst_n,            // reset button (active low)
    output led [8],         // 8 user controllable LEDs
    input switch1            // external switch determining which counter to show
  ) {

  sig rst;                  // reset signal

  const UP = 1;
  const DOWN = 0;

  .clk(clk) {
    // The reset conditioner is used to synchronize the reset signal to the FPGA
    // clock. This ensures the entire FPGA comes out of reset at the same time.
    reset_conditioner reset_cond;

    .rst(rst) {
      slowCounter countUp; // default is UP - also valid: directionalSlowCount countUp(#DIRECTION(UP));
      slowCounter countDown(#DIRECTION(DOWN));
    }
  }

  always {
    reset_cond.in = ~rst_n; // input raw inverted reset signal
    rst = reset_cond.out;   // conditioned reset

    led = switch1 ? countUp.value : countDown.value;
  }
}

This means that there are two counters running simultaneously. We see the value of each depending on the state of the switch.

I noticed as I switched between the counters that they had the same pattern, except that where the UP counter had the LED on, the DOWN counter had the same LED off. This led me to Wikipedia where I learned about the ones' complement.

I wrote about this discovery in a previous post: How I accidentally learned something unexpected from a simple binary counter.

To apply what I learned, I completely removed the DOWN counter and replaced the LED output with the following line:

led = switch1 ? countUp.value : ~countUp.value;

By simply adding the ~, I set the value of the LEDs to the inverted value of the counter, giving me the same result as having another counter running alongside it counting in the opposite direction.