/ FPGA

Reversible Binary Counter on the Mojo FPGA

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

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.

Michael Earls

Michael Earls

Michael has been a computer nerd since he was ten years old and he begged his parents to buy him a computer for Christmas. In 1982, he was the proud owner of a TI-99/4A. He's been coding since.

Read More
Reversible Binary Counter on the Mojo FPGA
Share this

Subscribe to cerkit