Go Board Notes    Peter Halverson Last update 3/15/2020 http://halverscience.net/index.html

NanLand Go Board Notes, including how to setup Lattice iCECube2 on Linux Ubuntu 16

Link to latest notes on Google Docs:  https://docs.google.com/document/d/17WlW-UdGRF7cPRGuRcYEWLN411LGdGJSxkyKU7m-21c/edit?usp=sharing

These are Halverson's personal notes. They are unedited and there is no guarantee of accuracy.  Use at your own risk. I am making them available to you because they might actually be helpful.  If they are helpful, I would really appreciate a "thank you". 

Link to the live version of these notes:  https://docs.google.com/document/d/17WlW-UdGRF7cPRGuRcYEWLN411LGdGJSxkyKU7m-21c/edit?usp=sharing

Go Board Index Page  https://www.nandland.com/goboard/index.html     **** Start here

NandLand home page: https://www.nandland.com/

Go Board home page:  https://www.nandland.com/goboard/

GoBoard basic specs:
----Clock = 25 MHz
----Voltage = 3.3 V              
----Memory: 64kBits    Number of RAM4k Blocks: 16
----FPGA Device Family = iCE40,  Device = HX1K, Device Package = VQ100
----The "Home page" for the iCE40 FPGA is here:  http://www.latticesemi.com/Products/FPGAandCPLD/iCE40.aspx
The "Application Notes" link at the bottom of the page is useful.

-----------------------------  Communication with the Go Board via USB.  ------------------------------
I got this info from the comments section of the You Tube Video  "Nandland Go Board - Watch This When You Receive Your Board" at https://www.youtube.com/watch?time_continue=123&v=wWMIY9kjlJ0

FOR LINUX USERS. For recent linux (over Ubuntu 11.10, kernel 3.0.0-19) (mine is kernel 4.4.0-140-generic based on ubuntu 16.04) you just need: 
1. sudo apt-get install gtkterm 
2. connect your go-board 
3. sudo gtkterm -p /dev/ttyUSB1 -s 115200 -b 8 -t 1                <----------- YES ********

You DO NOT NEED to install any drivers; they already come with the kernel and they recognize the go-board (FTDI serial port). 

BOTH ports /dev/ttyUSB0 and dev/ttyUSB1 are seen by: 
dmesg | grep FTDI 
that answers: 
[ 5997.028880] usb 2-3: Manufacturer: FTDI 
[ 5997.029520] ftdi_sio 2-3:1.0: FTDI USB Serial Device converter detected 
[ 5997.030774] usb 2-3: FTDI USB Serial Device converter now attached to ttyUSB0 
[ 5997.031048] ftdi_sio 2-3:1.1: FTDI USB Serial Device converter detected 
[ 5997.031462] usb 2-3: FTDI USB Serial Device converter now attached to ttyUSB1 

BUT only /dev/ttyUSB1 worked for me.

------------------------- Continuing with setting up the programming environment  --------------
I am now using the info here: https://www.nandland.com/goboard/setting-up-environment-icecube.html

Lattice Semiconductor's web page for the IceCube2 FPGA programming tool: http://www.latticesemi.com/en/Products/DesignSoftwareAndIP/FPGAandLDS/iCEcube2.aspx
(Works on Windows and on Linux)

Downloading for Linux, 361 Mb, iCEcube2setup_Sep_12_2017_1708.tgz

Unpack and then right-click > run the iCEcube2setup_Sep_12_2017_1708 file.

It asks for the IceCube2 license file.   Get it from the Lattice web site > products> Software Tools > IceCube2 > Licensing > IceCube2 Free License.
It asks for my computer's mac address.  In a terminal, I type
The first line of output says 
eth0      Link encap:Ethernet  HWaddr f4:4d:30:66:91:b9
and the mac address is the "HWaddr" above.  (It wants the colons replaced with dashes.)
It now emails the license to me.   (I decide to install the license later)

When I start IceCube2, it looks but fails to find the license file here:  /usr/local/flexlm/licenses/license.dat

So I create the directory and put the license.dat file in there.  (I had to use "sudo")

The IceCube2 program is in ~/lscc/iCEcube2.2017.08/ICEcube2    It works!

(Note that there is a "LicenseSetup" program there that I guess would move the license to where it belongs automatically.)

I now get the Lattice Programmer tool from here:

I click "Programmer Standalone 3.11.1 64-bit for Linux"   and start the 62 Mb download.

I extract the file and it seems to have unpacked a file intended to go into /usr/local  
Wait and see for now.

I am now here:  https://www.nandland.com/goboard/your-first-go-board-project.html

Create a file Switches_To_LEDs.v using Text Editor and save to ~/Documents

Create a project.  My project directory is ~/Documents/GoBoard_work.  

Project settings "In the New Project" window that need changing are
Device > Device Family > iCE40
            > Device > HX1K
            > Device Package > VQ100
IOBank Voltage(V) > topBank > 3.3                           left, bottom, right also 3.3

Get constraints file. Go_Board_Constraints.pcf   Put it in my project by clicking P&R Flow > Add P&R Files > right-click Constraints Files

ADDED NOTE:  You eventually need Go_Board_Clock_Constraint.sdc, which you put into the project by opening Synthesis Tool > right-clicking Constraints Files

Try running Synthesis, and I get error: Child process exit with 2.

I tried to fix by reinstalling license (using the license installer) and running the setup and selecting "repair" but that didn't help.  Finally I found in the discussion at the bottom of the page this solution:
          I tried a test project but failed to pass synthesis (I always got
          'error 2' on both Windows and Linux).
         The solution to this problem is as follows: In Lattice iCEcube2: right-click 
         on "Synthesis Tool". 
          A pop-up appears, showing "Select Synthesis Tools...". Click on the pop-up 
         and select "Lattice LSE". This changes the command-tree to 
         "Run Lattice LSE Synthesis" making it finally possible to create a bitstream.             

******** YES *******
Now Synthesis works.

--------------------- Getting the bit file into the Go Board ---------------------------------------

I couldn't get the Diamond programmer to work.  Use the open-source "IceStorm" programmer instead.

(The Diamond programmer download is a .rpm file, which tells me it is a RedHat or Centos type file.  "Alien" is supposed to be able to install such files, but the installed software is not working.)

Instead, I will try to use IceStorm.  (Suggestion in the discussion)

Installing prerequisites (this command is for Ubuntu 14.04):
sudo apt-get install build-essential clang bison flex libreadline-dev \
                     gawk tcl-dev libffi-dev git mercurial graphviz   \
                     xdot pkg-config python python3 libftdi-dev \
                     qt5-default python3-dev libboost-all-dev cmake

Installing the IceStorm Tools (icepack, icebox, iceprog, icetime, chip databases):
git clone https://github.com/cliffordwolf/icestorm.git icestorm
cd icestorm
make -j$(nproc)
sudo make install

I want to use iceprog invoking it with the bitfile which was previously created
iceprog Switches_To_LEDs_bitmap.bin

but I get an error:

Can't find iCE FTDI USB device (vendor_id 0x0403, device_id 0x6010 or 0x6014).

But THIS Works:                    <-------********** YES **********
sudo iceprog Switches_To_LEDs_bitmap.bin    And the code programs the FPGA OK!!

------------- How to program the Go Board without having to use "sudo" ----------------------
I found advice here https://stackoverflow.com/questions/36633819/iceprog-cant-find-ice-ftdi-usb-device-linux-permission-issue

sudo pico /etc/udev/rules.d/53-lattice-ftdi.rules
I put this in the .rules file:
ACTION=="add", ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", MODE:="666"
After fixing that file, and disconnecting and reconnecting the device, you should be able to program the FPGA as normal user without sudo.     <-----*********** YES, it works

 ---------------------- Try installing the rest of the IceStorm system. ----------------------

Note:  As far as I can tell, the rest of IceStorm is not needed for using the Go Board.  OK to skip.

I ran into a problem where cmake was looking for "Eigen3"  
Solved with this command:
sudo apt-get install libeigen3-dev

Making the rest of IceStorm:

git clone https://github.com/cseed/arachne-pnr.git arachne-pnr
cd arachne-pnr
make -j$(nproc)
sudo make install

git clone https://github.com/YosysHQ/nextpnr nextpnr
cd nextpnr
cmake -DARCH=ice40 -DCMAKE_INSTALL_PREFIX=/usr/local .
make -j$(nproc)
sudo make install

Simple user manual for IceStorm:

------------------------- Simulation using EDA Playground ----------------------
Login:  Use my work address,   PW="the usual K"

------------------------- Go Board's PMOD connectors ----------------------------
Looking at the connector, into the holes you see two rows of 6 holes:
oooooo          1st row
oooooo          2nd row

The first row, which is for PMOD module 1, going left-to-right is
Pin 6, VCC (+3.3 V)
Pin 5, Ground
Pin 4, io_PMOD_4  (usually a clock signal to the module)
Pin 3, io_PMOD_3  (can be data or other signal)
Pin 2, io_PMOD_2  (usually data to or from the module)
Pin 1, io_PMOD_1  (usually a select or "activate" signal, active low, to the module)

The second row, which is for PMOD module 2, going left-to-right is
Pin 12, VCC (+3.3 V)
Pin 11, Ground
Pin 10, io_PMOD_4  (usually a clock signal to the module)
Pin   9, io_PMOD_3  (can be data or other signal)
Pin   8, io_PMOD_2  (usually data to or from the module)
Pin   7, io_PMOD_1  (usually a select or "activate" signal, active low, to the module)

------------------------- Go Board's VGA connector ----------------------------
Looking at the connector, into the holes you see two rows of  holes:
ooooo          1st row (Five holes)
 ooooo         2nd row (Five holes)
ooooo          3rd row (Five holes)

The first row, going left-to-right is
Pin 5, Ground
Pin 4, nc  (no connection)
Pin 3, Blue signal (connects to o_VGA_Blu_0, _1, _2 via resistors)
Pin 2, Green signal (connects to o_VGA_Grn_0, _1, _2 via resistors)
Pin 1, Red signal (connects to o_VGA_Red_0, _1, _2 via resistors)

The second row, going left-to-right is
Pin 10, Ground
Pin   9, nc
Pin   8, Ground
Pin   7, Ground
Pin   6, Ground

The 3rd row, going left-to-right is
Pin 15, nc
Pin 14, Vertical sync signal, o_VGA_VSync   (I sometimes use this to trigger the oscilloscope)
Pin 13, Horizontal sync signal, o_VGA_HSync
Pin 12, nc
Pin 11, nc

Note that the sync signals, pins 14 and 13 are a convenient place output
an oscilloscope trigger signal, assuming you're not connect a VGA display.

------------------------- pmod "AD1" ADC from Digilent ----------------------------
"Home" page for PmodAD1:

"Sales" page:
Two channels, 1 Msample/s each channel.  500 kHz low pass anti-alias filters.

I got the AD1 module to work on an Arduino.  Info here: https://www.hackster.io/56479/using-the-pmod-ad1-with-arduino-uno-38dd4a
 In the process I learned that the optimum clock frequency is 20 MHz, and the 25 MHz clock on the GoBoard is inconvenient.  However, the Lattice ICE-40 HX1 on the GoBoard has an internal PLL that should be able to derive 20 MHz from the 25 MHz.

Background info on the SPI serial data format used by Pmod devices, including the AD1:
More info here: https://reference.digilentinc.com/learn/programmable-logic/tutorials/pmod-ips/start

J1 Pin connections to the controller or FPGA:
Pin 1     CS      Chip Select   
Pin 2     D0       Data out for 1st ADC       
Pin 3     D1       Data out for 2nd ADC   
Pin 4     CLK     Serial Clock       
Pin 5     GND                
Pin 6     VCC                

J2 pin connections for the analog output:
Pin 1   A0   Analog in for 1st ADC
Pin 2   GND
Pin 3   A1 Analog in for 2nd ADC
Pin 4   GND
Pin 5   GND
Pin 6   Vcc

------------------------- pmod "DA2" DAC from Digilent ----------------------------
"Home" page for PmodDA2:

Texas Instruments Data Sheet:

Max clock = 30 MHz

I notice that it has trouble handling more than 250000 samples/s.
According to data sheet the "settling time" is 8 microseconds, which implies
a maximum of 125000 samples/s

J1 Pin connections to the controller or FPGA:
Pin 1     ~SYNC         (active low)       
Pin 2     DINA                
Pin 3     DINB                
Pin 4     SCLK                
Pin 5     GND                
Pin 6     VCC                

J2 pin connections for the analog output:
Pin 1   Vout 1
Pin 2   
Pin 3   Vout 2
Pin 4
Pin 5   GND
Pin 6   Vcc

------------------------ How to get different clock frequencies: the PLL ---------------------------------
Badnews:  The ICE40 in the VQ100 package has NO plls.  This info is from here:

I haven't yet gotten it to work, but here is some info:

Application Note for the PLL:  http://www.latticesemi.com/view_document?document_id=47778

The tool to create Verilog Code to activate (instantiate) the PLL seems to be Lattice Radiant, downloadable for Windows and Linux:

The Lattice Radiant User Manual is here: https://www.latticesemi.com/-/media/LatticeSemi/Documents/UserManuals/EI2/FPGA-TN-02052-1-0-iCE40UP-sysCLOCK-PLL-Radiant-SW.ashx?document_id=52236

A good starting point for ICE40 info in general is: http://www.latticesemi.com/en/Products/FPGAandCPLD/iCE40#_21E33C7EC0BD48AA80FE384ED73CC895

---------------------- I need to implement Memory!  How? Some info might be here ----------------
Link to Application Note on Memory:

NICE!   The application note's Appendix A has example code on how to infor (automatically use) the memory.  Single and dual port.

Memory capacity = 64 kBits = 8 kBytes = 4 kWords (16 bit) = 5.333 kWords (12 bit)

======================= READ ADC - Verilog Code =========================

Separate this Verilog code into three files to compile

// Filename:  Read_ADC_Top.v
// Written by me, Peter Halverson, and posted on my web page http://halverscience.net/   Nov 4, 2019
// This Verilog code is intended to run on a GoBoard, available from nandland.com,
// and it uses a PmodAD1 analog-to-digital converter, available from Digilent
// This is the top module.  NOTE: I had trouble with the Lattice LSE Synthesis tool
// not "autoguessing" that this is the top module.  I had to explicitly tell the tool.
// To do that, go into Tool > Tool Options > LSE (tab) > Top Level Unit and type in "Read_ADC_Top"

module Read_ADC_Top
  (input  i_Clk,       // Wire from the Main Clock, 25 MHz
   output o_Segment1_A,  // Wiring to the 1st 7-segment display.
   output o_Segment1_B,
   output o_Segment1_C,
   output o_Segment1_D,
   output o_Segment1_E,
   output o_Segment1_F,
   output o_Segment1_G,
   output o_Segment2_A,  // Wiring to the 2nd 7-segment display.
   output o_Segment2_B,
   output o_Segment2_C,
   output o_Segment2_D,
   output o_Segment2_E,
   output o_Segment2_F,
   output o_Segment2_G,
   output o_LED_1,       // Wiring to the LEDs
   output o_LED_2,
   output o_LED_3,
   output o_LED_4,
   output io_PMOD_1,     // Wiring to the ADC board ~ chip select (active low)
   input  io_PMOD_2,     // data from ADC 0
   input  io_PMOD_3,     // data from ADC 1  (not used)
   output io_PMOD_4,     // clock to read out data
   input i_Switch_1,     // Wires to the switches.  Not used now, but useful for debugging.
   input i_Switch_2,
   input i_Switch_3,
   input i_Switch_4);
  wire w_Segment1_A, w_Segment2_A;
  wire w_Segment1_B, w_Segment2_B;
  wire w_Segment1_C, w_Segment2_C;
  wire w_Segment1_D, w_Segment2_D;
  wire w_Segment1_E, w_Segment2_E;
  wire w_Segment1_F, w_Segment2_F;
  wire w_Segment1_G, w_Segment2_G;
  wire w_LED_1, w_LED_2, w_LED_3, w_LED_4;

  wire [11:0] w_ADC_Data;
  wire w_ADC_Data_Valid;
  reg [31:0] r_Readout_Count  = 0;
  parameter Readout_Period = 125000;  // 125000 gives 200 per second (25 MHz clock / 125000 )
  reg [11:0] r_ADC_Data;   // Only low order 12 bits are used.   Four high order bits always zero
  reg r_ADC_Data_Requested = 1'b0;
  // Code to read the ADC and put the results on the 7-segment display (upper 8 bits)
  // and the LEDS (lower 4 bits)
  always @(posedge i_Clk) begin
    if (r_Readout_Count >= Readout_Period) begin
      r_Readout_Count <= 0;
      r_ADC_Data_Requested <= 1'b1;    //  Tell Read_ADC we want data
    end else begin
      r_Readout_Count <= r_Readout_Count + 1;
      r_ADC_Data_Requested <= 1'b0;
    if (w_ADC_Data_Valid == 1'b1) begin
    //if (1'b1 == 1'b1) begin
      r_ADC_Data <= w_ADC_Data;    // Get the data from Read_ADC
  // Interface (instantiation) to the code that triggers the ADC and reads its data.
  // parameter ADC_CLKS_PER_BIT determines the readout speed of the bits from the ADC.
  // Its the GoBoard's clock frequency divided by the parameter.
  // Example: 25,000,000 / 25 would give 1 mega-baud.
  // Maximum, according to Analog Devices AD7476 data sheet is 20 mega-baud
  Read_ADC #(.ADC_CLKS_PER_BIT(4)) Read_ADC_Inst   // 4 is gets me 6.25 Mbaud, 160 ns clock

  // Binary to 7-Segment Converter for Upper Digit, highest nibble of ADC data
  Binary_To_7Segment SevenSeg1_Inst
  assign o_Segment1_A = ~w_Segment1_A;
  assign o_Segment1_B = ~w_Segment1_B;
  assign o_Segment1_C = ~w_Segment1_C;
  assign o_Segment1_D = ~w_Segment1_D;
  assign o_Segment1_E = ~w_Segment1_E;
  assign o_Segment1_F = ~w_Segment1_F;
  assign o_Segment1_G = ~w_Segment1_G;
  // Binary to 7-Segment Converter for Lower Digit, middle nibble of ADC data
  Binary_To_7Segment SevenSeg2_Inst
  assign o_Segment2_A = ~w_Segment2_A;
  assign o_Segment2_B = ~w_Segment2_B;
  assign o_Segment2_C = ~w_Segment2_C;
  assign o_Segment2_D = ~w_Segment2_D;
  assign o_Segment2_E = ~w_Segment2_E;
  assign o_Segment2_F = ~w_Segment2_F;
  assign o_Segment2_G = ~w_Segment2_G;

  assign o_LED_1 = r_ADC_Data[3];   // Lowest nibble of ADC data will be displayed on the four LEDs
  assign o_LED_2 = r_ADC_Data[2];
  assign o_LED_3 = r_ADC_Data[1];
  //assign o_LED_3 = i_Switch_3;
  //assign o_LED_4 = i_Switch_4;
  //assign o_LED_4 = r_Readout_Count[22];
  assign o_LED_4 = r_ADC_Data[0];
endmodule // Read_ADC_Top


// Filename:  Read_ADC.v
// ADC Readout for Digilent PMOD AD1, which has two Analog Devices AD7476A 12-bit ADCs
// Written by Peter Halverson and posted on http://halverscience.net/  Nov. 4, 2019
// Based on UART RX from http://www.nandland.com

module Read_ADC
  #(parameter ADC_CLKS_PER_BIT = 25)
   input        i_Clock,
   input        i_ADC_Data_Serial,
   input        i_ADC_Data_Requested,// Set this to True when you want an ADC readout
   output       o_ADC_Data_Valid,    // When this is true, it means the adc data is ready
   output [11:0] o_ADC_Data,         //Its a 12 bit ADC
   output       o_ADC_Chip_Select_Not, // The ~CS line is active when False
   output       o_ADC_Clock          // Falling edge requests next bit, bit is read on rising edge
  parameter IDLE                 = 2'b00;   // State Machine states
  parameter ADC_CONVERSION_DELAY = 2'b01;   // Not needed? Datasheet says 10 ns minimum is needed.
  parameter READ_DATA_BITS       = 2'b10;
  parameter CLEANUP              = 2'b11;
  reg [7:0]     r_Clock_Count    = 0;
  reg [3:0]     r_Bit_Index      = 15; //4 zero bits + 12 data bits = 16 bits total
  reg [15:0]    r_ADC_Data       = 0;  // First 4 bits always zero
  reg           r_ADC_Data_Valid = 0;
  reg [2:0]     r_SM_Main        = 0;
  reg           r_ADC_Chip_Select_Not = 1;
  reg           r_ADC_Clock      = 1;
  reg [7:0]    r_Delay_Clock_Count = 0;
  reg           r_Got_The_Bit    = 1'b0;
  // Read ADC state machine
  always @(posedge i_Clock)
    case (r_SM_Main)
      IDLE : begin
          r_ADC_Data_Valid    <= 1'b0;
          r_Clock_Count       <= 0;
          r_Delay_Clock_Count <= 0;
          r_Bit_Index         <= 14;  // ADC send 15 bits (not 16)   High order bits first
          r_ADC_Clock         <= 1'b1;
          if (i_ADC_Data_Requested == 1'b1) begin
            r_SM_Main <= ADC_CONVERSION_DELAY;
            r_ADC_Chip_Select_Not <= 1'b0;        // Start the conversion
          end else begin
            r_SM_Main <= IDLE;
            r_ADC_Chip_Select_Not <= 1'b1;        // Don't start the conversion
      end // case: IDLE
        if (r_Delay_Clock_Count < 0) begin   // Adjust to give time for ADC to start a conversion
          // 0 gives 80 ns (Three cycles of 25 MHz clock), 1 gives 120 ns, 2 gives 160 ns, etc
          r_Delay_Clock_Count <= r_Delay_Clock_Count + 1;
          r_SM_Main <= ADC_CONVERSION_DELAY;
        end else begin
          r_Delay_Clock_Count <= 0;
          r_SM_Main <= READ_DATA_BITS;
      end // case: ADC_CONVERSION_DELAY
      READ_DATA_BITS : begin
        if (r_Clock_Count < ADC_CLKS_PER_BIT-1) begin
          if (r_Clock_Count < (ADC_CLKS_PER_BIT/2)) begin
            r_ADC_Clock <= 1'b0;     // Falling edge tells ADC to output a bit
            r_Got_The_Bit <= 1'b0;
          end else begin
            r_ADC_Clock <= 1'b1;     // Rising edge is when we get the bit.  (It is now stable)
            if (r_Got_The_Bit == 1'b0) begin
              r_ADC_Data[r_Bit_Index] <= i_ADC_Data_Serial;  // GET THE DATA BIT!!
              r_Got_The_Bit <= 1'b1;   //We want to latch the bit only once
              // Check if we have received all bits
              if (r_Bit_Index > 0) begin      // We need to get more bits (We get 16 bits, 1st four are zero)
                r_Bit_Index <= r_Bit_Index - 1;  //ADC send bit 15 first, then bit 14, ...
                r_SM_Main   <= READ_DATA_BITS;
              end else begin
                r_ADC_Data_Valid <= 1'b1;         // All 15 bits are now valid. Tell caller to get the data.
                r_ADC_Chip_Select_Not <= 1'b1;    // Stop the conversion
                r_SM_Main     <= CLEANUP;
          r_Clock_Count <= r_Clock_Count + 1;
        end else begin
          r_Clock_Count <= 0;
      end // case: READ_DATA_BITS      
      CLEANUP : begin      // Stay here 1 clock
         // r_Delay_Clock_Count <= 0;
          r_SM_Main <= IDLE;
          r_ADC_Data_Valid   <= 1'b0;
      end // case: CLEANUP       
      default :
        r_SM_Main <= IDLE;

  assign o_ADC_Data_Valid   = r_ADC_Data_Valid;
  assign o_ADC_Data = r_ADC_Data[11:0];
  assign o_ADC_Chip_Select_Not = r_ADC_Chip_Select_Not;
  assign o_ADC_Clock = r_ADC_Clock;
endmodule // Read_ADC


// Filename:  Binary_To_7Segment.v
// File downloaded from http://www.nandland.com
// This file converts an input binary number into an output which can get sent
// to a 7-Segment LED.  7-Segment LEDs have the ability to display all decimal
// numbers 0-9 as well as hex digits A, B, C, D, E and F.  The input to this
// module is a 4-bit binary number.  This module will properly drive the
// individual segments of a 7-Segment LED in order to display the digit.
// Hex encoding table can be viewed at:
// http://en.wikipedia.org/wiki/Seven-segment_display
module Binary_To_7Segment
   input       i_Clk,
   input [3:0] i_Binary_Num,
   output      o_Segment_A,
   output      o_Segment_B,
   output      o_Segment_C,
   output      o_Segment_D,
   output      o_Segment_E,
   output      o_Segment_F,
   output      o_Segment_G
  reg [6:0]    r_Hex_Encoding = 7'h00;
  // Purpose: Creates a case statement for all possible input binary numbers.
  // Drives r_Hex_Encoding appropriately for each input combination.
  always @(posedge i_Clk)
      case (i_Binary_Num)
        4'b0000 : r_Hex_Encoding <= 7'h7E;
        4'b0001 : r_Hex_Encoding <= 7'h30;
        4'b0010 : r_Hex_Encoding <= 7'h6D;
        4'b0011 : r_Hex_Encoding <= 7'h79;
        4'b0100 : r_Hex_Encoding <= 7'h33;          
        4'b0101 : r_Hex_Encoding <= 7'h5B;
        4'b0110 : r_Hex_Encoding <= 7'h5F;
        4'b0111 : r_Hex_Encoding <= 7'h70;
        4'b1000 : r_Hex_Encoding <= 7'h7F;
        4'b1001 : r_Hex_Encoding <= 7'h7B;
        4'b1010 : r_Hex_Encoding <= 7'h77;
        4'b1011 : r_Hex_Encoding <= 7'h1F;
        4'b1100 : r_Hex_Encoding <= 7'h4E;
        4'b1101 : r_Hex_Encoding <= 7'h3D;
        4'b1110 : r_Hex_Encoding <= 7'h4F;
        4'b1111 : r_Hex_Encoding <= 7'h47;
    end // always @ (posedge i_Clk)
  // r_Hex_Encoding[7] is unused
  assign o_Segment_A = r_Hex_Encoding[6];
  assign o_Segment_B = r_Hex_Encoding[5];
  assign o_Segment_C = r_Hex_Encoding[4];
  assign o_Segment_D = r_Hex_Encoding[3];
  assign o_Segment_E = r_Hex_Encoding[2];
  assign o_Segment_F = r_Hex_Encoding[1];
  assign o_Segment_G = r_Hex_Encoding[0];
endmodule // Binary_To_7Segment