forked from FPGALover/RISCV_picorv32_fpga
Removing unnecessary files
parent
5d939e2448
commit
41103bdf5b
|
@ -1,53 +0,0 @@
|
|||
OSFLAG :=
|
||||
ifeq ($(OS),Windows_NT)
|
||||
RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX = C:\riscv_precompiled
|
||||
else
|
||||
RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX = /opt/riscv32
|
||||
endif
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PYTHON_VER = python
|
||||
else
|
||||
PYTHON_VER = python3
|
||||
endif
|
||||
|
||||
|
||||
FIRMWARE_OBJS = firmware/start.o firmware/irq.o firmware/print.o firmware/inch.o firmware/timer.o firmware/prng.o firmware/leds.o firmware/fftbench.o firmware/main.o
|
||||
GCC_WARNS = -Wall -Wextra -Wshadow -Wundef -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings
|
||||
GCC_WARNS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes -pedantic # -Wconversion
|
||||
ifeq ($(OS),Windows_NT)
|
||||
TOOLCHAIN_PREFIX = $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)/bin/riscv-none-elf-
|
||||
else
|
||||
TOOLCHAIN_PREFIX = $(RISCV_GNU_TOOLCHAIN_INSTALL_PREFIX)im/bin/riscv32-unknown-elf-
|
||||
endif
|
||||
COMPRESSED_ISA =
|
||||
|
||||
firmware/firmware.mif: firmware/firmware.bin firmware/makemif.py
|
||||
$(PYTHON_VER) firmware/makemif.py $< 16384 > $@
|
||||
|
||||
firmware/firmware.hex: firmware/firmware.bin firmware/makehex.py
|
||||
$(PYTHON_VER) firmware/makehex.py $< 16384 firmware > $@
|
||||
|
||||
firmware/firmware.fpga:firmware/firmware.hex
|
||||
$(PYTHON_VER) firmware/makebin.py $< 16384 > $@
|
||||
|
||||
firmware/firmware.bin: firmware/firmware.elf
|
||||
$(TOOLCHAIN_PREFIX)objcopy -O binary $< $@
|
||||
chmod -x $@
|
||||
|
||||
firmware/firmware.elf: $(FIRMWARE_OBJS) $(TEST_OBJS) firmware/sections.lds
|
||||
$(TOOLCHAIN_PREFIX)gcc -Os -ffreestanding -nostdlib -o $@ \
|
||||
-Wl,-Bstatic,-T,firmware/sections.lds,-Map,firmware/firmware.map,--strip-debug \
|
||||
$(FIRMWARE_OBJS) $(TEST_OBJS) -lgcc
|
||||
chmod -x $@
|
||||
|
||||
firmware/start.o: firmware/start.S
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -march=rv32im$(subst C,c,$(COMPRESSED_ISA)) -o $@ $<
|
||||
|
||||
firmware/%.o: firmware/%.c
|
||||
$(TOOLCHAIN_PREFIX)gcc -c -march=rv32im$(subst C,c,$(COMPRESSED_ISA)) -Os -W --std=c99 $(GCC_WARNS) -ffreestanding -nostdlib -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -vrf $(FIRMWARE_OBJS) $(TEST_OBJS) \
|
||||
firmware/firmware.elf firmware/firmware.bin firmware/firmware.hex firmware/firmware.mif firmware/firmware.map firmware/Memory.v_toplevel_memory_1_symbol*
|
||||
|
||||
.PHONY: clean
|
|
@ -1,102 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#define regnum_q0 0
|
||||
#define regnum_q1 1
|
||||
#define regnum_q2 2
|
||||
#define regnum_q3 3
|
||||
|
||||
#define regnum_x0 0
|
||||
#define regnum_x1 1
|
||||
#define regnum_x2 2
|
||||
#define regnum_x3 3
|
||||
#define regnum_x4 4
|
||||
#define regnum_x5 5
|
||||
#define regnum_x6 6
|
||||
#define regnum_x7 7
|
||||
#define regnum_x8 8
|
||||
#define regnum_x9 9
|
||||
#define regnum_x10 10
|
||||
#define regnum_x11 11
|
||||
#define regnum_x12 12
|
||||
#define regnum_x13 13
|
||||
#define regnum_x14 14
|
||||
#define regnum_x15 15
|
||||
#define regnum_x16 16
|
||||
#define regnum_x17 17
|
||||
#define regnum_x18 18
|
||||
#define regnum_x19 19
|
||||
#define regnum_x20 20
|
||||
#define regnum_x21 21
|
||||
#define regnum_x22 22
|
||||
#define regnum_x23 23
|
||||
#define regnum_x24 24
|
||||
#define regnum_x25 25
|
||||
#define regnum_x26 26
|
||||
#define regnum_x27 27
|
||||
#define regnum_x28 28
|
||||
#define regnum_x29 29
|
||||
#define regnum_x30 30
|
||||
#define regnum_x31 31
|
||||
|
||||
#define regnum_zero 0
|
||||
#define regnum_ra 1
|
||||
#define regnum_sp 2
|
||||
#define regnum_gp 3
|
||||
#define regnum_tp 4
|
||||
#define regnum_t0 5
|
||||
#define regnum_t1 6
|
||||
#define regnum_t2 7
|
||||
#define regnum_s0 8
|
||||
#define regnum_s1 9
|
||||
#define regnum_a0 10
|
||||
#define regnum_a1 11
|
||||
#define regnum_a2 12
|
||||
#define regnum_a3 13
|
||||
#define regnum_a4 14
|
||||
#define regnum_a5 15
|
||||
#define regnum_a6 16
|
||||
#define regnum_a7 17
|
||||
#define regnum_s2 18
|
||||
#define regnum_s3 19
|
||||
#define regnum_s4 20
|
||||
#define regnum_s5 21
|
||||
#define regnum_s6 22
|
||||
#define regnum_s7 23
|
||||
#define regnum_s8 24
|
||||
#define regnum_s9 25
|
||||
#define regnum_s10 26
|
||||
#define regnum_s11 27
|
||||
#define regnum_t3 28
|
||||
#define regnum_t4 29
|
||||
#define regnum_t5 30
|
||||
#define regnum_t6 31
|
||||
|
||||
// x8 is s0 and also fp
|
||||
#define regnum_fp 8
|
||||
|
||||
#define r_type_insn(_f7, _rs2, _rs1, _f3, _rd, _opc) \
|
||||
.word (((_f7) << 25) | ((_rs2) << 20) | ((_rs1) << 15) | ((_f3) << 12) | ((_rd) << 7) | ((_opc) << 0))
|
||||
|
||||
#define picorv32_getq_insn(_rd, _qs) \
|
||||
r_type_insn(0b0000000, 0, regnum_ ## _qs, 0b100, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_setq_insn(_qd, _rs) \
|
||||
r_type_insn(0b0000001, 0, regnum_ ## _rs, 0b010, regnum_ ## _qd, 0b0001011)
|
||||
|
||||
#define picorv32_retirq_insn() \
|
||||
r_type_insn(0b0000010, 0, 0, 0b000, 0, 0b0001011)
|
||||
|
||||
#define picorv32_maskirq_insn(_rd, _rs) \
|
||||
r_type_insn(0b0000011, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_waitirq_insn(_rd) \
|
||||
r_type_insn(0b0000100, 0, 0, 0b100, regnum_ ## _rd, 0b0001011)
|
||||
|
||||
#define picorv32_timer_insn(_rd, _rs) \
|
||||
r_type_insn(0b0000101, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011)
|
||||
|
|
@ -1,406 +0,0 @@
|
|||
//
|
||||
// fftbench.c
|
||||
//
|
||||
// A simple FFT implmentation for use as a micro-controller benchmark. This is an in-place
|
||||
// Radix-2 Decimation In Time FFT using fixed point arithmetic.
|
||||
//
|
||||
// When reimplementing this benchmark in other languages please honour the intention of
|
||||
// this benchmark by following the algorithm as closely as possible. This version is based off
|
||||
// of bech_fft.spin which is to be regarded as the "mother" of all versions of this benchmark
|
||||
// in other languages.
|
||||
//
|
||||
// This FFT was developed from the description by Douglas L. Jones at
|
||||
// http://cnx.org/content/m12016/latest/.
|
||||
// It is written as a direct implementation of the discussion and diagrams on that page
|
||||
// with an emphasis on clarity and ease of understanding rather than speed.
|
||||
//
|
||||
//
|
||||
// This file is released under the terms of the MIT license. See below.
|
||||
//
|
||||
// Credits:
|
||||
//
|
||||
// A big thank you to Dave Hein for clearing up some issues during a great FFT debate on
|
||||
// the Parallax Inc Propller discussion forum:
|
||||
// http://forums.parallax.com/showthread.php?127306-Fourier-for-dummies-under-construction
|
||||
//
|
||||
// History:
|
||||
//
|
||||
// 2011-02-27 v1.0 Initial version.
|
||||
//
|
||||
// 2012-10-04 v1.1 Added support for parallel processing using OpenMP
|
||||
// A crude attempt at parallelization using up to 4 cores max.
|
||||
//
|
||||
// 2012-12-05 v1.2 Changed to use "parallel for" OMP construct.
|
||||
// Configured for 4 cores max.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "firmware.h"
|
||||
|
||||
|
||||
|
||||
//#ifdef _OPENMP
|
||||
// Only include omp if it is available
|
||||
//#include <omp.h>
|
||||
//#else
|
||||
// Otherwise redefine some omp functions to remove compiler errors
|
||||
#define omp_get_max_threads() 1
|
||||
#define omp_get_thread_num() 1
|
||||
//#endif
|
||||
|
||||
#define int32_t int
|
||||
#define int16_t short int
|
||||
|
||||
// Specify size of FFT buffer here with length and log base 2 of the length.
|
||||
// N.B. Changing this will require changing the "twiddle factor" tables.
|
||||
// and may also require changing the fixed point format (if going bigger)
|
||||
#define FFT_SIZE 1024
|
||||
#define LOG2_FFT_SIZE 10
|
||||
|
||||
// cos and sin parts of the signal to be analysed
|
||||
// Result is written back to here.
|
||||
// Just write input sammles to bx and zero all by.
|
||||
static int32_t bx[FFT_SIZE];
|
||||
static int32_t by[FFT_SIZE];
|
||||
|
||||
// Set if array bounds exceeded
|
||||
int rangeError = 0;
|
||||
|
||||
static void fillInput(void);
|
||||
static void decimate(void);
|
||||
void butterflies(int32_t* bx, int32_t* by, int32_t firstLevel, int32_t lastLevel, int32_t slices, int32_t slen);
|
||||
static void printSpectrum(void);
|
||||
|
||||
static void print_omp_version(void) {
|
||||
/*#ifdef _OPENMP
|
||||
printf("OpenMP version = ");
|
||||
switch (_OPENMP) {
|
||||
case 200805:
|
||||
printf("3.0");
|
||||
break;
|
||||
case 200505:
|
||||
printf("2.5");
|
||||
break;
|
||||
case 200203:
|
||||
printf("2.0");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown. _OPENMP = %d", _OPENMP);
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
#else
|
||||
print_str("OpenMP not available on this system\r\n");
|
||||
#endif*/
|
||||
print_str("OpenMP not available on this system\r\n");
|
||||
}
|
||||
|
||||
void fft_bench(void) {
|
||||
long long startTime, endTime;
|
||||
/*#ifdef _OPENMP
|
||||
int tid;
|
||||
#endif*/
|
||||
int s, slen;
|
||||
int firstLevel;
|
||||
int lastLevel;
|
||||
int slice;
|
||||
int slices;
|
||||
|
||||
print_str ("fft_bench v1.2\r\n");
|
||||
|
||||
print_omp_version();
|
||||
|
||||
// Input some data
|
||||
fillInput();
|
||||
|
||||
// HACK, when playing on a single CPU ensure we have some threads like 4 core
|
||||
// omp_set_num_threads(2);
|
||||
|
||||
// Start benchmark timer
|
||||
startTime = time_us();
|
||||
|
||||
// Radix-2 Decimation In Time, the bit-reversal step.
|
||||
decimate();
|
||||
|
||||
// Our FFT array will be split into slices. each slice can be handled by it's own thread
|
||||
// slices = 1;
|
||||
// lastLevel = LOG2_FFT_SIZE - 1;
|
||||
slices = 2;
|
||||
lastLevel = LOG2_FFT_SIZE - 2;
|
||||
//slices = 4;
|
||||
//lastLevel = LOG2_FFT_SIZE - 3;
|
||||
// slices = 8;
|
||||
// lastLevel = LOG2_FFT_SIZE - 4;
|
||||
// slices = 16;
|
||||
// lastLevel = LOG2_FFT_SIZE - 5;
|
||||
|
||||
firstLevel = 0;
|
||||
// for ( ; slices >= 1; slices = slices / 2) {
|
||||
/* #pragma omp parallel for default (none) \
|
||||
shared (bx, by) \
|
||||
private (slice, s, slen, tid) \
|
||||
firstprivate(slices, firstLevel, lastLevel)*/
|
||||
/* for (slice = 0; slice < slices; slice++) {
|
||||
s = FFT_SIZE * slice / slices;
|
||||
slen = FFT_SIZE / slices;
|
||||
butterflies(&bx[s], &by[s], firstLevel, lastLevel, slices, slen);
|
||||
}
|
||||
lastLevel = lastLevel + 1;
|
||||
firstLevel = lastLevel;
|
||||
}*/
|
||||
// Did we have an array bounds violation?
|
||||
if (rangeError) print_str ("Error: Array bounds violation\n");
|
||||
|
||||
// Stop benchmark timer
|
||||
endTime = time_us();
|
||||
|
||||
// Print resulting spectrum
|
||||
printSpectrum();
|
||||
|
||||
print_str("1024 point bit-reversal and butterfly run time = ");
|
||||
print_dec (endTime - startTime);
|
||||
print_str("us\r\n");
|
||||
}
|
||||
|
||||
// Integer square root
|
||||
static int sqrti(int i) {
|
||||
int s = 0;
|
||||
int t = 1 << 30;
|
||||
while (t) {
|
||||
s |= t;
|
||||
if (s <= i) {
|
||||
i -= s;
|
||||
s += t;
|
||||
}
|
||||
else
|
||||
s -= t;
|
||||
s >>= 1;
|
||||
t >>= 2;
|
||||
}
|
||||
return(s);
|
||||
}
|
||||
|
||||
static void printSpectrum() {
|
||||
int32_t f, real, imag, magnitude;
|
||||
|
||||
// Spectrum is available in first half of the buffers after FFT.
|
||||
print_str("Freq. Magnitude\r\n");
|
||||
for (f = 0; f <= FFT_SIZE / 2; f++) {
|
||||
// Frequency magnitde is square root of cos part sqaured plus sin part squared
|
||||
real = bx[f] / FFT_SIZE;
|
||||
imag = by[f] / FFT_SIZE;
|
||||
magnitude = sqrti ((real * real) + (imag * imag));
|
||||
if (magnitude > 0) {
|
||||
print_hex (f, 8);
|
||||
print_str(" ");
|
||||
print_hex (magnitude, 8);
|
||||
print_str("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For testing define 16 samples of an input wave form here.
|
||||
static int32_t input[] = {4096, 3784, 2896, 1567, 0, -1567, -2896, -3784, -4096, -3784, -2896, -1567, 0, 1567, 2896, 3784};
|
||||
|
||||
// Fill buffer bx with samples of of an imput signal and clear by.
|
||||
static void fillInput() {
|
||||
int32_t k;
|
||||
|
||||
for (k = 0; k <=FFT_SIZE - 1; k++) {
|
||||
// Two frequencies of the waveform defined in input
|
||||
bx[k] = (input[(3*k) % 16] / 4);
|
||||
bx[k] += (input[(5*k) % 16] / 4);
|
||||
|
||||
// The highest frequency
|
||||
if (k & 1)
|
||||
bx[k] += (4096 / 8);
|
||||
else
|
||||
bx[k] += (-4096 / 8);
|
||||
|
||||
// A DC level
|
||||
bx[k] += (4096 / 8);
|
||||
|
||||
// Clear Y array.
|
||||
by[k] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse length low order bits of integer
|
||||
static unsigned int bitReverse(unsigned int x, unsigned int length) {
|
||||
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
|
||||
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
|
||||
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
|
||||
x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
|
||||
x = (x >> 16) | (x << 16);
|
||||
return (x >> (32 - length));
|
||||
}
|
||||
|
||||
// Radix-2 decimation in time.
|
||||
// Moves every sample of bx and by to a postion given by
|
||||
// reversing the bits of its original array index.
|
||||
static void decimate() {
|
||||
int32_t i, revi, tx1, ty1;
|
||||
|
||||
for (i = 0; i <= FFT_SIZE - 1; i++) {
|
||||
revi = bitReverse (i, LOG2_FFT_SIZE);
|
||||
if (i < revi) {
|
||||
tx1 = bx[i];
|
||||
ty1 = by[i];
|
||||
|
||||
bx[i] = bx[revi];
|
||||
by[i] = by[revi];
|
||||
|
||||
bx[revi] = tx1;
|
||||
by[revi] = ty1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t *wx;
|
||||
static int32_t *wy;
|
||||
|
||||
// Apply FFT butterflies to N complex samples in buffers bx and by, in time decimated order!
|
||||
// Resulting FFT is produced in bx and by in the correct order.
|
||||
void butterflies(int32_t* bx, int32_t* by, int32_t firstLevel, int32_t lastLevel, int32_t slices, int32_t slen) {
|
||||
|
||||
int32_t flightSize = 1 << firstLevel;
|
||||
int32_t wDelta = FFT_SIZE / (2 * (1 << firstLevel));
|
||||
int32_t noFlights = wDelta / slices;
|
||||
|
||||
// Loop though the decimation levels
|
||||
// lastLevel is logN - 1
|
||||
for (int32_t level = firstLevel; level <= lastLevel; level++) {
|
||||
|
||||
int32_t flightIndex = 0;
|
||||
// Loop through each flight on a level.
|
||||
for (int32_t flight = 0; flight < noFlights; flight++) {
|
||||
int32_t wIndex = 0;
|
||||
|
||||
// Loop through butterflies within a flight.
|
||||
for (int32_t butterfly = 0; butterfly < flightSize; butterfly++) {
|
||||
int32_t b0 = flightIndex + butterfly;
|
||||
int32_t b1 = b0 + flightSize;
|
||||
|
||||
// Check that we are within our array slice
|
||||
if ((b0 < 0) || (b0 >= slen)) rangeError = 1;
|
||||
if ((b1 < 0) || (b1 >= slen)) rangeError = 1;
|
||||
|
||||
// At last...the butterfly.
|
||||
// Get X[b1]
|
||||
int32_t a = bx[b1];
|
||||
int32_t b = by[b1];
|
||||
|
||||
// Get W[wIndex]
|
||||
int32_t c = wx[wIndex];
|
||||
int32_t d = wy[wIndex];
|
||||
|
||||
// Somewhat optimized complex multiply
|
||||
int32_t k1 = (a * (c + d)) >> 12;
|
||||
// T = X[b1] * W[wIndex]
|
||||
int32_t k2 = (d * (a + b)) >> 12;
|
||||
int32_t k3 = (c * (b - a)) >> 12;
|
||||
|
||||
int32_t tx = k1 - k2;
|
||||
int32_t ty = k1 + k3;
|
||||
|
||||
k1 = bx[b0];
|
||||
k2 = by[b0];
|
||||
// X[b1] = X[b0] * T
|
||||
bx[b1] = k1 - tx;
|
||||
by[b1] = k2 - ty;
|
||||
|
||||
// X[b0] = X[b0] * T
|
||||
bx[b0] = k1 + tx;
|
||||
by[b0] = k2 + ty;
|
||||
|
||||
wIndex += wDelta;
|
||||
}
|
||||
flightIndex += flightSize << 1;
|
||||
}
|
||||
flightSize <<= 1;
|
||||
noFlights >>= 1;
|
||||
wDelta >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Cosine from 0 to 3π/2 (0 to 270 degrees)
|
||||
static int32_t cos[768] = {
|
||||
4095, 4094, 4094, 4094, 4093, 4093, 4092, 4091, 4090, 4088, 4087, 4085, 4083, 4081, 4079, 4077,
|
||||
4075, 4072, 4070, 4067, 4064, 4061, 4057, 4054, 4050, 4046, 4042, 4038, 4034, 4030, 4025, 4021,
|
||||
4016, 4011, 4006, 4000, 3995, 3989, 3984, 3978, 3972, 3966, 3959, 3953, 3946, 3939, 3932, 3925,
|
||||
3918, 3911, 3903, 3896, 3888, 3880, 3872, 3864, 3855, 3847, 3838, 3829, 3820, 3811, 3802, 3792,
|
||||
3783, 3773, 3763, 3753, 3743, 3733, 3723, 3712, 3701, 3691, 3680, 3668, 3657, 3646, 3634, 3623,
|
||||
3611, 3599, 3587, 3575, 3563, 3550, 3537, 3525, 3512, 3499, 3486, 3473, 3459, 3446, 3432, 3418,
|
||||
3404, 3390, 3376, 3362, 3348, 3333, 3318, 3304, 3289, 3274, 3258, 3243, 3228, 3212, 3197, 3181,
|
||||
3165, 3149, 3133, 3117, 3100, 3084, 3067, 3051, 3034, 3017, 3000, 2983, 2965, 2948, 2930, 2913,
|
||||
2895, 2877, 2859, 2841, 2823, 2805, 2787, 2768, 2750, 2731, 2712, 2693, 2674, 2655, 2636, 2617,
|
||||
2597, 2578, 2558, 2539, 2519, 2499, 2479, 2459, 2439, 2419, 2398, 2378, 2357, 2337, 2316, 2295,
|
||||
2275, 2254, 2233, 2211, 2190, 2169, 2148, 2126, 2105, 2083, 2061, 2040, 2018, 1996, 1974, 1952,
|
||||
1930, 1908, 1885, 1863, 1841, 1818, 1796, 1773, 1750, 1728, 1705, 1682, 1659, 1636, 1613, 1590,
|
||||
1567, 1543, 1520, 1497, 1473, 1450, 1426, 1403, 1379, 1355, 1332, 1308, 1284, 1260, 1236, 1212,
|
||||
1188, 1164, 1140, 1116, 1092, 1067, 1043, 1019, 994, 970, 946, 921, 897, 872, 848, 823,
|
||||
798, 774, 749, 724, 700, 675, 650, 625, 600, 575, 551, 526, 501, 476, 451, 426,
|
||||
401, 376, 351, 326, 301, 276, 251, 226, 200, 175, 150, 125, 100, 75, 50, 25,
|
||||
0, -25, -50, -75, -100, -125, -150, -175, -200, -226, -251, -276, -301, -326, -351, -376,
|
||||
-401, -426, -451, -476, -501, -526, -551, -576, -600, -625, -650, -675, -700, -724, -749, -774,
|
||||
-798, -823, -848, -872, -897, -921, -946, -970, -995, -1019, -1043, -1067, -1092, -1116, -1140, -1164,
|
||||
-1188, -1212, -1236, -1260, -1284, -1308, -1332, -1355, -1379, -1403, -1426, -1450, -1473, -1497, -1520, -1543,
|
||||
-1567, -1590, -1613, -1636, -1659, -1682, -1705, -1728, -1750, -1773, -1796, -1818, -1841, -1863, -1885, -1908,
|
||||
-1930, -1952, -1974, -1996, -2018, -2040, -2062, -2083, -2105, -2126, -2148, -2169, -2190, -2212, -2233, -2254,
|
||||
-2275, -2295, -2316, -2337, -2357, -2378, -2398, -2419, -2439, -2459, -2479, -2499, -2519, -2539, -2558, -2578,
|
||||
-2597, -2617, -2636, -2655, -2674, -2693, -2712, -2731, -2750, -2768, -2787, -2805, -2823, -2841, -2859, -2877,
|
||||
-2895, -2913, -2930, -2948, -2965, -2983, -3000, -3017, -3034, -3051, -3067, -3084, -3100, -3117, -3133, -3149,
|
||||
-3165, -3181, -3197, -3212, -3228, -3243, -3258, -3274, -3289, -3304, -3318, -3333, -3348, -3362, -3376, -3390,
|
||||
-3404, -3418, -3432, -3446, -3459, -3473, -3486, -3499, -3512, -3525, -3537, -3550, -3563, -3575, -3587, -3599,
|
||||
-3611, -3623, -3634, -3646, -3657, -3669, -3680, -3691, -3701, -3712, -3723, -3733, -3743, -3753, -3763, -3773,
|
||||
-3783, -3792, -3802, -3811, -3820, -3829, -3838, -3847, -3855, -3864, -3872, -3880, -3888, -3896, -3903, -3911,
|
||||
-3918, -3925, -3932, -3939, -3946, -3953, -3959, -3966, -3972, -3978, -3984, -3989, -3995, -4000, -4006, -4011,
|
||||
-4016, -4021, -4025, -4030, -4034, -4038, -4043, -4046, -4050, -4054, -4057, -4061, -4064, -4067, -4070, -4072,
|
||||
-4075, -4077, -4079, -4081, -4083, -4085, -4087, -4088, -4090, -4091, -4092, -4093, -4093, -4094, -4094, -4094,
|
||||
-4094, -4094, -4094, -4094, -4093, -4093, -4092, -4091, -4090, -4088, -4087, -4085, -4083, -4081, -4079, -4077,
|
||||
-4075, -4072, -4070, -4067, -4064, -4061, -4057, -4054, -4050, -4046, -4042, -4038, -4034, -4030, -4025, -4021,
|
||||
-4016, -4011, -4006, -4000, -3995, -3989, -3984, -3978, -3972, -3966, -3959, -3953, -3946, -3939, -3932, -3925,
|
||||
-3918, -3911, -3903, -3896, -3888, -3880, -3872, -3863, -3855, -3847, -3838, -3829, -3820, -3811, -3802, -3792,
|
||||
-3783, -3773, -3763, -3753, -3743, -3733, -3723, -3712, -3701, -3691, -3680, -3668, -3657, -3646, -3634, -3623,
|
||||
-3611, -3599, -3587, -3575, -3562, -3550, -3537, -3525, -3512, -3499, -3486, -3473, -3459, -3446, -3432, -3418,
|
||||
-3404, -3390, -3376, -3362, -3347, -3333, -3318, -3304, -3289, -3274, -3258, -3243, -3228, -3212, -3197, -3181,
|
||||
-3165, -3149, -3133, -3117, -3100, -3084, -3067, -3050, -3034, -3017, -3000, -2983, -2965, -2948, -2930, -2913,
|
||||
-2895, -2877, -2859, -2841, -2823, -2805, -2787, -2768, -2749, -2731, -2712, -2693, -2674, -2655, -2636, -2617,
|
||||
-2597, -2578, -2558, -2539, -2519, -2499, -2479, -2459, -2439, -2419, -2398, -2378, -2357, -2337, -2316, -2295,
|
||||
-2275, -2254, -2233, -2211, -2190, -2169, -2148, -2126, -2105, -2083, -2061, -2040, -2018, -1996, -1974, -1952,
|
||||
-1930, -1908, -1885, -1863, -1841, -1818, -1796, -1773, -1750, -1728, -1705, -1682, -1659, -1636, -1613, -1590,
|
||||
-1567, -1543, -1520, -1497, -1473, -1450, -1426, -1403, -1379, -1355, -1332, -1308, -1284, -1260, -1236, -1212,
|
||||
-1188, -1164, -1140, -1116, -1092, -1067, -1043, -1019, -994, -970, -946, -921, -897, -872, -848, -823,
|
||||
-798, -774, -749, -724, -700, -675, -650, -625, -600, -575, -551, -526, -501, -476, -451, -426,
|
||||
-401, -376, -351, -326, -301, -276, -251, -225, -200, -175, -150, -125, -100, -75, -50, -25
|
||||
};
|
||||
|
||||
// Half cycle of cos
|
||||
static int32_t *wx = &cos[0];
|
||||
|
||||
// Half cycle of minus sine
|
||||
static int32_t *wy = &cos[256];
|
||||
|
||||
// This file is distributed under the terms of the The MIT License as follows:
|
||||
//
|
||||
// Copyright (c) 2012 Michael Rychlik
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
|
@ -1,55 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#ifndef FIRMWARE_H
|
||||
#define FIRMWARE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// irq.c
|
||||
uint32_t *irq(uint32_t *regs, uint32_t irqs);
|
||||
|
||||
// timer.c
|
||||
int32_t timer(void);
|
||||
long long time_us(void);
|
||||
|
||||
// prng.c
|
||||
uint32_t prng(void);
|
||||
|
||||
// leds.c
|
||||
void ledsOut(char ch);
|
||||
|
||||
// print.c
|
||||
void print_chr(char ch);
|
||||
void print_str(const char *p);
|
||||
void print_dec(unsigned int val);
|
||||
void print_hex(unsigned int val, int digits);
|
||||
|
||||
// inch.c
|
||||
char inch(void);
|
||||
|
||||
// sieve.c
|
||||
void sieve(void);
|
||||
|
||||
// multest.c
|
||||
uint32_t hard_mul(uint32_t a, uint32_t b);
|
||||
uint32_t hard_mulh(uint32_t a, uint32_t b);
|
||||
uint32_t hard_mulhsu(uint32_t a, uint32_t b);
|
||||
uint32_t hard_mulhu(uint32_t a, uint32_t b);
|
||||
void multest(void);
|
||||
|
||||
// stats.c
|
||||
void stats(void);
|
||||
|
||||
// fftbench.c
|
||||
void fft_bench(void);
|
||||
|
||||
// helloWorld.c
|
||||
void helloWorld(void);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,14 +0,0 @@
|
|||
#include "firmware.h"
|
||||
|
||||
#define DATA_PORT 0xffff0020
|
||||
#define STATUS_PORT 0xffff0024
|
||||
|
||||
char inch(void)
|
||||
{
|
||||
while (*((volatile uint32_t*)STATUS_PORT) == 0 )
|
||||
{
|
||||
// Spin waiting for UART Rx full.
|
||||
}
|
||||
return *((volatile uint32_t*)DATA_PORT);
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#include "firmware.h"
|
||||
|
||||
uint32_t *irq(uint32_t *regs, uint32_t irqs)
|
||||
{
|
||||
static unsigned int ext_irq_4_count = 0;
|
||||
static unsigned int ext_irq_5_count = 0;
|
||||
static unsigned int timer_irq_count = 0;
|
||||
|
||||
// checking compressed isa q0 reg handling
|
||||
if ((irqs & 6) != 0) {
|
||||
uint32_t pc = (regs[0] & 1) ? regs[0] - 3 : regs[0] - 4;
|
||||
uint32_t instr = *(uint16_t*)pc;
|
||||
|
||||
if ((instr & 3) == 3)
|
||||
instr = instr | (*(uint16_t*)(pc + 2)) << 16;
|
||||
|
||||
if (((instr & 3) != 3) != (regs[0] & 1)) {
|
||||
print_str("Mismatch between q0 LSB and decoded instruction word! q0=0x");
|
||||
print_hex(regs[0], 8);
|
||||
print_str(", instr=0x");
|
||||
if ((instr & 3) == 3)
|
||||
print_hex(instr, 8);
|
||||
else
|
||||
print_hex(instr, 4);
|
||||
print_str("\n");
|
||||
__asm__ volatile ("ebreak");
|
||||
}
|
||||
}
|
||||
|
||||
if ((irqs & (1<<4)) != 0) {
|
||||
ext_irq_4_count++;
|
||||
// print_str("[EXT-IRQ-4]");
|
||||
}
|
||||
|
||||
if ((irqs & (1<<5)) != 0) {
|
||||
ext_irq_5_count++;
|
||||
// print_str("[EXT-IRQ-5]");
|
||||
}
|
||||
|
||||
if ((irqs & 1) != 0) {
|
||||
timer_irq_count++;
|
||||
// print_str("[TIMER-IRQ]");
|
||||
}
|
||||
|
||||
if ((irqs & 6) != 0)
|
||||
{
|
||||
uint32_t pc = (regs[0] & 1) ? regs[0] - 3 : regs[0] - 4;
|
||||
uint32_t instr = *(uint16_t*)pc;
|
||||
|
||||
if ((instr & 3) == 3)
|
||||
instr = instr | (*(uint16_t*)(pc + 2)) << 16;
|
||||
|
||||
print_str("\n");
|
||||
print_str("------------------------------------------------------------\n");
|
||||
|
||||
if ((irqs & 2) != 0) {
|
||||
if (instr == 0x00100073 || instr == 0x9002) {
|
||||
print_str("EBREAK instruction at 0x");
|
||||
print_hex(pc, 8);
|
||||
print_str("\n");
|
||||
} else {
|
||||
print_str("Illegal Instruction at 0x");
|
||||
print_hex(pc, 8);
|
||||
print_str(": 0x");
|
||||
print_hex(instr, ((instr & 3) == 3) ? 8 : 4);
|
||||
print_str("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if ((irqs & 4) != 0) {
|
||||
print_str("Bus error in Instruction at 0x");
|
||||
print_hex(pc, 8);
|
||||
print_str(": 0x");
|
||||
print_hex(instr, ((instr & 3) == 3) ? 8 : 4);
|
||||
print_str("\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
int r = i + k*8;
|
||||
|
||||
if (r == 0) {
|
||||
print_str("pc ");
|
||||
} else
|
||||
if (r < 10) {
|
||||
print_chr('x');
|
||||
print_chr('0' + r);
|
||||
print_chr(' ');
|
||||
print_chr(' ');
|
||||
} else
|
||||
if (r < 20) {
|
||||
print_chr('x');
|
||||
print_chr('1');
|
||||
print_chr('0' + r - 10);
|
||||
print_chr(' ');
|
||||
} else
|
||||
if (r < 30) {
|
||||
print_chr('x');
|
||||
print_chr('2');
|
||||
print_chr('0' + r - 20);
|
||||
print_chr(' ');
|
||||
} else {
|
||||
print_chr('x');
|
||||
print_chr('3');
|
||||
print_chr('0' + r - 30);
|
||||
print_chr(' ');
|
||||
}
|
||||
|
||||
print_hex(regs[r], 8);
|
||||
print_str(k == 3 ? "\n" : " ");
|
||||
}
|
||||
|
||||
print_str("------------------------------------------------------------\n");
|
||||
|
||||
print_str("Number of fast external IRQs counted: ");
|
||||
print_dec(ext_irq_4_count);
|
||||
print_str("\n");
|
||||
|
||||
print_str("Number of slow external IRQs counted: ");
|
||||
print_dec(ext_irq_5_count);
|
||||
print_str("\n");
|
||||
|
||||
print_str("Number of timer IRQs counted: ");
|
||||
print_dec(timer_irq_count);
|
||||
print_str("\n");
|
||||
|
||||
__asm__ volatile ("ebreak");
|
||||
}
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#include "firmware.h"
|
||||
|
||||
#define LED_PORT 0xffff0060
|
||||
|
||||
volatile int n;
|
||||
|
||||
void ledsOut(char ch)
|
||||
{
|
||||
*((volatile uint32_t*)LED_PORT) = ch;
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
#include "firmware.h"
|
||||
|
||||
|
||||
void helloWorld (void)
|
||||
{
|
||||
int count = 0;
|
||||
uint32_t random;
|
||||
int32_t time;
|
||||
int32_t timeLast = 0;
|
||||
char c = 0;
|
||||
int errorCount = 0;
|
||||
const char* message = "Welcome to RISCV, FPGALover";
|
||||
const char* msgPtr = message;
|
||||
|
||||
while (1)
|
||||
{
|
||||
print_str(message);
|
||||
print_str("\r\n");
|
||||
|
||||
while (1) {
|
||||
c = inch();
|
||||
if (c == *msgPtr)
|
||||
{
|
||||
if (c == 0)
|
||||
{
|
||||
print_str("RX error count: ");
|
||||
print_hex(errorCount, 8);
|
||||
print_str("\r\n");
|
||||
msgPtr = message;
|
||||
}
|
||||
else
|
||||
{
|
||||
msgPtr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCount++;
|
||||
msgPtr = message;
|
||||
print_str("RX error count: ");
|
||||
print_hex(errorCount, 8);
|
||||
print_str("\r\n");
|
||||
ledsOut(128);
|
||||
}
|
||||
}
|
||||
|
||||
print_str("\r\n");
|
||||
|
||||
time = timer();
|
||||
print_hex(time, 8);
|
||||
|
||||
print_str(" : ");
|
||||
print_hex(time - timeLast, 8);
|
||||
timeLast = time;
|
||||
|
||||
print_str(" : ");
|
||||
random = prng();
|
||||
print_hex(random, 8);
|
||||
print_str("\r\n");
|
||||
|
||||
ledsOut(random);
|
||||
|
||||
//fft_bench();
|
||||
print_str("\r\n");
|
||||
|
||||
count++;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# makebin.py
|
||||
#
|
||||
# Prepares memory initialization files for the Verilog readmemb() functions generated by SpinalHDL.
|
||||
#
|
||||
# Input: A memory image file, hexadecimal, one 32 bit memory location per line.
|
||||
#
|
||||
# Output: Four, byte wide, symbol files in binary.
|
||||
#
|
||||
|
||||
# The memory image file in hexadecimal, one 32 bit location content per line.
|
||||
|
||||
import os
|
||||
import platform
|
||||
os_p = platform.system()
|
||||
file_dir = os.path.dirname(os.path.realpath('__file__'))
|
||||
|
||||
joiner='';
|
||||
if(os_p=="Linux"):
|
||||
joiner="/";
|
||||
else:
|
||||
joiner="\\";
|
||||
hexFileName = os.path.join(file_dir, 'firmware'+joiner+'firmware.hex')
|
||||
|
||||
# The binary symbol (byte) output files
|
||||
outFileName0 = os.path.join(file_dir, "firmware"+joiner+"Memory.v_toplevel_memory_1_symbol0.bin")
|
||||
outFileName1 = os.path.join(file_dir, "firmware"+joiner+"Memory.v_toplevel_memory_1_symbol1.bin")
|
||||
outFileName2 = os.path.join(file_dir, "firmware"+joiner+"Memory.v_toplevel_memory_1_symbol2.bin")
|
||||
outFileName3 = os.path.join(file_dir, "firmware"+joiner+"Memory.v_toplevel_memory_1_symbol3.bin")
|
||||
|
||||
hexFile = open(hexFileName, "r")
|
||||
|
||||
outFile0 = open(outFileName0, "w+")
|
||||
outFile1 = open(outFileName1, "w+")
|
||||
outFile2 = open(outFileName2, "w+")
|
||||
outFile3 = open(outFileName3, "w+")
|
||||
|
||||
# Read memory location values one per line
|
||||
for line in hexFile:
|
||||
|
||||
# Convert to 32 bit integer
|
||||
data = int(line, 16)
|
||||
|
||||
# Split into 4 bytes
|
||||
byte0 = (data >> 0) & 0xFF
|
||||
byte1 = (data >> 8) & 0xFF
|
||||
byte2 = (data >> 16) & 0xFF
|
||||
byte3 = (data >> 24) & 0xFF
|
||||
|
||||
# Write symbol ouptut files, one byte in binary per line
|
||||
outFile0.write(format(byte0, '08b') + '\n')
|
||||
outFile1.write(format(byte1, '08b') + '\n')
|
||||
outFile2.write(format(byte2, '08b') + '\n')
|
||||
outFile3.write(format(byte3, '08b') + '\n')
|
||||
|
||||
# Close up the shop.
|
||||
outFile0.close()
|
||||
outFile1.close()
|
||||
outFile2.close()
|
||||
outFile3.close()
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
|
||||
from sys import argv
|
||||
|
||||
binfile = argv[1]
|
||||
nwords = int(argv[2])
|
||||
path = argv[3] + "/"
|
||||
|
||||
with open(binfile, "rb") as f:
|
||||
bindata = f.read()
|
||||
|
||||
hexfile0 = "firmware0.hex"
|
||||
hexfile1 = "firmware1.hex"
|
||||
hexfile2 = "firmware2.hex"
|
||||
hexfile3 = "firmware3.hex"
|
||||
|
||||
miffile = "firmware.mif"
|
||||
|
||||
h0 = open(path + hexfile0, "w")
|
||||
h1 = open(path + hexfile1, "w")
|
||||
h2 = open(path + hexfile2, "w")
|
||||
h3 = open(path + hexfile3, "w")
|
||||
mif = open(path + miffile, "w")
|
||||
|
||||
print ("-- Altera Quartus Memory Initilization file .mif", file=mif)
|
||||
print ("DEPTH = 16384; -- The size of memory in words", file=mif)
|
||||
print ("WIDTH = 32; -- The size of data in bits", file=mif)
|
||||
print ("", file=mif)
|
||||
print ("ADDRESS_RADIX = HEX; -- The radix for address values", file=mif)
|
||||
print ("DATA_RADIX = HEX; -- The radix for data values", file=mif)
|
||||
print ("", file=mif)
|
||||
print ("CONTENT BEGIN -- start of (address : data pairs)", file=mif)
|
||||
|
||||
assert len(bindata) < 4*nwords
|
||||
#assert len(bindata) % 4 == 0
|
||||
|
||||
for i in range(nwords):
|
||||
if i < len(bindata) // 4:
|
||||
w = bindata[4*i : 4*i+4]
|
||||
print("%02x%02x%02x%02x" % (w[3], w[2], w[1], w[0]))
|
||||
print("%02X" % (w[0]), file=h0)
|
||||
print("%02X" % (w[1]), file=h1)
|
||||
print("%02X" % (w[2]), file=h2)
|
||||
print("%02X" % (w[3]), file=h3)
|
||||
print("%04x : %08x;" % (i ,(w[3] << 24) + (w[2] << 16) + (w[1] << 8) + w[0]) , file=mif)
|
||||
else:
|
||||
print("0")
|
||||
print("%02X" % (0), file=h0)
|
||||
print("%02X" % (0), file=h1)
|
||||
print("%02X" % (0), file=h2)
|
||||
print("%02X" % (0), file=h3)
|
||||
print("%04x : %08x;" % (i, 0), file=mif)
|
||||
|
||||
print ("END;", file=mif)
|
||||
|
||||
h0.close()
|
||||
h1.close()
|
||||
h2.close()
|
||||
h3.close()
|
||||
mif.close()
|
|
@ -1,37 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
|
||||
from sys import argv
|
||||
|
||||
binfile = argv[1]
|
||||
nwords = int(argv[2])
|
||||
|
||||
with open(binfile, "rb") as f:
|
||||
bindata = f.read()
|
||||
|
||||
print ("-- Altera Quartus Memory Initilization file .mif")
|
||||
print ("DEPTH = 16384; -- The size of memory in words")
|
||||
print ("WIDTH = 32; -- The size of data in bits")
|
||||
print ("")
|
||||
print ("ADDRESS_RADIX = HEX; -- The radix for address values")
|
||||
print ("DATA_RADIX = HEX; -- The radix for data values")
|
||||
print ("")
|
||||
print ("CONTENT BEGIN -- start of (address : data pairs)")
|
||||
|
||||
assert len(bindata) < 4 * nwords
|
||||
#assert len(bindata) % 4 == 0
|
||||
|
||||
for i in range(nwords):
|
||||
if i < len(bindata) // 4:
|
||||
w = bindata[4 * i : 4 * i + 4]
|
||||
print("%04x : %02x%02x%02x%02x;" % (i, w[3], w[2], w[1], w[0]))
|
||||
else:
|
||||
print("%04x : 00000000;" % (i))
|
||||
|
||||
print ("END;")
|
|
@ -1,48 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#include "firmware.h"
|
||||
|
||||
#define OUTPORT 0xffff0040
|
||||
|
||||
//volatile int n;
|
||||
|
||||
void print_chr(char ch)
|
||||
{
|
||||
while (*((volatile uint32_t*)OUTPORT) == 0 )
|
||||
{
|
||||
// Spin waiting for UART Tx empty.
|
||||
}
|
||||
*((volatile uint32_t*)OUTPORT) = ch;
|
||||
}
|
||||
|
||||
void print_str(const char *p)
|
||||
{
|
||||
while (*p != 0)
|
||||
{
|
||||
print_chr(*(p++));
|
||||
}
|
||||
}
|
||||
|
||||
void print_dec(unsigned int val)
|
||||
{
|
||||
char buffer[10];
|
||||
char *p = buffer;
|
||||
while (val || p == buffer) {
|
||||
*(p++) = val % 10;
|
||||
val = val / 10;
|
||||
}
|
||||
while (p != buffer) {
|
||||
print_chr('0' + *(--p));
|
||||
}
|
||||
}
|
||||
|
||||
void print_hex(unsigned int val, int digits)
|
||||
{
|
||||
for (int i = (4*digits)-4; i >= 0; i -= 4)
|
||||
print_chr("0123456789ABCDEF"[(val >> i) % 16]);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#include "firmware.h"
|
||||
|
||||
#define PRNG_PORT 0xffff0050
|
||||
|
||||
//volatile int n;
|
||||
|
||||
uint32_t prng()
|
||||
{
|
||||
return *((volatile uint32_t*)PRNG_PORT);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
*/
|
||||
|
||||
MEMORY {
|
||||
/* the memory in the testbench is 64k in size;
|
||||
* set LENGTH=48k and leave at least 16k for stack */
|
||||
mem : ORIGIN = 0x00000000, LENGTH = 0x0000c000
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.memory : {
|
||||
. = 0x000000;
|
||||
start*(.text);
|
||||
*(.text);
|
||||
*(*);
|
||||
end = .;
|
||||
} > mem
|
||||
}
|
|
@ -1,513 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
//#define ENABLE_INSTRTST
|
||||
//#define ENABLE_RVTST
|
||||
//#define ENABLE_SIEVE
|
||||
//#define ENABLE_MULTST
|
||||
//#define ENABLE_STATS
|
||||
|
||||
#ifndef ENABLE_QREGS
|
||||
# undef ENABLE_RVTST
|
||||
#endif
|
||||
|
||||
// Only save registers in IRQ wrapper that are to be saved by the caller in
|
||||
// the RISC-V ABI, with the excpetion of the stack pointer. The IRQ handler
|
||||
// will save the rest if necessary. I.e. skip x3, x4, x8, x9, and x18-x27.
|
||||
#undef ENABLE_FASTIRQ
|
||||
|
||||
#include "custom_ops.S"
|
||||
|
||||
.section .text
|
||||
.global irq
|
||||
.global sieve
|
||||
.global multest
|
||||
.global hard_mul
|
||||
.global hard_mulh
|
||||
.global hard_mulhsu
|
||||
.global hard_mulhu
|
||||
.global stats
|
||||
|
||||
reset_vec:
|
||||
// no more than 16 bytes here !
|
||||
//picorv32_waitirq_insn(zero)
|
||||
//picorv32_maskirq_insn(zero, zero)
|
||||
j start
|
||||
|
||||
|
||||
/* Interrupt handler
|
||||
**********************************/
|
||||
|
||||
.balign 16
|
||||
irq_vec:
|
||||
/* save registers */
|
||||
|
||||
#ifdef ENABLE_QREGS
|
||||
|
||||
picorv32_setq_insn(q2, x1)
|
||||
picorv32_setq_insn(q3, x2)
|
||||
|
||||
lui x1, %hi(irq_regs)
|
||||
addi x1, x1, %lo(irq_regs)
|
||||
|
||||
picorv32_getq_insn(x2, q0)
|
||||
sw x2, 0*4(x1)
|
||||
|
||||
picorv32_getq_insn(x2, q2)
|
||||
sw x2, 1*4(x1)
|
||||
|
||||
picorv32_getq_insn(x2, q3)
|
||||
sw x2, 2*4(x1)
|
||||
|
||||
#ifdef ENABLE_FASTIRQ
|
||||
sw x5, 5*4(x1)
|
||||
sw x6, 6*4(x1)
|
||||
sw x7, 7*4(x1)
|
||||
sw x10, 10*4(x1)
|
||||
sw x11, 11*4(x1)
|
||||
sw x12, 12*4(x1)
|
||||
sw x13, 13*4(x1)
|
||||
sw x14, 14*4(x1)
|
||||
sw x15, 15*4(x1)
|
||||
sw x16, 16*4(x1)
|
||||
sw x17, 17*4(x1)
|
||||
sw x28, 28*4(x1)
|
||||
sw x29, 29*4(x1)
|
||||
sw x30, 30*4(x1)
|
||||
sw x31, 31*4(x1)
|
||||
#else
|
||||
sw x3, 3*4(x1)
|
||||
sw x4, 4*4(x1)
|
||||
sw x5, 5*4(x1)
|
||||
sw x6, 6*4(x1)
|
||||
sw x7, 7*4(x1)
|
||||
sw x8, 8*4(x1)
|
||||
sw x9, 9*4(x1)
|
||||
sw x10, 10*4(x1)
|
||||
sw x11, 11*4(x1)
|
||||
sw x12, 12*4(x1)
|
||||
sw x13, 13*4(x1)
|
||||
sw x14, 14*4(x1)
|
||||
sw x15, 15*4(x1)
|
||||
sw x16, 16*4(x1)
|
||||
sw x17, 17*4(x1)
|
||||
sw x18, 18*4(x1)
|
||||
sw x19, 19*4(x1)
|
||||
sw x20, 20*4(x1)
|
||||
sw x21, 21*4(x1)
|
||||
sw x22, 22*4(x1)
|
||||
sw x23, 23*4(x1)
|
||||
sw x24, 24*4(x1)
|
||||
sw x25, 25*4(x1)
|
||||
sw x26, 26*4(x1)
|
||||
sw x27, 27*4(x1)
|
||||
sw x28, 28*4(x1)
|
||||
sw x29, 29*4(x1)
|
||||
sw x30, 30*4(x1)
|
||||
sw x31, 31*4(x1)
|
||||
#endif
|
||||
|
||||
#else // ENABLE_QREGS
|
||||
|
||||
#ifdef ENABLE_FASTIRQ
|
||||
sw gp, 0*4+0x200(zero)
|
||||
sw x1, 1*4+0x200(zero)
|
||||
sw x2, 2*4+0x200(zero)
|
||||
sw x5, 5*4+0x200(zero)
|
||||
sw x6, 6*4+0x200(zero)
|
||||
sw x7, 7*4+0x200(zero)
|
||||
sw x10, 10*4+0x200(zero)
|
||||
sw x11, 11*4+0x200(zero)
|
||||
sw x12, 12*4+0x200(zero)
|
||||
sw x13, 13*4+0x200(zero)
|
||||
sw x14, 14*4+0x200(zero)
|
||||
sw x15, 15*4+0x200(zero)
|
||||
sw x16, 16*4+0x200(zero)
|
||||
sw x17, 17*4+0x200(zero)
|
||||
sw x28, 28*4+0x200(zero)
|
||||
sw x29, 29*4+0x200(zero)
|
||||
sw x30, 30*4+0x200(zero)
|
||||
sw x31, 31*4+0x200(zero)
|
||||
#else
|
||||
sw gp, 0*4+0x200(zero)
|
||||
sw x1, 1*4+0x200(zero)
|
||||
sw x2, 2*4+0x200(zero)
|
||||
sw x3, 3*4+0x200(zero)
|
||||
sw x4, 4*4+0x200(zero)
|
||||
sw x5, 5*4+0x200(zero)
|
||||
sw x6, 6*4+0x200(zero)
|
||||
sw x7, 7*4+0x200(zero)
|
||||
sw x8, 8*4+0x200(zero)
|
||||
sw x9, 9*4+0x200(zero)
|
||||
sw x10, 10*4+0x200(zero)
|
||||
sw x11, 11*4+0x200(zero)
|
||||
sw x12, 12*4+0x200(zero)
|
||||
sw x13, 13*4+0x200(zero)
|
||||
sw x14, 14*4+0x200(zero)
|
||||
sw x15, 15*4+0x200(zero)
|
||||
sw x16, 16*4+0x200(zero)
|
||||
sw x17, 17*4+0x200(zero)
|
||||
sw x18, 18*4+0x200(zero)
|
||||
sw x19, 19*4+0x200(zero)
|
||||
sw x20, 20*4+0x200(zero)
|
||||
sw x21, 21*4+0x200(zero)
|
||||
sw x22, 22*4+0x200(zero)
|
||||
sw x23, 23*4+0x200(zero)
|
||||
sw x24, 24*4+0x200(zero)
|
||||
sw x25, 25*4+0x200(zero)
|
||||
sw x26, 26*4+0x200(zero)
|
||||
sw x27, 27*4+0x200(zero)
|
||||
sw x28, 28*4+0x200(zero)
|
||||
sw x29, 29*4+0x200(zero)
|
||||
sw x30, 30*4+0x200(zero)
|
||||
sw x31, 31*4+0x200(zero)
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_QREGS
|
||||
|
||||
/* call interrupt handler C function */
|
||||
|
||||
lui sp, %hi(irq_stack)
|
||||
addi sp, sp, %lo(irq_stack)
|
||||
|
||||
// arg0 = address of regs
|
||||
lui a0, %hi(irq_regs)
|
||||
addi a0, a0, %lo(irq_regs)
|
||||
|
||||
// arg1 = interrupt type
|
||||
#ifdef ENABLE_QREGS
|
||||
picorv32_getq_insn(a1, q1)
|
||||
#else
|
||||
addi a1, tp, 0
|
||||
#endif
|
||||
|
||||
// call to C function
|
||||
jal ra, irq
|
||||
|
||||
/* restore registers */
|
||||
|
||||
#ifdef ENABLE_QREGS
|
||||
|
||||
// new irq_regs address returned from C code in a0
|
||||
addi x1, a0, 0
|
||||
|
||||
lw x2, 0*4(x1)
|
||||
picorv32_setq_insn(q0, x2)
|
||||
|
||||
lw x2, 1*4(x1)
|
||||
picorv32_setq_insn(q1, x2)
|
||||
|
||||
lw x2, 2*4(x1)
|
||||
picorv32_setq_insn(q2, x2)
|
||||
|
||||
#ifdef ENABLE_FASTIRQ
|
||||
lw x5, 5*4(x1)
|
||||
lw x6, 6*4(x1)
|
||||
lw x7, 7*4(x1)
|
||||
lw x10, 10*4(x1)
|
||||
lw x11, 11*4(x1)
|
||||
lw x12, 12*4(x1)
|
||||
lw x13, 13*4(x1)
|
||||
lw x14, 14*4(x1)
|
||||
lw x15, 15*4(x1)
|
||||
lw x16, 16*4(x1)
|
||||
lw x17, 17*4(x1)
|
||||
lw x28, 28*4(x1)
|
||||
lw x29, 29*4(x1)
|
||||
lw x30, 30*4(x1)
|
||||
lw x31, 31*4(x1)
|
||||
#else
|
||||
lw x3, 3*4(x1)
|
||||
lw x4, 4*4(x1)
|
||||
lw x5, 5*4(x1)
|
||||
lw x6, 6*4(x1)
|
||||
lw x7, 7*4(x1)
|
||||
lw x8, 8*4(x1)
|
||||
lw x9, 9*4(x1)
|
||||
lw x10, 10*4(x1)
|
||||
lw x11, 11*4(x1)
|
||||
lw x12, 12*4(x1)
|
||||
lw x13, 13*4(x1)
|
||||
lw x14, 14*4(x1)
|
||||
lw x15, 15*4(x1)
|
||||
lw x16, 16*4(x1)
|
||||
lw x17, 17*4(x1)
|
||||
lw x18, 18*4(x1)
|
||||
lw x19, 19*4(x1)
|
||||
lw x20, 20*4(x1)
|
||||
lw x21, 21*4(x1)
|
||||
lw x22, 22*4(x1)
|
||||
lw x23, 23*4(x1)
|
||||
lw x24, 24*4(x1)
|
||||
lw x25, 25*4(x1)
|
||||
lw x26, 26*4(x1)
|
||||
lw x27, 27*4(x1)
|
||||
lw x28, 28*4(x1)
|
||||
lw x29, 29*4(x1)
|
||||
lw x30, 30*4(x1)
|
||||
lw x31, 31*4(x1)
|
||||
#endif
|
||||
|
||||
picorv32_getq_insn(x1, q1)
|
||||
picorv32_getq_insn(x2, q2)
|
||||
|
||||
#else // ENABLE_QREGS
|
||||
|
||||
// new irq_regs address returned from C code in a0
|
||||
addi a1, zero, 0x200
|
||||
beq a0, a1, 1f
|
||||
ebreak
|
||||
1:
|
||||
|
||||
#ifdef ENABLE_FASTIRQ
|
||||
lw gp, 0*4+0x200(zero)
|
||||
lw x1, 1*4+0x200(zero)
|
||||
lw x2, 2*4+0x200(zero)
|
||||
lw x5, 5*4+0x200(zero)
|
||||
lw x6, 6*4+0x200(zero)
|
||||
lw x7, 7*4+0x200(zero)
|
||||
lw x10, 10*4+0x200(zero)
|
||||
lw x11, 11*4+0x200(zero)
|
||||
lw x12, 12*4+0x200(zero)
|
||||
lw x13, 13*4+0x200(zero)
|
||||
lw x14, 14*4+0x200(zero)
|
||||
lw x15, 15*4+0x200(zero)
|
||||
lw x16, 16*4+0x200(zero)
|
||||
lw x17, 17*4+0x200(zero)
|
||||
lw x28, 28*4+0x200(zero)
|
||||
lw x29, 29*4+0x200(zero)
|
||||
lw x30, 30*4+0x200(zero)
|
||||
lw x31, 31*4+0x200(zero)
|
||||
#else
|
||||
lw gp, 0*4+0x200(zero)
|
||||
lw x1, 1*4+0x200(zero)
|
||||
lw x2, 2*4+0x200(zero)
|
||||
// do not restore x3 (gp)
|
||||
lw x4, 4*4+0x200(zero)
|
||||
lw x5, 5*4+0x200(zero)
|
||||
lw x6, 6*4+0x200(zero)
|
||||
lw x7, 7*4+0x200(zero)
|
||||
lw x8, 8*4+0x200(zero)
|
||||
lw x9, 9*4+0x200(zero)
|
||||
lw x10, 10*4+0x200(zero)
|
||||
lw x11, 11*4+0x200(zero)
|
||||
lw x12, 12*4+0x200(zero)
|
||||
lw x13, 13*4+0x200(zero)
|
||||
lw x14, 14*4+0x200(zero)
|
||||
lw x15, 15*4+0x200(zero)
|
||||
lw x16, 16*4+0x200(zero)
|
||||
lw x17, 17*4+0x200(zero)
|
||||
lw x18, 18*4+0x200(zero)
|
||||
lw x19, 19*4+0x200(zero)
|
||||
lw x20, 20*4+0x200(zero)
|
||||
lw x21, 21*4+0x200(zero)
|
||||
lw x22, 22*4+0x200(zero)
|
||||
lw x23, 23*4+0x200(zero)
|
||||
lw x24, 24*4+0x200(zero)
|
||||
lw x25, 25*4+0x200(zero)
|
||||
lw x26, 26*4+0x200(zero)
|
||||
lw x27, 27*4+0x200(zero)
|
||||
lw x28, 28*4+0x200(zero)
|
||||
lw x29, 29*4+0x200(zero)
|
||||
lw x30, 30*4+0x200(zero)
|
||||
lw x31, 31*4+0x200(zero)
|
||||
#endif
|
||||
|
||||
#endif // ENABLE_QREGS
|
||||
|
||||
picorv32_retirq_insn()
|
||||
|
||||
#ifndef ENABLE_QREGS
|
||||
.balign 0x200
|
||||
#endif
|
||||
irq_regs:
|
||||
// registers are saved to this memory region during interrupt handling
|
||||
// the program counter is saved as register 0
|
||||
.fill 32,4
|
||||
|
||||
// stack for the interrupt handler
|
||||
.fill 128,4
|
||||
irq_stack:
|
||||
|
||||
|
||||
/* Main program
|
||||
**********************************/
|
||||
|
||||
start:
|
||||
/* zero-initialize all registers */
|
||||
|
||||
addi x1, zero, 0
|
||||
addi x2, zero, 0
|
||||
addi x3, zero, 0
|
||||
addi x4, zero, 0
|
||||
addi x5, zero, 0
|
||||
addi x6, zero, 0
|
||||
addi x7, zero, 0
|
||||
addi x8, zero, 0
|
||||
addi x9, zero, 0
|
||||
addi x10, zero, 0
|
||||
addi x11, zero, 0
|
||||
addi x12, zero, 0
|
||||
addi x13, zero, 0
|
||||
addi x14, zero, 0
|
||||
addi x15, zero, 0
|
||||
addi x16, zero, 0
|
||||
addi x17, zero, 0
|
||||
addi x18, zero, 0
|
||||
addi x19, zero, 0
|
||||
addi x20, zero, 0
|
||||
addi x21, zero, 0
|
||||
addi x22, zero, 0
|
||||
addi x23, zero, 0
|
||||
addi x24, zero, 0
|
||||
addi x25, zero, 0
|
||||
addi x26, zero, 0
|
||||
addi x27, zero, 0
|
||||
addi x28, zero, 0
|
||||
addi x29, zero, 0
|
||||
addi x30, zero, 0
|
||||
addi x31, zero, 0
|
||||
|
||||
/* running tests from riscv-tests */
|
||||
|
||||
#ifdef ENABLE_RVTST
|
||||
# define TEST(n) \
|
||||
.global n; \
|
||||
addi x1, zero, 1000; \
|
||||
picorv32_timer_insn(zero, x1); \
|
||||
jal zero,n; \
|
||||
.global n ## _ret; \
|
||||
n ## _ret:
|
||||
#else
|
||||
# define TEST(n) \
|
||||
.global n ## _ret; \
|
||||
n ## _ret:
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_INSTRTST
|
||||
TEST(lui)
|
||||
TEST(auipc)
|
||||
TEST(j)
|
||||
TEST(jal)
|
||||
TEST(jalr)
|
||||
|
||||
TEST(beq)
|
||||
TEST(bne)
|
||||
TEST(blt)
|
||||
TEST(bge)
|
||||
TEST(bltu)
|
||||
TEST(bgeu)
|
||||
|
||||
TEST(lb)
|
||||
TEST(lh)
|
||||
TEST(lw)
|
||||
TEST(lbu)
|
||||
TEST(lhu)
|
||||
|
||||
TEST(sb)
|
||||
TEST(sh)
|
||||
TEST(sw)
|
||||
|
||||
TEST(addi)
|
||||
TEST(slti) // also tests sltiu
|
||||
TEST(xori)
|
||||
TEST(ori)
|
||||
TEST(andi)
|
||||
TEST(slli)
|
||||
TEST(srli)
|
||||
TEST(srai)
|
||||
|
||||
TEST(add)
|
||||
TEST(sub)
|
||||
TEST(sll)
|
||||
TEST(slt) // what is with sltu ?
|
||||
TEST(xor)
|
||||
TEST(srl)
|
||||
TEST(sra)
|
||||
TEST(or)
|
||||
TEST(and)
|
||||
|
||||
TEST(mulh)
|
||||
TEST(mulhsu)
|
||||
TEST(mulhu)
|
||||
TEST(mul)
|
||||
|
||||
TEST(div)
|
||||
TEST(divu)
|
||||
TEST(rem)
|
||||
TEST(remu)
|
||||
|
||||
TEST(simple)
|
||||
#endif // ENABLE_INSTRTST
|
||||
|
||||
/* set stack pointer */
|
||||
lui sp,(64*1024)>>12
|
||||
|
||||
/* set gp and tp */
|
||||
lui gp, %hi(0xdeadbeef)
|
||||
addi gp, gp, %lo(0xdeadbeef)
|
||||
addi tp, gp, 0
|
||||
|
||||
#ifdef ENABLE_SIEVE
|
||||
/* call sieve C code */
|
||||
jal ra,sieve
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MULTST
|
||||
/* call multest C code */
|
||||
jal ra,multest
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_STATS
|
||||
/* call stats C code */
|
||||
jal ra,stats
|
||||
#endif
|
||||
|
||||
|
||||
/* call helloWorld C code */
|
||||
jal ra,helloWorld
|
||||
|
||||
|
||||
/* print "DONE\n" */
|
||||
li a0,0xffff0040
|
||||
addi a1,zero,'D'
|
||||
addi a2,zero,'O'
|
||||
addi a3,zero,'N'
|
||||
addi a4,zero,'E'
|
||||
addi a5,zero,'\n'
|
||||
sw a1,0(a0)
|
||||
sw a2,0(a0)
|
||||
sw a3,0(a0)
|
||||
sw a4,0(a0)
|
||||
sw a5,0(a0)
|
||||
|
||||
li a0, 0x20000000
|
||||
li a1, 123456789
|
||||
sw a1,0(a0)
|
||||
|
||||
/* trap */
|
||||
ebreak
|
||||
|
||||
|
||||
/* Hard mul functions for multest.c
|
||||
**********************************/
|
||||
|
||||
hard_mul:
|
||||
mul a0, a0, a1
|
||||
ret
|
||||
|
||||
hard_mulh:
|
||||
mulh a0, a0, a1
|
||||
ret
|
||||
|
||||
hard_mulhsu:
|
||||
mulhsu a0, a0, a1
|
||||
ret
|
||||
|
||||
hard_mulhu:
|
||||
mulhu a0, a0, a1
|
||||
ret
|
|
@ -1,22 +0,0 @@
|
|||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
|
||||
#include "firmware.h"
|
||||
|
||||
#define TIMER_PORT 0xffff0030
|
||||
|
||||
//volatile int n;
|
||||
|
||||
int32_t timer(void)
|
||||
{
|
||||
return *((volatile uint32_t*)TIMER_PORT);
|
||||
}
|
||||
|
||||
long long time_us(void)
|
||||
{
|
||||
return *((volatile uint32_t*)TIMER_PORT) / 100;
|
||||
}
|
Loading…
Reference in New Issue