Created first 3 blogposts from old website
All checks were successful
Build and deploy Hugo website / build-and-deploy (push) Successful in 10s
44
content/posts/fpgatoolchain-01.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
+++
|
||||||
|
title = "Unified FPGA toolchain script"
|
||||||
|
tags = ["Embedded", "FPGA", "Python"]
|
||||||
|
date = "2022-09-11"
|
||||||
|
+++
|
||||||
|
|
||||||
|
[View project on gitea](https://git.joppeb.nl/joppe/remotesyn)
|
||||||
|
|
||||||
|
The vendor provided toolchains for FPGA’s… a nuisance for the most of us but unfortunately unreplacable! (Yes, I know. There are a few open source alternatives and they are very promising but I think everybody can agree that for a lot of devices the open source toolchains are not as mature as the vendor provided ones). Me not being a big fan of slow and unresponsive GUIs (yes, looking at you Vivado!) I always reach out to the command line tools the vendors provide and with a bunch of scripts the whole workflow can be done from the command line and the project source tree becomes more version controllable. There I was, a bunch of clunky scripts which needed fix after fix and big changes from project to project wishing there was a better way to do this. After some searching some tools came up and they are awesome (think of TerosHDL for VSCode and fusesoc) but they all missed one thing: the option for remote building on my big PC at home while I am working on my old and low laptop somewhere else. In the scripts I wrote I used SSH and a lot of copying files from one side to the other to provide this option but every project had its own set of scripts.
|
||||||
|
|
||||||
|
That’s why I came up with the plan to write one tool for all projects, be it with Quartus, the old ISE, Vivado, just simulation or even formal verification with SymbiYosys. A single project configuration file is used to define the actions which could be locally or remotely executed and with the setup of the code of the tool, new FPGA toolchains or other action types can be easily added when they are needed.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[project]
|
||||||
|
name = spartan6_project
|
||||||
|
version = 0.1
|
||||||
|
out_dir = OUT
|
||||||
|
build_dir = BUILD
|
||||||
|
|
||||||
|
# Basic synthesis
|
||||||
|
[target.synth]
|
||||||
|
toolchain = ISE
|
||||||
|
family = spartan6
|
||||||
|
device = xc6slx9
|
||||||
|
package = tqg144
|
||||||
|
speedgrade = -2
|
||||||
|
toplevel = toplevel
|
||||||
|
|
||||||
|
files_vhdl = RTL/toplevel.vhd
|
||||||
|
files_con = CON/toplevel.ucf
|
||||||
|
|
||||||
|
# Behavioural simulation
|
||||||
|
[target.sim]
|
||||||
|
toolchain = ghdl
|
||||||
|
toplevel = tb_toplevel
|
||||||
|
runtime = all
|
||||||
|
|
||||||
|
files_vhdl = RTL/toplevel.vhd
|
||||||
|
SIM/tb_toplevel.vhd
|
||||||
|
```
|
||||||
|
|
||||||
|
With this simple configuration file the execution of ‘rbuild synth’ will run the full Xilinx ISE toolchain and ‘rbuild sim’ will run GHDL and perform a behavioral simulation. Deciding to move to a different device from a different vendor? Instead of creating a whole new project in the vendor specific toolchains or creating a bunch of new scripts the only thing which must be done is changing a few lines in the project configuration file (not counting the device specific parts of the design of course).
|
||||||
|
|
||||||
|
I have not used the tool itself that much yet but that will definitely change pretty soon and I will keep adding and updating the actions when I need to. One last thing must se said I suppose: even though the remote building can be pretty useful it also provides a way to share one installation with multiple people (which is cool but you’ll probably be walking a legally grey line with it) . Using the tool for remote building (or any other set of tools) could potentially void licensing and EULA agreements so some research has to be done (or ignore it and we’ll all find out soon if it has consequences or not).
|
69
content/posts/mimasfirmware-01.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
+++
|
||||||
|
title = "Mimas Spartan 6 FPGA - New firmware, driver and PC-FPGA interface"
|
||||||
|
tags = ["Driver", "Embedded", "Firmware", "FPGA"]
|
||||||
|
date = "2022-03-17"
|
||||||
|
+++
|
||||||
|
|
||||||
|
[View project on github](https://github.com/Jojojoppe/MimasV1Firmware)
|
||||||
|
|
||||||
|
The [Numato Lab Mimas Spartan 6 FPGA development board](https://numato.com/product/mimas-spartan-6-fpga-development-board/) is a simple FPGA development board with a Xilinx Spartan 6 (xc6slx9) on it with a usb interface for programming the on-board flash. The flash is a 16 Mb SPI flash connected to both the FPGA an a Microchip PIC (18f14k50). The PIC runs firmware which presents itself as serial port to the connected PC and uses a python script to upload the generated bit-file.
|
||||||
|
|
||||||
|
Since the original firmware used a 9600 baud serial connection, the uploading of the bitfile it takes quite some time to upload. And next to that communication between the FPGA and the USB port is not implemented even though the PIC has connections to the FPGA. This was the reason to develop new firmware which could program the SPI flash faster and has an FPGA-USB interface for serial communication and/or datalogging purposes (like a logic analyzer).
|
||||||
|
|
||||||
|
The repository for this project contains the firmware for the PIC (in the `firmware` folder), the driver for programming and comunicating with the PIC (in the `driver` folder) and some usefull VHDL blocks for communication between the PIC and the FPGA. Information specific for the firmware, driver of hardware are located in their folders.
|
||||||
|
|
||||||
|
### FPGA-PIC Interface
|
||||||
|
|
||||||
|
The full schematics of the Mimas board can be found [here](https://numato.com/blog/wp-content/uploads/2016/08/MimasSpartan6ModuleSch.pdf) (which are published by Numato Lab under the CC BY-SA licence). The relevant parts are shown below. As can be seen, 7 lines are directly connected to the FPGA (`D[0..3]`, `CLK`, `RD` and `WR`) next to the SPI bus which both the FPGA and the MCU use to communicate to the SPI flash. The SPI bus is used for the communication between the FPGA and the MCU (while keeping the SPI flash disabled). Next to the SPI bus the CLK line from the mentioned signals is used as reset line to reset the FPGA from the MCU.
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *PIC side of the interface* |
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *FPGA side of the interface* |
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *Interface IP block pinout* |
|
||||||
|
|
||||||
|
The project also provides an IP block written in VHDL which can be used together with this interface. It translates the serial data into 6 general purpose ports and two 8 bit channels. Each time a serial transfer takes place the IP block sends out the status of the 6 general purpose inputs and the internal buffer for channel 0 and 1 while it receives the values for the 6 general purpose outputs and the data for channels 0 and 1. When the transfer is complete the GPIO data and the channel data are clocked to the output and the valid line for the channel is held high for one clock period.
|
||||||
|
|
||||||
|
The transfer message consist out of 3 bytes: one status byte with GPIO values and a byte for each channel. The status byte has the 6 GPIO bits and a bit for both channels indicating if the corresponding byte contains valid data. If this bit is low it means that there is no data transfered over that channel. All data is sent MSB first.
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *Serial transfer layout* |
|
||||||
|
|
||||||
|
With the current SPI settings on the MCU the communication happens at roughly 272 kB per second over SPI if all the SPI transfers are spaced like in the captured image below. Unfortunately due to the path the data takes (PC->USB->MCU->SPI and back) the spacing between consecutive 'packets' are much larger and results in roughly 15 kB per second (or 5000 transfers per second/bps over one endpoint).
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *Signals captured with a logic analyzer* |
|
||||||
|
|
||||||
|
### USB Message Format
|
||||||
|
|
||||||
|
The PIC registers itself as a classless USB device with device ID `0000:0001`. It serves one endpoint on interface 0 which is used for all communication. The commands and other data are done with bulk writes/reads and the message layout is as stated in the table below.
|
||||||
|
|
||||||
|
> **NOTE:** The USB device ID is not a registered and valid VID-PID pair! Feel free to change the pair (which should be done in `firmware/usb_descriptors.c` line 14-15 and `driver/mimasdriver`/`mimas_interface.py` line 6-7).
|
||||||
|
|
||||||
|
| Command group | Command | Arguments | Extra info |
|
||||||
|
|---------------|-----------------|----------------|----------------------------------------------------------------------------------------|
|
||||||
|
| NOP (0x00) | | | Does nothing |
|
||||||
|
| FLASH (0x01) | NOP (0x00) | | Does nothing |
|
||||||
|
| FLASH (0x01) | PROGRAM (0x01) | `llllaaaa` | Write a sector starting from `a` for `l` bytes |
|
||||||
|
| FLASH (0x01) | READ (0x02) | `llllaaaa` | Read a sector from flash starting from `a` for `l` bytes. Perform `l/64` bulk reads. |
|
||||||
|
| FLASH (0x01) | GETID (0x03) | | Get the flash ID. Perform 1 bulk read. |
|
||||||
|
| HF (0x02) | NOP (0x00) | | Does nothing |
|
||||||
|
| HF (0x02) | TRANSFER (0x01) | `GAB` | Transfer one message to the FPGA. `G` contains the GPIO bits and the status bits and `A` and `B` contain the channel data. Perform 1 bulk read to get a message back (in the same format). |
|
||||||
|
| HF (0x02) | HRST (0x02) | | Assert reset line |
|
||||||
|
| HF (0x02) | LRST (0x03) | | Deassert reset line |
|
||||||
|
|
||||||
|
### Why not…
|
||||||
|
|
||||||
|
- **Why not adding a simple serial link between the FPGA and the PIC instead of the SPI interface with two channels?**
|
||||||
|
Well… I wish I could have done that. As can be seen in the schematic the RX line is used as SPI chip select for the flash so using the hardware UART in the PIC is not an option, hence this bit-banged solution.
|
||||||
|
|
||||||
|
- **Why not using USB-CDC for the communication instead of this custom protocol?**
|
||||||
|
To be honest, I wanted to do that! Unfortunately I couldn't get the combination of custom endpoint for programming and CDC class interface for communication working correctly so I switched it to the current setup. This does not mean that it wont be implented forever though. Next to that I really want to design some on-chip logic analyzers which is easier with the current setup than to do that over UART.
|
37
content/posts/mimasfirmware-02.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
+++
|
||||||
|
title = "Mimas PC-FPGA interface with Wishbone master"
|
||||||
|
tags = ["Embedded", "FPGA", "Wishbone"]
|
||||||
|
date = "2022-09-10"
|
||||||
|
+++
|
||||||
|
|
||||||
|
[View project on github](https://github.com/Jojojoppe/MimasV1Firmware)
|
||||||
|
|
||||||
|
With the created [PC-FPGA interface for the Mimas Spartan 6]({{< ref "/posts/mimasfirmware-01" >}}) development board, it was time to do something useful with it. I decided to make a Wishbone (version 4 pipelined) bus master which is controlled by the USB interface. This "Hardware-Firmware (HF) to Wishbone" interface can be connected to one of the HF interface channels and uses one transfer (one byte) for communicating a command and a multiple of four transfers (four bytes) for address and data transfers.
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *System layout* |
|
||||||
|
|
||||||
|
### Bus Reset
|
||||||
|
|
||||||
|
The first command is the reset command (`CMD=0x00`) which brings the wishbone bus state back to idle. The issuer must wait for the first valid transaction on that channel and check if a valid response code is transfered (`A0`, an error is indicated with return code `AF`).
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *HF side of bus reset* |
|
||||||
|
|
||||||
|
### Bus Write
|
||||||
|
|
||||||
|
The second command is the write command (`CMD=0x01`) which requires an address and data word. After the transfers of the address and data bytes, the wishbone write transaction is activated. The issuer must wait for the first valid transaction on that channel and check if a valid response code is transferred (`A0`, an error is indicated with return code `AF`).
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *HF side of bus write* |
|
||||||
|
|
||||||
|
### Bus Read
|
||||||
|
|
||||||
|
The third command is the read command (`CMD=0x02`) which requires an address. After the transfers of the address bytes, the wishbone read transaction is activated. The issuer must wait for the first valid transaction on that channel and read in 4 subsequent bytes which will contain the read-back data. Then the issuer must read one last transaction and check if a valid response code is transferred (`A0`, an error is indicated with return code `AF`).
|
||||||
|
|
||||||
|
|  |
|
||||||
|
|:--:|
|
||||||
|
| *HF side of bus read* |
|
@ -1,35 +0,0 @@
|
|||||||
+++
|
|
||||||
title = "Test 1"
|
|
||||||
tags = ["test"]
|
|
||||||
date = "1012-01-01"
|
|
||||||
+++
|
|
||||||
|
|
||||||
Test 1
|
|
||||||
I am referencing a footnote[^1]
|
|
||||||
|
|
||||||
```go {linenos=inline}
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println("{linenos=inline}")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```go {linenos=table}
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println("{linenos=table}")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis in dictum tortor.
|
|
||||||
Morbi laoreet enim id sem euismod lobortis. Donec quam libero, bibendum non cursus vitae, dictum vel eros.
|
|
||||||
```
|
|
||||||
|
|
||||||
[^1]: I am the footnote
|
|
BIN
static/images/blog/mimas/HFinterface.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
static/images/blog/mimas/fpgaside.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
static/images/blog/mimas/hfread.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
static/images/blog/mimas/hfreset.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
static/images/blog/mimas/hfwrite.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
static/images/blog/mimas/logicanalyzer.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
static/images/blog/mimas/picside.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
static/images/blog/mimas/signals.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
static/images/blog/mimas/wb_bridge.png
Normal file
After Width: | Height: | Size: 71 KiB |