FPGA Page

From bibbleWiki
Revision as of 05:46, 17 December 2024 by Iwiseman (talk | contribs) (First Edited Project)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Introduction

FPGA stands for Field-programmable gate array. I wish I had wrote this up last time but hey on the way now.

First Project

My first project was from Digikey videos [[1]] which I struggle with in several ways. So lets write them down so I do not forget

Python

We us apio which is a python apt to make things easy. It loads the tools required to build a binary.

mkdir <project_name>
cd<project_name>
virtualenv venv 
source venv/bin/activate

Install Apio

Install apio. He installed 0.6.3 but I mine worked on 0.9.5

pip apio

Before project A

Before creating the blink example we need to make sure we are configured for the correct board. For me this was the ice40up5k-b-evn which I believe it the marketing name. It was quite hard to track the chip down and therefore the pinout. I eventually found

  • FPGAUG0200110.pdf which lists my board at the bottom once.
  • iCE40UP5K-SG48 is the chip and listed under features
  • iCE40UltraUltraPlusSG48PinMigration.xlsx is the pinout really poorly named

Here is the pinout

Before project B

We need to install gtkwave with

sudo apt install gtkwave

Fix up the tcl install as mine moaned about not have specific version. It first created a link for the /usr/local/lib with

sudo ln -s  /usr/share/tcltk/tcl8.6  /usr/local/lib/

Then changed the init.tcl

#package require -exact Tcl 8.6.14
package require -exact Tcl 8.6.12

Create project

So we create a project using the examples provide with this command

apio examples  -d icestick/leds

My default this creates a files called

  • apio.ini
  • led.pcf

The apio.ini contains the board and top module to use. For the board we need to fix this and we do so with

# To list the boards
apio boards --list
# And for us we use
apio init --board iCE40-UP5K

This then produces the following apio.ini file

[env]
board = iCE40-UP5K
top-module = main

We need to replace the main with the name of the first module which is leds

[env]
board = iCE40-UP5K
top-module = leds

Now we need to modify the project constraints file. This is a file which on the left has the name of the pin used in the project and on the right has you pin number. Because we used a icestick example the pins will be different. Here is the corrected file for the iCE40UP5K-SG48 based off the xls spreadsheet

# -----------------------------------------------------------------------------
#- Leds example for the iCEstick board
#- Constraint file (.pcf)
# -----------------------------------------------------------------------------
# --  Pinout: https://github.com/Obijuan/open-fpga-verilog-tutorial/blob/master/tutorial/doc/images/icestick_pinout.png
# --  Guide: https://github.com/Obijuan/open-fpga-verilog-tutorial/blob/master/tutorial/doc/icestickusermanual.pdf

# ------------ User Leds ------------------------------------------------------
set_io  D1 23 
set_io  D2 25 
set_io  D3 26 
set_io  D4 27 
set_io  D5 32

Now we are ready. No idea what some of these commands do and will not doubt file this in when I understand. Maybe just the sim I struggle with

# Parse the syntax
apio verify
# Simulate with gtkwave
apio sim
# Build
apio build
# Upload
apio upload

And here is a picture for fun.

First Edited Project

So this was my real first project as I copied the code but knew what it did. Made a pcf with the 5 leds and 4 buttons

# Leds
# ====
#set_io  led_0 25 
#set_io   led_1 23 
#set_io  led_2 26
set_io  led_3 27 
#set_io  led_4 32 

# Buttons
# =======
set_io -pullup yes pmod_0 38
set_io -pullup yes pmod_1 36
set_io -pullup yes pmod_2 28 
set_io -pullup yes pmod_3 42

And then wrote some logic

// Verilog module called and_gate
module main (
    // Inputs
    input pmod_0,
    input pmod_1,

    // Outpu
    output led_3
);

assign led_3 = ~pmod_0 & ~pmod_1;

endmodule

Does not do a lot, the important bits were the pullup resistor for the buttons. For the logic it merely sets led_3 on when both buttons are pressed

Second Edited Project

So it probably will seem basic looking back but rock and rolling along. We are building this

  • If button 0 is pressed LED 0 and LED 1 come on
  • If button 0 and 1 are pressed all 3 leds come on

This shows us how to define out inputs/outputs in arrays and what a wire is. First the pcf file. Pretty simple, just like arrays

set_io  led[0]  25 
set_io  led[1]  23 
set_io  led[2]  26
set_io  led[3]  27 
set_io  led[4]  32 

set_io -pullup yes pmod[0] 38
set_io -pullup yes pmod[1] 36
set_io -pullup yes pmod[2] 28 
set_io -pullup yes pmod[3] 42

Now the module. Not as simple but added comments to help remember. Replicate seemed to be the thing to remember. To me the wire is just a named resource but I am sure there is more to come.

module main (
    // Inputs
    input [1:0]     pmod,

    // Outpu
    output [2:0]    led
);

    // Named connection we are going to use
    wire not_pmod_0;

    // Continuous assignment

    // Connect the pmod[0] to this named connection
    assign not_pmod_0 = ~pmod[0];

    // Replicate twice the value of not_pmod, starting a led[0]
    assign led[1:0] = {2{not_pmod_0}};

    // Now switch on the led[2] if not pmod_0 and not pmod[1]
    assign led[2] = not_pmod_0 & ~pmod[1];

endmodule

Design

Here is the flow for design.