Giter VIP home page Giter VIP logo

gatemate-riscv's Introduction

Welcome

I enjoy designing and building electronics hardware (development boards), and learning how to code low-level. I have been working on FPGA PMOD design, on solar position tracking for photovoltaic systems, and with a long work history in Information Security some repos are security-related.

Frank's github statsTop Langs

gatemate-riscv's People

Contributors

fm4dd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gatemate-riscv's Issues

step22 - fails for Gatemate flash programming or flash reading

In step22, the application expects the app image data to be uploaded into the flash memory at a 1M offset. This step currently fails due to issues with SPI flash access. The issue is that no output is visible on the serial line. This can have several possible root causes:

(A) Selected wrong flash read mode for spi_flash.v. 4 modes are defined:

  1. SPI_FLASH_READ
  2. SPI_FLASH_FAST_READ
  3. SPI_FLASH_FAST_READ_DUAL_OUTPUT
  4. SPI_FLASH_FAST_READ_DUAL_IO

So far, I unsuccessfully tried 1. and 4.

(B) Using the wrong openFPGALoader flash offset value

openFPGALoader only understands an offset provided in bytes. I am using openFPGALoader -b gatemate_evb_spi -o 1048576 data/scene1.dat, assuming the 1M offset calculates with 1024.

(C) It is the first time that I am using the +uCIO flag for the Gatemate place and route tool 'p_r', trying to directly access the flash from the FPGA.

(D) A pin swap is another common cause (e.g. MOSI->MISO), hopefully it's that simple.

The make output example below shows the successful flash execution, but the program output does not show :-(

fm@nuc7fpga:~/fpga/projects/git/gatemate-riscv/step22$ make prog
Programming scene data at 1M offset:
/home/fm/cc-toolchain-linux/bin/openFPGALoader/openFPGALoader -b gatemate_evb_spi -o 1048576 data/scene1.dat
Jtag frequency : requested 6.00MHz   -> real 6.00MHz  
Detail: 
Jedec ID          : c2
memory type       : 28
memory capacity   : 17
EDID + CFD length : c2
EDID              : 1728
CFD               : 
00
Detail: 
Jedec ID          : c2
memory type       : 28
memory capacity   : 17
EDID + CFD length : c2
EDID              : 1728
CFD               : 
flash chip unknown: use basic protection detection
Erasing: [==================================================] 100.00%
Done
Writing: [==================================================] 100.00%
Done
Wait for CFG_DONE DONE
Programming E1 SPI Config:
/home/fm/cc-toolchain-linux/bin/openFPGALoader/openFPGALoader -b gatemate_evb_spi SOC_00.cfg
Jtag frequency : requested 6.00MHz   -> real 6.00MHz  
Detail: 
Jedec ID          : c2
memory type       : 28
memory capacity   : 17
EDID + CFD length : c2
EDID              : 1728
CFD               : 
00
Detail: 
Jedec ID          : c2
memory type       : 28
memory capacity   : 17
EDID + CFD length : c2
EDID              : 1728
CFD               : 
flash chip unknown: use basic protection detection
Erasing: [==================================================] 100.00%
Done
Writing: [==================================================] 100.00%
Done
Wait for CFG_DONE DONE

step-17 and above - UART speed differs from Verilog encoded baudrate

The target UART speed is configured inside the SOC module as 1.000.000 baud. However the real output rate on the UART USB adapter is well below the target value. This is the baud rate setting in SOC.v:

   corescore_emitter_uart #(
      .clk_freq_hz(`CPU_FREQ*1000000),
      .baud_rate(1000000)                           
   ) UART(
      .i_clk(clk),
      .i_rst(!resetn),
      .i_data(mem_wdata[7:0]),  
      .i_valid(uart_valid),
      .o_ready(uart_ready),
      .o_uart_tx(TXD)                                
   );

On the output, Sigrok PulseView measured a baudrate of 833.333 instead:

I am using Digilent's PMOD-USBUART plugged into port PMOD-B, and connected a protocol analyzer like this:

The UART speed, that is supposed to stay fixed at 1Mbaud, changes along with changing the FPGA CPU frequency setting CPU_FREQ. I recorded the following values:

Verilog corescore_emitter_uart() baud_rate setting 1000000 (original):

CPU_FREQ measured baud_rate
5 MHz n/a (program fails execution)
10 MHz 833.333
20 MHz 909.090
30 MHz 952.380
40 MHz n/a (program fails execution)

Trying to raise the Verilog corescore_emitter_uart() baud_rate setting to 1100000:

CPU_FREQ measured baud_rate
5 MHz n/a (program fails execution)
10 MHz 909.090
20 MHz 1.000.000
30 MHz 1.052.631
40 MHz n/a (program fails execution)

Cologne Chips place&route 'p_r' fails with "Error: Exception Handler called. ExitCode: 112"

This error occurs when executing Cologne Chips place and route 'p_r' in step08 and step10 only.

Observed error output details:

home/fm/cc-toolchain-linux/bin/p_r/p_r -i SOC_synth.v -o SOC -ccf ../gatemate-e1.ccf +uCIO > SOC_pr.log
make: *** [../config.mk:35: impl] Error 112

fm@nuc7fpga:~/fpga/projects/git/gatemate-riscv/step10$ tail SOC_pr.log
    7  Netlength: 2685.74   diff(%): 3.26346   1
    8  Netlength: 2623.89   diff(%): 2.35712   1
    9  Netlength: 2580.43   diff(%): 1.68426   1
   10  Netlength: 2593.39   diff(%): -0.49977   1
   11  Netlength: 2792.54   diff(%): -7.13145   2

Time (s):       1.303
Combine RAMs 877 and 876
#### Error: Exception Handler called. ExitCode: 112
Exception Class: EAccessViolation

Error Origin:
The error traces back to the constraints file gatemate-e1.ccf in line 57:

Pin_out "TXD" Loc = "IO_NB_B5"; # RXD

The problem in this pin assignment seems to be with PMOD bank NB. As soon as a different IO bank such as SB or EA is configured, 'p_r' works. E.g. changing "IO_NB_B5" to "IO_SB_B5" lets p_r finish the routing fine.

It is mysterious why this pin assignment fails for the particular step08 and step10 only, while the same constrains file shared across all steps works without issue there. The NB bank pin is assigned to the attached Digilent PMOD USBUART serial TX line, and is verified to work.

p_r version:

fm@nuc7fpga:~/fpga/projects/gatemate/learn-fpga/step10$ /home/fm/cc-toolchain-linux/bin/p_r/p_r -h
GateMate (c) Place and Route
Version 4.2 (1 Jul 2023)
All Rights Reserved (c) Cologne Chip AG

fm@nuc7fpga:~$ cat cc-toolchain-linux/bin/VERSION 
yosys-gcc-static-0.29+42
openFPGALoader-mingw64-v.0.10.0
p_r-dcclinux64-2023.07-002

Workaround:
Create a local constraints file and a local Makefile inside the step08 and step10 folders, copied from the global master. Remove the UART pin assignment line inside the local constraints file copy. The serial line is only needed from step17 onwards, so taking them out for step08 and step10 will not break the code. Finally, adjust the local Makefile to let 'p_r' use the local constraints file, and run 'make'.

step23 - Incomplete program read from flash memory

In this step we need to use a different Flash offset address than the original 128K that was used by BrunoLevy in his tutorial. The Gatemate toolchain creates a bigger FPGA bitstream file that exceeds the 128K file size:

fm@nuc7fpga:~/fpga/projects/git/gatemate-riscv/step23$ ls -l SOC_00.cfg.bit
-rwxrwxrwx 1 root root 316128 Oct 15 15:48 SOC_00.cfg.bit

The 300K-sized bitstream data would easily overwrite the RISC-V program if it were uploaded at 128K. To solve this, I modified the "ldscripts-shared/spiflash0.ld" linker script file from 0x820000 (128K) offset to 0x880000 (512K) offset, and also changed the data read address value inside SOC.v.

   initial begin
      LI(a0,32'h00880000); // jump to SPI FLASH at 512 kB offset
      JALR(zero,a0,0);
   end

Finally inside the Makefile, I upload the RISC-V binary file with the 512K offset:
openFPGALoader -b gatemate_evb_spi -o 524288 src-hello/hello.spiflash0.bin -f

Issue: The RISC-V program code is not completely read from flash memory, and therefore does not run.

In simulation (not using flash but reading the program from file), it works fine. This is a good sign that the compiled assembly program works as intended:

fm@nuc7fpga:~/fpga/projects/git/gatemate-riscv/step23$ make test
Running testbench simulation
test ! -e SOC.tb || rm SOC.tb
test ! -e SOC.vcd || rm SOC.vcd
/usr/bin/iverilog -DBENCH -o SOC.tb -s SOC_tb SOC_tb.v SOC.v ../rtl-shared/clockworks.v ../rtl-shared/pll_gatemate.v ../rtl-shared/emmitter_uart.v ../rtl-shared/spi_flash.v
/usr/bin/vvp SOC.tb
Gatemate E1 RISC-V: Hello World, running from Flash!

When I check the real FPGA execution with the protocol analyzer, I can see the SPI flash read for the RISC-V program starts at 0x80000, as intended. It reads the correct values (1st four bytes of the RISC-V program are "b7 01 40 00") and continues with the next 4 bytes. However, the SPI reading always stops after doing 15 times 4-byte read cycles, at address 0x80090. The last byte sequence received is "63 0a 05 00". This loads only 60 bytes of the 306-byte hello.spiflash0.bin program, and not even in the correct address sequence.

20231015-step23-incomplete-program-load Screenshot of the last 9x 4-byte SPI-reads.

After the SPI data load stops mid-program, the SPI read starts again at the beginning 0x80000, and the 60-byte read repeats in a permanent loop.

I think something is wrong with the SPI flash read logic.

When I reduce the size of the hello.spiflash0.bin (removing the "wait" function, shorten the output string), I even get it almost to work. A single character starts flooding the UART by chance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.