From 3fce9cca770d9abde646532432f1828a926bb126 Mon Sep 17 00:00:00 2001 From: Nick Hebdon Date: Sun, 22 Sep 2024 14:08:07 +0100 Subject: [PATCH] trenz icezero added, note read TUTORIALS/IceZero.md for spi flash tools --- FemtoRV/BOARDS/icezero.mk | 41 +++ FemtoRV/BOARDS/icezero.pcf | 70 +++++ .../icezero.pcf.long.fix-for-icetime.txt | 248 ++++++++++++++++++ FemtoRV/FIRMWARE/ASM_EXAMPLES/test_OLED.S | 3 + FemtoRV/FIRMWARE/ASM_EXAMPLES/tinyblinky.S | 3 + FemtoRV/FIRMWARE/CRT/spiflash_icezero.ld | 102 +++++++ FemtoRV/FIRMWARE/EXAMPLES/ledtest.c | 43 +++ FemtoRV/FIRMWARE/EXAMPLES/malloc_test.c | 4 +- FemtoRV/FIRMWARE/EXAMPLES/pi.c | 6 +- FemtoRV/FIRMWARE/EXAMPLES/sieve.c | 2 +- FemtoRV/FIRMWARE/EXAMPLES/sysconfig.c | 2 +- FemtoRV/FIRMWARE/LIBFEMTORV32/femtorv32.h | 2 +- FemtoRV/FIRMWARE/makefile.inc | 30 ++- FemtoRV/Makefile | 1 + FemtoRV/RTL/CONFIGS/icezero_config.v | 75 ++++++ FemtoRV/RTL/DEVICES/MappedSPIFlash.v | 8 + FemtoRV/RTL/PLL/femtopll.v | 2 + FemtoRV/RTL/PLL/pll_icezero.v | 239 +++++++++++++++++ FemtoRV/RTL/femtosoc_config.v | 13 + FemtoRV/RTL/get_config.v | 4 + .../FROM_BLINKER_TO_RISCV/BOARDS/icezero.pcf | 99 +++++++ .../BOARDS/run_ice4pi.sh | 25 ++ .../BOARDS/run_icezero.sh | 28 ++ .../FROM_BLINKER_TO_RISCV/FIRMWARE/Makefile | 21 +- .../FIRMWARE/spiflash0_icezero.ld | 10 + .../FIRMWARE/spiflash1_icezero.ld | 60 +++++ .../FIRMWARE/spiflash2_icezero.ld | 80 ++++++ .../FROM_BLINKER_TO_RISCV/clockworks.v | 4 + .../FROM_BLINKER_TO_RISCV/spi_flash.v | 13 + .../TUTORIALS/FROM_BLINKER_TO_RISCV/step17.v | 3 +- .../TUTORIALS/FROM_BLINKER_TO_RISCV/step18.v | 3 +- .../TUTORIALS/FROM_BLINKER_TO_RISCV/step20.v | 4 +- .../TUTORIALS/FROM_BLINKER_TO_RISCV/step22.v | 3 +- .../TUTORIALS/FROM_BLINKER_TO_RISCV/step23.v | 12 +- .../TUTORIALS/FROM_BLINKER_TO_RISCV/step24.v | 7 +- FemtoRV/TUTORIALS/IceZero.md | 46 ++++ FemtoRV/TUTORIALS/README.md | 1 + 37 files changed, 1283 insertions(+), 34 deletions(-) create mode 100644 FemtoRV/BOARDS/icezero.mk create mode 100644 FemtoRV/BOARDS/icezero.pcf create mode 100644 FemtoRV/BOARDS/icezero.pcf.long.fix-for-icetime.txt create mode 100644 FemtoRV/FIRMWARE/CRT/spiflash_icezero.ld create mode 100644 FemtoRV/FIRMWARE/EXAMPLES/ledtest.c create mode 100644 FemtoRV/RTL/CONFIGS/icezero_config.v create mode 100644 FemtoRV/RTL/PLL/pll_icezero.v create mode 100644 FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/icezero.pcf create mode 100755 FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_ice4pi.sh create mode 100755 FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_icezero.sh create mode 100644 FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash0_icezero.ld create mode 100644 FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash1_icezero.ld create mode 100644 FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash2_icezero.ld create mode 100644 FemtoRV/TUTORIALS/IceZero.md diff --git a/FemtoRV/BOARDS/icezero.mk b/FemtoRV/BOARDS/icezero.mk new file mode 100644 index 00000000..4aa8380d --- /dev/null +++ b/FemtoRV/BOARDS/icezero.mk @@ -0,0 +1,41 @@ +MINFREQ=12 #i'm a novice, not sure but giving lax timing requirements seem to work for this 100MHz clocked board +YOSYS_ICEZERO_OPT=-DICE_ZERO -q -p "synth_ice40 -relut -top $(PROJECTNAME) -json $(PROJECTNAME).json" +NEXTPNR_ICEZERO_OPT=--force --json $(PROJECTNAME).json --pcf BOARDS/icezero.pcf --asc $(PROJECTNAME).asc \ + --freq $(MINFREQ) --hx8k --package tq144:4k --opt-timing +#NEXTPNR_ICEZERO_OPT=--force --seed 18 --json $(PROJECTNAME).json --pcf BOARDS/icezero.pcf --asc $(PROJECTNAME).asc \ +# --freq $(XTAL_FREQ) --hx8k --package tq144:4k --opt-timing + + +####################################################################################################################### + +ICEZERO: ICEZERO.firmware_config ICEZERO.synth ICEZERO.prog + +ICEZERO.synth: + yosys $(YOSYS_ICEZERO_OPT) $(VERILOGS) + nextpnr-ice40 $(NEXTPNR_ICEZERO_OPT) + icetime -p BOARDS/icezero.pcf -P tq144:4k -r $(PROJECTNAME).timings -d hx8k -t $(PROJECTNAME).asc + icepack -s $(PROJECTNAME).asc $(PROJECTNAME).bin + +#ICEZERO.synth: +# yosys $(YOSYS_ICEZERO_OPT) $(VERILOGS) +# nextpnr-ice40 $(NEXTPNR_ICEZERO_OPT) +# icetime -c $(XTAL_FREQ) -p BOARDS/icezero.pcf -P tq144:4k -r $(PROJECTNAME).timings -d hx8k -t $(PROJECTNAME).asc +# icepack -s $(PROJECTNAME).asc $(PROJECTNAME).bin + +ICEZERO.show: + yosys $(YOSYS_ICEZERO_OPT) $(VERILOGS) + nextpnr-ice40 $(NEXTPNR_ICEZERO_OPT) --gui + +ICEZERO.prog: + rcp $(PROJECTNAME).bin lattice@ice.local://home/lattice/trenz + #iceprog $(PROJECTNAME).bin + +ICEZERO.firmware_config: + BOARD=icezero TOOLS/make_config.sh -DICE_ZERO + (cd FIRMWARE; make libs) + +ICEZERO.lint: + verilator -DICE_ZERO -DBENCH --lint-only --top-module $(PROJECTNAME) \ + -IRTL -IRTL/PROCESSOR -IRTL/DEVICES -IRTL/PLL $(VERILOGS) + +####################################################################################################################### diff --git a/FemtoRV/BOARDS/icezero.pcf b/FemtoRV/BOARDS/icezero.pcf new file mode 100644 index 00000000..17e1417a --- /dev/null +++ b/FemtoRV/BOARDS/icezero.pcf @@ -0,0 +1,70 @@ +#tested with D5 remap, D5 is not available programmatically through RV code it is wired to the verilog error logic +#had used ice4pi to get familiar with tools before trying to add trenz version of icezero +#appear to be 3 onboard leds and seems 5 are expected +#icezero has legended LEDS D2,D3,D4 +#as error is apparently signalled on D5 will probably alias physical D2 for D5 +#NEGATIVE reset and correct to have RESET on 47 + +#set_io clk_100m 49 -pullup yes +set_io pclk 49 + +#set_io p1_d[0] 141 -pullup yes +#set_io p1_d[1] 139 -pullup yes +#set_io p1_d[2] 138 -pullup yes +#set_io p1_d[3] 137 -pullup yes +#set_io p1_d[4] 136 -pullup yes +#set_io p1_d[5] 135 -pullup yes +#set_io p1_d[6] 134 -pullup yes +#set_io p1_d[7] 130 -pullup yes +#PMOD P1 at opposite end of pcb than with ice4pi, but 3v3 and gnd have same positions relative to 40pin header this way +set_io oled_DIN 134 #p1d6 BLUE +set_io oled_CLK 136 #p1d4 YELLOW +set_io oled_CS 138 #p1d2 ORANGE +set_io oled_DC 141 #p1d0 GREEN +set_io oled_RST 139 #p1d1 WHITE +#PMOD P1 LED matrix pin out untested +set_io ledmtx_DIN 130 #p1d7 +set_io ledmtx_CS 135 #p1d5 +set_io ledmtx_CLK 137 #p1d3 + + +#set_io led_te[0] 93 -pullup yes #deduced was tbd[8] check +#set_io led_te[1] 94 -pullup yes #deduced was tbd[9] check +#set_io ok_led 110 -pullup yes + +#map missing LEDS to p4, could be anywhere really, just need to allocate free pins +#set_io p4_d[0] 1 -pullup yes +#set_io p4_d[1] 144 -pullup yes + +#substituting D5 for D2 as apparently D5 used for error signalling +#so right now verilog D2 and D1 can't be seen without adding LEDS + RESISTOR for each +set_io D5 110 #following PCB legend D2,D3,D4 visible pretend that legend D2 is D5 so that errors can be indicated +set_io D4 94 +set_io D3 93 +set_io D2 1 +set_io D1 144 + + +#set_io pi_uart_ro 112 -pullup yes +#set_io pi_uart_wi 113 -pullup yes +set_io RXD 113 +set_io TXD 112 + + +#set_io cfg_so 67 +#set_io cfg_si 68 +#set_io cfg_sck 70 +#set_io cfg_ss 71 +set_io spi_cs_n 71 +set_io spi_miso 68 +set_io spi_mosi 67 +set_io spi_clk 70 + + +set_io RESET 47 + +####NOT PRESENT ON PCB +####set_io irda_TXD 105 +####set_io irda_RXD 106 +####set_io irda_SD 107 + diff --git a/FemtoRV/BOARDS/icezero.pcf.long.fix-for-icetime.txt b/FemtoRV/BOARDS/icezero.pcf.long.fix-for-icetime.txt new file mode 100644 index 00000000..7f6af41a --- /dev/null +++ b/FemtoRV/BOARDS/icezero.pcf.long.fix-for-icetime.txt @@ -0,0 +1,248 @@ +#had used ice4pi to get familiar with tools before trying to add trenz version of icezero +#right now pmod P1 connection order will be wrong need to take mapping from Oyster PMOD +#appear to be 3 onboard leds and seems 5 are expected +#icezero has legended LEDS D2,D3,D4 +#as error is apparently signalled on D5 will alias physical D2 for D5 +#if compile stops because of missing D1 and D2 will bring them out onto P4 +#assuming NEGATIVE reset and correct to have RESET on 47 +#will check before uploading to FPGA + +#-pullup yes causes problems for parsing + +#set_io pclk 21 +#set_io clk_100m 49 -pullup yes +set_io pclk 49 -pullup yes + + +#set_io oled_DIN 91 +#set_io oled_CLK 90 +#set_io oled_CS 88 +#set_io oled_DC 87 +#set_io oled_RST 78 +#set_io ledmtx_DIN 81 +#set_io ledmtx_CS 80 +#set_io ledmtx_CLK 79 +#set_io p1_d[0] 141 -pullup yes +#set_io p1_d[1] 139 -pullup yes +#set_io p1_d[2] 138 -pullup yes +#set_io p1_d[3] 137 -pullup yes +#set_io p1_d[4] 136 -pullup yes +#set_io p1_d[5] 135 -pullup yes +#set_io p1_d[6] 134 -pullup yes +#set_io p1_d[7] 130 -pullup yes +#assign at random to start with to get it to compile +#P1 at opposite end of pcb than with ice4pi, but 3v3 and gnd have same possitions this way + +#see corrected pmod assignments in icezero.pcf +#set_io oled_DIN 141 +#set_io oled_CLK 139 +#set_io oled_CS 138 +#set_io oled_DC 137 +#set_io oled_RST 136 +#set_io ledmtx_DIN 135 +#set_io ledmtx_CS 134 +#set_io ledmtx_CLK 130 + + +#set_io D1 99 +#set_io D2 98 +#set_io D3 97 +####set_io D4 96 +####set_io D5 95 +#set_io led_te[0] 93 -pullup yes #deduced was tbd[8] check +#set_io led_te[1] 94 -pullup yes #deduced was tbd[9] check +#set_io ok_led 110 -pullup yes + +#see corrected pmod assignments in icezero.pcf +#set_io D5 93 -pullup yes #these leds will most probably be out of sequence, following PCB legend +#set_io D3 94 -pullup yes #correct later +#set_io D4 110 -pullup yes + +#set_io p4_d[0] 1 -pullup yes +#set_io p4_d[1] 144 -pullup yes + +#see corrected pmod assignments in icezero.pcf +#set_io D2 1 +#set_io D1 144 + +#will be substituting D5 for D2 as apparently D5 used for error signalling +#need to sort out where D2 is so can comment properly + +#set_io TXD 8 +#set_io RXD 9 +#set_io pi_uart_ro 112 -pullup yes +#set_io pi_uart_wi 113 -pullup yes + +#see corrected pmod assignments in icezero.pcf +#set_io RXD 112 -pullup yes +#set_io TXD 113 -pullup yes + + +#set_io spi_cs_n 71 +#set_io spi_miso 68 +#set_io spi_mosi 67 +#set_io spi_clk 70 +#set_io cfg_so 67 +#set_io cfg_si 68 +#set_io cfg_sck 70 +#set_io cfg_ss 71 +set_io spi_cs_n 71 +set_io spi_miso 68 +set_io spi_mosi 67 +set_io spi_clk 70 + + +set_io RESET 47 + +####NOT PRESENT ON PCB +####set_io irda_TXD 105 +####set_io irda_RXD 106 +####set_io irda_SD 107 + +#TAKE FROM BELOW IF ADDING MAPPED SRAM +#ALSO HAS OTHER PMODS AND SOME Raspberry Pi GPIO +#WILL NEED TO SORT OUT -pullup yes type syntax +#Also don't know yet what button on trenz icezero is for. + +################################################################# +# iCEcube PCF +# Version: 2012.09SP1.22498 +# File Generated: May 1 2013 11:36:30 +# Family & Device: iCE40HX4K +# Package: TQ144 +# ################################################################# +set_io sram_a[9] 2 -pullup yes #[22] +set_io sram_a[8] 3 -pullup yes #[21] +set_io sram_a[7] 4 -pullup yes #[20] +set_io rsvd[0] 7 -pullup yes +set_io rsvd[1] 8 -pullup yes +set_io sram_a[6] 9 -pullup yes #[19] +set_io sram_a[5] 10 -pullup yes #[18] +set_io sram_we_l 11 -pullup yes #[17] +set_io sram_d[7] 12 -pullup yes #[16] + +set_io sram_d[6] 15 -pullup yes #[15] +set_io sram_d[5] 16 -pullup yes #[14] +set_io sram_d[4] 17 -pullup yes #[13] + +set_io sram_d[3] 18 -pullup yes #[10] +set_io sram_d[2] 19 -pullup yes #[9] + +set_io sram_d[1] 22 -pullup yes #[8] +set_io sram_d[0] 23 -pullup yes #[7] +set_io sram_ce_l 24 -pullup yes #[6] +set_io sram_a[4] 25 -pullup yes #[5] +set_io rsvd[2] 26 -pullup yes +set_io rsvd[3] 28 -pullup yes +set_io rsvd[4] 29 -pullup yes + +set_io sram_a[3] 31 -pullup yes #[4] +set_io sram_a[2] 32 -pullup yes #[3] +set_io sram_a[1] 33 -pullup yes #[2] +set_io sram_a[0] 34 -pullup yes #[1] + +set_io tbd[0] 35 -pullup yes +set_io tbd[1] 36 -pullup yes + +#set_io clk_100m 49 -pullup yes + +set_io tbd[2] 50 -pullup yes +set_io tbd[3] 51 -pullup yes +set_io tbd[4] 52 -pullup yes + + +set_io tbd[5] 58 -pullup yes + +set_io sram_a[16] 60 -pullup yes #[43] +set_io sram_a[17] 61 -pullup yes #[44] +set_io sram_a[15] 62 -pullup yes #[42] + +set_io cbsel[0] 63 -pullup yes +set_io cbsel[1] 64 -pullup yes + +# set_io cfg_done 65 +# set_io cfg_rst_l 66 +set_io cfg_so 67 +set_io cfg_si 68 +set_io cfg_sck 70 +set_io cfg_ss 71 +set_io tbd[6] 72 -pullup yes + +set_io pi_id[0] 73 -pullup yes +set_io pi_id[1] 74 -pullup yes + +set_io sram_ub_l 75 -pullup yes #[42] +set_io sram_oe_l 76 -pullup yes #[41] +set_io tbd[7] 77 -pullup yes + +set_io pi_spi_ce[1] 78 -pullup yes +set_io pi_spi_sck 79 -pullup yes +set_io sram_d[15] 80 -pullup yes #[38] + +set_io sram_lb_l 81 -pullup yes #[39] +set_io sram_d[13] 82 -pullup yes #[36] +set_io sram_d[14] 83 -pullup yes #[37] +set_io sram_d[12] 84 -pullup yes #[35] +set_io pi_spi_ce[0] 85 -pullup yes +set_io pi_spi_miso 87 -pullup yes +set_io pi_gpio[0] 88 -pullup yes +set_io pi_spi_mosi 90 -pullup yes +set_io sram_d[11] 91 -pullup yes #[32] +set_io led_te[0] 93 -pullup yes #deduced was tbd[8] check +set_io led_te[1] 94 -pullup yes #deduced was tbd[9] check +set_io sram_d[10] 95 -pullup yes #[31] +set_io sram_d[9] 96 -pullup yes #[30] +set_io sram_d[8] 97 -pullup yes #[29] +set_io sram_a[18] 98 -pullup yes #[28] +set_io pi_gpio[1] 99 -pullup yes +set_io pi_gpio[2] 101 -pullup yes +set_io sram_a[14] 102 -pullup yes #[27] +set_io sram_a[13] 104 -pullup yes #[26] +set_io sram_a[12] 105 -pullup yes #[25] +set_io sram_a[11] 106 -pullup yes #[24] +set_io sram_a[10] 107 -pullup yes #[23] +set_io ok_led 110 -pullup yes +set_io pi_uart_ro 112 -pullup yes +set_io pi_uart_wi 113 -pullup yes +set_io pi_i2c_scl 114 -pullup yes +set_io pi_i2c_sda 115 -pullup yes + +set_io xtra_a[2] 116 -pullup yes +set_io xtra_a[3] 117 -pullup yes +set_io xtra_a[4] 118 -pullup yes +set_io ftdi_wo 119 -pullup yes +set_io xtra_a[0] 120 -pullup yes +set_io xtra_a[1] 121 -pullup yes +set_io ftdi_wi 122 -pullup yes +set_io ftdi_ro 124 -pullup yes +set_io ftdi_ri 125 -pullup yes +set_io j0_l 128 -pullup yes # Input Only Clock Capable +set_io j1_l 129 -pullup yes # Input Only Clock Capable + +set_io p1_d[0] 141 -pullup yes +set_io p1_d[1] 139 -pullup yes +set_io p1_d[2] 138 -pullup yes +set_io p1_d[3] 137 -pullup yes +set_io p1_d[4] 136 -pullup yes +set_io p1_d[5] 135 -pullup yes +set_io p1_d[6] 134 -pullup yes +set_io p1_d[7] 130 -pullup yes + +set_io p2_d[0] 55 -pullup yes +set_io p2_d[1] 56 -pullup yes +set_io p2_d[2] 47 -pullup yes +set_io p2_d[3] 48 -pullup yes +set_io p2_d[4] 44 -pullup yes +set_io p2_d[5] 45 -pullup yes +set_io p2_d[6] 42 -pullup yes +set_io p2_d[7] 43 -pullup yes + +set_io p3_d[0] 41 -pullup yes +set_io p3_d[1] 39 -pullup yes +set_io p3_d[2] 38 -pullup yes +set_io p3_d[3] 37 -pullup yes + +set_io p4_d[0] 1 -pullup yes +set_io p4_d[1] 144 -pullup yes +set_io p4_d[2] 143 -pullup yes +set_io p4_d[3] 142 -pullup yes diff --git a/FemtoRV/FIRMWARE/ASM_EXAMPLES/test_OLED.S b/FemtoRV/FIRMWARE/ASM_EXAMPLES/test_OLED.S index 8fb2bd03..0e1a1570 100644 --- a/FemtoRV/FIRMWARE/ASM_EXAMPLES/test_OLED.S +++ b/FemtoRV/FIRMWARE/ASM_EXAMPLES/test_OLED.S @@ -8,6 +8,9 @@ .ifdef ICE_STICK .section .fastcode .endif +.ifdef ICE_ZERO +.section .fastcode +.endif .globl main .type main, @function diff --git a/FemtoRV/FIRMWARE/ASM_EXAMPLES/tinyblinky.S b/FemtoRV/FIRMWARE/ASM_EXAMPLES/tinyblinky.S index 70cdf53c..a371d18c 100644 --- a/FemtoRV/FIRMWARE/ASM_EXAMPLES/tinyblinky.S +++ b/FemtoRV/FIRMWARE/ASM_EXAMPLES/tinyblinky.S @@ -8,6 +8,9 @@ .ifdef ICE_STICK .section .fastcode .endif +.ifdef ICE_ZERO +.section .fastcode +.endif main: li x8, 0x400004 # LED register diff --git a/FemtoRV/FIRMWARE/CRT/spiflash_icezero.ld b/FemtoRV/FIRMWARE/CRT/spiflash_icezero.ld new file mode 100644 index 00000000..e5cfdb22 --- /dev/null +++ b/FemtoRV/FIRMWARE/CRT/spiflash_icezero.ld @@ -0,0 +1,102 @@ +/*based on spiflash_icestick.ld, USING the ADDITIONAL 8K of BRAM available on this part*/ + +/* Linker script for programs stored in SPI flash */ +/* Inspired from picorv32/picosoc/sections.lds */ +/* */ +/* text and rodata sections are sent to flash */ +/* bss sections are sent to BRAM */ +/* data sections are sent to BRAM and have */ +/* initialization data in flash. */ +/* AT keyword specifies LMA (Load Memory Address) */ + +MEMORY { + FLASH (rx) : ORIGIN = 0x00830000, LENGTH = 0x100000 - 0x30000 /* 4 MB in flash */ + RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x3800 /* 6 kB + 8 kB in RAM */ +} + +SECTIONS { + + /* + * This is the initialized data and fastcode section + * The program executes knowing that the data is in the RAM + * but the loader puts the initial values in the FLASH (inidata). + * It is one task of the startup (crt0_spiflash.S) to copy the initial values from FLASH to RAM. + */ + .data_and_fastcode : AT ( _sidata ) { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + _ram_start = .; /* create a global symbol at ram start (e.g., for garbage collector) */ + + /* Initialized data */ + *(.data) + *(.data*) + *(.sdata) + *(.sdata*) + + /* functions with attribute((section(".fastcode"))) */ + /* (e.g., some functions in femtoGL) */ + *(.fastcode*) + + /* integer mul and div */ + */libgcc.a:muldi3.o(.text) + */libgcc.a:div.o(.text) + + /* low-level graphics functions */ + */libfemtorv32.a:ssd1351_1331.o(.text) + + /* timing */ + wait_cycles.o(.text) + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */ + } > RAM + + /* The (non fastcode) program code and other data goes into FLASH */ + .text : { + . = ALIGN(4); + crt0_spiflash.o(.text) /* c runtime initialization (code) */ + + + /* + * I do not understand why, but if I do not put that here, I got + * an overlapping sections error with some programs (for instance pi.c + * or C++ programs) + */ + *(.eh_frame) + *(.eh_frame_hdr) + *(.init_array) + *(.gcc_except_table*) + + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.srodata) /* .rodata sections (constants, strings, etc.) */ + *(.srodata*) /* .rodata* sections (constants, strings, etc.) */ + _etext = .; /* define a global symbol at end of code */ + _sidata = _etext; /* This is used by the startup in order to initialize the .data section */ + } >FLASH + + /* Uninitialized data section */ + .bss : { + . = ALIGN(4); + _sbss = .; /* define a global symbol at bss start; used by startup code */ + *(.bss) + *(.bss*) + *(.sbss) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end; used by startup code */ + } >RAM + + /* this is to define the start of the heap, and make sure we have a minimum size */ + .heap : { + . = ALIGN(4); + _heap_start = .; /* define a global symbol at heap start */ + _end = .; /* as expected by syscalls.c */ + } >RAM + + +} diff --git a/FemtoRV/FIRMWARE/EXAMPLES/ledtest.c b/FemtoRV/FIRMWARE/EXAMPLES/ledtest.c new file mode 100644 index 00000000..47486c58 --- /dev/null +++ b/FemtoRV/FIRMWARE/EXAMPLES/ledtest.c @@ -0,0 +1,43 @@ +#include +//#include + +int main() { + + int bits=0x3f; + //GL_tty_init(GL_MODE_OLED); + printf("femtorv32 LED pcf assignment check\n"); + for(;;) { + + IO_OUT(IO_LEDS, bits); + printf("bits=%x\n", (int)bits); + + int c = getchar(); + if(c != 10 && c !=13) { + //putchar(c); + // printf("char=%d\n", (int)c); + switch (c) { + case '+': + bits++; + break; + case '-': + bits--; + break; + case '<': + bits = bits << 1; + break; + case '>': + bits = bits >> 1; + break; + default: + putchar('?'); + break; + } + bits = bits & 0xff; + } else { + putchar('\n'); + putchar(']'); + } + } + return 0; +} + diff --git a/FemtoRV/FIRMWARE/EXAMPLES/malloc_test.c b/FemtoRV/FIRMWARE/EXAMPLES/malloc_test.c index b7c5737a..27bf5b2e 100644 --- a/FemtoRV/FIRMWARE/EXAMPLES/malloc_test.c +++ b/FemtoRV/FIRMWARE/EXAMPLES/malloc_test.c @@ -3,7 +3,7 @@ extern int femtosoc_tty_init(); int main() { - femtosoc_tty_init(); + //femtosoc_tty_init(); void* p1 = malloc(10); void* p2 = malloc(100); printf("p1=0x%x\n",p1); @@ -11,6 +11,6 @@ int main() { free(p2); free(p1); void* p3 = malloc(50); - printf("p1=0x%x\n",p3); + printf("p3=0x%x\n",p3); exit(0); } diff --git a/FemtoRV/FIRMWARE/EXAMPLES/pi.c b/FemtoRV/FIRMWARE/EXAMPLES/pi.c index ea3e63b3..e87ce57a 100644 --- a/FemtoRV/FIRMWARE/EXAMPLES/pi.c +++ b/FemtoRV/FIRMWARE/EXAMPLES/pi.c @@ -175,10 +175,10 @@ int digits(int n) { int main() { - MAX7219_tty_init(); // Uncomment to display on led matrix. -// femtosoc_tty_init(); + //MAX7219_tty_init(); // Uncomment to display on led matrix. + // femtosoc_tty_init(); // GL_set_font(&Font3x5); -// GL_set_font(&Font8x16); + // GL_set_font(&Font8x16); printf("pi = 3."); for(int n=1; ;n+=9) { printf("%d",digits(n)); diff --git a/FemtoRV/FIRMWARE/EXAMPLES/sieve.c b/FemtoRV/FIRMWARE/EXAMPLES/sieve.c index 026cbc3a..ff142f18 100644 --- a/FemtoRV/FIRMWARE/EXAMPLES/sieve.c +++ b/FemtoRV/FIRMWARE/EXAMPLES/sieve.c @@ -103,7 +103,7 @@ int main(void) * using the led matrix, or GL_tty_init() if you know you are * using the small OLED display. */ - femtosoc_tty_init(); + //femtosoc_tty_init(); for(;;) { sieve(); diff --git a/FemtoRV/FIRMWARE/EXAMPLES/sysconfig.c b/FemtoRV/FIRMWARE/EXAMPLES/sysconfig.c index 17739364..b5c2af61 100644 --- a/FemtoRV/FIRMWARE/EXAMPLES/sysconfig.c +++ b/FemtoRV/FIRMWARE/EXAMPLES/sysconfig.c @@ -36,7 +36,7 @@ int main() { for(;;) { show_config(); - delay(3000); + delay(10000); } return 0; diff --git a/FemtoRV/FIRMWARE/LIBFEMTORV32/femtorv32.h b/FemtoRV/FIRMWARE/LIBFEMTORV32/femtorv32.h index 394366df..30aaf30e 100644 --- a/FemtoRV/FIRMWARE/LIBFEMTORV32/femtorv32.h +++ b/FemtoRV/FIRMWARE/LIBFEMTORV32/femtorv32.h @@ -10,7 +10,7 @@ * (much faster) RAM (but use it wisely, you only got 7kB). * Other devices are sufficient RAM to load all the code. */ -#if defined(ICE_STICK) || defined(ICE_BREAKER) +#if defined(ICE_STICK) || defined(ICE_BREAKER) || defined(ICE_ZERO) #define RV32_FASTCODE __attribute((section(".fastcode"))) #else #define RV32_FASTCODE diff --git a/FemtoRV/FIRMWARE/makefile.inc b/FemtoRV/FIRMWARE/makefile.inc index 84b82224..21dcb6c7 100644 --- a/FemtoRV/FIRMWARE/makefile.inc +++ b/FemtoRV/FIRMWARE/makefile.inc @@ -7,17 +7,27 @@ ##################################################################### # Base directory of the firmware +#nfs mount for raspberry pi hosting trenz icezero fpga hardware + + FIRMWARE_DIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +RASPI_REMOTE_DIR=$(abspath $(FIRMWARE_DIR)../../../mnt/) + include $(FIRMWARE_DIR)/config.mk DEVICES_ASM=$(subst -D,-defsym ,$(DEVICES)) show_config: +ifeq ($(BOARD),icezero) + @echo "RASPI_REMOTE_DIR=$(RASPI_REMOTE_DIR)/trenz" +else ifeq ($(BOARD),ice4pi) + @echo "RASPI_REMOTE_DIR=$(RASPI_REMOTE_DIR)" +endif @echo "ARCH=$(ARCH)" - @echo "ABI=$(ABI)" - @echo "OPTIMIZE=$(OPTIMIZE)" + @echo "ABI=$(ABI)" + @echo "OPTIMIZE=$(OPTIMIZE)" @echo "DEVICES=$(DEVICES)" - @echo "DEVICES_ASM=$(DEVICES_ASM)" + @echo "DEVICES_ASM=$(DEVICES_ASM)" ################################################################################ @@ -83,10 +93,18 @@ RVGCC_LIB= $(RVTOOLCHAIN_LIB_DIR)/libc.a \ # My utility that converts elf executables into a format understood by Verilog FIRMWARE_WORDS=$(FIRMWARE_DIR)/TOOLS/firmware_words +#need to link icezero spiflash programs for 192k offset +LINKADJUST=.ld + ifeq ($(BOARD),icesugar_nano) - TOOLCHAIN_PROG_CMD=icesprog -o 0x20000 + TOOLCHAIN_PROG_CMD=icesprog -o 0x20000 $< +else ifeq ($(BOARD),ice4pi) + TOOLCHAIN_PROG_CMD=cp $< $(RASPI_REMOTE_DIR)/ +else ifeq ($(BOARD),icezero) + TOOLCHAIN_PROG_CMD=cp $< $(RASPI_REMOTE_DIR)/trenz/ + LINKADJUST=_icezero.ld else - TOOLCHAIN_PROG_CMD=iceprog -o 128k + TOOLCHAIN_PROG_CMD=iceprog -o 128k $< endif ################################################################################ @@ -148,7 +166,7 @@ FEMTORV32_LIBS_SMALL=-L$(RVTOOLCHAIN_LIB_DIR)\ # Sends the generated executable in flat binary form to SPI flash %.prog: %.spiflash.bin - $(TOOLCHAIN_PROG_CMD) $< + $(TOOLCHAIN_PROG_CMD) # Generate a disassembly (for inspection if need be) %.list: %.baremetal.elf diff --git a/FemtoRV/Makefile b/FemtoRV/Makefile index 020916ee..e20bc0d1 100644 --- a/FemtoRV/Makefile +++ b/FemtoRV/Makefile @@ -3,6 +3,7 @@ PROJECTNAME=femtosoc VERILOGS=RTL/$(PROJECTNAME).v include BOARDS/bench.mk +include BOARDS/icezero.mk include BOARDS/ice4pi.mk include BOARDS/icestick.mk include BOARDS/icestick_mecrisp_quintus.mk diff --git a/FemtoRV/RTL/CONFIGS/icezero_config.v b/FemtoRV/RTL/CONFIGS/icezero_config.v new file mode 100644 index 00000000..cd52c740 --- /dev/null +++ b/FemtoRV/RTL/CONFIGS/icezero_config.v @@ -0,0 +1,75 @@ +/********************************************************************************************************************/ +//N O T E icezero *Port to icezero is first go by a novice at fpga +//N O T E icezero *an example for icezero tachyon defines can be found below +//N O T E icezero *femtosoc configurations file info for IceZero {quark, tachyon and gracilis confirmed on silicon} +//N O T E icezero *with NRV_FREQ quark==40, tachyon==55, gracilis==24 other processors not tested yet +//icezero board clocking adopted according to output from synthesis tool +//N.B. `define NRV_FREQ 24 #for gracilis, but just room to go to 25 without overclock +//14kB BRAM, note TUTORIAL version left at 6kB BRAM to stay compatible with documentation and sources +//icezero has 3 onboard LEDS not 5 these have legends D2, D3, D4 +//Mapped IO, pcf aliased D2 for D5 as comments seen about error reporting on D5, but D3=D3 and D4=D4 +//MAX_7219 pcf untested but we have losts of space compared to an icestick so left active +//tested with waveshare SSD1351 +/********************************************************************************************************************/ + +/************************* Devices **********************************************************************************/ + +`define NRV_IO_LEDS // Mapped IO, LEDs D2,D3,D4 (D5 is used to display errors) #will alias D2 for D5 because of error reporting nature +//`define NRV_IO_IRDA // In IO_LEDS, support for the IRDA on the IceStick (WIP) +`define NRV_IO_UART // Mapped IO, virtual UART #not (USB) /dev/ttyS0 on raspberry pi 40pin header +`define NRV_IO_SSD1351 // Mapped IO, 128x128x64K OLED screen +`define NRV_IO_MAX7219 // Mapped IO, 8x8 led matrix NOT TESTED BUT WE HAVE PLENTY OF SPACE TO LEAVE ACTIVE +`define NRV_MAPPED_SPI_FLASH // SPI flash mapped in address space. Can be used to run code from SPI flash. + +/************************* Processor configuration *******************************************************************/ + +/* +`define NRV_FEMTORV32_TACHYON // "Tachyon" (carefully latched for max highfreq). Needs more space (remove MAX7219). +`define NRV_FREQ 60 // Validated at 60 MHz on the IceStick. Can overclock to 80-95 MHz. +`define NRV_RESET_ADDR 32'h00820000 // Jump execution to SPI Flash (800000h, +128k(20000h) for FPGA bitstream) +`define NRV_COUNTER_WIDTH 24 // Number of bits in cycles counter +`define NRV_TWOLEVEL_SHIFTER // Faster shifts +*/ +// tinyraytracer: 90 MHz, stick was ??:?? +// 95 MHz, stick was ??:?? + +/* trenz icezero tachyon example +//take care over NVR_RAM and NVR_RESET_ADDR as discordent with icestick examples +`define NRV_FEMTORV32_TACHYON // "Tachyon" (carefully latched for max highfreq). Needs more space (remove MAX7219). +`define NRV_FREQ 55 // Validated at 60 MHz on the IceStick. Can overclock to 80-95 MHz. +`define NRV_RESET_ADDR 32'h00830000 // Jump execution to SPI Flash (800000h, +128k(20000h) for FPGA bitstream) +`define NRV_COUNTER_WIDTH 24 // Number of bits in cycles counter +`define NRV_TWOLEVEL_SHIFTER // Faster shifts +`define NRV_RAM 14336 // 6144 was default for ICESTICK we use all BRAMS available to us regfile=2k 14k=((2*8k) - regfile) +*/ + + +//`define NRV_FEMTORV32_QUARK +`define NRV_FEMTORV32_TACHYON // RV32I high freq +//`define NRV_FEMTORV32_QUARK_BICYCLE // RV32I 2 CPI +//`define NRV_FEMTORV32_ELECTRON // RV32IM +//`define NRV_FEMTORV32_GRACILIS // RV32IMC, IRQ //tested on icezero from trenz at 24MHz, could do 25 without entering overclock territory +//`define NRV_FEMTORV32_PETITBATEAU + + +`define NRV_FREQ 55 // Validated at 50 MHz on the IceStick. Can overclock to 70 MHz. +`define NRV_RESET_ADDR 32'h00830000 // Jump execution to SPI Flash (800000h, +192k(30000h) for FPGA bitstream on icezero) +`define NRV_COUNTER_WIDTH 24 // Number of bits in cycles counter +`define NRV_TWOLEVEL_SHIFTER // Faster shifts +// tinyraytracer: 70 MHz, stick was 17:30 + + +/************************* RAM (in bytes, needs to be a multiple of 4)***********************************************/ + +//`define NRV_RAM 6144 //6144 was default for ICESTICK +`define NRV_RAM 14336 //(hx8k is double icestick BRAM capacity) 16384-2048 = 14336 + +/************************* Advanced devices configuration ***********************************************************/ + +`define NRV_RUN_FROM_SPI_FLASH // Do not 'readmemh()' firmware from '.hex' file +`define NRV_IO_HARDWARE_CONFIG // Comment-out to disable hardware config registers mapped in IO-Space + // (note: firmware libfemtorv32 depends on it) + +/********************************************************************************************************************/ + +`define NRV_CONFIGURED diff --git a/FemtoRV/RTL/DEVICES/MappedSPIFlash.v b/FemtoRV/RTL/DEVICES/MappedSPIFlash.v index 8258982d..f7ca5ebd 100644 --- a/FemtoRV/RTL/DEVICES/MappedSPIFlash.v +++ b/FemtoRV/RTL/DEVICES/MappedSPIFlash.v @@ -45,9 +45,17 @@ `define SPI_FLASH_CONFIGURED `endif +`ifdef ICE_ZERO + `define SPI_FLASH_FAST_READ_DUAL_IO + `define SPI_FLASH_CONFIGURED +`endif + `ifdef ICE4PI `undef SPI_FLASH_FAST_READ_DUAL_IO `undef SPI_FLASH_CONFIGURED + `define SPI_FLASH_FAST_READ_DUAL_IO + `define SPI_FLASH_DUMMY_CLOCKS 4 // Winbond w25q32 SPI chips on ice4pi uses 4 dummy clocks + `define SPI_FLASH_CONFIGURED `endif `ifdef ICE_BREAKER diff --git a/FemtoRV/RTL/PLL/femtopll.v b/FemtoRV/RTL/PLL/femtopll.v index 7ec6b8b4..e7150a12 100644 --- a/FemtoRV/RTL/PLL/femtopll.v +++ b/FemtoRV/RTL/PLL/femtopll.v @@ -24,6 +24,8 @@ endmodule `else `ifdef ICE_STICK `include "pll_icestick.v" + `elsif ICE_ZERO + `include "pll_icezero.v" `elsif ICE_BREAKER `include "pll_icebreaker.v" `elsif ICE_FEATHER diff --git a/FemtoRV/RTL/PLL/pll_icezero.v b/FemtoRV/RTL/PLL/pll_icezero.v new file mode 100644 index 00000000..9abd5a17 --- /dev/null +++ b/FemtoRV/RTL/PLL/pll_icezero.v @@ -0,0 +1,239 @@ +/* + * Do not edit this file, it was generated by gen_pll.sh + * + * FPGA kind : ICE40 + * Input frequency: 100 MHz + */ + + module femtoPLL #( + parameter freq = 40 + ) ( + input wire pclk, + output wire clk + ); + + SB_PLL40_PAD pll ( + .PACKAGEPIN(pclk), + .PLLOUTCORE(clk), + .RESETB(1'b1), + .BYPASS(1'b0) + ); + defparam pll.FEEDBACK_PATH="SIMPLE"; + defparam pll.PLLOUT_SELECT="GENCLK"; + generate + case(freq) + 16: begin + defparam pll.DIVR = 4'b0011; + defparam pll.DIVF = 7'b0101000; + defparam pll.DIVQ = 3'b110; + defparam pll.FILTER_RANGE = 3'b010; + end + 20: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011111; + defparam pll.DIVQ = 3'b101; + defparam pll.FILTER_RANGE = 3'b010; + end + 24: begin + defparam pll.DIVR = 4'b0010; + defparam pll.DIVF = 7'b0010110; + defparam pll.DIVQ = 3'b101; + defparam pll.FILTER_RANGE = 3'b011; + end + 25: begin + defparam pll.DIVR = 4'b0000; + defparam pll.DIVF = 7'b0000111; + defparam pll.DIVQ = 3'b101; + defparam pll.FILTER_RANGE = 3'b101; + end + 30: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0101111; + defparam pll.DIVQ = 3'b101; + defparam pll.FILTER_RANGE = 3'b010; + end + 35: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011011; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b010; + end + 40: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011111; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b010; + end + 45: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0100011; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b010; + end + 48: begin + defparam pll.DIVR = 4'b0010; + defparam pll.DIVF = 7'b0010110; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b011; + end + 50: begin + defparam pll.DIVR = 4'b0000; + defparam pll.DIVF = 7'b0000111; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b101; + end + 55: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0101011; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b010; + end + 60: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0101111; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b010; + end + 65: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0110011; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b010; + end + 66: begin + defparam pll.DIVR = 4'b1000; + defparam pll.DIVF = 7'b1011110; + defparam pll.DIVQ = 3'b100; + defparam pll.FILTER_RANGE = 3'b001; + end + 70: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011011; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 75: begin + defparam pll.DIVR = 4'b0000; + defparam pll.DIVF = 7'b0000101; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b101; + end + 80: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011111; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 85: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0100001; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 90: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0100011; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 95: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0100101; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 100: begin + defparam pll.DIVR = 4'b0000; + defparam pll.DIVF = 7'b0000111; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b101; + end + 105: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0101001; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 110: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0101011; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 115: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0101101; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 120: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0101111; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 125: begin + defparam pll.DIVR = 4'b0000; + defparam pll.DIVF = 7'b0001001; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b101; + end + 130: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0110011; + defparam pll.DIVQ = 3'b011; + defparam pll.FILTER_RANGE = 3'b010; + end + 135: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011010; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b010; + end + 140: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011011; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b010; + end + 150: begin + defparam pll.DIVR = 4'b0000; + defparam pll.DIVF = 7'b0000101; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b101; + end + 160: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0011111; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b010; + end + 170: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0100001; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b010; + end + 180: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0100011; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b010; + end + 190: begin + defparam pll.DIVR = 4'b0100; + defparam pll.DIVF = 7'b0100101; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b010; + end + 200: begin + defparam pll.DIVR = 4'b0000; + defparam pll.DIVF = 7'b0000111; + defparam pll.DIVQ = 3'b010; + defparam pll.FILTER_RANGE = 3'b101; + end + default: UNKNOWN_FREQUENCY unknown_frequency(); + endcase + endgenerate + +endmodule diff --git a/FemtoRV/RTL/femtosoc_config.v b/FemtoRV/RTL/femtosoc_config.v index 6ce68f9f..80cf3e8d 100644 --- a/FemtoRV/RTL/femtosoc_config.v +++ b/FemtoRV/RTL/femtosoc_config.v @@ -8,6 +8,10 @@ `include "CONFIGS/ulx3s_config.v" `endif +`ifdef ICE_ZERO +`include "CONFIGS/icezero_config.v" +`endif + `ifdef ICE_STICK `include "CONFIGS/icestick_config.v" `endif @@ -47,6 +51,10 @@ * (wire a push button and a pullup resistor to * pin 47 or change in nanorv.pcf). */ +`ifdef ICE_ZERO +`define NRV_NEGATIVE_RESET +`endif + `ifdef ICE_STICK //`define NRV_NEGATIVE_RESET `endif @@ -74,6 +82,11 @@ // Toggle FPGA defines (ICE40, ECP5) in function of board defines (ICE_STICK, ECP5_EVN) // Board defines are set in Makefile. +`ifdef ICE_ZERO + `define ICE40 +// `define PASSTHROUGH_PLL +`endif + `ifdef ICE_STICK `define ICE40 `endif diff --git a/FemtoRV/RTL/get_config.v b/FemtoRV/RTL/get_config.v index 4c89f451..a24d7c8b 100644 --- a/FemtoRV/RTL/get_config.v +++ b/FemtoRV/RTL/get_config.v @@ -23,6 +23,7 @@ initial begin // the makefile also passes that to the assembler after // some text substitution, and the assembler needs "=1" + $write("DEVICES="); `ifdef NRV_IO_FGA $write(" -DFGA=1"); @@ -45,6 +46,9 @@ initial begin `ifdef ICE_BREAKER $write(" -DICE_BREAKER=1"); `endif +`ifdef ICE_ZERO + $write(" -DICE_ZERO=1"); +`endif `ifdef ICE_SUGAR_NANO $write(" -DICE_SUGAR_NANO=1"); `endif diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/icezero.pcf b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/icezero.pcf new file mode 100644 index 00000000..7af9cabd --- /dev/null +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/icezero.pcf @@ -0,0 +1,99 @@ +#had used ice4pi to get familiar with tools before trying to add trenz version of icezero +#right now pmod P1 connection order will be wrong need to take mapping from Oyster PMOD +#appear to be 3 onboard leds and seems 5 are expected +#icezero has legended LEDS D2,D3,D4 +#as error is apparently signalled on D5 will alias physical D2 for D5 +#if compile stops becaue of missing D1 and D2 will bring them out onto P4 +#assuming NEGATIVE reset and correct to have RESET on 47 +#will check before uploading to FPGA + +#set_io pclk 21 +#set_io clk_100m 49 -pullup yes +set_io CLK 49 #-pullup yes + + +#set_io oled_DIN 91 +#set_io oled_CLK 90 +#set_io oled_CS 88 +#set_io oled_DC 87 +#set_io oled_RST 78 +#set_io ledmtx_DIN 81 +#set_io ledmtx_CS 80 +#set_io ledmtx_CLK 79 +#set_io p1_d[0] 141 -pullup yes +#set_io p1_d[1] 139 -pullup yes +#set_io p1_d[2] 138 -pullup yes +#set_io p1_d[3] 137 -pullup yes +#set_io p1_d[4] 136 -pullup yes +#set_io p1_d[5] 135 -pullup yes +#set_io p1_d[6] 134 -pullup yes +#set_io p1_d[7] 130 -pullup yes +#assign at random to start with to get it to compile +#P1 at opposite end of pcb than with ice4pi, but 3v3 and gnd have same possitions this way +set_io oled_DIN 134 +set_io oled_CLK 136 +set_io oled_CS 138 +set_io oled_DC 141 +set_io oled_RST 139 +set_io ledmtx_DIN 130 +set_io ledmtx_CS 135 +set_io ledmtx_CLK 137 + + +#set_io D1 99 +#set_io D2 98 +#set_io D3 97 +####set_io D4 96 +####set_io D5 95 +#set_io led_te[0] 93 -pullup yes #deduced was tbd[8] check +#set_io led_te[1] 94 -pullup yes #deduced was tbd[9] check +#set_io ok_led 110 -pullup yes + +#set_io p4_d[0] 1 -pullup yes +#set_io p4_d[1] 144 -pullup yes + +set_io LEDS[0] 1 +set_io LEDS[1] 144 + +set_io LEDS[2] 110 #-pullup yes #these leds will most probably be out of sequence, following PCB legend +set_io LEDS[3] 93 #-pullup yes #correct later +set_io LEDS[4] 94 #-pullup yes + + +#will be substituting D5 for D2 as apparently D5 used for error signalling +#need to sort out where D2 is so can comment properly + +#set_io TXD 8 +#set_io RXD 9 +#set_io pi_uart_ro 112 -pullup yes +#set_io pi_uart_wi 113 -pullup yes +##set_io RXD 112 #-pullup yes +##set_io TXD 113 #-pullup yes +set_io RXD 113 #-pullup yes +set_io TXD 112 #-pullup yes + + +#set_io spi_cs_n 71 +#set_io spi_miso 68 +#set_io spi_mosi 67 +#set_io spi_clk 70 +#set_io cfg_so 67 +#set_io cfg_si 68 +#set_io cfg_sck 70 +#set_io cfg_ss 71 +set_io SPIFLASH_CS_N 71 +set_io SPIFLASH_MISO 68 +set_io SPIFLASH_MOSI 67 +set_io SPIFLASH_CLK 70 + +set_io SPIFLASH_IO[0] 67 +set_io SPIFLASH_IO[1] 68 + + +set_io RESET 47 + +####NOT PRESENT ON PCB +####set_io irda_TXD 105 +####set_io irda_RXD 106 +####set_io irda_SD 107 + diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_ice4pi.sh b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_ice4pi.sh new file mode 100755 index 00000000..969d6248 --- /dev/null +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_ice4pi.sh @@ -0,0 +1,25 @@ +PROJECTNAME=SOC +BOARD=icestick +BOARD_FREQ=12 +#CPU_FREQ=45 +#20 works +#CPU_FREQ=20 +#35 for step24.v to be inside timing requirements +#CPU_FREQ=35 +#go back to default to see if it gets the run from mapped spi flash working +CPU_FREQ=45 +FPGA_VARIANT=hx1k +FPGA_PACKAGE=tq144 +VERILOGS=$1 +yosys -q -DICE4PI -DICE_STICK -DBOARD_FREQ=$BOARD_FREQ -DCPU_FREQ=$CPU_FREQ -p "synth_ice40 -relut -top $PROJECTNAME -json $PROJECTNAME.json" $VERILOGS || exit +nextpnr-ice40 --force --timing-allow-fail --json $PROJECTNAME.json --pcf BOARDS/$BOARD.pcf --asc $PROJECTNAME.asc --freq $CPU_FREQ --$FPGA_VARIANT --package $FPGA_PACKAGE --pcf-allow-unconstrained --opt-timing || exit +icetime -p BOARDS/$BOARD.pcf -P $FPGA_PACKAGE -r $PROJECTNAME.timings -d $FPGA_VARIANT -t $PROJECTNAME.asc +#add -s flag to icepack options to keep flash awake +icepack -s $PROJECTNAME.asc $PROJECTNAME.bin || exit +#icepack $PROJECTNAME.asc $PROJECTNAME.bin || exit +#iceprog $PROJECTNAME.bin || exit +echo "run upload tool from pi with ice4pi pcb on board" +echo "if pi5 is host apparently you have to dance around enabling and disabling spi from sudo raspi-config" +cp $PROJECTNAME.bin ../../../../mnt +echo DONE. + diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_icezero.sh b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_icezero.sh new file mode 100755 index 00000000..59bd946e --- /dev/null +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/BOARDS/run_icezero.sh @@ -0,0 +1,28 @@ +PROJECTNAME=SOC +BOARD=icezero +BOARD_FREQ=100 +#CPU_FREQ=45 +#20 works +#CPU_FREQ=20 +#35 for step24.v to be inside timing requirements +#CPU_FREQ=35 +#go back to default to see if it gets the run from mapped spi flash working +CPU_FREQ=35 +MIN_FREQ=12 +FPGA_VARIANT=hx8k +FPGA_PACKAGE=tq144:4k +VERILOGS=$1 +yosys -q -DICE_ZERO -DBOARD_FREQ=$BOARD_FREQ -DCPU_FREQ=$CPU_FREQ -p "synth_ice40 -relut -top $PROJECTNAME -json $PROJECTNAME.json" $VERILOGS || exit +nextpnr-ice40 --force --timing-allow-fail --json $PROJECTNAME.json --pcf BOARDS/$BOARD.pcf --asc $PROJECTNAME.asc --freq $MIN_FREQ --$FPGA_VARIANT --package $FPGA_PACKAGE --pcf-allow-unconstrained --opt-timing || exit +icetime -p BOARDS/$BOARD.pcf -P $FPGA_PACKAGE -r $PROJECTNAME.timings -d $FPGA_VARIANT -t $PROJECTNAME.asc +#add -s flag to icepack options to keep flash awake +icepack -s $PROJECTNAME.asc $PROJECTNAME.bin || exit +#icepack $PROJECTNAME.asc $PROJECTNAME.bin || exit +#iceprog $PROJECTNAME.bin || exit +echo "run upload tool from pi with icezero pcb on board" +ABSPATH=$(cd -- "../../../../mnt/trenz/TUTORIAL/" && pwd -P) +echo "copying duplicate files "$ABSPATH"/SOC_"$VERILOGS".bin for convenience and SOC.bin in keeping with documentation" +cp $PROJECTNAME.bin $ABSPATH"/SOC_"$VERILOGS".bin" +cp $PROJECTNAME.bin $ABSPATH"/SOC.bin" +echo DONE. + diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/Makefile b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/Makefile index 7bc57849..d401ed87 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/Makefile +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/Makefile @@ -17,45 +17,42 @@ LIBOBJECTS=putchar.o wait.o print.o memcpy.o errno.o perf.o cp $@ ../obj_dir/firmware.hex echo $@ > ../firmware.txt - # SPI FLASH 0 (sends everything to SPI flash) %.spiflash0.elf: %.o start.o $(LIBOBJECTS) $(RV_BINARIES) - $(RVLD) -T spiflash0.ld -m elf32lriscv -nostdlib -norelax $< $(LIBOBJECTS) $(RVTOOLCHAIN_GCC_LIB_DIR)/libgcc.a -o $@ + $(RVLD) -T spiflash0$(LINKADJUST) -m elf32lriscv -nostdlib -norelax $< $(LIBOBJECTS) $(RVTOOLCHAIN_GCC_LIB_DIR)/libgcc.a -o $@ %.spiflash0.bin: %.spiflash0.elf $(RVOBJCOPY) $< $@ -O binary %.spiflash0.prog: %.spiflash0.bin - iceprog -o 128k $< + $(TOOLCHAIN_PROG_CMD) + #iceprog -o 128k $< # SPI FLASH 1 (sends code and variables initialization to SPI flash, variables to RAM) %.spiflash1.elf: %.o start_spiflash1.o $(LIBOBJECTS) $(RV_BINARIES) - $(RVLD) -T spiflash1.ld -m elf32lriscv -nostdlib -norelax $< $(LIBOBJECTS) $(RVTOOLCHAIN_GCC_LIB_DIR)/libgcc.a -o $@ + $(RVLD) -T spiflash1$(LINKADJUST) -m elf32lriscv -nostdlib -norelax $< $(LIBOBJECTS) $(RVTOOLCHAIN_GCC_LIB_DIR)/libgcc.a -o $@ %.spiflash1.bin: %.spiflash1.elf $(RVOBJCOPY) $< $@ -O binary %.spiflash1.prog: %.spiflash1.bin - iceprog -o 128k $< + $(TOOLCHAIN_PROG_CMD) + #iceprog -o 128k $< # SPI FLASH 2 (sends code and variables initialization to SPI flash, variables and fastcode to RAM) - %.spiflash2.elf: %.o start_spiflash1.o $(LIBOBJECTS) $(RV_BINARIES) - $(RVLD) -T spiflash2.ld -m elf32lriscv -nostdlib -norelax $< $(LIBOBJECTS) -L$(RVTOOLCHAIN_LIB_DIR) -lm $(RVTOOLCHAIN_GCC_LIB_DIR)/libgcc.a -o $@ - + $(RVLD) -T spiflash2$(LINKADJUST) -m elf32lriscv -nostdlib -norelax $< $(LIBOBJECTS) -L$(RVTOOLCHAIN_LIB_DIR) -lm $(RVTOOLCHAIN_GCC_LIB_DIR)/libgcc.a -o $@ %.spiflash2.bin: %.spiflash2.elf $(RVOBJCOPY) $< $@ -O binary %.spiflash2.prog: %.spiflash2.bin - iceprog -o 128k $< - -%.spiflash2.list: %.spiflash2.elf - $(RVOBJDUMP) -Mnumeric -D $< > $@ + $(TOOLCHAIN_PROG_CMD) + #iceprog -o 128k $< # DUAL MEMORY (64 kb program ROM, 64 kb data RAM) diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash0_icezero.ld b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash0_icezero.ld new file mode 100644 index 00000000..361d746c --- /dev/null +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash0_icezero.ld @@ -0,0 +1,10 @@ +MEMORY { + FLASH (RX) : ORIGIN = 0x00830000, LENGTH = 0x100000 - 0x30000 /* 4 MB in flash */ +} +SECTIONS { + everything : { + . = ALIGN(4); + start.o (.text) + *(.*) + } >FLASH +} diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash1_icezero.ld b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash1_icezero.ld new file mode 100644 index 00000000..c02bc613 --- /dev/null +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash1_icezero.ld @@ -0,0 +1,60 @@ +/* Linker script for programs stored in SPI flash */ +/* Inspired from picorv32/picosoc/sections.lds */ +/* */ +/* text and rodata sections are sent to flash */ +/* bss sections are sent to BRAM */ +/* data sections are sent to BRAM and have */ +/* initialization data in flash. */ +/* AT keyword specifies LMA (Load Memory Address) */ + +MEMORY { + FLASH (rx) : ORIGIN = 0x00830000, LENGTH = 0x100000 - 0x30000 /* 4 MB in flash */ + RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x1800 /* 6 kB in RAM */ +} + +SECTIONS { + + /* + * This is the initialized data and fastcode section + * The program executes knowing that the data is in the RAM + * but the loader puts the initial values in the FLASH (inidata). + * It is one task of the startup (crt0_spiflash.S) to copy the initial values from FLASH to RAM. + */ + .data : AT ( _sidata ) { + + . = ALIGN(4); + + _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + _ram_start = .; /* create a global symbol at ram start (e.g., for garbage collector) */ + + /* Initialized data */ + *(.data*) + *(.sdata*) + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */ + } > RAM + + /* The (non fastcode) program code and other data goes into FLASH */ + .text : { + . = ALIGN(4); + start_spiflash1.o(.text) /* c runtime initialization (code) */ + *(.text*) /* .text* sections (code) */ + . = ALIGN(4); + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.srodata*) /* .rodata* sections (constants, strings, etc.) */ + _etext = .; /* define a global symbol at end of code */ + _sidata = _etext; /* This is used by the startup in order to initialize the .data section */ + } >FLASH + + /* Uninitialized data section */ + .bss : { + . = ALIGN(4); + _sbss = .; /* define a global symbol at bss start; used by startup code */ + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end; used by startup code */ + } >RAM +} diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash2_icezero.ld b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash2_icezero.ld new file mode 100644 index 00000000..3c944c2c --- /dev/null +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/FIRMWARE/spiflash2_icezero.ld @@ -0,0 +1,80 @@ +/* Linker script for programs stored in SPI flash */ +/* Inspired from picorv32/picosoc/sections.lds */ +/* */ +/* text and rodata sections are sent to flash */ +/* bss sections are sent to BRAM */ +/* data sections are sent to BRAM and have */ +/* initialization data in flash. */ +/* AT keyword specifies LMA (Load Memory Address) */ + +MEMORY { + FLASH (rx) : ORIGIN = 0x00830000, LENGTH = 0x100000 - 0x30000 /* 4 MB in flash */ + RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x1800 /* 6 kB in RAM */ +} + +SECTIONS { + + + /* + * This is the initialized data and fastcode section + * The program executes knowing that the data is in the RAM + * but the loader puts the initial values in the FLASH (inidata). + * It is one task of the startup (crt0_spiflash.S) to copy the initial values from FLASH to RAM. + */ + .data_and_fastcode : AT ( _sidata ) { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */ + _ram_start = .; /* create a global symbol at ram start (e.g., for garbage collector) */ + + /* Initialized data */ + *(.data*) + *(.sdata*) + + /* integer mul and div */ + */libgcc.a:muldi3.o(.text) + */libgcc.a:div.o(.text) + + putchar.o(.text) + print.o(.text) + + /* functions with attribute((section(".fastcode"))) */ + *(.fastcode*) + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */ + } > RAM + + /* The (non fastcode) program code and other data goes into FLASH */ + .text : { + . = ALIGN(4); + start_spiflash1.o(.text) /* c runtime initialization (code) */ + + /* + * I do not understand why, but if I do not put this section, I got + * an overlapping sections error with some programs (for instance pi.c + * or C++ programs) + */ + *(.eh_frame) + *(.eh_frame_hdr) + *(.init_array) + *(.gcc_except_table*) + + *(.text*) /* .text* sections (code) */ + . = ALIGN(4); + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.srodata*) /* .rodata* sections (constants, strings, etc.) */ + _etext = .; /* define a global symbol at end of code */ + _sidata = _etext; /* This is used by the startup in order to initialize the .data section */ + } >FLASH + + /* Uninitialized data section */ + .bss : { + . = ALIGN(4); + _sbss = .; /* define a global symbol at bss start; used by startup code */ + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end; used by startup code */ + } >RAM +} diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/clockworks.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/clockworks.v index 763fea6a..a3e7bbe2 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/clockworks.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/clockworks.v @@ -22,6 +22,10 @@ `include "../../RTL/PLL/femtopll.v" +`ifdef ICE_ZERO +`define NEGATIVE_RESET +`endif + `ifdef ECP5_EVN `define NEGATIVE_RESET `endif diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/spi_flash.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/spi_flash.v index e65467be..ef01274a 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/spi_flash.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/spi_flash.v @@ -45,6 +45,19 @@ `define SPI_FLASH_CONFIGURED `endif +`ifdef ICE_ZERO + `define SPI_FLASH_FAST_READ_DUAL_IO + `define SPI_FLASH_CONFIGURED +`endif + +`ifdef ICE4PI + `undef SPI_FLASH_FAST_READ_DUAL_IO + `undef SPI_FLASH_CONFIGURED + `define SPI_FLASH_FAST_READ_DUAL_IO + `define SPI_FLASH_DUMMY_CLOCKS 4 // Winbond w25q32 SPI chips on ice4pi uses 4 dummy clocks + `define SPI_FLASH_CONFIGURED +`endif + `ifdef ICE_BREAKER `define SPI_FLASH_FAST_READ_DUAL_IO `define SPI_FLASH_DUMMY_CLOCKS 4 // Winbond SPI chips on icebreaker uses 4 dummy clocks diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step17.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step17.v index f6d6ed06..d5ee8bb3 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step17.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step17.v @@ -453,7 +453,8 @@ module SOC ( corescore_emitter_uart #( .clk_freq_hz(`CPU_FREQ*1000000), - .baud_rate(1000000) + .baud_rate(115200) +// .baud_rate(1000000) ) UART( .i_clk(clk), .i_rst(!resetn), diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step18.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step18.v index d24ca90f..3937bf9a 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step18.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step18.v @@ -547,7 +547,8 @@ module SOC ( corescore_emitter_uart #( .clk_freq_hz(`CPU_FREQ*1000000), - .baud_rate(1000000) + .baud_rate(115200) +// .baud_rate(1000000) ) UART( .i_clk(clk), .i_rst(!resetn), diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step20.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step20.v index a2ee5444..5a334c7c 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step20.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step20.v @@ -370,8 +370,8 @@ module SOC ( corescore_emitter_uart #( .clk_freq_hz(`CPU_FREQ*1000000), -// .baud_rate(115200) - .baud_rate(1000000) + .baud_rate(115200) +// .baud_rate(1000000) ) UART( .i_clk(clk), .i_rst(!resetn), diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step22.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step22.v index 1b6e6bb0..85fa90e9 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step22.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step22.v @@ -396,7 +396,8 @@ module SOC ( corescore_emitter_uart #( .clk_freq_hz(`CPU_FREQ*1000000), - .baud_rate(1000000) +// .baud_rate(1000000) + .baud_rate(115200) ) UART( .i_clk(clk), .i_rst(!resetn), diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step23.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step23.v index 61c69c97..7cce2c5d 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step23.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step23.v @@ -19,12 +19,19 @@ module Memory ( reg [31:0] MEM [0:1535]; // 1536 4-bytes words = 6 Kb of RAM in total +`ifdef ICE_ZERO +`include "riscv_assembly.v" + initial begin + LI(a0,32'h00830000); // jump to SPI FLASH + 192 kB + JALR(zero,a0,0); + end +`else `include "riscv_assembly.v" initial begin LI(a0,32'h00820000); // jump to SPI FLASH + 128 kB JALR(zero,a0,0); end - +`endif wire [10:0] word_addr = mem_addr[12:2]; always @(posedge clk) begin @@ -400,7 +407,8 @@ module SOC ( corescore_emitter_uart #( .clk_freq_hz(`CPU_FREQ*1000000), - .baud_rate(1000000) +// .baud_rate(1000000) + .baud_rate(115200) ) UART( .i_clk(clk), .i_rst(!resetn), diff --git a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step24.v b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step24.v index 4897bb8c..465b3ee7 100644 --- a/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step24.v +++ b/FemtoRV/TUTORIALS/FROM_BLINKER_TO_RISCV/step24.v @@ -265,7 +265,11 @@ module Processor ( always @(posedge clk) begin if(!resetn) begin +`ifdef ICE_ZERO + PC <= 32'h00830000; // jump to SPI FLASH + 128 + 64kB would collide with fpga init image if only 128K offset used +`else PC <= 32'h00820000; // jump to SPI FLASH + 128 kB +`endif state <= WAIT_DATA; // just wait for !mem_rbusy end else begin if(writeBackEn && rdId != 0) begin @@ -395,7 +399,8 @@ module SOC ( corescore_emitter_uart #( .clk_freq_hz(`CPU_FREQ*1000000), - .baud_rate(1000000) +// .baud_rate(1000000) + .baud_rate(115200) ) UART( .i_clk(clk), .i_rst(!resetn), diff --git a/FemtoRV/TUTORIALS/IceZero.md b/FemtoRV/TUTORIALS/IceZero.md new file mode 100644 index 00000000..e8857a6c --- /dev/null +++ b/FemtoRV/TUTORIALS/IceZero.md @@ -0,0 +1,46 @@ +#Trenz IceZero + +With the icestick being typically more like $120 at the moment an Icezero and raspberry pizero2wh may be more attractive but you will need to have access to a soldering iron to make full use of learn-fpga. I think there is potential to get the on board SRAM mapped into FemtoRV32 program space, but haven't tried yet. The TUTORIALS can be done without the need for soldering on a header. + + +The original board: + +[https://hackaday.com/2017/02/08/adding-icezero-to-the-raspberry-pi/](URL) + + +The trenz version of the populated icezero pcb: + +[https://blackmesalabs.wordpress.com/2017/07/04/icezero-fpga-hat-for-raspberrypi-servo-example/](URL) + +[https://shop.trenz-electronic.de/en/TE0876-02-A-IceZero-with-Lattice-ICE40HX-4-Mbit-external-SRAM-3.05-x-6.5-cm](URL) + + +I belive I saw somewhere on the trenz site that you can ask for headers to be soldered on when ordering. I don't know the cost or if there is a minimum batch size for that service. + +Repository where the .pcf came from for this port of "learn-fpga" to trenz icezero +[https://www.dropbox.com/s/hwhhca1dxey5whh/default_te.tar.gz?dl=0](URL) + +I started from Ice4Pi and there are a few mods for that board which work for my hardware but potentially might not work for the earlier Ice4Pi version. + +For programming the IceZero from raspberry pi via bit banging I have made a quick and dirty fork of the icotools github repository [https://github.com/thekroko/icotools](URL) which is itself a fork of [https://github.com/cliffordwolf/icotools](URL) + +Programming tool sources at [https://github.com/njheb/icotools](URL) + +You will be interested in making icezprog, icezprog-0x830000 and icezprog-0x1000000 + +I'm going to ask about getting this fork adpoted but I don't know the best way to integrate my changes. + +For development I used an x86 pc running Ubuntu 20.04 for syntesis and a piz2w with header as the host for the icezero. I mounted an nfs share on a third device and accesed it from the x86 box and piz2wh. + +I added an environment variable "RASPI_REMOTE_DIR=$(abspath $(FIRMWARE_DIR)../../../mnt/)" to FemtoRv/FIRMWARE/makefile.inc you should put a dir called "mnt" at the same level as "learn-fpga" or change this environment variable accordingly. + +If there is intereset in this tree then it should not be difficult to get it to fit in. I thought it best to leave the hacky raspberry pi icezprog* tools in my own fork for now, location mentioned above. + +The TUTORIAL behaves like the ICESTICK in that it has 6k BRAM but the "make ICEZERO" femtosoc.bin targets 14k BRAM which is the maximum available. + +Some of the TUTORIAL bauds are down from 1000000 to 115200 as this works without change on the raspberry pi. I belive it would be possible to go faster by changing the boot config.txt in relation to /dev/ttyS0, but I have not tried and I doubt 1000000 would be possible on none usb adapters. + +I've tested with waveshare OLED but not the LEDmatrix. Also there are 3 onboard leds rather than 5, see changes for details. + +I'm hopeful that the SRAM will be an easy target for another mapped device, but I am a complete novice with FPGA related stuff. So am pausing here to see how this is recieved. + \ No newline at end of file diff --git a/FemtoRV/TUTORIALS/README.md b/FemtoRV/TUTORIALS/README.md index 1a169c07..6d7950d0 100644 --- a/FemtoRV/TUTORIALS/README.md +++ b/FemtoRV/TUTORIALS/README.md @@ -9,6 +9,7 @@ FemtoRV32 Tutorials - [FOMU tutorial](FOMU.md) _(WIP) - [Oyster PMOD](OysterPMOD.md) - [Adding a new board](newboard.md) +- [IceZero new board](IceZero.md) _(WIP not in main tree yet) - [Mecrisp-quintus on the IceStick (Forth)](https://github.com/BrunoLevy/learn-fpga/blob/master/FemtoRV/FIRMWARE/MECRISP_QUINTUS/README.md) FemtoRV32 Notes