Add Vexriscv demo and murax.

This commit is contained in:
Colin 2025-03-24 23:54:57 +08:00
parent f03117dfd7
commit 202042c913
24 changed files with 12173 additions and 0 deletions

1
VexRiscv/demo/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

26
VexRiscv/demo/gcc.mk Normal file
View File

@ -0,0 +1,26 @@
# Set it to yes if you are using the sifive precompiled GCC pack
SIFIVE_GCC_PACK ?= yes
ifeq ($(SIFIVE_GCC_PACK),yes)
RISCV_NAME ?= riscv64-unknown-elf
RISCV_PATH ?= /opt/riscv/
else
RISCV_NAME ?= riscv32-unknown-elf
ifeq ($(MULDIV),yes)
RISCV_PATH ?= /opt/riscv32im/
else
RISCV_PATH ?= /opt/riscv32i/
endif
endif
MABI=ilp32
MARCH := rv32i_zicsr
ifeq ($(MULDIV),yes)
MARCH := $(MARCH)m
endif
ifeq ($(COMPRESSED),yes)
MARCH := $(MARCH)ac
endif
CFLAGS += -march=$(MARCH) -mabi=$(MABI)
LDFLAGS += -march=$(MARCH) -mabi=$(MABI)

15
VexRiscv/demo/libs/gpio.h Executable file
View File

@ -0,0 +1,15 @@
#ifndef GPIO_H_
#define GPIO_H_
typedef struct
{
volatile uint32_t INPUT;
volatile uint32_t OUTPUT;
volatile uint32_t OUTPUT_ENABLE;
} Gpio_Reg;
#endif /* GPIO_H_ */

View File

@ -0,0 +1,17 @@
#ifndef INTERRUPTCTRL_H_
#define INTERRUPTCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t PENDINGS;
volatile uint32_t MASKS;
} InterruptCtrl_Reg;
static void interruptCtrl_init(InterruptCtrl_Reg* reg){
reg->MASKS = 0;
reg->PENDINGS = 0xFFFFFFFF;
}
#endif /* INTERRUPTCTRL_H_ */

109
VexRiscv/demo/libs/linker.ld Executable file
View File

@ -0,0 +1,109 @@
/*
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.
*/
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(crtStart)
MEMORY {
onChipRam : ORIGIN = 0x80000000, LENGTH = 8k
}
_stack_size = DEFINED(_stack_size) ? _stack_size : 512;
_heap_size = DEFINED(_heap_size) ? _heap_size : 0;
SECTIONS {
.vector : {
*crt.o(.text);
} > onChipRam
.memory : {
*(.text);
end = .;
} > onChipRam
.rodata :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} > onChipRam
.ctors :
{
. = ALIGN(4);
_ctors_start = .;
KEEP(*(.init_array*))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4);
_ctors_end = .;
} > onChipRam
.data :
{
*(.rdata)
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} > onChipRam
.bss (NOLOAD) : {
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_bss_start = .;
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > onChipRam
.noinit (NOLOAD) : {
. = ALIGN(4);
*(.noinit .noinit.*)
. = ALIGN(4);
} > onChipRam
._user_heap (NOLOAD):
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
PROVIDE ( _heap_start = .);
. = . + _heap_size;
. = ALIGN(8);
PROVIDE ( _heap_end = .);
} > onChipRam
._stack (NOLOAD):
{
. = ALIGN(16);
PROVIDE (_stack_end = .);
. = . + _stack_size;
. = ALIGN(16);
PROVIDE (_stack_start = .);
} > onChipRam
}

View File

@ -0,0 +1,28 @@
/*
* briey.h
*
* Created on: Aug 24, 2016
* Author: clp
*/
#ifndef BRIEY_H_
#define BRIEY_H_
#include "timer.h"
#include "prescaler.h"
#include "interrupt.h"
#include "gpio.h"
#include "uart.h"
#define CORE_HZ 12000000
#define GPIO_A ((Gpio_Reg*)(0xF0000000))
#define TIMER_PRESCALER ((Prescaler_Reg*)0xF0020000)
#define TIMER_INTERRUPT ((InterruptCtrl_Reg*)0xF0020010)
#define TIMER_A ((Timer_Reg*)0xF0020040)
#define TIMER_B ((Timer_Reg*)0xF0020050)
#define UART ((Uart_Reg*)(0xF0010000))
#define UART_SAMPLE_PER_BAUD 5
#endif /* BRIEY_H_ */

View File

@ -0,0 +1,16 @@
#ifndef PRESCALERCTRL_H_
#define PRESCALERCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t LIMIT;
} Prescaler_Reg;
static void prescaler_init(Prescaler_Reg* reg){
}
#endif /* PRESCALERCTRL_H_ */

View File

@ -0,0 +1,20 @@
#ifndef TIMERCTRL_H_
#define TIMERCTRL_H_
#include <stdint.h>
typedef struct
{
volatile uint32_t CLEARS_TICKS;
volatile uint32_t LIMIT;
volatile uint32_t VALUE;
} Timer_Reg;
static void timer_init(Timer_Reg *reg){
reg->CLEARS_TICKS = 0;
reg->VALUE = 0;
}
#endif /* TIMERCTRL_H_ */

42
VexRiscv/demo/libs/uart.h Executable file
View File

@ -0,0 +1,42 @@
#ifndef UART_H_
#define UART_H_
typedef struct
{
volatile uint32_t DATA;
volatile uint32_t STATUS;
volatile uint32_t CLOCK_DIVIDER;
volatile uint32_t FRAME_CONFIG;
} Uart_Reg;
enum UartParity {NONE = 0,EVEN = 1,ODD = 2};
enum UartStop {ONE = 0,TWO = 1};
typedef struct {
uint32_t dataLength;
enum UartParity parity;
enum UartStop stop;
uint32_t clockDivider;
} Uart_Config;
static uint32_t uart_writeAvailability(Uart_Reg *reg){
return (reg->STATUS >> 16) & 0xFF;
}
static uint32_t uart_readOccupancy(Uart_Reg *reg){
return reg->STATUS >> 24;
}
static void uart_write(Uart_Reg *reg, uint32_t data){
while(uart_writeAvailability(reg) == 0);
reg->DATA = data;
}
static void uart_applyConfig(Uart_Reg *reg, Uart_Config *config){
reg->CLOCK_DIVIDER = config->clockDivider;
reg->FRAME_CONFIG = ((config->dataLength-1) << 0) | (config->parity << 8) | (config->stop << 16);
}
#endif /* UART_H_ */

78
VexRiscv/demo/libs/vga.h Normal file
View File

@ -0,0 +1,78 @@
/*
* vga.h
*
* Created on: Jul 8, 2017
* Author: spinalvm
*/
#ifndef VGA_H_
#define VGA_H_
#include <stdint.h>
typedef struct {
uint32_t hSyncStart ,hSyncEnd;
uint32_t hColorStart,hColorEnd;
uint32_t vSyncStart ,vSyncEnd;
uint32_t vColorStart,vColorEnd;
}Vga_Timing;
static const Vga_Timing vga_h640_v480_r60 = {
.hSyncStart = 96,
.hSyncEnd = 800,
.hColorStart = 96 + 16,
.hColorEnd = 800 - 48,
.vSyncStart = 2,
.vSyncEnd = 525,
.vColorStart = 2 + 10,
.vColorEnd = 525 - 33
};
static const Vga_Timing vga_simRes = {
.hSyncStart = 8,
.hSyncEnd = 70,
.hColorStart = 16,
.hColorEnd = 64,
.vSyncStart = 2,
.vSyncEnd = 48,
.vColorStart = 8,
.vColorEnd = 40
};
static const Vga_Timing vga_simRes_h160_v120 = {
.hSyncStart = 8,
.hSyncEnd = 24+160,
.hColorStart = 16,
.hColorEnd = 16+160,
.vSyncStart = 2,
.vSyncEnd = 10+120,
.vColorStart = 6,
.vColorEnd = 6+120
};
typedef struct
{
volatile uint32_t STATUS;
volatile uint32_t FRAME_SIZE;
volatile uint32_t FRAME_BASE;
volatile uint32_t DUMMY0[13];
volatile Vga_Timing TIMING;
} Vga_Reg;
static uint32_t vga_isBusy(Vga_Reg *reg){
return (reg->STATUS & 2) != 0;
}
static void vga_run(Vga_Reg *reg){
reg->STATUS = 1;
}
static void vga_stop(Vga_Reg *reg){
reg->STATUS = 0;
while(vga_isBusy(reg));
}
#endif /* VGA_H_ */

20
VexRiscv/demo/makefile Executable file
View File

@ -0,0 +1,20 @@
PROJ_NAME=demo
DEBUG=yes
BENCH=no
MULDIV=no
SRCS = $(wildcard src/*.c) \
$(wildcard src/*.cpp) \
$(wildcard src/*.S)
INC += -I./libs/
INC += -I./libs/
LDSCRIPT = ./libs/linker.ld
include ./gcc.mk
include ./subproject.mk

97
VexRiscv/demo/src/crt.S Executable file
View File

@ -0,0 +1,97 @@
.global crtStart
.global main
.global irqCallback
crtStart:
j crtInit
nop
nop
nop
nop
nop
nop
nop
.global trap_entry
trap_entry:
sw x1, - 1*4(sp)
sw x5, - 2*4(sp)
sw x6, - 3*4(sp)
sw x7, - 4*4(sp)
sw x10, - 5*4(sp)
sw x11, - 6*4(sp)
sw x12, - 7*4(sp)
sw x13, - 8*4(sp)
sw x14, - 9*4(sp)
sw x15, -10*4(sp)
sw x16, -11*4(sp)
sw x17, -12*4(sp)
sw x28, -13*4(sp)
sw x29, -14*4(sp)
sw x30, -15*4(sp)
sw x31, -16*4(sp)
addi sp,sp,-16*4
call irqCallback
lw x1 , 15*4(sp)
lw x5, 14*4(sp)
lw x6, 13*4(sp)
lw x7, 12*4(sp)
lw x10, 11*4(sp)
lw x11, 10*4(sp)
lw x12, 9*4(sp)
lw x13, 8*4(sp)
lw x14, 7*4(sp)
lw x15, 6*4(sp)
lw x16, 5*4(sp)
lw x17, 4*4(sp)
lw x28, 3*4(sp)
lw x29, 2*4(sp)
lw x30, 1*4(sp)
lw x31, 0*4(sp)
addi sp,sp,16*4
mret
.text
crtInit:
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _stack_start
bss_init:
la a0, _bss_start
la a1, _bss_end
bss_loop:
beq a0,a1,bss_done
sw zero,0(a0)
add a0,a0,4
j bss_loop
bss_done:
ctors_init:
la a0, _ctors_start
addi sp,sp,-4
ctors_loop:
la a1, _ctors_end
beq a0,a1,ctors_done
lw a3,0(a0)
add a0,a0,4
sw a0,0(sp)
jalr a3
lw a0,0(sp)
j ctors_loop
ctors_done:
addi sp,sp,4
li a0, 0x880 //880 enable timer + external interrupts
csrw mie,a0
li a0, 0x1808 //1808 enable interrupts
csrw mstatus,a0
call main
infinitLoop:
j infinitLoop

47
VexRiscv/demo/src/main.c Executable file
View File

@ -0,0 +1,47 @@
#include <stdint.h>
#include <murax.h>
void main() {
volatile uint32_t a = 1, b = 2, c = 3;
uint32_t result = 0;
interruptCtrl_init(TIMER_INTERRUPT);
prescaler_init(TIMER_PRESCALER);
timer_init(TIMER_A);
TIMER_PRESCALER->LIMIT = 12000-1; //1 ms rate
TIMER_A->LIMIT = 1000-1; //1 second rate
TIMER_A->CLEARS_TICKS = 0x00010002;
TIMER_INTERRUPT->PENDINGS = 0xF;
TIMER_INTERRUPT->MASKS = 0x1;
GPIO_A->OUTPUT_ENABLE = 0x000000FF;
GPIO_A->OUTPUT = 0x00000000;
UART->STATUS = 2; //Enable RX interrupts
UART->DATA = 'A';
while(1){
result += a;
result += b + c;
for(uint32_t idx = 0;idx < 50000;idx++) asm volatile("");
GPIO_A->OUTPUT = (GPIO_A->OUTPUT & ~0x3F) | ((GPIO_A->OUTPUT + 1) & 0x3F); //Counter on LED[5:0]
}
}
void irqCallback(){
if(TIMER_INTERRUPT->PENDINGS & 1){ //Timer A interrupt
GPIO_A->OUTPUT ^= 0x80; //Toogle led 7
TIMER_INTERRUPT->PENDINGS = 1;
}
while(UART->STATUS & (1 << 9)){ //UART RX interrupt
UART->DATA = (UART->DATA) & 0xFF;
}
}

87
VexRiscv/demo/subproject.mk Executable file
View File

@ -0,0 +1,87 @@
ifeq ($(DEBUG),yes)
CFLAGS += -g3 -O0
endif
ifeq ($(DEBUG),no)
CFLAGS += -g -O3
endif
ifeq ($(BENCH),yes)
CFLAGS += -fno-inline
endif
ifeq ($(SIFIVE_GCC_PACK),yes)
RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/$(MARCH)/$(MABI)/
else
RISCV_CLIB=$(RISCV_PATH)/$(RISCV_NAME)/lib/
endif
RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
RISCV_CC=$(RISCV_PATH)/bin/$(RISCV_NAME)-gcc
CFLAGS += -MD -fstrict-volatile-bitfields
LDFLAGS += -nostdlib -lgcc -mcmodel=medany -nostartfiles -ffreestanding -Wl,-Bstatic,-T,$(LDSCRIPT),-Map,$(OBJDIR)/$(PROJ_NAME).map,--print-memory-usage
#LDFLAGS += -lgcc -lc -lg -nostdlib -lgcc -msave-restore --strip-debug,
OBJDIR = build
OBJS := $(SRCS)
OBJS := $(OBJS:.c=.o)
OBJS := $(OBJS:.cpp=.o)
OBJS := $(OBJS:.S=.o)
OBJS := $(OBJS:..=miaou)
OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
all: $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v
$(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
$(RISCV_CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
%.hex: %.elf
$(RISCV_OBJCOPY) -O ihex $^ $@
%.bin: %.elf
$(RISCV_OBJCOPY) -O binary $^ $@
%.v: %.elf
$(RISCV_OBJCOPY) -O verilog $^ $@
%.asm: %.elf
$(RISCV_OBJDUMP) -S -d $^ > $@
$(OBJDIR)/%.o: %.c
mkdir -p $(dir $@)
$(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
$(OBJDIR)/%.o: %.cpp
mkdir -p $(dir $@)
$(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
$(OBJDIR)/%.o: %.S
mkdir -p $(dir $@)
$(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
$(OBJDIR):
mkdir -p $@
clean:
rm -f $(OBJDIR)/$(PROJ_NAME).elf
rm -f $(OBJDIR)/$(PROJ_NAME).hex
rm -f $(OBJDIR)/$(PROJ_NAME).map
rm -f $(OBJDIR)/$(PROJ_NAME).v
rm -f $(OBJDIR)/$(PROJ_NAME).asm
find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
.SECONDARY: $(OBJS)

1
VexRiscv/murax/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
obj_dir

View File

7319
VexRiscv/murax/Murax.v Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

64
VexRiscv/murax/main.cpp Normal file
View File

@ -0,0 +1,64 @@
#include "VMurax.h"
#include "VMurax_Murax.h"
#include "verilated.h"
#include "verilated_vcd_c.h"
#include "../common/framework.h"
#include "../common/jtag.h"
#include "../common/uart.h"
class MuraxWorkspace : public Workspace<VMurax>{
public:
MuraxWorkspace() : Workspace("Murax"){
ClockDomain *mainClk = new ClockDomain(&top->io_mainClk,NULL,83333,300000);
AsyncReset *asyncReset = new AsyncReset(&top->io_asyncReset,50000);
UartRx *uartRx = new UartRx(&top->io_uart_txd,1.0e12/115200);
UartTx *uartTx = new UartTx(&top->io_uart_rxd,1.0e12/115200);
timeProcesses.push_back(mainClk);
timeProcesses.push_back(asyncReset);
timeProcesses.push_back(uartRx);
timeProcesses.push_back(uartTx);
Jtag *jtag = new Jtag(&top->io_jtag_tms,&top->io_jtag_tdi,&top->io_jtag_tdo,&top->io_jtag_tck,83333*4);
timeProcesses.push_back(jtag);
#ifdef TRACE
//speedFactor = 10e-3;
//cout << "Simulation caped to " << speedFactor << " of real time"<< endl;
#endif
}
};
struct timespec timer_start(){
struct timespec start_time;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
return start_time;
}
long timer_end(struct timespec start_time){
struct timespec end_time;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time);
uint64_t diffInNanos = end_time.tv_sec*1e9 + end_time.tv_nsec - start_time.tv_sec*1e9 - start_time.tv_nsec;
return diffInNanos;
}
int main(int argc, char **argv, char **env) {
Verilated::randReset(2);
Verilated::commandArgs(argc, argv);
printf("BOOT\n");
timespec startedAt = timer_start();
MuraxWorkspace().run(1e9);
uint64_t duration = timer_end(startedAt);
cout << endl << "****************************************************************" << endl;
exit(0);
}

39
VexRiscv/murax/makefile Normal file
View File

@ -0,0 +1,39 @@
DEBUG?=no
TRACE?=no
PRINT_PERF?=no
TRACE_START=0
ADDCFLAGS += -CFLAGS -pthread -LDFLAGS -pthread
ifeq ($(TRACE),yes)
VERILATOR_ARGS += --trace
ADDCFLAGS += -CFLAGS -DTRACE --trace-fst
endif
ifeq ($(DEBUG),yes)
ADDCFLAGS += -CFLAGS "-g3 -O0"
endif
ifneq ($(DEBUG),yes)
ADDCFLAGS += -CFLAGS "-O3"
endif
ifeq ($(PRINT_PERF),yes)
ADDCFLAGS += -CFLAGS -DPRINT_PERF
endif
ADDCFLAGS += -CFLAGS -DTRACE_START=${TRACE_START}
all: clean compile
run: compile
./obj_dir/VMurax
verilate: ./Murax.v
verilator -cc ./Murax.v ${ADDCFLAGS} --gdbbt ${VERILATOR_ARGS} -Wno-WIDTH -Wno-UNOPTFLAT --x-assign unique --exe main.cpp
compile: verilate
make -j -C obj_dir/ -f VMurax.mk VMurax
clean:
rm -rf obj_dir

51
VexRiscv/murax/murax.gtkw Normal file
View File

@ -0,0 +1,51 @@
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Mon Jul 31 17:03:11 2017
[*]
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/murax/Murax.vcd"
[dumpfile_mtime] "Mon Jul 31 17:03:01 2017"
[dumpfile_size] 1539276802
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/murax/murax.gtkw"
[timestart] 300964770000
[size] 1776 953
[pos] -1 -353
*-23.000000 300989600000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] TOP.
[treeopen] TOP.Murax.
[treeopen] TOP.Murax.system_uartCtrl.
[treeopen] TOP.Murax.system_uartCtrl.uartCtrl_1.
[sst_width] 454
[signals_width] 327
[sst_expanded] 1
[sst_vpaned_height] 279
@28
TOP.Murax.system_uartCtrl.io_uart_rxd
TOP.Murax.system_uartCtrl.io_uart_txd
TOP.Murax.system_uartCtrl.io_interrupt
TOP.Murax.system_cpu.CsrPlugin_mstatus_MIE
@22
TOP.Murax.system_uartCtrl.streamFifo_2.io_push_payload[7:0]
@28
TOP.Murax.system_uartCtrl.streamFifo_2.io_push_valid
TOP.Murax.system_uartCtrl.streamFifo_2.io_pop_valid
TOP.Murax.system_uartCtrl.streamFifo_2.io_pop_ready
@22
TOP.Murax.system_uartCtrl.streamFifo_2.io_pop_payload[7:0]
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.io_read_payload[7:0]
@28
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.io_read_valid
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.stateMachine_state[2:0]
@22
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.stateMachine_shifter[7:0]
@28
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.bitTimer_tick
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.bitTimer_counter[2:0]
@29
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.io_rxd
@28
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.sampler_value
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.sampler_tick
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.sampler_samples_1
TOP.Murax.system_uartCtrl.uartCtrl_1.rx.sampler_samples_2
[pattern_trace] 1
[pattern_trace] 0