Magellan – a hardware monitor/debugger

Part 1 – Seven segment display

The Basys 3 board has a plethora of interactive resources: push buttons, switches, LEDs, and a four-digit seven-segment display, among others.

In this series of articles, we will describe Magellan. Magellan is a hardware monitor/debugger which we will put to use for debugging our designs.

In my experience, the integration part of a product is lengthy and many times, painful. We need as many tools as we can allow ourselves to tackle the bugs and issues that, more often than not, will arise during the bring-up, integration, and support, of our FPGA-based product.

Magellan is a tool that is completely hardware based. There is no microprocessor and no software needed to put it to use. On the other hand, to achieve the flexibility we need for an efficient debug tool, we need configuration capabilities. We will achieve this by using many methods that we will see in the following articles of this series.

In this first post, we describe the four-digit, seven-segment driver. We will use it to represent a four-digit hex value encoded using the Basys 3 sixteen switches. Later on, we will use it to get and set values of registers.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity top is
	
  port (
	CLK				: in  std_logic;
		
	-- inputs 
	SW				: in  std_logic_vector(15 downto 0);
	
	-- outputs
	LED             : out std_logic_vector (15 downto 0);
    SSEG_CA 		: out std_logic_vector (7 downto 0);
    SSEG_AN 		: out std_logic_vector (3 downto 0)
  );
end top;


architecture rtl of top is
  component bin2_7seg is
     port (
        data_in:    in std_logic_vector (3 downto 0);
        data_out:   out std_logic_vector (6 downto 0)
     );
  end component;
  
  signal counter_reg  : std_logic_vector (17 downto 0);
  signal disp_drv     : std_logic_vector (3 downto 0) := "1110";
  signal disp_dig     : std_logic_vector (6 downto 0);
  signal disp_data_in : std_logic_vector (3 downto 0);

begin 
  LED <= SW;
  SSEG_AN <= disp_drv;
  SSEG_CA(6 downto 0) <= disp_dig;
  SSEG_CA(7) <= '1';   -- Digital point always off
  
  counter_pr: process (CLK) 
  begin 
    if (rising_edge(CLK)) then
      counter_reg <= counter_reg - 1;	-- decrement counter
      
      -- change active seven-segment digit
      if (counter_reg = 0) then
        if (disp_drv = "0111") then
          disp_drv <= "1110";
        else
          disp_drv <= disp_drv(2 downto 0) & '1';
        end if;
      end if;
    end if;
  end process counter_pr;
  
  bin2_7seg_i : bin2_7seg
  port map (
    data_in  => disp_data_in,
    data_out => disp_dig
  );
  
  disp_data_in <= SW(3 downto 0) when disp_drv = "1110" else
                  SW(7 downto 4) when disp_drv = "1101" else
                  SW(11 downto 8) when disp_drv = "1011" else
                  SW(15 downto 12);
  
end rtl;

All the sixteen board LEDs are put into use, and each one reflects the state of its neighbor switch.

The Basys 3 board uses a time-multiplexing strategy to reduce the pin count needed to drive the seven-segment digits. If they had directly connected each seven segment to a dedicated pin, they would have used 8 x 4 = 32 pins (seven pins for each segment, an additional one for the decimal point, multiplied by four digits). Using the multiplexing strategy, only 8 + 4 = 12 pins are needed. This is possible since, by rapidly scanning the values for each digit, our eye persistence of vision will give us a complete view for all values. If the scanning was slow, we would see flickering and/or dimmed digits.

We use an 18 bits counter so the time each display will be lit is in the order of 2ms. The exact calculation is 2*218 / 100*106, giving us a value of 2.62 ms.

The counter_pr process not only updates this counter, but also the disp_drv variable that is used to sequentially enable each seven-segment digit.

Image credit: Basys 3 reference manual – Digilent

Finally, the digits data must be multiplexed together with the enable signal. This is done on lines 62-65.

The design instantiates a bin2_7seg component, which can be found in the Code Snippets section.

You can find the sources for this project on GitHub

Scope capture of the enable signal of one of the digits, showing it is close to the calculated value (2.62ms)

Go to part 2 of this tutorial

One thought on “Magellan – a hardware monitor/debugger

Leave a Reply

Your email address will not be published. Required fields are marked *