Add icebreaker example PicoSoC implementation
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
1afe3af452
commit
68c69136b9
|
@ -1,8 +1,5 @@
|
||||||
/spiflash_tb.vcd
|
/spiflash_tb.vcd
|
||||||
/spiflash_tb.vvp
|
/spiflash_tb.vvp
|
||||||
/firmware.elf
|
|
||||||
/firmware.hex
|
|
||||||
/firmware.bin
|
|
||||||
/hx8kdemo.asc
|
/hx8kdemo.asc
|
||||||
/hx8kdemo.bin
|
/hx8kdemo.bin
|
||||||
/hx8kdemo.blif
|
/hx8kdemo.blif
|
||||||
|
@ -11,6 +8,9 @@
|
||||||
/hx8kdemo_syn.v
|
/hx8kdemo_syn.v
|
||||||
/hx8kdemo_syn_tb.vvp
|
/hx8kdemo_syn_tb.vvp
|
||||||
/hx8kdemo_tb.vvp
|
/hx8kdemo_tb.vvp
|
||||||
|
/hx8kdemo_fw.elf
|
||||||
|
/hx8kdemo_fw.hex
|
||||||
|
/hx8kdemo_fw.bin
|
||||||
/icebreaker.asc
|
/icebreaker.asc
|
||||||
/icebreaker.bin
|
/icebreaker.bin
|
||||||
/icebreaker.json
|
/icebreaker.json
|
||||||
|
@ -19,5 +19,8 @@
|
||||||
/icebreaker_syn.v
|
/icebreaker_syn.v
|
||||||
/icebreaker_syn_tb.vvp
|
/icebreaker_syn_tb.vvp
|
||||||
/icebreaker_tb.vvp
|
/icebreaker_tb.vvp
|
||||||
|
/icebreaker_fw.elf
|
||||||
|
/icebreaker_fw.hex
|
||||||
|
/icebreaker_fw.bin
|
||||||
/testbench.vcd
|
/testbench.vcd
|
||||||
/cmos.log
|
/cmos.log
|
||||||
|
|
|
@ -33,6 +33,15 @@ hx8kprog: hx8kdemo.bin firmware.bin
|
||||||
hx8kprog_fw: firmware.bin
|
hx8kprog_fw: firmware.bin
|
||||||
iceprog -o 1M firmware.bin
|
iceprog -o 1M firmware.bin
|
||||||
|
|
||||||
|
hx8kdemo_fw.elf: sections.lds start.s firmware.c
|
||||||
|
riscv32-unknown-elf-gcc -DHX8KDEMO -march=rv32imc -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o hx8kdemo_fw.elf start.s firmware.c
|
||||||
|
|
||||||
|
hx8kdemo_fw.hex: hx8kdemo_fw.elf
|
||||||
|
riscv32-unknown-elf-objcopy -O verilog hx8kdemo_fw.elf hx8kdemo_fw.hex
|
||||||
|
|
||||||
|
hx8kdemo_fw.bin: hx8kdemo_fw.elf
|
||||||
|
riscv32-unknown-elf-objcopy -O binary hx8kdemo_fw.elf hx8kdemo_fw.bin
|
||||||
|
|
||||||
# ---- iCE40 IceBreaker Board ----
|
# ---- iCE40 IceBreaker Board ----
|
||||||
|
|
||||||
icebsim: icebreaker_tb.vvp firmware.hex
|
icebsim: icebreaker_tb.vvp firmware.hex
|
||||||
|
@ -60,23 +69,21 @@ icebreaker.bin: icebreaker.asc
|
||||||
icetime -d up5k -c 12 -mtr icebreaker.rpt icebreaker.asc
|
icetime -d up5k -c 12 -mtr icebreaker.rpt icebreaker.asc
|
||||||
icepack icebreaker.asc icebreaker.bin
|
icepack icebreaker.asc icebreaker.bin
|
||||||
|
|
||||||
icebprog: icebreaker.bin firmware.bin
|
icebprog: icebreaker.bin icebreaker_fw.bin
|
||||||
iceprog icebreaker.bin
|
iceprog icebreaker.bin
|
||||||
iceprog -o 1M firmware.bin
|
iceprog -o 1M icebreaker_fw.bin
|
||||||
|
|
||||||
icebprog_fw: firmware.bin
|
icebprog_fw: icebreaker_fw.bin
|
||||||
iceprog -o 1M firmware.bin
|
iceprog -o 1M icebreaker_fw.bin
|
||||||
|
|
||||||
# ---- Example Firmware ----
|
icebreaker_fw.elf: sections.lds start.s firmware.c
|
||||||
|
riscv32-unknown-elf-gcc -DICEBREAKER -march=rv32ic -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o icebreaker_fw.elf start.s firmware.c
|
||||||
|
|
||||||
firmware.elf: sections.lds start.s firmware.c
|
icebreaker_fw.hex: icebreaker_fw.elf
|
||||||
riscv32-unknown-elf-gcc -march=rv32ic -Wl,-Bstatic,-T,sections.lds,--strip-debug -ffreestanding -nostdlib -o firmware.elf start.s firmware.c
|
riscv32-unknown-elf-objcopy -O verilog icebreaker_fw.elf icebreaker_fw.hex
|
||||||
|
|
||||||
firmware.hex: firmware.elf
|
icebreaker_fw.bin: icebreaker_fw.elf
|
||||||
riscv32-unknown-elf-objcopy -O verilog firmware.elf firmware.hex
|
riscv32-unknown-elf-objcopy -O binary icebreaker_fw.elf icebreaker_fw.bin
|
||||||
|
|
||||||
firmware.bin: firmware.elf
|
|
||||||
riscv32-unknown-elf-objcopy -O binary firmware.elf firmware.bin
|
|
||||||
|
|
||||||
# ---- Testbench for SPI Flash Model ----
|
# ---- Testbench for SPI Flash Model ----
|
||||||
|
|
||||||
|
@ -95,7 +102,8 @@ cmos.log: spimemio.v simpleuart.v picosoc.v ../picorv32.v
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f testbench.vvp testbench.vcd spiflash_tb.vvp spiflash_tb.vcd
|
rm -f testbench.vvp testbench.vcd spiflash_tb.vvp spiflash_tb.vcd
|
||||||
rm -f firmware.elf firmware.hex firmware.bin cmos.log
|
rm -f hx8kdemo_fw.elf hx8kdemo_fw.hex hx8kdemo_fw.bin cmos.log
|
||||||
|
rm -f icebreaker_fw.elf icebreaker_fw.hex icebreaker_fw.bin
|
||||||
rm -f hx8kdemo.blif hx8kdemo.log hx8kdemo.asc hx8kdemo.rpt hx8kdemo.bin
|
rm -f hx8kdemo.blif hx8kdemo.log hx8kdemo.asc hx8kdemo.rpt hx8kdemo.bin
|
||||||
rm -f hx8kdemo_syn.v hx8kdemo_syn_tb.vvp hx8kdemo_tb.vvp
|
rm -f hx8kdemo_syn.v hx8kdemo_syn_tb.vvp hx8kdemo_tb.vvp
|
||||||
rm -f icebreaker.json icebreaker.log icebreaker.asc icebreaker.rpt icebreaker.bin
|
rm -f icebreaker.json icebreaker.log icebreaker.asc icebreaker.rpt icebreaker.bin
|
||||||
|
|
|
@ -20,21 +20,28 @@ The reset vector is set to 0x00100000, i.e. at 1MB into in the flash memory.
|
||||||
See the included demo firmware and linker script for how to build a firmware
|
See the included demo firmware and linker script for how to build a firmware
|
||||||
image for this system.
|
image for this system.
|
||||||
|
|
||||||
Run `make test` to run the test bench (and create `testbench.vcd`).
|
Run `make hx8ksim` or `make icebsim` to run the test bench (and create `testbench.vcd`).
|
||||||
|
|
||||||
Run `make prog` to build the configuration bit-stream and firmware images
|
Run `make hx8kprog` to build the configuration bit-stream and firmware images
|
||||||
and upload them to a connected iCE40-HX8K Breakout Board.
|
and upload them to a connected iCE40-HX8K Breakout Board.
|
||||||
|
|
||||||
| File | Description |
|
Run `make icebprog` to build the configuration bit-stream and firmware images
|
||||||
| ----------------------------- | --------------------------------------------------------------- |
|
and upload them to a connected iCEBreaker Board.
|
||||||
| [picosoc.v](picosoc.v) | Top-level PicoSoC Verilog module |
|
|
||||||
| [spimemio.v](spimemio.v) | Memory controller that interfaces to external SPI flash |
|
| File | Description |
|
||||||
| [simpleuart.v](simpleuart.v) | Simple UART core connected directly to SoC TX/RX lines |
|
| --------------------------------- | --------------------------------------------------------------- |
|
||||||
| [start.s](start.s) | Assembler source for firmware.hex/firmware.bin |
|
| [picosoc.v](picosoc.v) | Top-level PicoSoC Verilog module |
|
||||||
| [firmware.c](firmware.c) | C source for firmware.hex/firmware.bin |
|
| [spimemio.v](spimemio.v) | Memory controller that interfaces to external SPI flash |
|
||||||
| [sections.lds](sections.lds) | Linker script for firmware.hex/firmware.bin |
|
| [simpleuart.v](simpleuart.v) | Simple UART core connected directly to SoC TX/RX lines |
|
||||||
| [hx8kdemo.v](hx8kdemo.v) | FPGA-based example implementation on iCE40-HX8K Breakout Board |
|
| [start.s](start.s) | Assembler source for firmware.hex/firmware.bin |
|
||||||
| [hx8kdemo.pcf](hx8kdemo.pcf) | Pin constraints for implementation on iCE40-HX8K Breakout Board |
|
| [firmware.c](firmware.c) | C source for firmware.hex/firmware.bin |
|
||||||
|
| [sections.lds](sections.lds) | Linker script for firmware.hex/firmware.bin |
|
||||||
|
| [hx8kdemo.v](hx8kdemo.v) | FPGA-based example implementation on iCE40-HX8K Breakout Board |
|
||||||
|
| [hx8kdemo.pcf](hx8kdemo.pcf) | Pin constraints for implementation on iCE40-HX8K Breakout Board |
|
||||||
|
| [hx8kdemo\_tb.v](hx8kdemo_tb.v) | Testbench for implementation on iCE40-HX8K Breakout Board |
|
||||||
|
| [icebreaker.v](hx8kdemo.v) | FPGA-based example implementation on iCEBreaker Board |
|
||||||
|
| [icebreaker.pcf](hx8kdemo.pcf) | Pin constraints for implementation on iCEBreaker Board |
|
||||||
|
| [icebreaker\_tb.v](hx8kdemo_tb.v) | Testbench for implementation on iCEBreaker Board |
|
||||||
|
|
||||||
### Memory map:
|
### Memory map:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,29 @@
|
||||||
|
/*
|
||||||
|
* PicoSoC - A simple example SoC using PicoRV32
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#if !defined(ICEBREAKER) && !defined(HX8KDEMO)
|
||||||
|
# error "Set -DICEBREAKER or -DHX8KDEMO when compiling firmware.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
// a pointer to this is a null pointer, but the compiler does not
|
// a pointer to this is a null pointer, but the compiler does not
|
||||||
// know that because "sram" is a linker symbol from sections.lds.
|
// know that because "sram" is a linker symbol from sections.lds.
|
||||||
extern uint32_t sram;
|
extern uint32_t sram;
|
||||||
|
@ -28,11 +51,10 @@ void flashio(uint8_t *data, int len, uint8_t wrencmd)
|
||||||
((void(*)(uint8_t*, uint32_t, uint32_t))func)(data, len, wrencmd);
|
((void(*)(uint8_t*, uint32_t, uint32_t))func)(data, len, wrencmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HX8KBOARD
|
||||||
void set_flash_qspi_flag()
|
void set_flash_qspi_flag()
|
||||||
{
|
{
|
||||||
uint8_t buffer[8];
|
uint8_t buffer[8];
|
||||||
|
|
||||||
#if 1
|
|
||||||
uint32_t addr_cr1v = 0x800002;
|
uint32_t addr_cr1v = 0x800002;
|
||||||
|
|
||||||
// Read Any Register (RDAR 65h)
|
// Read Any Register (RDAR 65h)
|
||||||
|
@ -52,26 +74,26 @@ void set_flash_qspi_flag()
|
||||||
buffer[3] = addr_cr1v;
|
buffer[3] = addr_cr1v;
|
||||||
buffer[4] = cr1v | 2; // Enable QSPI
|
buffer[4] = cr1v | 2; // Enable QSPI
|
||||||
flashio(buffer, 5, 0x06);
|
flashio(buffer, 5, 0x06);
|
||||||
#else
|
}
|
||||||
// Read Status Register 1 (RDSR1 05h)
|
#endif
|
||||||
buffer[0] = 0x05;
|
|
||||||
buffer[1] = 0x00; // rdata
|
#ifdef ICEBREAKER
|
||||||
flashio(buffer, 2, 0);
|
void set_flash_qspi_flag()
|
||||||
uint8_t sr1v = buffer[1];
|
{
|
||||||
|
uint8_t buffer[8];
|
||||||
|
|
||||||
// Read Configuration Registers (RDCR1 35h)
|
// Read Configuration Registers (RDCR1 35h)
|
||||||
buffer[0] = 0x35;
|
buffer[0] = 0x35;
|
||||||
buffer[1] = 0x00; // rdata
|
buffer[1] = 0x00; // rdata
|
||||||
flashio(buffer, 2, 0);
|
flashio(buffer, 2, 0);
|
||||||
uint8_t cr1v = buffer[1];
|
uint8_t sr2 = buffer[1];
|
||||||
|
|
||||||
// Write Enable (WREN 06h) + Write Registers (WRR 01h)
|
// Write Enable Volatile (50h) + Write Status Register 2 (31h)
|
||||||
buffer[0] = 0x01;
|
buffer[0] = 0x31;
|
||||||
buffer[1] = sr1v;
|
buffer[1] = sr2 | 2; // Enable QSPI
|
||||||
buffer[2] = cr1v | 2; // Enable QSPI
|
flashio(buffer, 2, 0x50);
|
||||||
flashio(buffer, 3, 0x06);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void set_flash_latency(uint8_t value)
|
void set_flash_latency(uint8_t value)
|
||||||
{
|
{
|
||||||
|
@ -185,6 +207,7 @@ void cmd_read_flash_id()
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef HX8KDEMO
|
||||||
uint8_t cmd_read_flash_regs_print(uint32_t addr, const char *name)
|
uint8_t cmd_read_flash_regs_print(uint32_t addr, const char *name)
|
||||||
{
|
{
|
||||||
set_flash_latency(8);
|
set_flash_latency(8);
|
||||||
|
@ -213,6 +236,70 @@ void cmd_read_flash_regs()
|
||||||
uint8_t cr3v = cmd_read_flash_regs_print(0x800004, "CR3V");
|
uint8_t cr3v = cmd_read_flash_regs_print(0x800004, "CR3V");
|
||||||
uint8_t vdlp = cmd_read_flash_regs_print(0x800005, "VDLP");
|
uint8_t vdlp = cmd_read_flash_regs_print(0x800005, "VDLP");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ICEBREAKER
|
||||||
|
uint8_t cmd_read_flash_reg(uint8_t cmd)
|
||||||
|
{
|
||||||
|
set_flash_latency(8);
|
||||||
|
|
||||||
|
uint8_t buffer[2] = {cmd, 0};
|
||||||
|
flashio(buffer, 2, 0);
|
||||||
|
return buffer[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_reg_bit(int val, const char *name)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
if (*name == 0)
|
||||||
|
putchar(' ');
|
||||||
|
else
|
||||||
|
putchar(*(name++));
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar(val ? '1' : '0');
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_read_flash_regs()
|
||||||
|
{
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
uint8_t sr1 = cmd_read_flash_reg(0x05);
|
||||||
|
uint8_t sr2 = cmd_read_flash_reg(0x35);
|
||||||
|
uint8_t sr3 = cmd_read_flash_reg(0x15);
|
||||||
|
|
||||||
|
print_reg_bit(sr1 & 0x01, "S0 (BUSY)");
|
||||||
|
print_reg_bit(sr1 & 0x02, "S1 (WEL)");
|
||||||
|
print_reg_bit(sr1 & 0x04, "S2 (BP0)");
|
||||||
|
print_reg_bit(sr1 & 0x08, "S3 (BP1)");
|
||||||
|
print_reg_bit(sr1 & 0x10, "S4 (BP2)");
|
||||||
|
print_reg_bit(sr1 & 0x20, "S5 (TB)");
|
||||||
|
print_reg_bit(sr1 & 0x40, "S6 (SEC)");
|
||||||
|
print_reg_bit(sr1 & 0x80, "S7 (SRP)");
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
print_reg_bit(sr2 & 0x01, "S8 (SRL)");
|
||||||
|
print_reg_bit(sr2 & 0x02, "S9 (QE)");
|
||||||
|
print_reg_bit(sr2 & 0x04, "S10 ----");
|
||||||
|
print_reg_bit(sr2 & 0x08, "S11 (LB1)");
|
||||||
|
print_reg_bit(sr2 & 0x10, "S12 (LB2)");
|
||||||
|
print_reg_bit(sr2 & 0x20, "S13 (LB3)");
|
||||||
|
print_reg_bit(sr2 & 0x40, "S14 (CMP)");
|
||||||
|
print_reg_bit(sr2 & 0x80, "S15 (SUS)");
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
print_reg_bit(sr3 & 0x01, "S16 ----");
|
||||||
|
print_reg_bit(sr3 & 0x02, "S17 ----");
|
||||||
|
print_reg_bit(sr3 & 0x04, "S18 (WPS)");
|
||||||
|
print_reg_bit(sr3 & 0x08, "S19 ----");
|
||||||
|
print_reg_bit(sr3 & 0x10, "S20 ----");
|
||||||
|
print_reg_bit(sr3 & 0x20, "S21 (DRV0)");
|
||||||
|
print_reg_bit(sr3 & 0x40, "S22 (DRV1)");
|
||||||
|
print_reg_bit(sr3 & 0x80, "S23 (HOLD)");
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
@ -483,4 +570,3 @@ void main()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
// Cypress S25FL064L http://www.cypress.com/file/316661/download
|
// Cypress S25FL064L http://www.cypress.com/file/316661/download
|
||||||
// Cypress S25FL128L http://www.cypress.com/file/316171/download
|
// Cypress S25FL128L http://www.cypress.com/file/316171/download
|
||||||
//
|
//
|
||||||
|
// SPI flash used on iCEBreaker board:
|
||||||
|
// https://www.winbond.com/resource-files/w25q128jv%20dtr%20revb%2011042016.pdf
|
||||||
|
//
|
||||||
|
|
||||||
module spiflash (
|
module spiflash (
|
||||||
input csb,
|
input csb,
|
||||||
|
|
Loading…
Reference in New Issue