Browse Source

Publishable (re-loaded)

master
kaqu 3 months ago
parent
commit
e284a266b6
10 changed files with 23 additions and 202 deletions
  1. BIN
      Neopixelar_Overview.png
  2. +5
    -4
      README.md
  3. BIN
      impress/stamp.odp
  4. +11
    -10
      software/linker/ram1.ld
  5. +6
    -6
      software/linker/ram2.ld
  6. +1
    -8
      software/ramcreate.sh
  7. +0
    -1
      software/source/README.md
  8. +0
    -144
      software/source/dramtransfer.c
  9. +0
    -1
      software/source/illumination.c
  10. +0
    -28
      software/source/main.c

BIN
Neopixelar_Overview.png View File

Before After
Width: 1739  |  Height: 1074  |  Size: 1.8 MiB

+ 5
- 4
README.md View File

@ -1,5 +1,5 @@
![Showtime](Neopixelar_Overview.jpg)
![Showtime](Neopixelar_Overview.png)
# Neopixelar - the FPGA project #
@ -42,9 +42,10 @@ https://blog.pcbxprt.com/index.php/2020/07/19/running-risc-v-core-on-small-fpga-
## Program structure: ##
1. Neopixelar.py - this is the main FPGA building source
2. neopixelengine.py - this is the actual NeoPixel driving engine
3. helpers subdir - contains python helpers for load & flash etc.
4. firmware subdir - contains some modified BIOS files (relative to the original version)
5. software subdir - contains a separate build, load & flash logic for separate (RV32i) application code
3. libmodules subdir - DRAM DMA loader helper & system time support
4. helpers subdir - contains python helpers for load & flash etc.
5. firmware subdir - contains some modified BIOS files (relative to the original version)
6. software subdir - contains a separate build, load & flash logic for separate (RV32i) application code
(the rest is of minor importance ...)
## Quickstart ##


BIN
Neopixelar_Overview.jpg → impress/stamp.odp View File


+ 11
- 10
software/linker/ram1.ld View File

@ -4,7 +4,8 @@ ENTRY(_start)
INCLUDE ../build/colorlight_5a_75b/software/include/generated/regions.ld
MEMORY {
main_sram : ORIGIN = 0x40380000, LENGTH = 0x00080000
main_ram1 : ORIGIN = 0x40000000, LENGTH = 0x00200000
dram_vars : ORIGIN = 0x40380000, LENGTH = 0x00080000
}
SECTIONS
@ -20,7 +21,7 @@ SECTIONS
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > main_ram
} > main_ram1
.rodata :
{
@ -36,14 +37,14 @@ SECTIONS
FILL(0);
. = ALIGN(8);
_erodata = .;
} > main_ram
} > main_ram1
.commands :
{
PROVIDE_HIDDEN (__bios_cmd_start = .);
KEEP(*(.bios_cmd))
PROVIDE_HIDDEN (__bios_cmd_end = .);
} > main_ram
} > main_ram1
.data :
{
@ -58,8 +59,8 @@ SECTIONS
FILL(0);
. = ALIGN(8);
_edata = .;
/* sram -> main_sram (DRAM) */
} > main_sram AT > main_ram
/* sram -> dram_vars (DRAM) */
} > dram_vars AT > main_ram1
.bss :
{
@ -74,8 +75,8 @@ SECTIONS
. = ALIGN(8);
_ebss = .;
_end = .;
/* sram -> main_sram (DRAM) */
} > main_sram AT > main_ram
/* sram -> dram_vars (DRAM) */
} > dram_vars AT > main_ram1
/DISCARD/ :
{
@ -84,8 +85,8 @@ SECTIONS
}
}
/* STACK: sram -> main_sram (DRAM) */
PROVIDE(_fstack = ORIGIN(main_sram) + LENGTH(main_sram) - 8);
/* STACK: sram -> dram_vars (DRAM) */
PROVIDE(_fstack = ORIGIN(dram_vars) + LENGTH(dram_vars) - 8);
PROVIDE(_fdata_rom = LOADADDR(.data));
PROVIDE(_edata_rom = LOADADDR(.data) + SIZEOF(.data));

+ 6
- 6
software/linker/ram2.ld View File

@ -4,8 +4,8 @@ ENTRY(_start)
INCLUDE ../build/colorlight_5a_75b/software/include/generated/regions.ld
MEMORY {
main_ram2 : ORIGIN = 0x40200000, LENGTH = 0x00200000
main_sram : ORIGIN = 0x40380000, LENGTH = 0x00080000
main_ram2 : ORIGIN = 0x40200000, LENGTH = 0x00180000
dram_vars : ORIGIN = 0x40380000, LENGTH = 0x00080000
}
SECTIONS
@ -59,7 +59,7 @@ SECTIONS
FILL(0);
. = ALIGN(8);
_edata = .;
} > main_sram AT > main_ram2
} > dram_vars AT > main_ram2
.bss :
{
@ -74,7 +74,7 @@ SECTIONS
. = ALIGN(8);
_ebss = .;
_end = .;
} > main_sram AT > main_ram2
} > dram_vars AT > main_ram2
/DISCARD/ :
{
@ -83,8 +83,8 @@ SECTIONS
}
}
/* STACK: sram -> main_sram (DRAM) */
PROVIDE(_fstack = ORIGIN(main_sram) + LENGTH(main_sram) - 8);
/* STACK: sram -> dram_vars (DRAM) */
PROVIDE(_fstack = ORIGIN(dram_vars) + LENGTH(dram_vars) - 8);
PROVIDE(_fdata_rom = LOADADDR(.data));
PROVIDE(_edata_rom = LOADADDR(.data) + SIZEOF(.data));

+ 1
- 8
software/ramcreate.sh View File

@ -20,7 +20,6 @@ echo "Creating $PROJECTNAME application ..."
# Additional user libs, not project specific
LIBSYSTIME="systime"
LIBPRINTF="my_vsnprintf"
LIBDRAMTRANSFER="dramtransfer"
# Adjust these paths according to your local installation !!!
MY_LOCAL_LITEX_PATH=$HOME"/fpga/litex"
@ -88,15 +87,9 @@ then
echo "*** gcc for $LIBSYSTIME.c failed!"
exit $?
fi
$MY_LOCAL_LITEX_PATH/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc -c $COMMONFLAGS $CFLAGS -Wa,-fPIC source/$LIBDRAMTRANSFER.c -o build/$LIBDRAMTRANSFER.o
if [ $? -ne 0 ];
then
echo "*** gcc for $LIBDRAMTRANSFER.c failed!"
exit $?
fi
echo "Linking ..."
$MY_LOCAL_LITEX_PATH/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-ld $LDFLAGS -T linker/ram$3.ld -N $CRT0 $OBJECTS $LXR build/$2.o build/$1.o build/$LIBSYSTIME.o build/$LIBPRINTF.o build/$LIBDRAMTRANSFER.o lib/rv32ilibm.a lib/rv32ilibgcc.a -o build/$1.elf
$MY_LOCAL_LITEX_PATH/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-ld $LDFLAGS -T linker/ram$3.ld -N $CRT0 $OBJECTS $LXR build/$2.o build/$1.o build/$LIBSYSTIME.o build/$LIBPRINTF.o lib/rv32ilibm.a lib/rv32ilibgcc.a -o build/$1.elf
if [ $? -ne 0 ];
then
echo "*** Link/Loader for build/$1.elf failed!"


+ 0
- 1
software/source/README.md View File

@ -3,5 +3,4 @@ illumination.c - This is a sample application, demonstrating the use
of the 'neopixelengine' (the documentation can be found
under ./build/documentation/http/index.html)
my_vsnprintf.c - Some helpers. For float formatting use printf1() (really ugly!)
dramtransfer.c - DMA DRAM access loader
systime.c - (Daily) Time helper

+ 0
- 144
software/source/dramtransfer.c View File

@ -1,144 +0,0 @@
//
// dramtransfer.c
// DRAM transfer routines
//
// History:
// --------
// 21.12.20/KQ Initial version
//
#include <stdio.h>
#include <stdlib.h>
#include <console.h>
#include <string.h>
#include <uart.h>
#include <system.h>
#include <id.h>
#include <irq.h>
#include <crc.h>
#include "boot.h"
#include "readline.h"
#include "helpers.h"
#include "command.h"
#include "../../build/colorlight_5a_75b/software/include/generated/csr.h"
#include "../../build/colorlight_5a_75b/software/include/generated/soc.h"
#include "../../build/colorlight_5a_75b/software/include/generated/mem.h"
#include "../../build/colorlight_5a_75b/software/include/generated/git.h"
#include <spiflash.h>
#include <liblitedram/sdram.h>
#include <libliteeth/udp.h>
#include <libliteeth/mdio.h>
#include <liblitespi/spiflash.h>
#include <liblitesdcard/sdcard.h>
#include "../include/systime.h"
#include "../include/dramtransfer.h"
extern void busy_wait(unsigned int ms); // Worx!
// Load FPGA from DRAM
int load_FPGA(uint32_t iBaseAddress, int8_t bLen)
{
int i;
flush_l2_cache(); // Strictly nec. for longer transfers
if((iBaseAddress & 0xF) != 0) {
iBaseAddress &= 0xFFFFFFF0; // Enforce 16-byte alignment
printf("*** load_FPGA(): iBaseAddress alignment needs to be 16 Byte! Using %08Xh\n", iBaseAddress);
}
if((iBaseAddress < 0x40000000) || (iBaseAddress > 0x40400000)) {
printf("*** load_FPGA(): iBaseAddress not within DRAM range!\n");
return 0;
}
dramtransfer_bEnable_write(0); // For address change, turn off first!
dramtransfer_b32Address_write(iBaseAddress); // Provide a valid DRAM address
dramtransfer_bEnable_write(1); // Start DMA pickup & FIFO fill ...
for(i = 0; i < TIMEOUT; i++) {
if(dramtransfer_bValid_read()) // Wait 'til transfer done
break;
}
dramtransfer_bEnable_write(0); // Indicate termination of action
if(i>=TIMEOUT) { // Timing?
printf("*** TIMEOUT: bValid not set?\n");
return 0;
}
return 1; // Ok, FPGA loaded!
}
// Retrieve FPGA memory@offset
int32_t retrieve_FPGA(int iOffset)
{
if((iOffset < 0) || (iOffset >= FIFOSIZE)) {
printf("*** retrieve_FPGA(): Invalid offset?!\n");
iOffset = 0;
}
dramtransfer_b9Offset_write(iOffset); // ->memory[offset]
return dramtransfer_b32Data_read(); // memory[offset]
}
#define BASEADDRESS 0x40190000
#define MAXLOOPS 64 // 8x 0x400 (8x 256 * 4 = 8x 1024) => 0x2000
void dramtest(void)
{
uint32_t *TxPtr;
int i, j;
uint32_t iStart;
printf("---- DRAM transfer test ----\n");
iStart = systime(1); // Reset to defined value ...
int iSum = 0; // Time aggregate
for(j = 0; j < MAXLOOPS; j++) {
// Attention: int32_t Assignments require at least 4 bytes boundary alignment!
TxPtr = (uint32_t *)((BASEADDRESS & 0xFFFFFFFC) + j * (FIFOSIZE * sizeof(int32_t)));
for(i = 0; i < FIFOSIZE; i++) { // Fill source range data within DRAM
*(uint32_t *)(TxPtr+i) = j*FIFOSIZE + i+1;
}
iStart = systime(0); // Expect 0.70 ms/transfer ...
if(load_FPGA((uint32_t)TxPtr, 0)) { // Load <n> bytes from 0x40190000 ... (16 byte aligned!)
iSum += (systime(0) - iStart); // Time delta added
for(i=0;i<FIFOSIZE;i++) {
if((j*FIFOSIZE + i + 1) != retrieve_FPGA(i)) {
printf("%d: TxPtr -> %08X (%d 32-bit words) (Count before: %d) ", j, (uint32_t)TxPtr, FIFOSIZE, dramtransfer_b32RCount_read());
printf("\n*** FAIL mem[%03d] %d != %08Xh\n", i, j * FIFOSIZE + i + 1, retrieve_FPGA(i));
break;
}
}
}
else {
printf("*** load_FPGA(): FAILED?!\n");
break;
}
}
if(j >= MAXLOOPS) {
printf("PASS: %d bytes transferred in %dms w/ %d chuncks of %d bytes/each (0.%d ms/transfer), range %08Xh-%08Xh.\n",
MAXLOOPS * 4 * FIFOSIZE, iSum, MAXLOOPS, 4 * FIFOSIZE, iSum*100/MAXLOOPS, BASEADDRESS, BASEADDRESS+MAXLOOPS*4*FIFOSIZE-1);
}
#ifdef XXX
printf("\n---- System time test ----\n");
systime(86399999-1000);
printf("Pre: %d\n", systime(0));
busy_wait(2000);
printf("Post: %d\n", systime(0));
int hh, mm, ss; // ------------------ Time adjust test ----------------------
setsystime(13,55,0);
getsystime(&hh, &mm, &ss);
printf("Time now: %02d:%02d:%02d\nWait 60s, press [x] to terminate ...\n", hh, mm, ss);
while(!key_eval()) {
busy_wait(60000); // 60s
getsystime(&hh, &mm, &ss);
printf("Time now: %02d:%02d:%02d\nWait 60s, press [x] to terminate ...\n", hh, mm, ss);
}
#endif
}

+ 0
- 1
software/source/illumination.c View File

@ -40,7 +40,6 @@
#include <liblitesdcard/sdcard.h>
#include "../include/dramtransfer.h"
#include "../include/illumination.h"
extern void busy_wait(unsigned int ms); // Worx!


+ 0
- 28
software/source/main.c View File

@ -58,9 +58,6 @@ int __errno; // Needed by lib
int main(int i, char **c)
{
// Create our own start status indicator
// Read command: 'mr 0x403ffffc 4'
int32_t *statept = (int32_t *)(MAIN_RAM_BASE + MAIN_RAM_SIZE - sizeof(int32_t));
char buffer[CMD_LINE_BUFFER_SIZE];
char *params[MAX_PARAM];
char *command;
@ -73,24 +70,6 @@ int main(int i, char **c)
#endif
setsystime(14, 30, 00); // Reset to defined value (14:30) ...
#ifdef XXXX
// Prepare first output
int32_t green = 0x040201;
int32_t red = 0x010402;
int32_t blue = 0x020104;
int iTable;
iTable = 0;
load_triple_LEDs(iTable, green, red, blue); // 1st load
iTable = 1;
load_triple_LEDs(iTable, red, blue, green);
iTable = 2;
load_triple_LEDs(iTable, blue, green, red);
send_LEDs();
enable_LEDS(1);
busy_wait(2000);
enable_LEDS(0);
#endif
uart_init();
printf("\n");
@ -105,7 +84,6 @@ int main(int i, char **c)
if((mycpc >= MAIN_RAM_BASE) && (mycpc < (MAIN_RAM_BASE + MAIN_RAM_SIZE))) {
#ifdef CONSOLE_NON_BLOCKING
set_console(1); // 1=Non-blocking (0=standard/blocking)
*statept = get_console(); // Make sure, we know what was going on ...
#endif
printf("\e[1mExecuting within RAM ...\e[0m\n");
@ -114,7 +92,6 @@ int main(int i, char **c)
if(illumination()) // The DEMO !
break;
}
*statept = get_console(); // Make sure, we know what was going on ...
#ifdef FLOAT_TEST
// Float test
@ -150,13 +127,8 @@ int main(int i, char **c)
illumination(); // more DEMO ...
}
}
#ifdef CONSOLE_NON_BLOCKING
*statept = get_console(); // Make sure, we know what was going on ...
#endif
}
}
//else
// printf("Non-RAM execution @%08Xh, no action ...\n", cpc);
while(1);
return 0;
}


Loading…
Cancel
Save