Removing unnecessary files

main
FPGALover 2023-09-17 00:32:22 -07:00
parent 5d939e2448
commit 41103bdf5b
18 changed files with 0 additions and 18039 deletions

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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++;
}
}

View File

@ -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()

View File

@ -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()

View File

@ -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;")

View File

@ -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]);
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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

View File

@ -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;
}