├── .gitignore ├── .gitmodules ├── BuildnRun.md ├── HartTransplant.md ├── LICENSE ├── Linux.md ├── README.md ├── Simulation.md ├── doc ├── IPC.jpg ├── coremark.png ├── design.png ├── fpgaol.png ├── linux1.png ├── linux2.png ├── linux3.png ├── linux4.png ├── micropython.jpg ├── mmulinux.jpg └── pingo.jpg ├── firmware ├── Makefile ├── bootrom │ ├── basic.c │ ├── basic.h │ ├── bootrom.S │ ├── bootrom.c │ ├── bootrom.dat │ ├── bootrom_sim.S │ ├── bootrom_sim.c │ ├── bootrom_sim.dat │ └── linker_bootrom.ld ├── fpgaolbl │ ├── fpgaolbl.S │ ├── fpgaolbl.c │ └── linker_fpgaolbl.ld ├── sd_kpbl │ ├── linker_uartbl.ld │ ├── uartbl.S │ └── uartbl.c ├── sd_uartbl │ ├── linker_uartbl.ld │ ├── uartbl.S │ ├── uartbl.bin │ └── uartbl.c └── vt100 │ ├── Makefile │ ├── link.ld │ ├── vt100.S │ ├── vt100.c │ └── vt100.dat ├── fpgaol.md ├── la32rsim.md ├── rtl ├── abandoned │ ├── PYNQ-Z1_C.xdc │ ├── alu_old.v │ ├── arbitrator.v │ ├── clock_div_pulse.v │ ├── cpu-multi-cycle.v │ ├── cpu_control_unit.v │ ├── cpu_coprocessor0.v │ ├── cpu_multicyc_simu.v │ ├── fifo.v │ ├── fifo_simu.v │ ├── keyboard.v │ ├── labkit_sd.v │ ├── mmu.v │ ├── reset.v │ ├── sdmm.v │ ├── top.v │ ├── uart.v │ └── uart_simu.v ├── board-specific │ ├── a7-lite-openxc7 │ │ ├── Makefile.openxc7.caas │ │ ├── bank35_voltage_vivado.xdc │ │ ├── caas.conf │ │ ├── clocking_wizard_clk_wiz_raw.v │ │ ├── clocking_wizard_raw.v │ │ ├── constraints.py │ │ ├── microphase-a7-lite.xdc │ │ ├── quasi.vh │ │ ├── quasi_main_openxc7.v │ │ ├── run_caas_manual.sh │ │ └── show_bels.py │ ├── memblaze │ │ ├── memblaze.xdc │ │ ├── pCPU.vh │ │ └── pcpu_main.v │ ├── muzy-2 │ │ ├── Muzy-2.xdc │ │ ├── quasi.vh │ │ └── quasi_main.v │ ├── nexys-video-openxc7 │ │ ├── Makefile.caas │ │ ├── Nexys-Video-Master.xdc │ │ ├── caas.conf │ │ ├── clocking_wizard_clk_wiz_raw.v │ │ ├── clocking_wizard_raw.v │ │ ├── constraints.py │ │ ├── quasi.vh │ │ ├── quasi_bkup.vh │ │ ├── quasi_main_openxc7.v │ │ ├── run_caas_manual.sh │ │ └── show_bels.py │ ├── nexys-video │ │ ├── Nexys-Video-Master.xdc │ │ ├── NexysVideoMIG.ucf │ │ ├── quasi.vh │ │ └── quasi_main.v │ ├── pynq-z1-with-ext │ │ ├── PYNQ-Z1_C.xdc │ │ ├── pCPU.vh │ │ └── pcpu_main.v │ ├── squeakyboard │ │ ├── quasi.vh │ │ ├── quasi_main.v │ │ ├── squeakyboard-symbi.xdc │ │ ├── squeakyboard.sdc │ │ └── squeakyboard.xdc │ ├── unknown-spartan6 │ │ ├── constraint.ucf │ │ ├── pCPU_spartan6.vh │ │ └── pcpu_main_spartan6.v │ ├── ustc-fpgaol-nboard │ │ ├── nboard.xdc │ │ ├── quasi.vh │ │ └── quasi_main_nboard.v │ └── ustc-fpgaol │ │ ├── clocking_xc7.v │ │ ├── fpgaol1.xdc │ │ ├── quasi.vh │ │ └── quasi_main.v ├── hart_transplant │ ├── openla500 │ │ ├── axi2axilite.v │ │ ├── axi_addr.v │ │ ├── axil2mm.v │ │ ├── firmware │ │ │ ├── gen_sim_dat.sh │ │ │ ├── get_start_vmlinux_docker.sh │ │ │ └── soft_compile.sh │ │ ├── iv_simu.v │ │ ├── loonghighmapper.v │ │ ├── loonglowmapper.v │ │ ├── mmcm_50.v │ │ ├── mmcm_50_sim.v │ │ ├── quasi.vh │ │ ├── quasi_loong_main.v │ │ ├── ram_way.v │ │ ├── sfifo.v │ │ ├── sim │ │ │ ├── run_sim.sh │ │ │ └── sim_main.cpp │ │ └── skidbuffer.v │ └── picorv32 │ │ ├── get.sh │ │ ├── picorv32.v │ │ ├── picorv32_busbr.v │ │ ├── quasi.vh │ │ └── quasi_main.v ├── null.dat ├── pcpu │ ├── alu.v │ ├── mmu.v │ ├── privilege.v │ ├── regfile.dat │ ├── register_file.v │ ├── register_file_bram.v │ ├── riscv-multicyc.v │ ├── rv32a.v │ └── rv32m.v └── quasisoc │ ├── bus │ ├── arbitrator.v │ ├── highmapper.v │ └── lowmapper.v │ ├── cache │ ├── cache_cpu.v │ └── cacheway.v │ ├── ch375b │ └── ch375b.v │ ├── clk │ └── clocking_xc7.v │ ├── clocked_rom.v │ ├── debounce.v │ ├── fifo.v │ ├── gpio │ └── gpio.v │ ├── hdmi │ ├── attributemap.v │ ├── console.v │ ├── glyphmap.v │ ├── hdmi_hw_fpga4fun.v │ └── hdmi_mkrvidor4000.sv │ ├── interrupt │ ├── aclint.v │ └── interrupt_unit.v │ ├── lcd │ └── lcd_ili9486.v │ ├── mm2axi4.v │ ├── mm2wb.v │ ├── mmapper.v │ ├── ps2 │ ├── ps2.v │ └── ps2_driver.v │ ├── pspi │ └── pspi_host.v │ ├── psram │ ├── burst │ │ ├── memory_controller_basic.v │ │ ├── memory_controller_burst.v │ │ └── psram_controller_qpi.v │ └── slow │ │ ├── memory_controller_slow.v │ │ └── psram_controller_spi.v │ ├── sdcard │ ├── sd_controller.v │ └── sdcard.v │ ├── sdram │ ├── hdl_util_sdram_controller.sv │ └── sdram_br.v │ ├── simple_dp_ram.v │ ├── simple_ram.v │ ├── simple_rom.v │ ├── uart │ ├── baud_rate_gen.v │ ├── serialboot.v │ ├── uart16550.v │ ├── uartnew.v │ ├── uartreset.v │ └── uartsim.v │ ├── vt100 │ ├── vt100-squeakyboard.xdc │ ├── vt100.v │ └── vt100_top.v │ └── w5500 │ └── w5500.v ├── sim ├── debounce_simu.v ├── iv_simu.v ├── mem_simu.v ├── quasi.vh ├── run_sim.sh ├── rv32m_simu.v ├── sim_main.cpp ├── top_simu.v └── zeros.dat └── software ├── Makefile ├── binpatch.py ├── coremark ├── .gitignore ├── Makefile ├── README.md ├── core_list_join.c ├── core_main.c ├── core_matrix.c ├── core_portme.c ├── core_portme.h ├── core_state.c ├── core_util.c ├── coremark.h ├── linker.ld ├── mmio_basic.c ├── mmio_basic.h ├── newlib │ ├── crt0.S │ └── syscall.c ├── sdboot.S ├── timer.c └── timer.h ├── kernel ├── Image └── quasi.dts ├── kernelboot.sh ├── mmukernel ├── Image └── mmu.dts ├── mmukernelboot.sh ├── newlib ├── crt0.S └── syscall.c ├── pingo_renderer ├── Makefile ├── linker_sdboot.ld ├── pingo │ ├── .gitignore │ ├── LICENSE │ ├── Makefile │ ├── Makefile.RV │ ├── Pingo.pro │ ├── README.md │ ├── example │ │ ├── console.png │ │ ├── consolebackend.c │ │ ├── consolebackend.h │ │ ├── cube.c │ │ ├── cube.h │ │ ├── main.c │ │ ├── memorybackend.c │ │ ├── memorybackend.h │ │ ├── pingo_mesh.c │ │ ├── pingo_mesh.h │ │ ├── shading.png │ │ ├── teapot.c │ │ ├── teapot.h │ │ ├── texture.data │ │ ├── viking.c │ │ ├── viking.h │ │ ├── viking.png │ │ ├── windowbackend.c │ │ └── windowbackend.h │ ├── manualmake.sh │ ├── math │ │ ├── mat3.c │ │ ├── mat3.h │ │ ├── mat4.c │ │ ├── mat4.h │ │ ├── types.h │ │ ├── vec2.c │ │ ├── vec2.h │ │ ├── vec3.c │ │ ├── vec3.h │ │ ├── vec4.c │ │ └── vec4.h │ ├── render │ │ ├── backend.h │ │ ├── depth.c │ │ ├── depth.h │ │ ├── material.c │ │ ├── material.h │ │ ├── mesh.c │ │ ├── mesh.h │ │ ├── object.c │ │ ├── object.h │ │ ├── pixel.c │ │ ├── pixel.h │ │ ├── rasterizer.c │ │ ├── rasterizer.h │ │ ├── renderable.c │ │ ├── renderable.h │ │ ├── renderer.c │ │ ├── renderer.h │ │ ├── scene.c │ │ ├── scene.h │ │ ├── sprite.c │ │ ├── sprite.h │ │ ├── texture.c │ │ └── texture.h │ └── sftrdr_main.h ├── sdboot.S └── sdboot.c ├── ssbi ├── Makefile ├── linker.ld ├── sbi.S └── sbi.c ├── tests ├── Makefile ├── firmware │ ├── linker.ld │ └── start.S └── riscv_tests │ ├── LICENSE │ ├── README │ ├── add.S │ ├── addi.S │ ├── amoadd_w.S │ ├── amoand_w.S │ ├── amomax_w.S │ ├── amomaxu_w.S │ ├── amomin_w.S │ ├── amominu_w.S │ ├── amoor_w.S │ ├── amoswap_w.S │ ├── amoxor_w.S │ ├── and.S │ ├── andi.S │ ├── auipc.S │ ├── beq.S │ ├── bge.S │ ├── bgeu.S │ ├── blt.S │ ├── bltu.S │ ├── bne.S │ ├── csr.S │ ├── div.S │ ├── divu.S │ ├── encoding.h │ ├── j.S │ ├── jal.S │ ├── jalr.S │ ├── lb.S │ ├── lbu.S │ ├── lh.S │ ├── lhu.S │ ├── lrsc.S │ ├── lui.S │ ├── lw.S │ ├── mcsr.S │ ├── mul.S │ ├── mulh.S │ ├── mulhsu.S │ ├── mulhu.S │ ├── or.S │ ├── ori.S │ ├── rem.S │ ├── remu.S │ ├── riscv_test.h │ ├── sb.S │ ├── sh.S │ ├── simple.S │ ├── sll.S │ ├── slli.S │ ├── slt.S │ ├── slti.S │ ├── sltiu.S │ ├── sra.S │ ├── srai.S │ ├── srl.S │ ├── srli.S │ ├── sub.S │ ├── sw.S │ ├── test_macros.h │ ├── xor.S │ └── xori.S └── uartboot.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.bin 3 | *.elf 4 | *.c_o 5 | *.log 6 | *.txt 7 | *.dtb 8 | *.bak 9 | a.out 10 | obj_dir 11 | build 12 | work 13 | eda_projects 14 | run_caas.sh 15 | *.vcd 16 | *.stash 17 | *.fasm 18 | *.frames 19 | *.json 20 | *.bit 21 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rtl/3rdparty/UberDDR3"] 2 | path = rtl/3rdparty/UberDDR3 3 | url = https://github.com/AngeloJacobo/UberDDR3 4 | -------------------------------------------------------------------------------- /HartTransplant.md: -------------------------------------------------------------------------------- 1 | ## Quasi SoC -- Hart Transplant 2 | 3 | It's not hard to use Quasi SoC peripherals with other/better/self-written RISC-V cores. Usually little change is required on software side. 4 | 5 | Main hardware modifications: 6 | 7 | - Clock and reset -- running at 62.5 MHz is recommended 8 | - Bus interface -- bridging required, **pay significant attention to endian problems** 9 | - PC start address -- ∂CPU has `0xf0000000` 10 | - Interrupt -- this is tricky ... 11 | 12 | #### [PicoRV32](https://github.com/cliffordwolf/picorv32) 13 | 14 | See `rtl/hart_transplant/picorv32/`. PicoRV32 uses simple valid-ready bus and bus bridging is not hard. But "misaligned"(non-32-bit, sb/sh, a.k.a. `mem_wstrb != 4'b1111`) store need manual processing(read then write). The core itself needs zero modification. Interrupt disabled. 15 | 16 | With mul/div enabled, all three examples(tests, coremark, renderer) run without any modification. Coremark is ~0.22 CoreMark/MHz, which is very low compared with [this](https://www.eembc.org/viewer/?benchmark_seq=13365), seems my crappy bus converter chopped performance half. 17 | 18 | #### [VexRiscv]() 19 | 20 | TODO -------------------------------------------------------------------------------- /Linux.md: -------------------------------------------------------------------------------- 1 | ## Linux Kernel on Quasi SoC 2 | 3 | Nommu 32-bit RISC-V is not officially supported by Linux yet, but one can get it work with various dirty hacks. 4 | 5 | TODO -------------------------------------------------------------------------------- /Simulation.md: -------------------------------------------------------------------------------- 1 | ## Quasi SoC -- Simulation 2 | 3 | Probably you don't have the same hardware as me, so begin from simulation is a good idea. 4 | 5 | #### Preparation 6 | 7 | The 32-bit RISC-V toolchain is required to build firmware files. 8 | 9 | You should first have RISC-V 32-bit toolchain with Newlib -- [RISC-V GNU Compiler Toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain), probably configure with `./configure --prefix=/opt/riscv32_xxx --with-arch=rv32ima_zicsr --with-abi=ilp32 && make newlib`. 10 | 11 | Or you can use pre-built Docker containers including the tools (much easier!): `regymm/rv32ima` 12 | 13 | Then run `make` in `firmware/` to generate SoC boot ROM. Or `docker run -it --rm -v .:/mnt regymm/rv32ima:latest` and `make -C /mnt/firmware`. 14 | 15 | `make` in `software/tests` compiles the riscv_tests to test all RISC-V instructions. 16 | 17 | `make` in `software/ssbi` builds the SBI to run MMU Linux kernels. 18 | 19 | #### Simulation 20 | 21 | In the `sim` directory, ordinary firmware, No-MMU kernel, and MMU kernel simulation can be run with Verilator: 22 | 23 | Ordinary firmware, like the riscv_tests: 24 | 25 | `./run_sim.sh ../software/tests/firmware/firmware.bin` 26 | 27 | You're expected to see something like this right after simulation starts: 28 | 29 | ``` 30 | Launching simulation... 31 | [bootrom_sim]c_start 32 | [bootrom_sim]xfer ctrl to 0x20001000 33 | 00 34 | 00 35 | 31 36 | OKlui..ok 37 | auipc..ok 38 | j..ok 39 | jal..ok 40 | jalr..ok 41 | beq..ok 42 | (omitted) 43 | ``` 44 | 45 | No MMU Linux kernel, kernel binary and device tree included in the repo: 46 | 47 | `./run_sim.sh kernel ../software/kernel/Image ../software/kernel/quasi.dtb` 48 | 49 | MMU Linux kernel, loaded via a simple SBI implementation: 50 | 51 | `./run_sim.sh mmukernel ../software/mmukernel/Image ../software/mmukernel/mmu0x2000.dtb ../software/ssbi/sbi.bin` 52 | 53 | An executable file for iverilog will also be compiled as `./a.out`, but the speed is much slower. 54 | 55 | 56 | -------------------------------------------------------------------------------- /doc/IPC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/IPC.jpg -------------------------------------------------------------------------------- /doc/coremark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/coremark.png -------------------------------------------------------------------------------- /doc/design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/design.png -------------------------------------------------------------------------------- /doc/fpgaol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/fpgaol.png -------------------------------------------------------------------------------- /doc/linux1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/linux1.png -------------------------------------------------------------------------------- /doc/linux2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/linux2.png -------------------------------------------------------------------------------- /doc/linux3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/linux3.png -------------------------------------------------------------------------------- /doc/linux4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/linux4.png -------------------------------------------------------------------------------- /doc/micropython.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/micropython.jpg -------------------------------------------------------------------------------- /doc/mmulinux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/mmulinux.jpg -------------------------------------------------------------------------------- /doc/pingo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/doc/pingo.jpg -------------------------------------------------------------------------------- /firmware/Makefile: -------------------------------------------------------------------------------- 1 | #RISCV = /opt/riscv32ima/bin/riscv32-unknown-linux-gnu- 2 | RISCVDIR= /opt/riscv32i 3 | RISCV = riscv32-unknown-elf- 4 | AS = $(RISCV)as 5 | ASFLAGS = -march=rv32ima_zicsr -mabi=ilp32 6 | #ASFLAGS = -march=rv32ima -mabi=ilp32 7 | LD = $(RISCV)ld 8 | #LDFLAGS = -m elf32lriscv --nostdlib 9 | LDFLAGS = -m elf32lriscv 10 | CC = $(RISCV)gcc 11 | CPP = $(RISCV)g++ 12 | #CC_L_F = -march=rv32i -mabi=ilp32 -nostdlib -mstrict-align -O0 -static 13 | CFLAGS = -march=rv32ima -mabi=ilp32 -mstrict-align -O0 -static 14 | CPPFLAGS= $(CFLAGS) -nostdlib 15 | OBJCOPY = $(RISCV)objcopy 16 | READELF = $(RISCV)readelf 17 | 18 | all: sd_uartbl/uartbl.bin bootrom/bootrom.dat bootrom/bootrom_sim.dat sd_kpbl/kpbl.bin fpgaolbl/fpgaolbl.dat 19 | 20 | %.dat: %.bin 21 | xxd -c 4 -p $*.bin > $*.dat 22 | 23 | %.bin: %.elf 24 | $(OBJCOPY) -O binary $*.elf $*.bin 25 | python3 ../software/binpatch.py $*.bin $*.elf 26 | 27 | %.o: %.S 28 | $(AS) $(ASFLAGS) $*.S -o $*.o 29 | 30 | %.c_o: %.c 31 | $(CC) -c $(CFLAGS) $*.c -o $*.c_o 32 | 33 | bootrom/bootrom_sim.elf: bootrom/bootrom_sim.o bootrom/bootrom_sim.c_o bootrom/basic.c_o 34 | $(LD) $(LDFLAGS) $^ -o $@ --script bootrom/linker_bootrom.ld 35 | 36 | bootrom/bootrom.elf: bootrom/bootrom.o bootrom/bootrom.c_o bootrom/basic.c_o 37 | $(LD) $(LDFLAGS) $^ -o $@ --script bootrom/linker_bootrom.ld 38 | 39 | sd_uartbl/uartbl.elf: sd_uartbl/uartbl.o sd_uartbl/uartbl.c_o 40 | $(LD) $(LDFLAGS) $^ -o $@ --script sd_uartbl/linker_uartbl.ld 41 | 42 | sd_kpbl/kpbl.elf: sd_kpbl/uartbl.o sd_kpbl/uartbl.c_o 43 | $(LD) $(LDFLAGS) $^ -o $@ --script sd_uartbl/linker_uartbl.ld 44 | 45 | fpgaolbl/fpgaolbl.elf: fpgaolbl/fpgaolbl.o fpgaolbl/fpgaolbl.c_o 46 | $(LD) $(LDFLAGS) $^ -o $@ --script fpgaolbl/linker_fpgaolbl.ld 47 | 48 | clean: 49 | -rm -f *.elf 50 | -rm -f *.bin 51 | -rm -f bootrom/*.dat 52 | -rm -f *.o 53 | -rm -f *.c_o 54 | -rm -f sd_uartbl/*.o 55 | -rm -f sd_uartbl/*.c_o 56 | -rm -f sd_uartbl/*.elf 57 | -rm -f sd_uartbl/*.bin 58 | -rm -f bootrom/*.o 59 | -rm -f bootrom/*.c_o 60 | -rm -f bootrom/*.elf 61 | -rm -f bootrom/*.bin 62 | -rm -f sd_kpbl/*.o 63 | -rm -f sd_kpbl/*.c_o 64 | -rm -f sd_kpbl/*.elf 65 | -rm -f sd_kpbl/*.bin 66 | 67 | #bootrom/bootrom_sim.dat: bootrom/bootrom_sim.bin 68 | #xxd -c 4 -p bootrom/bootrom_sim.bin > bootrom/result_bootrom_sim.dat 69 | 70 | #bootrom/bootrom.dat: bootrom/bootrom.bin 71 | #xxd -c 4 -p bootrom/bootrom.bin > bootrom/result_bootrom.dat 72 | 73 | -------------------------------------------------------------------------------- /firmware/bootrom/basic.c: -------------------------------------------------------------------------------- 1 | #include "basic.h" 2 | volatile int* uart_tx = (int*) 0x93000000; 3 | volatile int* uart_tx_done = (int*) 0x93000008; 4 | volatile int* uart_rx_reset = (int*) 0x93000004; 5 | volatile int* uart_rx_new = (int*) 0x93000004; 6 | volatile int* uart_rx_data = (int*) 0x93000000; 7 | 8 | volatile int* psram_base = (int*) 0x20000000; 9 | 10 | volatile int* distram_base = (int*) 0x10000000; 11 | 12 | volatile int* video_base = (int*) 0x94000000; 13 | 14 | volatile int* sd_cache_base = (int*) 0x96000000; 15 | volatile int* sd_address = (int*) 0x96001000; 16 | volatile int* sd_do_read = (int*) 0x96001004; 17 | volatile int* sd_do_write = (int*) 0x96001008; 18 | volatile int* sd_ncd = (int*) 0x96002000; 19 | volatile int* sd_ready = (int*) 0x96002010; 20 | volatile int* sd_cache_dirty = (int*) 0x96002014; 21 | 22 | volatile int* gpio_ctrl = (int*) 0x92000000; 23 | 24 | volatile int* uart_dma_ctrl = (int*) 0x99000000; 25 | 26 | int video_x = 0; 27 | int video_y = 0; 28 | 29 | char uart_getchar() 30 | { 31 | /**uart_rx_reset = 1;*/ 32 | while(! *uart_rx_new); 33 | char c = *uart_rx_data; 34 | *uart_rx_reset = 1; 35 | return c; 36 | /*return *uart_rx_data;*/ 37 | } 38 | void uart_putchar(char c) 39 | { 40 | while(! *uart_tx_done); 41 | *uart_tx = c; 42 | while(! *uart_tx_done); 43 | } 44 | void hdmi_putchar(char c) 45 | { 46 | /*int i;*/ 47 | /*int video_y_temp;*/ 48 | /*int video_x_temp;*/ 49 | /*if (c == '\r') video_x = 0;*/ 50 | /*else if (c == '\n') {*/ 51 | /*if (video_y == 29) video_y = 0;*/ 52 | /*else video_y++;*/ 53 | /*for (i = 0; i < 80; i++) {*/ 54 | /*video_base[video_y * 80 + i] = 0;*/ 55 | /*video_base[(video_y + 1) * 80 + i] = 0;*/ 56 | /*}*/ 57 | /*}*/ 58 | /*else {*/ 59 | /*video_base[video_y * 80 + video_x] = c + 0x0600;*/ 60 | /*if (video_x == 79) {*/ 61 | /*video_x = 0;*/ 62 | /*if (video_y == 29) video_y = 0;*/ 63 | /*else video_y++;*/ 64 | /*}*/ 65 | /*else video_x++;*/ 66 | /*}*/ 67 | } 68 | 69 | void uart_putstr(const char* str) 70 | { 71 | int n = 0; 72 | while(str[n]) uart_putchar(str[n++]); 73 | } 74 | 75 | -------------------------------------------------------------------------------- /firmware/bootrom/basic.h: -------------------------------------------------------------------------------- 1 | // pComputer basic MMIO library 2 | #ifndef MMIO_BASIC_H 3 | #define MMIO_BASIC_H 4 | extern volatile int* uart_tx; 5 | extern volatile int* uart_tx_done; 6 | extern volatile int* uart_rx_reset; 7 | extern volatile int* uart_rx_new; 8 | extern volatile int* uart_rx_data; 9 | 10 | extern volatile int* psram_base; 11 | 12 | extern volatile int* video_base; 13 | 14 | extern volatile int* distram_base; 15 | 16 | extern volatile int* sd_cache_base; 17 | extern volatile int* sd_address; 18 | extern volatile int* sd_do_read; 19 | extern volatile int* sd_do_write; 20 | extern volatile int* sd_ncd; 21 | extern volatile int* sd_ready; 22 | extern volatile int* sd_cache_dirty; 23 | 24 | extern volatile int* gpio_ctrl; 25 | 26 | extern volatile int* uart_dma_ctrl; 27 | 28 | char uart_getchar(); 29 | void uart_putchar(char c); 30 | void uart_putstr(const char* str); 31 | #endif 32 | -------------------------------------------------------------------------------- /firmware/bootrom/bootrom_sim.c: -------------------------------------------------------------------------------- 1 | #include "basic.h" 2 | 3 | void c_start() 4 | { 5 | uart_putstr("[bootrom_sim]c_start\n\r"); 6 | uart_putstr("[bootrom_sim]xfer ctrl to 0x20001000\n\r\n\r"); 7 | volatile int* psram_test1 = (int*) 0x20039a74; 8 | volatile int* psram_test2 = (int*) 0x20210a44; 9 | volatile int* psram_test3 = (int*) 0x200034c4; 10 | int c; 11 | c = *psram_test1; 12 | uart_putchar('0' + c%0x10); 13 | uart_putchar('0' + (c>>4)%0x10); 14 | uart_putchar('\r'); 15 | uart_putchar('\n'); 16 | c = *psram_test2; 17 | uart_putchar('0' + c%0x10); 18 | uart_putchar('0' + (c>>4)%0x10); 19 | uart_putchar('\r'); 20 | uart_putchar('\n'); 21 | c = *psram_test3; 22 | uart_putchar('0' + c%0x10); 23 | uart_putchar('0' + (c>>4)%0x10); 24 | uart_putchar('\r'); 25 | uart_putchar('\n'); 26 | asm("li a0, 0;" ::: "a0" ); 27 | asm("la a1, 0x20700000;" ::: "a1" ); 28 | asm("la t0, 0x20001000; jr t0;" ::: "t0" ); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /firmware/bootrom/linker_bootrom.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | . = 0xf0000000; 6 | .text : { 7 | _start = .; 8 | *(.text.boot) 9 | *(.text) 10 | } 11 | .data : { *(.data) } 12 | 13 | /DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) *(.reginfo) *(.MIPS.abiflags) *(.pdr)} 14 | } 15 | -------------------------------------------------------------------------------- /firmware/fpgaolbl/fpgaolbl.S: -------------------------------------------------------------------------------- 1 | .section .text.boot 2 | 3 | # C functions 4 | .globl sd_uart_bl 5 | .globl BOOT_ENTRY 6 | 7 | .equ BOOT_ENTRY, 0x20001000 8 | 9 | # entry point, at 0x20000000 10 | sd_start: 11 | # turn off all the LEDs 12 | la a0, 0x92000000 13 | li a1, 0 14 | sw a1, 24(a0) 15 | sw a1, 28(a0) 16 | sw a1, 32(a0) 17 | sw a1, 36(a0) 18 | 19 | # setup stack 20 | la sp, 0x10001ffc 21 | # read code from UART to memory 22 | jal fpgaolbl 23 | 24 | # prepare kernel a0 and a1 25 | li a0, 0 26 | la a1, 0x20700000 27 | 28 | # jump to the code. uartbl finished. 29 | la t0, BOOT_ENTRY 30 | jr t0 31 | 32 | # never here 33 | j end 34 | end: 35 | la a0, 0x92000000 36 | li a1, 1 37 | #sw a1, 24(a0) 38 | sw a1, 28(a0) 39 | #sw a1, 32(a0) 40 | sw a1, 36(a0) 41 | j end 42 | -------------------------------------------------------------------------------- /firmware/fpgaolbl/linker_fpgaolbl.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | . = 0xf0000000; 4 | .text : { *(.text.boot) } 5 | .text : { *(.text) } 6 | .data : { *(.data) } 7 | } 8 | -------------------------------------------------------------------------------- /firmware/sd_kpbl/linker_uartbl.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | . = 0x20000000; 4 | .text : { *(.text.boot) } 5 | .text : { *(.text) } 6 | .data : { *(.data) } 7 | } 8 | -------------------------------------------------------------------------------- /firmware/sd_kpbl/uartbl.S: -------------------------------------------------------------------------------- 1 | .section .text.boot 2 | 3 | # C functions 4 | .globl sd_uart_bl 5 | .globl BOOT_ENTRY 6 | 7 | .equ BOOT_ENTRY, 0x20001000 8 | 9 | # entry point, at 0x20000000 10 | sd_start: 11 | # turn off all the LEDs 12 | la a0, 0x92000000 13 | li a1, 1 14 | sw a1, 24(a0) 15 | sw a1, 28(a0) 16 | sw a1, 32(a0) 17 | sw a1, 36(a0) 18 | 19 | # setup stack 20 | la sp, 0x20000ffc 21 | # read code from UART to memory 22 | jal sd_uart_bl 23 | 24 | # prepare kernel a0 and a1 25 | li a0, 0 26 | la a1, 0x20700000 27 | 28 | # jump to the code. uartbl finished. 29 | la t0, BOOT_ENTRY 30 | jr t0 31 | 32 | # never here 33 | j end 34 | end: 35 | la a0, 0x92000000 36 | li a1, 1 37 | #sw a1, 24(a0) 38 | sw a1, 28(a0) 39 | #sw a1, 32(a0) 40 | sw a1, 36(a0) 41 | j end 42 | -------------------------------------------------------------------------------- /firmware/sd_uartbl/linker_uartbl.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | . = 0x20000000; 4 | .text : { *(.text.boot) } 5 | .text : { *(.text) } 6 | .data : { *(.data) } 7 | } 8 | -------------------------------------------------------------------------------- /firmware/sd_uartbl/uartbl.S: -------------------------------------------------------------------------------- 1 | .section .text.boot 2 | 3 | # C functions 4 | .globl sd_uart_bl 5 | .globl BOOT_ENTRY 6 | 7 | .equ BOOT_ENTRY, 0x20001000 8 | 9 | # entry point, at 0x20000000 10 | sd_start: 11 | # turn off all the LEDs 12 | la a0, 0x92000000 13 | li a1, 1 14 | sw a1, 24(a0) 15 | sw a1, 28(a0) 16 | sw a1, 32(a0) 17 | sw a1, 36(a0) 18 | 19 | # setup stack 20 | la sp, 0x200ffffc 21 | # read code from UART to memory 22 | jal sd_uart_bl 23 | 24 | # jump to the code. uartbl finished. 25 | la a0, BOOT_ENTRY 26 | jr a0 27 | 28 | # never here 29 | j end 30 | end: 31 | la a0, 0x92000000 32 | li a1, 1 33 | #sw a1, 24(a0) 34 | sw a1, 28(a0) 35 | #sw a1, 32(a0) 36 | sw a1, 36(a0) 37 | j end 38 | -------------------------------------------------------------------------------- /firmware/sd_uartbl/uartbl.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/firmware/sd_uartbl/uartbl.bin -------------------------------------------------------------------------------- /firmware/vt100/Makefile: -------------------------------------------------------------------------------- 1 | TOOLCHAIN_PREFIX=riscv32-unknown-elf- 2 | 3 | all: vt100.dat 4 | 5 | vt100.elf: vt100.S vt100.c link.ld 6 | $(TOOLCHAIN_PREFIX)gcc -nostartfiles -nostdlib -march=rv32i -mabi=ilp32 -Tlink.ld -ovt100.elf vt100.S vt100.c -lgcc -Os 7 | %.bin: %.elf 8 | $(TOOLCHAIN_PREFIX)objcopy -O binary $< $@ 9 | %.dat: %.bin 10 | xxd -c 4 -p $< > $@ 11 | #python3 makehex.py $< 1024 > $@ # use 512 for mininum 12 | 13 | clean: 14 | rm -f *.elf *.bin *.hex *.dat 15 | -------------------------------------------------------------------------------- /firmware/vt100/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY(_start) 3 | 4 | SECTIONS 5 | { 6 | . = 0x00000000; 7 | .text : { *(.text) } 8 | .data : { *(.data) } 9 | .bss : { *(.bss) } 10 | } 11 | -------------------------------------------------------------------------------- /firmware/vt100/vt100.S: -------------------------------------------------------------------------------- 1 | .globl _start 2 | .globl cpld_write_cmd 3 | .globl cpld_is_ready 4 | .globl rx_has_new 5 | .globl rx_val 6 | .globl rx_next 7 | .globl led 8 | .globl c_start 9 | 10 | 11 | _start: 12 | # li s0, 0 13 | # li s1, 0 14 | # li s2, 0 15 | # li s3, 0 16 | # li s4, 0 17 | # li s5, 0 18 | # li s6, 0 19 | # li s7, 0 20 | # li s8, 0 21 | # li s9, 0 22 | # li s10, 0 23 | # li s11, 0 24 | # li x11, 0 25 | # li x12, 0 26 | # li x13, 0 27 | # li x14, 0 28 | # li x15, 0 29 | # li x16, 0 30 | # li x17, 0 31 | # li x18, 0 32 | # li x19, 0 33 | # li x20, 0 34 | # li x21, 0 35 | # li x22, 0 36 | # li x23, 0 37 | # li x24, 0 38 | # li x25, 0 39 | # li x26, 0 40 | # li x27, 0 41 | # li x28, 0 42 | # li x29, 0 43 | # li x30, 0 44 | # li x31, 0 45 | li sp, 0x4FEC # stack 46 | j c_start 47 | 48 | cpld_write_cmd: 49 | ret 50 | li t0, 0xf000 51 | slli a0, a0, 8 52 | andi a1, a1, 0xFF 53 | add a0, a0, a1 54 | sw a0, (t0) 55 | sw a0, (t0) 56 | # sw a0, (t0) 57 | # sw a0, (t0) 58 | ret 59 | # including old rx_to_queue, rx_has_new 60 | #cpld_wait_safe: 61 | # addi sp, sp, -16 62 | # sw ra, 12(sp) 63 | # jal rx_to_queue 64 | # ret 65 | cpld_is_ready: 66 | # li t0, 0xf000 67 | # lw a0, (t0) 68 | ret 69 | rx_has_new: 70 | li t0, 0x8000 71 | lw a0, (t0) 72 | srli a0, a0, 8 73 | ret 74 | rx_val: 75 | li t0, 0x8000 76 | lw a0, (t0) 77 | andi a0, a0, 0xFF 78 | ret 79 | rx_next: 80 | li t0, 0x8000 81 | sw zero, (t0) 82 | ret 83 | #led: 84 | # li t0, 0xe000 85 | # sw a0, (t0) 86 | # ret 87 | -------------------------------------------------------------------------------- /fpgaol.md: -------------------------------------------------------------------------------- 1 | ## Quasi SoC @ USTC FPGAOL 2 | 3 | *Outsiders may find this less useful* 4 | 5 | As of 2022.1 early-stage dev 6 | 7 | fpgaol.ustc.edu.cn 8 | 9 | ![](doc/fpgaol.png) 10 | 11 | `eda_projects/pCPU-ustc-fpgaol-vivado/vivado.tcl` create project. 12 | 13 | `rtl/board-specific/ustc-fpgaol/` top design file, see quasi.vh for enabled parts(most disabled), currently half of all BRAMs(256KB if calculated correct) used as main memory. 14 | 15 | D14 button controls reset, need to slide on then off on start, then you'll see UART output. 16 | 17 | LEDs are PWM-driven so look strange. 18 | 19 | Paste your "firmware"'s' `xxd -p` result into UART(wait till finish), add a space, then Enter. Now `software/tests/` works. RAM *may* no enough for CoreMark. [RISC-V test ready-to-paste](https://gist.github.com/regymm/8f4c846782605a89368df945b00e7d89) 20 | 21 | -------------------------------------------------------------------------------- /rtl/abandoned/alu_old.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // ALU 3 | // 2020 COD Lab1 4 | // ustcpetergu 5 | 6 | module alu 7 | #(parameter WIDTH = 32) 8 | ( 9 | input [2:0]m, // selection 10 | input [WIDTH-1:0]a, b, // input 11 | output reg [WIDTH-1:0]y, // result 12 | output reg zf, // zero flag 13 | output reg cf, // carry out flag: WIDTH bit 14 | output reg of, // overflow flag 15 | output wire sf // sign flag: WIDTH-1 sign bit 16 | ); 17 | 18 | assign sf = y[WIDTH-1]; 19 | 20 | always @ (*) begin 21 | y = 0; zf = 0; cf = 0; of = 0; 22 | case(m) 23 | 3'b000: begin // add 24 | {cf, y} = a + b; 25 | of = (!a[WIDTH-1] & !b[WIDTH-1] & y[WIDTH-1]) | 26 | (a[WIDTH-1] & b[WIDTH-1] & !y[WIDTH-1]); 27 | zf = (y == 0); 28 | end 29 | 3'b001: begin // sub 30 | {cf, y} = a - b; 31 | of = (!a[WIDTH-1] & b[WIDTH-1] & y[WIDTH-1]) | 32 | (a[WIDTH-1] & !b[WIDTH-1] & !y[WIDTH-1]); 33 | zf = (y == 0); 34 | end 35 | 3'b010: begin // and 36 | y = a & b; 37 | zf = (y == 0); 38 | end 39 | 3'b011: begin // or 40 | y = a | b; 41 | zf = (y == 0); 42 | end 43 | 3'b100: begin // xor 44 | y = a ^ b; 45 | zf = (y == 0); 46 | end 47 | 3'b101: begin // sll 48 | y = b << a; 49 | end 50 | 3'b110: begin // srl 51 | y = b >> a; 52 | end 53 | default: begin // error 54 | end 55 | endcase 56 | end 57 | endmodule 58 | -------------------------------------------------------------------------------- /rtl/abandoned/arbitrator.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : arbitrator.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.03.26 6 | * Last Modified Date: 2021.03.26 7 | */ 8 | `timescale 1ns / 1ps 9 | // pCPU bus arbitrator 10 | // demux cpu, gpu, dbu and connect to mmapper 11 | 12 | module arbitrator 13 | ( 14 | input clk, 15 | input rst, 16 | 17 | input [31:0]cpu_a, 18 | input [31:0]cpu_d, 19 | input cpu_we, 20 | input cpu_rd, 21 | output reg [31:0]cpu_spo, 22 | output reg cpu_ready = 1, 23 | output reg cpu_grant = 0, 24 | 25 | input [31:0]gpu_a, 26 | input [31:0]gpu_d, 27 | input gpu_we, 28 | input gpu_rd, 29 | output reg [31:0]gpu_spo, 30 | output reg gpu_ready = 1, 31 | output reg gpu_grant = 0, 32 | 33 | input [31:0]dbu_a, 34 | input [31:0]dbu_d, 35 | input dbu_we, 36 | input dbu_rd, 37 | output reg [31:0]dbu_spo, 38 | output reg dbu_ready = 1, 39 | output reg dbu_grant = 0, 40 | 41 | (*mark_debug = "true"*)output reg [31:0]a, 42 | (*mark_debug = "true"*)output reg [31:0]d, 43 | (*mark_debug = "true"*)output reg we, 44 | (*mark_debug = "true"*)output reg rd, 45 | (*mark_debug = "true"*)input [31:0]spo, 46 | (*mark_debug = "true"*)input ready 47 | ); 48 | 49 | always @ (*) begin 50 | end 51 | 52 | always @ (posedge clk) begin 53 | if (rst) begin 54 | end else begin 55 | end 56 | end 57 | endmodule 58 | -------------------------------------------------------------------------------- /rtl/abandoned/clock_div_pulse.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // copied & modified from https://github.com/jamieiles/uart, GPLv2 3 | 4 | /* 5 | * Hacky baud rate generator to divide a 50MHz clock into a 115200 baud 6 | * rx/tx pair where the rx clcken oversamples by 16x. 7 | */ 8 | module baud_rate_gen 9 | ( 10 | input wire clk, 11 | input rst, 12 | output wire rxclk_en, 13 | output wire txclk_en 14 | ); 15 | 16 | parameter CLOCK_FREQ = 100000000; 17 | //parameter CLOCK_FREQ = 62500000; 18 | parameter RX_ACC_MAX = CLOCK_FREQ / (115200 * 16); 19 | parameter TX_ACC_MAX = CLOCK_FREQ / 115200; 20 | parameter RX_ACC_WIDTH = 20; 21 | parameter TX_ACC_WIDTH = 20; 22 | //parameter RX_ACC_WIDTH = $clog2(RX_ACC_MAX); 23 | //parameter TX_ACC_WIDTH = $clog2(TX_ACC_MAX); 24 | reg [RX_ACC_WIDTH - 1:0] rx_acc = 0; 25 | reg [TX_ACC_WIDTH - 1:0] tx_acc = 0; 26 | 27 | assign rxclk_en = (rx_acc == 0); 28 | assign txclk_en = (tx_acc == 0); 29 | 30 | always @(posedge clk) begin 31 | if (rst) rx_acc <= 1; 32 | else if (rx_acc == RX_ACC_MAX[RX_ACC_WIDTH - 1:0]) 33 | rx_acc <= 0; 34 | else 35 | rx_acc <= rx_acc + 1; 36 | end 37 | 38 | always @(posedge clk) begin 39 | if (rst) tx_acc <= 1; 40 | else if (tx_acc == TX_ACC_MAX[TX_ACC_WIDTH - 1:0]) 41 | tx_acc <= 0; 42 | else 43 | tx_acc <= tx_acc + 1; 44 | end 45 | 46 | endmodule 47 | -------------------------------------------------------------------------------- /rtl/abandoned/cpu_multicyc_simu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // CPU, mmapper, bootrom simulation 3 | 4 | module cpu_multicyc_simu(); 5 | reg clk = 0; 6 | initial begin 7 | clk = 0; 8 | forever #5 clk = ~clk; 9 | end 10 | endmodule 11 | -------------------------------------------------------------------------------- /rtl/abandoned/fifo.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // pComputer 8*512 fifo, simultaneous enqueue/dequeue 3 | 4 | module fifo 5 | ( 6 | input clk, rst, 7 | input [7:0]din, 8 | input enqueue, 9 | input dequeue, 10 | output [7:0]dout, 11 | output full, 12 | output empty, 13 | output reg [8:0]count = 0 14 | ); 15 | 16 | //reg [7:0]din0 = 0; 17 | //reg enqueue0 = 0; 18 | //reg dequeue0 = 0; 19 | //always @ (posedge clk) begin 20 | //din0 <= din; 21 | //enqueue0 <= enqueue; 22 | //dequeue0 <= dequeue; 23 | //end 24 | 25 | 26 | reg [8:0]head = 9'b0; 27 | reg [8:0]tailp1 = 9'b0; 28 | 29 | assign full = (count == 9'b111111111); 30 | assign empty = (count == 9'b0); 31 | wire enq_real = enqueue & (count != 9'b111111111); 32 | wire deq_real = dequeue & (count != 9'b0); 33 | 34 | //reg we = 0; 35 | wire we = enq_real; 36 | reg [8:0]deq_a = 0; 37 | reg [8:0]enq_a = 0; 38 | fifo_ram fifo_ram_inst ( 39 | .clk(clk), 40 | .we(we), 41 | .a(enq_a), 42 | .d(din), 43 | .dpra(deq_a), 44 | //.spo(dout), 45 | .dpo(dout) 46 | ); 47 | 48 | always @ (posedge clk) begin 49 | if (rst) begin 50 | head <= 0; 51 | tailp1 <= 1; 52 | count <= 0; 53 | deq_a <= 0; 54 | enq_a <= 0; 55 | end 56 | else begin 57 | if (deq_real) begin 58 | deq_a <= head; 59 | head <= head + 1; 60 | end 61 | if (enq_real) begin 62 | enq_a <= tailp1; 63 | tailp1 <= tailp1 + 1; 64 | end 65 | 66 | count <= count - {8'b0, deq_real} + {8'b0, enq_real}; 67 | end 68 | end 69 | endmodule 70 | 71 | -------------------------------------------------------------------------------- /rtl/abandoned/fifo_simu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // pComputer FIFO simulation 3 | 4 | module fifo_simu(); 5 | reg clk; 6 | reg rst; 7 | 8 | reg [7:0]din = 0; 9 | reg enqueue = 0; 10 | reg dequeue = 0; 11 | fifo fifo_inst 12 | ( 13 | .clk(clk), 14 | .rst(rst), 15 | .din(din), 16 | .enqueue(enqueue), 17 | .dequeue(dequeue) 18 | ); 19 | 20 | initial begin 21 | clk = 0; 22 | forever #5 clk = ~clk; 23 | end 24 | initial begin 25 | rst = 1; 26 | #10 27 | rst = 0; 28 | din = 9; 29 | enqueue = 1; 30 | #10 31 | din = 8; 32 | #10 33 | #10 34 | dequeue = 1; 35 | #10 36 | enqueue = 0; 37 | #80 38 | $finish; 39 | end 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /rtl/abandoned/keyboard.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 06/01/2020 10:36:27 AM 7 | // Design Name: 8 | // Module Name: keyboard 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module keyboard( 24 | 25 | ); 26 | endmodule 27 | -------------------------------------------------------------------------------- /rtl/abandoned/reset.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : reset.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.01.24 6 | * Last Modified Date: 2021.01.24 7 | */ 8 | `timescale 1ns / 1ps 9 | 10 | 11 | module reset 12 | ( 13 | input clk, 14 | input rst_globl, 15 | 16 | //input [2:0]a, 17 | input [31:0]d, 18 | input we, 19 | //output reg [31:0]spo, 20 | 21 | output reg rst_gpio, 22 | output reg rst_uart, 23 | output reg rst_sdcard, 24 | output reg rst_video, 25 | output reg rst_usb, 26 | output reg rst_psram, 27 | output reg rst_interrupt, 28 | output reg rst_sb, 29 | output reg rst_timer, 30 | output reg rst_mmu 31 | ); 32 | 33 | wire [31:0]data = {d[7:0], d[15:8], d[23:16], d[31:24]}; 34 | 35 | reg rst_globl_reg = 1; 36 | 37 | // TODO: simplify 38 | always @ (posedge clk) begin 39 | if (rst_globl) begin 40 | {rst_gpio, rst_uart, rst_sdcard, rst_video, rst_usb, rst_psram, rst_interrupt, rst_sb, rst_timer, rst_mmu} <= 10'b1111111111; 41 | rst_globl_reg <= 1; 42 | end else if (we) {rst_gpio, rst_uart, rst_sdcard, rst_video, rst_usb, rst_psram, rst_interrupt, rst_sb, rst_timer, rst_mmu} <= data[9:0]; 43 | else if (rst_globl_reg) begin 44 | {rst_gpio, rst_uart, rst_sdcard, rst_video, rst_usb, rst_psram, rst_interrupt, rst_sb, rst_timer, rst_mmu} <= 10'b0; 45 | rst_globl_reg <= 0; 46 | end 47 | end 48 | endmodule 49 | -------------------------------------------------------------------------------- /rtl/abandoned/uart_simu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // pComputer UART simulation 3 | 4 | 5 | module uart_simu(); 6 | reg clk; 7 | reg rst; 8 | reg txclk_en = 1; 9 | 10 | reg [1:0]a = 0; 11 | reg [31:0]d = 0; 12 | reg we = 0; 13 | reg rx = 0; 14 | wire [31:0]spo; 15 | wire tx; 16 | uart uart_inst 17 | ( 18 | .clk_50M(clk), 19 | .rxclk_en(0), 20 | .txclk_en(txclk_en), 21 | .rst(rst), 22 | 23 | .a(a), 24 | .d(d), 25 | .we(we), 26 | .spo(spo), 27 | 28 | .rx(rx), 29 | .tx(tx) 30 | ); 31 | 32 | initial begin 33 | clk = 0; 34 | forever #5 clk = ~clk; 35 | end 36 | //initial begin 37 | //txclk_en = 0; 38 | //forever #25 txclk_en = ~txclk_en; 39 | //end 40 | initial begin 41 | rst = 1; 42 | #10 43 | rst = 0; 44 | a = 2'b00; 45 | we = 0; 46 | 47 | #10 48 | d = 48; 49 | we = 1; 50 | #10 51 | d = 65; 52 | #20 53 | d = 97; 54 | #10 55 | we = 0; 56 | a = 2'b10; 57 | #1000 58 | $finish; 59 | end 60 | endmodule 61 | -------------------------------------------------------------------------------- /rtl/board-specific/a7-lite-openxc7/bank35_voltage_vivado.xdc: -------------------------------------------------------------------------------- 1 | set_property INTERNAL_VREF 0.75 [get_iobanks 35] 2 | -------------------------------------------------------------------------------- /rtl/board-specific/a7-lite-openxc7/caas.conf: -------------------------------------------------------------------------------- 1 | [caas] 2 | Server = http://127.0.0.1:18888 3 | 4 | [project] 5 | Backend = openxc7 6 | Part = xc7a100tfgg484-2 7 | Top = quasi_main_openxc7 8 | Constraint = microphase-a7-lite.xdc 9 | #Sources = *.v,*.vh,../../../rtl/pcpu/*.v,../../../rtl/quasisoc/*.v,../../../rtl/quasisoc/bus/*.v,../../../rtl/quasisoc/gpio/*.v,../../../rtl/quasisoc/interrupt/*.v,../../../rtl/quasisoc/sdcard/*.v,../../../rtl/quasisoc/uart/*.v,../../../rtl/3rdparty/DDR3_Controller/rtl/ddr3*.v,../../../rtl/quasisoc/hdmi/*.v,../../../rtl/quasisoc/hdmi/*.sv #vivado 10 | Sources = *.v,../../../rtl/pcpu/*.v,../../../rtl/quasisoc/*.v,../../../rtl/quasisoc/bus/*.v,../../../rtl/quasisoc/gpio/*.v,../../../rtl/quasisoc/interrupt/*.v,../../../rtl/quasisoc/sdcard/*.v,../../../rtl/quasisoc/uart/*.v,../../../rtl/3rdparty/DDR3_Controller/rtl/ddr3*.v,../../../rtl/quasisoc/hdmi/*.v,../../../rtl/quasisoc/hdmi/*.sv,../../../rtl/quasisoc/vt100/vt100.v #openxc7 11 | #,../../../rtl/hart_transplant/picorv32/*.v 12 | Misc = firmware/bootrom/bootrom.dat 13 | -------------------------------------------------------------------------------- /rtl/board-specific/a7-lite-openxc7/constraints.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | print('constraints.py') 3 | ddr3_name = 'ddr3_top_inst.ddr3_phy_inst' 4 | def get_cells(name_part): 5 | return list(map(lambda c: c.second, filter(lambda c: name_part in c.first, ctx.cells))) 6 | 7 | def get_cell(name_part): 8 | return get_cells(name_part)[0] 9 | 10 | c1=get_cell(ddr3_name + '.genblk5[0].ISERDESE2_train') 11 | c3=get_cell(ddr3_name + '.genblk5[0].OSERDESE2_train') 12 | print(c1) 13 | print(c3) 14 | 15 | # c2=get_cell(ddr3_name + '.genblk5[1].ISERDESE2_train') 16 | # c4=get_cell(ddr3_name + '.genblk5[1].OSERDESE2_train') 17 | 18 | # Usually, nextpnr-xilinx would place these on X0Y149, but 19 | # prjxray has missing PIPs on _SING tiles, so we need to 20 | # place these on a non-SING tile to make it work 21 | c1.setAttr('BEL', 'ILOGIC_X0Y97/ISERDESE2') 22 | c3.setAttr('BEL', 'OLOGIC_X0Y97/OSERDESE2') 23 | # c2.setAttr('BEL', 'ILOGIC_X0Y245/ISERDESE2') 24 | # c4.setAttr('BEL', 'OLOGIC_X0Y245/OSERDESE2') 25 | -------------------------------------------------------------------------------- /rtl/board-specific/a7-lite-openxc7/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | // CPU features 3 | `define RV32M 4 | `define RV32A 5 | `define IRQ_EN 6 | //`define MMU_EN 7 | `define OPENXC7 8 | `define NOARB 9 | 10 | 11 | `ifdef SIMULATION 12 | // `define GPIO_EN 13 | `define UART_EN 14 | // `define CACHE_EN 15 | // `define MEM_SIMU_EN 16 | // `define SERIALBOOT_EN 17 | // `define UART_RST_EN 18 | `else 19 | // peripheral features 20 | `define GPIO_EN 21 | `define UART_EN 22 | `define DDR_EN 23 | //`define PSRAM_EN 24 | //`define CACHE_EN 25 | `define SDCARD_EN 26 | //`define CH375B_EN 27 | `define VIDEO_EN 28 | `define VT100_EN 29 | //`define LCD_EN 30 | //`define PS2_EN 31 | //`define ETH_EN 32 | 33 | //`define SERIALBOOT_EN 34 | `define UART_RST_EN 35 | 36 | //`define AXI_GPIO_TEST 37 | `endif 38 | 39 | 40 | -------------------------------------------------------------------------------- /rtl/board-specific/a7-lite-openxc7/run_caas_manual.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | if [[ $(uname -m) == "aarch64" ]]; then 3 | append="-arm" 4 | else 5 | append="" 6 | fi 7 | 8 | cd ../../.. 9 | docker run --pull never -it --rm -m 8G \ 10 | -v `pwd`:/mnt \ 11 | -v /chipdb:/chipdb \ 12 | --tmpfs /tmp \ 13 | regymm/openxc7${append} make -C /mnt/rtl/board-specific/a7-lite-openxc7 -f Makefile.openxc7.caas 14 | -------------------------------------------------------------------------------- /rtl/board-specific/a7-lite-openxc7/show_bels.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | print('show_bels.py') 3 | ddr3_name = 'ddr3_top_inst.ddr3_phy_inst' 4 | def get_cells(name_part): 5 | return list(map(lambda c: c.second, filter(lambda c: name_part in c.first, ctx.cells))) 6 | 7 | def get_cell(name_part): 8 | return get_cells(name_part)[0] 9 | 10 | c1_name = ddr3_name + '.genblk5[0].ISERDESE2_train' 11 | # c2_name = ddr3_name + '.genblk5[1].ISERDESE2_train' 12 | c3_name = ddr3_name + '.genblk5[0].OSERDESE2_train' 13 | # c4_name = ddr3_name + '.genblk5[1].OSERDESE2_train' 14 | 15 | c1=get_cell(c1_name) 16 | # c2=get_cell(c2_name) 17 | c3=get_cell(c3_name) 18 | # c4=get_cell(c4_name) 19 | 20 | print('show_bels: ' + c1_name + ": ", c1.bel) 21 | # print('show_bels: ' + c2_name + ": ", c2.bel) 22 | print('show_bels: ' + c3_name + ": ", c3.bel) 23 | # print('show_bels: ' + c4_name + ": ", c4.bel) 24 | -------------------------------------------------------------------------------- /rtl/board-specific/memblaze/pCPU.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | 3 | // clock freq 4 | `define CLOCK_FREQ 62500000; 5 | // CPU features 6 | `define RV32M 7 | 8 | // peripheral features 9 | `define GPIO_EN 10 | `define UART_EN 11 | `define PSRAM_EN 12 | `define SDCARD_EN 13 | //`define CH375B_EN 14 | `define VIDEO_EN 15 | `define VIDEO_FALSEDIFFPAIR 16 | `define IRQ_EN 17 | //`define PS2_EN 18 | //`define MMU_EN 19 | 20 | `define SERIALBOOT_EN 21 | `define UART_RST_EN 22 | -------------------------------------------------------------------------------- /rtl/board-specific/muzy-2/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | // CPU features 3 | `define RV32M 4 | `define RV32A 5 | `define IRQ_EN 6 | `define MMU_EN 7 | 8 | 9 | `ifdef SIMULATION 10 | `define GPIO_EN 11 | `define UART_EN 12 | // `define CACHE_EN 13 | // `define MEM_SIMU_EN 14 | // `define SERIALBOOT_EN 15 | // `define UART_RST_EN 16 | `else 17 | // peripheral features 18 | `define GPIO_EN 19 | `define UART_EN 20 | `define SDRAM_EN 21 | //`define DDR_EN 22 | //`define PSRAM_EN 23 | //`define CACHE_EN 24 | `define SDCARD_EN 25 | //`define CH375B_EN 26 | //`define VIDEO_EN 27 | //`define LCD_EN 28 | //`define PS2_EN 29 | //`define ETH_EN 30 | 31 | `define SERIALBOOT_EN 32 | `define UART_RST_EN 33 | 34 | //`define AXI_GPIO_TEST 35 | `endif 36 | 37 | 38 | -------------------------------------------------------------------------------- /rtl/board-specific/nexys-video-openxc7/caas.conf: -------------------------------------------------------------------------------- 1 | [caas] 2 | Server = http://127.0.0.1:18888 3 | 4 | [project] 5 | Backend = openxc7 6 | Part = xc7a200tsbg484-1 7 | Top = quasi_main_openxc7 8 | Constraint = ../../../rtl/board-specific/nexys-video-openxc7/Nexys-Video-Master.xdc 9 | Sources = *.v,../../../rtl/pcpu/*.v,../../../rtl/quasisoc/*.v,../../../rtl/quasisoc/bus/*.v,../../../rtl/quasisoc/gpio/*.v,../../../rtl/quasisoc/interrupt/*.v,../../../rtl/quasisoc/sdcard/*.v,../../../rtl/quasisoc/uart/*.v,../../../rtl/3rdparty/DDR3_Controller/rtl/ddr3*.v,../../../rtl/quasisoc/hdmi/*.v,../../../rtl/quasisoc/hdmi/*.sv,../../../rtl/hart_transplant/picorv32/*.v,../../../rtl/quasisoc/vt100/vt100.v 10 | Misc = firmware/bootrom/bootrom.dat 11 | -------------------------------------------------------------------------------- /rtl/board-specific/nexys-video-openxc7/constraints.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ddr3_name = 'ddr3_top_inst.ddr3_phy_inst' 3 | def get_cells(name_part): 4 | return list(map(lambda c: c.second, filter(lambda c: name_part in c.first, ctx.cells))) 5 | 6 | def get_cell(name_part): 7 | return get_cells(name_part)[0] 8 | 9 | c1=get_cell(ddr3_name + '.genblk5[0].ISERDESE2_train') 10 | c3=get_cell(ddr3_name + '.genblk5[0].OSERDESE2_train') 11 | 12 | # c2=get_cell(ddr3_name + '.genblk5[1].ISERDESE2_train') 13 | # c4=get_cell(ddr3_name + '.genblk5[1].OSERDESE2_train') 14 | 15 | # Usually, nextpnr-xilinx would place these on X0Y149, but 16 | # prjxray has missing PIPs on _SING tiles, so we need to 17 | # place these on a non-SING tile to make it work 18 | c1.setAttr('BEL', 'ILOGIC_X1Y193/ISERDESE2') 19 | c3.setAttr('BEL', 'OLOGIC_X1Y193/OSERDESE2') 20 | # c2.setAttr('BEL', 'ILOGIC_X0Y245/ISERDESE2') 21 | # c4.setAttr('BEL', 'OLOGIC_X0Y245/OSERDESE2') 22 | -------------------------------------------------------------------------------- /rtl/board-specific/nexys-video-openxc7/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | // CPU features 3 | `define RV32M 4 | `define RV32A 5 | `define IRQ_EN 6 | //`define MMU_EN 7 | `define OPENXC7 8 | `define NOARB 9 | 10 | 11 | `ifdef SIMULATION 12 | // `define GPIO_EN 13 | `define UART_EN 14 | // `define CACHE_EN 15 | // `define MEM_SIMU_EN 16 | // `define SERIALBOOT_EN 17 | // `define UART_RST_EN 18 | `else 19 | // peripheral features 20 | `define GPIO_EN 21 | `define UART_EN 22 | `define DDR_EN 23 | //`define PSRAM_EN 24 | //`define CACHE_EN 25 | `define SDCARD_EN 26 | //`define CH375B_EN 27 | `define VIDEO_EN 28 | `define VT100_EN 29 | //`define LCD_EN 30 | //`define PS2_EN 31 | //`define ETH_EN 32 | 33 | //`define SERIALBOOT_EN 34 | `define UART_RST_EN 35 | 36 | //`define AXI_GPIO_TEST 37 | `endif 38 | 39 | 40 | -------------------------------------------------------------------------------- /rtl/board-specific/nexys-video-openxc7/quasi_bkup.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | // CPU features 3 | `define RV32M 4 | `define RV32A 5 | `define IRQ_EN 6 | `define MMU_EN 7 | //`define OPENXC7 8 | 9 | `ifdef SIMULATION 10 | // `define GPIO_EN 11 | `define UART_EN 12 | // `define CACHE_EN 13 | // `define MEM_SIMU_EN 14 | // `define SERIALBOOT_EN 15 | // `define UART_RST_EN 16 | `else 17 | // peripheral features 18 | `define GPIO_EN 19 | `define UART_EN 20 | `define DDR_EN 21 | //`define PSRAM_EN 22 | //`define CACHE_EN 23 | `define SDCARD_EN 24 | //`define CH375B_EN 25 | //`define VIDEO_EN 26 | //`define LCD_EN 27 | //`define PS2_EN 28 | //`define ETH_EN 29 | 30 | `define SERIALBOOT_EN 31 | `define UART_RST_EN 32 | 33 | //`define AXI_GPIO_TEST 34 | `endif 35 | 36 | 37 | -------------------------------------------------------------------------------- /rtl/board-specific/nexys-video-openxc7/run_caas_manual.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | if [[ $(uname -m) == "aarch64" ]]; then 3 | append="-arm" 4 | else 5 | append="" 6 | fi 7 | 8 | cd ../../.. 9 | docker run --pull never -it --rm -m 8G \ 10 | -v `pwd`:/mnt \ 11 | -v /chipdb:/chipdb \ 12 | --tmpfs /tmp \ 13 | regymm/openxc7${append} make -C /mnt/rtl/board-specific/nexys-video-openxc7 -f Makefile.openxc7.caas 14 | -------------------------------------------------------------------------------- /rtl/board-specific/nexys-video-openxc7/show_bels.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | ddr3_name = 'ddr3_top_inst.ddr3_phy_inst' 3 | def get_cells(name_part): 4 | return list(map(lambda c: c.second, filter(lambda c: name_part in c.first, ctx.cells))) 5 | 6 | def get_cell(name_part): 7 | return get_cells(name_part)[0] 8 | 9 | c1_name = ddr3_name + '.genblk5[0].ISERDESE2_train' 10 | # c2_name = ddr3_name + '.genblk5[1].ISERDESE2_train' 11 | c3_name = ddr3_name + '.genblk5[0].OSERDESE2_train' 12 | # c4_name = ddr3_name + '.genblk5[1].OSERDESE2_train' 13 | 14 | c1=get_cell(c1_name) 15 | # c2=get_cell(c2_name) 16 | c3=get_cell(c3_name) 17 | # c4=get_cell(c4_name) 18 | 19 | print('show_bels: ' + c1_name + ": ", c1.bel) 20 | # print('show_bels: ' + c2_name + ": ", c2.bel) 21 | print('show_bels: ' + c3_name + ": ", c3.bel) 22 | # print('show_bels: ' + c4_name + ": ", c4.bel) 23 | -------------------------------------------------------------------------------- /rtl/board-specific/nexys-video/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | // CPU features 3 | `define RV32M 4 | //`define RV32A 5 | //`define IRQ_EN 6 | //`define MMU_EN 7 | `define NOARB 8 | 9 | `ifdef SIMULATION 10 | // `define GPIO_EN 11 | `define UART_EN 12 | // `define CACHE_EN 13 | // `define MEM_SIMU_EN 14 | // `define SERIALBOOT_EN 15 | // `define UART_RST_EN 16 | `else 17 | // peripheral features 18 | //`define GPIO_EN 19 | `define UART_EN 20 | `define DDR_EN 21 | //`define PSRAM_EN 22 | //`define CACHE_EN 23 | `define SDCARD_EN 24 | //`define CH375B_EN 25 | //`define VIDEO_EN 26 | //`define LCD_EN 27 | //`define PS2_EN 28 | //`define ETH_EN 29 | 30 | //`define SERIALBOOT_EN 31 | //`define UART_RST_EN 32 | 33 | //`define AXI_GPIO_TEST 34 | `endif 35 | 36 | 37 | -------------------------------------------------------------------------------- /rtl/board-specific/pynq-z1-with-ext/pCPU.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | 3 | // clock freq 4 | `define CLOCK_FREQ 62500000; 5 | // CPU features 6 | `define RV32M 7 | 8 | // peripheral features 9 | `define GPIO_EN 10 | `define UART_EN 11 | `define PSRAM_EN 12 | `define SDCARD_EN 13 | //`define CH375B_EN 14 | `define VIDEO_EN 15 | `define IRQ_EN 16 | //`define PS2_EN 17 | //`define MMU_EN 18 | 19 | `define SERIALBOOT_EN 20 | `define UART_RST_EN 21 | -------------------------------------------------------------------------------- /rtl/board-specific/squeakyboard/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | 3 | // clock freq 4 | `define CLOCK_FREQ 62500000; 5 | // CPU features 6 | `define RV32M 7 | `define RV32A 8 | `define IRQ_EN 9 | 10 | // peripheral features 11 | `define GPIO_EN 12 | `define UART_EN 13 | `define UART2_EN 14 | `define PSRAM_EN 15 | `define CACHE_EN 16 | `define SDCARD_EN 17 | //`define CH375B_EN 18 | `define VIDEO_EN 19 | `define TRUE_HDMI_EN 20 | `define VT100_EN 21 | //`define LCD_EN 22 | //`define PS2_EN 23 | //`define ETH_EN 24 | //`define MMU_EN 25 | 26 | `define SERIALBOOT_EN 27 | `define UART_RST_EN 28 | 29 | //`define AXI_GPIO_TEST 30 | -------------------------------------------------------------------------------- /rtl/board-specific/squeakyboard/squeakyboard.sdc: -------------------------------------------------------------------------------- 1 | #create_clock -period 20.000 [get_nets sysclk] 2 | #create_generated_clock -name c62d5 -source [get_pins clocking_xc7_inst/clk1_62d5] -divide_by 16 -multiply_by 20 -add -master_clock sysclk [get_pins clocking_xc7_inst/clk1_62d5] 3 | #create_generated_clock -name c125 -source [get_pins clocking_xc7_inst/clk2_125] -divide_by 8 -multiply_by 20 -add -master_clock sysclk [get_pins clocking_xc7_inst/clk2_125] 4 | #set_property PHASESHIFT_MODE WAVEFORM [get_cells -hierarchical *adv*] 5 | create_clock -period 20 sysclk 6 | create_clock -period 16 clk_main 7 | create_clock -period 8 clk_mem 8 | #create_clock -period 40 clk_hdmi_25 9 | #create_clock -period 4 clk_hdmi_250 10 | #create_clock -period 20 clk_2x 11 | -------------------------------------------------------------------------------- /rtl/board-specific/unknown-spartan6/pCPU_spartan6.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | 3 | // clock freq 4 | `define CLOCK_FREQ 62500000; 5 | // CPU features 6 | `define RV32M 7 | 8 | // peripheral features 9 | `define GPIO_EN 10 | `define UART_EN 11 | //`define PSRAM_EN 12 | //`define SDCARD_EN 13 | //`define CH375B_EN 14 | //`define VIDEO_EN 15 | `define IRQ_EN 16 | //`define PS2_EN 17 | //`define MMU_EN 18 | 19 | //`define SERIALBOOT_EN 20 | `define UART_RST_EN 21 | -------------------------------------------------------------------------------- /rtl/board-specific/ustc-fpgaol-nboard/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | // CPU features 3 | `define RV32M 4 | `define RV32A 5 | `define IRQ_EN 6 | `define MMU_EN 7 | //`define OPENXC7 8 | 9 | `ifdef SIMULATION 10 | // `define GPIO_EN 11 | `define UART_EN 12 | // `define CACHE_EN 13 | // `define MEM_SIMU_EN 14 | // `define SERIALBOOT_EN 15 | // `define UART_RST_EN 16 | `else 17 | // peripheral features 18 | `define GPIO_EN 19 | `define UART_EN 20 | `define DDR_EN 21 | //`define PSRAM_EN 22 | //`define CACHE_EN 23 | //`define SDCARD_EN 24 | //`define CH375B_EN 25 | //`define VIDEO_EN 26 | //`define LCD_EN 27 | //`define PS2_EN 28 | //`define ETH_EN 29 | 30 | `define SERIALBOOT_EN 31 | `define UART_RST_EN 32 | 33 | //`define AXI_GPIO_TEST 34 | `endif 35 | 36 | 37 | -------------------------------------------------------------------------------- /rtl/board-specific/ustc-fpgaol/clocking_xc7.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : clocking_xc7.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.10.21 6 | * Last Modified Date: 2021.10.21 7 | */ 8 | 9 | module clocking_xc7 ( 10 | input clk_50, 11 | output clk1_62d5, 12 | output clk2_125, 13 | output clk3_25, 14 | output clk4_250, 15 | output clk5_50 16 | ); 17 | wire clk_ibuf; 18 | wire clk_bufg; 19 | wire clk1_pll; 20 | wire clk2_pll; 21 | wire clk3_pll; 22 | wire clk4_pll; 23 | wire clk5_pll; 24 | 25 | PLLE2_ADV #( 26 | .CLKFBOUT_MULT(10), 27 | //.CLKFBOUT_MULT(30), 28 | .CLKIN1_PERIOD(10.0), 29 | .CLKOUT0_DIVIDE(40), 30 | //.CLKOUT0_DIVIDE(20), 31 | .CLKOUT0_PHASE(0), 32 | .CLKOUT1_DIVIDE(8), 33 | //.CLKOUT1_DIVIDE(10), 34 | .CLKOUT1_PHASE(0), 35 | .CLKOUT2_DIVIDE(40), 36 | .CLKOUT2_PHASE(0), 37 | .CLKOUT3_DIVIDE(4), 38 | .CLKOUT3_PHASE(0), 39 | .CLKOUT4_DIVIDE(20), 40 | .CLKOUT4_PHASE(0), 41 | .DIVCLK_DIVIDE(1'd1), 42 | .REF_JITTER1(0.01), 43 | .STARTUP_WAIT("FALSE") 44 | ) plle2_adv_inst ( 45 | .CLKFBIN(pll_fb), 46 | .CLKFBOUT(pll_fb), 47 | .CLKIN1(clk_bufg), 48 | .CLKOUT0(clk1_pll), 49 | .CLKOUT1(clk2_pll), 50 | .CLKOUT2(clk3_pll), 51 | .CLKOUT3(clk4_pll), 52 | .CLKOUT4(clk5_pll) 53 | ); 54 | 55 | IBUF clkbuf ( 56 | .I(clk_50), 57 | .O(clk_ibuf) 58 | ); 59 | BUFG bufg_in ( 60 | .I(clk_ibuf), 61 | .O(clk_bufg) 62 | ); 63 | BUFG bufg_1 ( 64 | .I(clk1_pll), 65 | .O(clk1_62d5) 66 | ); 67 | BUFG bufg_2 ( 68 | .I(clk2_pll), 69 | .O(clk2_125) 70 | ); 71 | BUFG bufg_3 ( 72 | .I(clk3_pll), 73 | .O(clk3_25) 74 | ); 75 | BUFG bufg_4 ( 76 | .I(clk4_pll), 77 | .O(clk4_250) 78 | ); 79 | BUFG bufg_5 ( 80 | .I(clk5_pll), 81 | .O(clk5_50) 82 | ); 83 | endmodule 84 | -------------------------------------------------------------------------------- /rtl/board-specific/ustc-fpgaol/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | 3 | // clock freq 4 | `define CLOCK_FREQ 25000000; 5 | // CPU features 6 | `define RV32M 7 | `define RV32A 8 | 9 | // peripheral features 10 | `define GPIO_EN 11 | `define UART_EN 12 | //`define PSRAM_EN 13 | //`define CACHE_EN 14 | //`define SDCARD_EN 15 | //`define CH375B_EN 16 | //`define VIDEO_EN 17 | `define IRQ_EN 18 | //`define PS2_EN 19 | //`define ETH_EN 20 | //`define MMU_EN 21 | 22 | //`define DDR_EN 23 | 24 | `define SERIALBOOT_EN 25 | `define UART_RST_EN 26 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/firmware/gen_sim_dat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | xxd -c 4 -e start.bin | awk '{print $2}' > start.dat 3 | rm -rf meminit.bin 4 | fallocate -l $((0x300000)) meminit.bin 5 | cat vmlinux.bin >> meminit.bin 6 | fallocate -l $((0x5f00000)) meminit.bin 7 | xxd -r -p init_5f.txt >> meminit.bin 8 | fallocate -l $((0x8000000)) meminit.bin 9 | xxd -c 4 -e meminit.bin | awk '{print $2}' > meminit.dat 10 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/firmware/get_start_vmlinux_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -it --rm -v .:/mnt regymm/la32r:latest /mnt/soft_compile.sh 3 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/firmware/soft_compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make -C /src/chiplab/sims/verilator/run_prog soft_compile 4 | cp /src/chiplab/sims/verilator/run_prog/obj/linux_obj/obj/vmlinux.bin /mnt 5 | cp /src/chiplab/sims/verilator/run_prog/obj/linux_obj/obj/start.bin /mnt 6 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/iv_simu.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : iv_simu.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2023.02.18 6 | * Last Modified Date: 2023.02.18 7 | */ 8 | // iverilog "interactive" simulation 9 | `timescale 1ns / 1ns 10 | `define SIMULATION 11 | 12 | module top_simu (); 13 | reg clk = 0; 14 | reg [1:0]sw = 0; 15 | reg [1:0]btn = 0; 16 | wire [3:0]led; 17 | 18 | wire tx; 19 | reg rx = 1; 20 | 21 | quasi_loong_main #( 22 | .SIMULATION(1), 23 | .INTERACTIVE_SIM(0) 24 | ) quasisoc_inst 25 | ( 26 | .sysclk(clk), 27 | .btn(btn), 28 | .led(led), 29 | .sw(sw), 30 | 31 | .uart_rx(rx), 32 | .uart_tx(tx) 33 | ); 34 | 35 | initial begin 36 | clk = 0; 37 | forever #10 clk = ~clk; 38 | end 39 | 40 | initial begin 41 | //$dumpfile("wave.vcd"); 42 | //$dumpvars(0, quasisoc_inst); 43 | sw = 2'b01; 44 | btn = 2'b11; 45 | #10000 46 | sw = 2'b00; 47 | btn = 2'b00; 48 | 49 | #200000000.0; 50 | $finish; 51 | end 52 | endmodule 53 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/loonghighmapper.v: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | // Author: regymm 3 | 4 | `timescale 1ns / 1ps 5 | // high mapper -- mux memory and MMIO slow devices apart 6 | // should have good timing 7 | 8 | module highmapper 9 | ( 10 | (*mark_debug = "true"*)input [31:0]a, 11 | (*mark_debug = "true"*)input [31:0]d, 12 | (*mark_debug = "true"*)input [3:0]web, 13 | (*mark_debug = "true"*)input rd, 14 | (*mark_debug = "true"*)output reg [31:0]spo, 15 | (*mark_debug = "true"*)output reg ready, 16 | 17 | output reg [31:0]mem_a, 18 | output reg [31:0]mem_d, 19 | output reg [3:0]mem_web, 20 | output reg mem_rd, 21 | input [31:0]mem_spo, 22 | input mem_ready, 23 | 24 | output reg [31:0]mmio_a, 25 | output reg [31:0]mmio_d, 26 | output reg [3:0]mmio_web, 27 | output reg mmio_rd, 28 | input [31:0]mmio_spo, 29 | input mmio_ready 30 | ); 31 | 32 | always @ (*) begin 33 | mem_a = a; 34 | mem_d = d; 35 | mmio_a = a; 36 | mmio_d = d; 37 | end 38 | 39 | always @ (*) begin 40 | mem_web = 0; 41 | mem_rd = 0; 42 | mmio_web = 0; 43 | mmio_rd = 0; 44 | spo = 0; 45 | ready = 1; 46 | if (a[31:28] == 4'h0) begin 47 | mem_web = web; 48 | mem_rd = rd; 49 | spo = mem_spo; 50 | ready = mem_ready; 51 | end else begin 52 | mmio_web = web; 53 | mmio_rd = rd; 54 | spo = mmio_spo; 55 | ready = mmio_ready; 56 | end 57 | end 58 | endmodule 59 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/mmcm_50.v: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | // Author: regymm 3 | 4 | `timescale 1ps/1ps 5 | 6 | module mmcm_50_to_50 ( 7 | input wire resetn, 8 | input wire clk_in1, 9 | output wire clk_out1, 10 | output wire locked 11 | ); 12 | wire clk_out1_mmcm; 13 | wire fb; 14 | wire fb_buf; 15 | MMCME2_ADV #( 16 | .BANDWIDTH ("OPTIMIZED"), 17 | .CLKOUT4_CASCADE ("FALSE"), 18 | .COMPENSATION ("ZHOLD"), 19 | .STARTUP_WAIT ("FALSE"), 20 | .DIVCLK_DIVIDE (1), 21 | .CLKFBOUT_MULT_F (20.000), // PLL 1000 MHz 22 | .CLKFBOUT_PHASE (0.000), 23 | .CLKFBOUT_USE_FINE_PS ("FALSE"), 24 | .CLKOUT0_DIVIDE_F (20.000), // 50 MHz 25 | .CLKOUT0_PHASE (0.000), 26 | .CLKOUT0_DUTY_CYCLE (0.500), 27 | .CLKOUT0_USE_FINE_PS ("FALSE"), 28 | .CLKIN1_PERIOD (20.000) 29 | ) mmcm_adv_inst ( 30 | .CLKFBOUT (fb), 31 | .CLKFBOUTB (), 32 | .CLKOUT0 (clk_out1_mmcm), 33 | .CLKOUT0B (), 34 | .CLKOUT1 (), 35 | .CLKOUT1B (), 36 | .CLKOUT2 (), 37 | .CLKOUT2B (), 38 | .CLKOUT3 (), 39 | .CLKOUT3B (), 40 | .CLKOUT4 (), 41 | .CLKOUT5 (), 42 | .CLKOUT6 (), 43 | .CLKFBIN (fb_buf), 44 | .CLKIN1 (clk_in1), 45 | .CLKIN2 (1'b0), 46 | .CLKINSEL (1'b1), 47 | .DADDR (7'h0), 48 | .DCLK (1'b0), 49 | .DEN (1'b0), 50 | .DI (16'h0), 51 | .DO (), 52 | .DRDY (), 53 | .DWE (1'b0), 54 | .PSCLK (1'b0), 55 | .PSEN (1'b0), 56 | .PSINCDEC (1'b0), 57 | .PSDONE (), 58 | .LOCKED (locked), 59 | .CLKINSTOPPED (), 60 | .CLKFBSTOPPED (), 61 | .PWRDWN (1'b0), 62 | .RST (~resetn)); 63 | BUFG clkf_buf 64 | (.O (fb_buf), 65 | .I (fb)); 66 | BUFG clkout1_buf 67 | (.O (clk_out1), 68 | .I (clk_out1_mmcm)); 69 | endmodule 70 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/mmcm_50_sim.v: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | // Author: regymm 3 | 4 | `timescale 1ps/1ps 5 | 6 | module mmcm_50_to_50 ( 7 | input wire resetn, 8 | input wire clk_in1, 9 | output wire clk_out1, 10 | output wire locked 11 | ); 12 | assign clk_out1 = clk_in1; 13 | assign locked = 1'b1; 14 | endmodule 15 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | 3 | `define CLOCK_FREQ 50000000; 4 | 5 | // peripheral features 6 | `define GPIO_EN 7 | `define UART_EN 8 | //`define PSRAM_EN 9 | //`define CACHE_EN 10 | //`define SDCARD_EN 11 | //`define CH375B_EN 12 | //`define VIDEO_EN 13 | //`define IRQ_EN 14 | //`define PS2_EN 15 | //`define ETH_EN 16 | //`define MMU_EN 17 | 18 | //`define SERIALBOOT_EN 19 | `define UART_RST_EN 20 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/ram_way.v: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | // Author: regymm 3 | 4 | `timescale 1ns / 1ps 5 | module data_bank_sram ( 6 | input clka, 7 | input [7:0]addra, 8 | input [31:0]dina, 9 | input [3:0]wea, 10 | input ena, 11 | output reg [31:0]douta 12 | ); 13 | 14 | reg [31:0]mem[255:0]; 15 | //integer i; 16 | //initial begin 17 | //for (i = 0; i < 256; i=i+1) 18 | //mem[i] = 32'b0; 19 | //end 20 | 21 | always @ (posedge clka) begin 22 | if (ena) begin 23 | if (wea[0]) mem[addra][7:0] <= dina[7:0]; 24 | if (wea[1]) mem[addra][15:8] <= dina[15:8]; 25 | if (wea[2]) mem[addra][23:16] <= dina[23:16]; 26 | if (wea[3]) mem[addra][31:24] <= dina[31:24]; 27 | douta <= mem[addra]; 28 | end else begin 29 | douta <= 0; 30 | end 31 | end 32 | endmodule 33 | 34 | module tagv_sram ( 35 | input clka, 36 | input [7:0]addra, 37 | input [20:0]dina, 38 | input [0:0]wea, 39 | input ena, 40 | output reg [20:0]douta 41 | ); 42 | 43 | reg [20:0]mem[255:0]; 44 | //integer i; 45 | //initial begin 46 | //for (i = 0; i < 256; i=i+1) 47 | //mem[i] = 21'b0; 48 | //end 49 | 50 | always @ (posedge clka) begin 51 | if (ena) begin 52 | if (wea) begin 53 | mem[addra] <= dina; 54 | end 55 | douta <= mem[addra]; 56 | end else begin 57 | douta <= 0; 58 | end 59 | end 60 | endmodule 61 | -------------------------------------------------------------------------------- /rtl/hart_transplant/openla500/sim/sim_main.cpp: -------------------------------------------------------------------------------- 1 | #include "Vquasi_main.h" 2 | #include "verilated.h" 3 | #include "fcntl.h" 4 | #include "termios.h" 5 | #include "unistd.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main (int argc, char* argv[]) 12 | { 13 | Verilated::commandArgs(argc, argv); 14 | Vquasi_main *top = new Vquasi_main; 15 | 16 | int timeout = 3600; 17 | if (argc == 2) 18 | timeout = atoi(argv[1]); 19 | 20 | int i = 0; 21 | int j = 0; 22 | top->sw = 1; 23 | 24 | char buf; 25 | fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); 26 | struct termios raw; 27 | tcgetattr(STDIN_FILENO, &raw); 28 | raw.c_lflag &= ~(ECHO | ICANON); 29 | tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); 30 | 31 | time_t start = time(0); 32 | unsigned long start_sec = (unsigned long) start; 33 | while(1) { 34 | if (top->uart_rxsim_en == 1) top->uart_rxsim_en = 0; 35 | if (j == 20) { 36 | j = 0; 37 | int input = read(0, &buf, 1); 38 | if (input > 0) { 39 | //printf("You said: %c\n", buf); 40 | top->uart_rxsim_en = 1; 41 | top->uart_rxsim_data = buf; 42 | } 43 | } 44 | else j++; 45 | 46 | if (i < 100) { 47 | i++; 48 | } 49 | if (i == 100) { 50 | top->sw = 0; 51 | } 52 | top->sysclk = 0; 53 | top->eval(); 54 | top->sysclk = 1; 55 | top->eval(); 56 | time_t now = time(0); 57 | unsigned long now_sec = (unsigned long) now; 58 | if (now_sec - start_sec > timeout) 59 | break; 60 | } 61 | top->final(); 62 | delete top; 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /rtl/hart_transplant/picorv32/get.sh: -------------------------------------------------------------------------------- 1 | wget https://github.com/cliffordwolf/picorv32/raw/master/picorv32.v 2 | -------------------------------------------------------------------------------- /rtl/hart_transplant/picorv32/picorv32_busbr.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : picorv32_busbr.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.11.19 6 | * Last Modified Date: 2021.11.19 7 | */ 8 | `timescale 1ns / 1ps 9 | 10 | module picorv32_busbr 11 | ( 12 | input clk, 13 | 14 | input ready, 15 | input [31:0]spo, 16 | output [31:0]a, 17 | output [31:0]d, 18 | output we, 19 | output rd, 20 | 21 | input mem_valid, 22 | input mem_instr, 23 | output mem_ready, 24 | input [31:0]mem_addr, 25 | input [31:0]mem_wdata, 26 | input [3:0]mem_wstrb, 27 | output [31:0]mem_rdata 28 | ); 29 | wire read = mem_wstrb == 0; 30 | wire w_normal = mem_valid & !read & mem_wstrb == 4'b1111; 31 | wire w_unalign = mem_valid & !read & mem_wstrb != 4'b1111; 32 | //wire write = mem_valid & !read; 33 | reg [1:0]state = 0; 34 | reg [31:0]unalign_save = 0; 35 | 36 | assign a = mem_addr; 37 | assign mem_rdata = spo; 38 | 39 | reg mem_valid_last = 0; 40 | always @ (posedge clk) begin 41 | mem_valid_last <= mem_valid; 42 | end 43 | wire mem_valid_posedge = mem_valid & !(mem_valid_last); 44 | 45 | assign rd = mem_valid_posedge & (read | w_unalign); 46 | assign we = state == 0 ? mem_valid_posedge & w_normal : state == 1; 47 | //assign rd = mem_valid_posedge; 48 | //assign we = state == 1; 49 | 50 | 51 | wire [31:0]unalign_mask = {{8{mem_wstrb[3]}}, {8{mem_wstrb[2]}}, {8{mem_wstrb[1]}}, {8{mem_wstrb[0]}}}; 52 | wire [31:0]unalign_w_data = (unalign_save & ~unalign_mask) + (mem_wdata & unalign_mask); 53 | 54 | assign d = state == 0 ? mem_wdata : unalign_w_data; 55 | 56 | reg unalign_done = 0; 57 | 58 | reg mem_ready_r = 0; 59 | assign mem_ready = mem_ready_r & mem_valid; 60 | 61 | always @ (posedge clk) begin 62 | if (!mem_valid) begin 63 | mem_ready_r <= 0; 64 | unalign_done <= 0; 65 | end else if (state == 0) begin 66 | if (ready) begin // ready should drop to 0 imm after valid high 67 | if (w_unalign & !unalign_done) begin 68 | //if (write & !unalign_done) begin 69 | unalign_save <= spo; 70 | state <= 1; 71 | end else mem_ready_r <= 1; 72 | end 73 | end else if (state == 1) begin 74 | state <= 2; 75 | end else if (state == 2) begin 76 | if (ready) begin 77 | state <= 0; 78 | unalign_done <= 1; 79 | mem_ready_r <= 1; 80 | end 81 | end 82 | end 83 | endmodule 84 | -------------------------------------------------------------------------------- /rtl/hart_transplant/picorv32/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | 3 | // clock freq 4 | `define CLOCK_FREQ 62500000; 5 | // CPU features 6 | `define RV32M 7 | 8 | // peripheral features 9 | `define GPIO_EN 10 | `define UART_EN 11 | `define PSRAM_EN 12 | `define CACHE_EN 13 | `define SDCARD_EN 14 | `define CH375B_EN 15 | `define VIDEO_EN 16 | `define IRQ_EN 17 | `define PS2_EN 18 | `define ETH_EN 19 | //`define MMU_EN 20 | 21 | `define SERIALBOOT_EN 22 | `define UART_RST_EN 23 | -------------------------------------------------------------------------------- /rtl/null.dat: -------------------------------------------------------------------------------- 1 | 00000000 2 | -------------------------------------------------------------------------------- /rtl/pcpu/alu.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : alu.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.10.17 6 | * Last Modified Date: 2022.07.07 7 | */ 8 | `timescale 1ns / 1ps 9 | // ALU with more operations 10 | // 4 bit ALUm: 11 | // 0000: add 12 | // 0001: sll 13 | // 0010: slt 14 | // 0011: sltu 15 | // 0100: xor 16 | // 0101: srl 17 | // 0110: or (csrrs) 18 | // 0111: and 19 | // 1000: sub 20 | // 1101: sra 21 | 22 | // 1010: pass a (csrrw) 23 | // 1110: and !a (csrrc) 24 | 25 | module alu 26 | ( 27 | input [3:0]m, 28 | input [31:0]a, b, 29 | output reg [31:0]y 30 | ); 31 | // zf: zero 32 | // cf: carry out, WIDTH bit 33 | // of: overflow 34 | // sf: sign, WIDTH-1 35 | 36 | wire signed [31:0]a_signed = a; 37 | wire [31:0]addition = a + b; 38 | wire [32:0]subtraction = a - b; 39 | wire sub_of = (!a[31] & b[31] & subtraction[31]) | 40 | (a[31] & !b[31] & !subtraction[31]); 41 | wire sub_zf = (subtraction[31:0] == 32'h0); 42 | wire sub_sf = subtraction[31]; 43 | wire sub_cf = subtraction[32]; 44 | always @ (*) begin 45 | case(m) 46 | 4'b0000: // add 47 | y = addition[31:0]; 48 | 4'b1000: // sub 49 | y = subtraction[31:0]; 50 | 4'b0001: // sll 51 | y = a << b[4:0]; 52 | 4'b0101: // srl 53 | y = a >> b[4:0]; 54 | 4'b1101: // sra 55 | y = a_signed >>> b[4:0]; 56 | 4'b0100: // xor 57 | y = a ^ b; 58 | 4'b0110: // or 59 | y = a | b; 60 | 4'b1010: // pass a, for csrrw(i) 61 | y = a; 62 | 4'b1110: // for csrrc(i) 63 | y = ~a & b; 64 | 4'b0111: // and 65 | y = a & b; 66 | 4'b0010: // slt 67 | y = {31'b0, (sub_of ^ sub_sf) & !sub_zf}; 68 | 4'b0011: // sltu 69 | y = {31'b0, sub_cf}; 70 | default: begin // error 71 | y = 32'hDEADBEEF; 72 | end 73 | endcase 74 | end 75 | endmodule 76 | -------------------------------------------------------------------------------- /rtl/pcpu/regfile.dat: -------------------------------------------------------------------------------- 1 | 0000f000 2 | 0000f001 3 | 0000f002 4 | 0000f003 5 | 0000f004 6 | 0000f005 7 | 0000f006 8 | 0000f007 9 | 0000f008 10 | 0000f009 11 | 0000f00a 12 | 0000f00b 13 | 0000f00c 14 | 0000f00d 15 | 0000f00e 16 | 0000f00f 17 | 0000f010 18 | 0000f011 19 | 0000f012 20 | 0000f013 21 | 0000f014 22 | 0000f015 23 | 0000f016 24 | 0000f017 25 | 0000f018 26 | 0000f019 27 | 0000f01a 28 | 0000f01b 29 | 0000f01c 30 | 0000f01d 31 | 0000f01e 32 | 0000f01f 33 | -------------------------------------------------------------------------------- /rtl/pcpu/register_file.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // pCPU regfile with debug port 3 | 4 | module register_file 5 | #(parameter WIDTH = 32) 6 | ( 7 | input clk, 8 | input [4:0]ra0, 9 | input [4:0]ra1, 10 | input [4:0]wa, 11 | input we, 12 | input [WIDTH-1:0]wd, 13 | output [WIDTH-1:0]rd0, 14 | output [WIDTH-1:0]rd1 15 | ); 16 | reg [WIDTH-1:0]regfile[31:0]; 17 | // initial $readmemh("/home/petergu/quasiSoC/rtl/pcpu/regfile.dat", regfile); 18 | assign rd0 = ra0 == 5'b0 ? 0 : regfile[ra0]; 19 | assign rd1 = ra1 == 5'b0 ? 0 : regfile[ra1]; 20 | always @ (posedge clk) begin 21 | if (we) regfile[wa] <= wd; 22 | end 23 | endmodule 24 | 25 | -------------------------------------------------------------------------------- /rtl/pcpu/register_file_bram.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // pCPU regfile based on bram 3 | // save resources, but no r/w forwarding 4 | 5 | module register_file_bram 6 | #(parameter WIDTH = 32) 7 | ( 8 | input clk, 9 | input [4:0]ra0, 10 | input [4:0]ra1, 11 | input [4:0]wa, 12 | input we, 13 | input [WIDTH-1:0]wd, 14 | output [WIDTH-1:0]rd0, 15 | output [WIDTH-1:0]rd1 16 | ); 17 | 18 | wire [31:0]rd0_ram; 19 | wire [31:0]rd1_ram; 20 | reg ra0iszero; 21 | reg ra1iszero; 22 | 23 | always @ (posedge clk) begin 24 | ra0iszero <= ra0 == 0; 25 | ra1iszero <= ra1 == 0; 26 | end 27 | 28 | assign rd0 = ra0iszero ? 0 : rd0_ram; 29 | assign rd1 = ra1iszero ? 0 : rd1_ram; 30 | 31 | simple_ram #(.WIDTH(32), .DEPTH(5)) reg1 ( 32 | .clk(clk), 33 | .a(we ? wa : ra0), 34 | .d(wd), 35 | .we(we), 36 | .spo(rd0_ram) 37 | ); 38 | simple_ram #(.WIDTH(32), .DEPTH(5)) reg2 ( 39 | .clk(clk), 40 | .a(we ? wa : ra1), 41 | .d(wd), 42 | .we(we), 43 | .spo(rd1_ram) 44 | ); 45 | endmodule 46 | 47 | -------------------------------------------------------------------------------- /rtl/pcpu/rv32a.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : rv32a.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2022.07.06 6 | * Last Modified Date: 2022.07.06 7 | */ 8 | `timescale 1ns / 1ps 9 | 10 | module rv32a 11 | ( 12 | ); 13 | endmodule 14 | -------------------------------------------------------------------------------- /rtl/quasisoc/bus/highmapper.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : highmapper.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2022.07.02 6 | * Last Modified Date: 2022.07.02 7 | */ 8 | `timescale 1ns / 1ps 9 | // high mapper -- mux memory and MMIO slow devices apart 10 | // should have good timing 11 | 12 | module highmapper 13 | ( 14 | // coming from arb 15 | (*mark_debug = "true"*)input [31:0]a, 16 | (*mark_debug = "true"*)input [31:0]d, 17 | (*mark_debug = "true"*)input we, 18 | (*mark_debug = "true"*)input rd, 19 | (*mark_debug = "true"*)output reg [31:0]spo, 20 | (*mark_debug = "true"*)output reg ready, 21 | 22 | output reg [31:0]mem_a, 23 | output reg [31:0]mem_d, 24 | output reg mem_we, 25 | output reg mem_rd, 26 | input [31:0]mem_spo, 27 | input mem_ready, 28 | 29 | output reg [31:0]mmio_a, 30 | output reg [31:0]mmio_d, 31 | output reg mmio_we, 32 | output reg mmio_rd, 33 | input [31:0]mmio_spo, 34 | input mmio_ready 35 | ); 36 | 37 | always @ (*) begin 38 | mem_a = a; 39 | mem_d = d; 40 | mmio_a = a; 41 | mmio_d = d; 42 | end 43 | 44 | always @ (*) begin 45 | mem_we = 0; 46 | mem_rd = 0; 47 | mmio_we = 0; 48 | mmio_rd = 0; 49 | spo = 0; 50 | ready = 1; 51 | // TODO: better MMIO address range arrangement 52 | // now: below 0x7ffffffc and above 0xf0000000 53 | if (a[31:28] != 4'h1 & !a[31]) begin 54 | mem_we = we; 55 | mem_rd = rd; 56 | spo = mem_spo; 57 | ready = mem_ready; 58 | end else begin 59 | mmio_we = we; 60 | mmio_rd = rd; 61 | spo = mmio_spo; 62 | ready = mmio_ready; 63 | end 64 | end 65 | endmodule 66 | -------------------------------------------------------------------------------- /rtl/quasisoc/cache/cacheway.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : cacheway.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.xx.xx 6 | * Last Modified Date: 2022.02.27 7 | */ 8 | `timescale 1ns / 1ps 9 | 10 | // one way of cache, 11 | // blocks as BRAM, tags as Dist. RAM 12 | module cacheway 13 | #( 14 | parameter LINES=2, 15 | parameter WORDS_PER_BLOCK=32, 16 | parameter TAG_LENGTH=32 17 | ) 18 | ( 19 | input clk, 20 | input rst, 21 | 22 | input en, 23 | 24 | input [31:0]a, 25 | input [31:0]d, 26 | input we, 27 | //input rd, 28 | output [31:0]spo, 29 | 30 | input invalidate, 31 | 32 | input tag_we, 33 | input [TAG_LENGTH-1:0]tag_in, 34 | (*mark_debug = "true"*)output [TAG_LENGTH-1:0]tag_out, 35 | 36 | output init_done 37 | ); 38 | 39 | wire [$clog2(WORDS_PER_BLOCK)-1:0]offset = a[$clog2(WORDS_PER_BLOCK)-1+2:2]; 40 | wire [$clog2(LINES)-1:0]index = a[$clog2(LINES)-1+$clog2(WORDS_PER_BLOCK)+2:$clog2(WORDS_PER_BLOCK)+2]; 41 | //wire index = 0; 42 | wire [$clog2(LINES * WORDS_PER_BLOCK)-1:0]bram_a = {index, offset}; 43 | //wire [$clog2(LINES * WORDS_PER_BLOCK)-1:0]bram_a = {offset}; 44 | 45 | reg [TAG_LENGTH-1:0]tags[LINES-1:0]; 46 | 47 | reg state; 48 | localparam INIT = 0; 49 | localparam INIT_DONE = 1; 50 | reg [$clog2(LINES)-1:0]count = 0; 51 | //reg count = 0; 52 | always @ (posedge clk) begin 53 | if (rst) begin 54 | state <= INIT; 55 | count <= 0; 56 | end 57 | else begin 58 | if (state == INIT) begin 59 | count <= count + 1; 60 | if (count == {($clog2(LINES)){1'b1}}) state <= INIT_DONE; 61 | //if (count == 1) state <= INIT_DONE; 62 | tags[count] <= 0; 63 | end else begin 64 | if (en & tag_we) tags[index] <= tag_in; 65 | if (invalidate) state <= INIT; 66 | end 67 | end 68 | end 69 | assign tag_out = tags[index]; 70 | 71 | assign init_done = state; 72 | 73 | simple_ram #( 74 | .WIDTH(32), 75 | .DEPTH($clog2(LINES * WORDS_PER_BLOCK)) 76 | ) c_way_bram ( 77 | .clk(clk), 78 | .a(bram_a), 79 | .d(d), 80 | .we(en & we), 81 | .rd(1), 82 | .spo(spo) 83 | //.ready(ready) 84 | ); 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /rtl/quasisoc/clk/clocking_xc7.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : clocking_xc7.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.10.21 6 | * Last Modified Date: 2021.10.21 7 | */ 8 | 9 | module clocking_xc7 ( 10 | input clk_50, 11 | output clk1_62d5, 12 | output clk2_125, 13 | output clk3_25, 14 | output clk4_250, 15 | output clk5_50 16 | ); 17 | wire clk_ibuf; 18 | wire clk_bufg; 19 | wire clk1_pll; 20 | wire clk2_pll; 21 | wire clk3_pll; 22 | wire clk4_pll; 23 | wire clk5_pll; 24 | 25 | PLLE2_ADV #( 26 | .CLKFBOUT_MULT(20), 27 | //.CLKFBOUT_MULT(30), 28 | .CLKIN1_PERIOD(20.0), 29 | .CLKOUT0_DIVIDE(16), 30 | //.CLKOUT0_DIVIDE(20), 31 | .CLKOUT0_PHASE(0), 32 | .CLKOUT1_DIVIDE(8), 33 | //.CLKOUT1_DIVIDE(10), 34 | .CLKOUT1_PHASE(0), 35 | .CLKOUT2_DIVIDE(40), 36 | .CLKOUT2_PHASE(0), 37 | .CLKOUT3_DIVIDE(4), 38 | .CLKOUT3_PHASE(0), 39 | .CLKOUT4_DIVIDE(20), 40 | .CLKOUT4_PHASE(0), 41 | .DIVCLK_DIVIDE(1'd1), 42 | .REF_JITTER1(0.01), 43 | .STARTUP_WAIT("FALSE") 44 | ) plle2_adv_inst ( 45 | .CLKFBIN(pll_fb), 46 | .CLKFBOUT(pll_fb), 47 | .CLKIN1(clk_bufg), 48 | .CLKOUT0(clk1_pll), 49 | .CLKOUT1(clk2_pll), 50 | .CLKOUT2(clk3_pll), 51 | .CLKOUT3(clk4_pll), 52 | .CLKOUT4(clk5_pll) 53 | ); 54 | 55 | IBUF clkbuf ( 56 | .I(clk_50), 57 | .O(clk_ibuf) 58 | ); 59 | BUFG bufg_in ( 60 | .I(clk_ibuf), 61 | .O(clk_bufg) 62 | ); 63 | BUFG bufg_1 ( 64 | .I(clk1_pll), 65 | .O(clk1_62d5) 66 | ); 67 | BUFG bufg_2 ( 68 | .I(clk2_pll), 69 | .O(clk2_125) 70 | ); 71 | BUFG bufg_3 ( 72 | .I(clk3_pll), 73 | .O(clk3_25) 74 | ); 75 | BUFG bufg_4 ( 76 | .I(clk4_pll), 77 | .O(clk4_250) 78 | ); 79 | BUFG bufg_5 ( 80 | .I(clk5_pll), 81 | .O(clk5_50) 82 | ); 83 | endmodule 84 | -------------------------------------------------------------------------------- /rtl/quasisoc/clocked_rom.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : clocked_rom.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.01.19 6 | * Last Modified Date: 2021.01.19 7 | */ 8 | 9 | `timescale 1ns / 1ps 10 | 11 | module clocked_rom 12 | #( 13 | parameter WIDTH = 32, 14 | parameter DEPTH = 1, 15 | parameter INIT = "/home/petergu/MyHome/pComputer/pCPU/null.dat" 16 | ) 17 | ( 18 | input clk, 19 | input [DEPTH-1:0]a, 20 | input rd, 21 | output reg [WIDTH-1:0]spo, 22 | output ready 23 | ); 24 | 25 | reg [WIDTH-1:0]mem[(2**DEPTH)-1:0]; 26 | initial $readmemh(INIT, mem); 27 | 28 | assign ready = ~rd; 29 | 30 | always @ (posedge clk) begin 31 | spo <= mem[a]; 32 | end 33 | endmodule 34 | -------------------------------------------------------------------------------- /rtl/quasisoc/debounce.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // input button debounce 3 | // https://timetoexplore.net/blog/arty-fpga-verilog-03 4 | 5 | module debounce 6 | #(parameter N = 2) 7 | ( 8 | input clk, 9 | input [N-1:0]i_btn, 10 | output reg [N-1:0]o_state = 0 11 | //output o_ondn, 12 | //output o_onup 13 | ); 14 | 15 | // sync with clock and combat metastability 16 | reg [N-1:0]sync_0 = 0; 17 | reg [N-1:0]sync_1 = 0; 18 | always @(posedge clk) sync_0 <= i_btn; 19 | always @(posedge clk) sync_1 <= sync_0; 20 | 21 | // 2.6 ms counter at 100 MHz 22 | reg [18:0] counter; 23 | wire idle = (o_state == sync_1); 24 | wire [18:0]max = 10; 25 | 26 | always @(posedge clk) 27 | begin 28 | if (idle) 29 | counter <= 0; 30 | else 31 | begin 32 | counter <= counter + 1; 33 | if (counter == max) 34 | o_state <= sync_1; 35 | end 36 | end 37 | 38 | //assign o_ondn = ~idle & max & ~o_state; 39 | //assign o_onup = ~idle & max & o_state; 40 | endmodule 41 | //module debounce 42 | //#(parameter N = 4) 43 | //( 44 | //input clk, 45 | //input [N-1:0]i_btn, 46 | //output reg [N-1:0]o_state = 0 47 | ////output o_ondn, 48 | ////output o_onup 49 | //); 50 | 51 | //// sync with clock and combat metastability 52 | //reg [N-1:0]sync_0 = 0; 53 | //reg [N-1:0]sync_1 = 0; 54 | //always @(posedge clk) sync_0 <= i_btn; 55 | //always @(posedge clk) sync_1 <= sync_0; 56 | 57 | //// 2.6 ms(*2) counter at 100 MHz 58 | //reg [18:0] counter = 0; 59 | ////reg [19:0] counter; 60 | //wire idle = (o_state == sync_1); 61 | 62 | //always @(posedge clk) 63 | //begin 64 | //if (idle) 65 | //counter <= 0; 66 | //else 67 | //begin 68 | //counter <= counter + 1; 69 | //if (counter == 19'b11111) 70 | ////o_state <= ~o_state; 71 | //o_state <= sync_1; 72 | //end 73 | //end 74 | 75 | ////assign o_ondn = ~idle & max & ~o_state; 76 | ////assign o_onup = ~idle & max & o_state; 77 | //endmodule 78 | -------------------------------------------------------------------------------- /rtl/quasisoc/fifo.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : fifo.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2022.07.02 6 | * Last Modified Date: 2022.07.02 7 | */ 8 | 9 | module myfifo #( 10 | parameter WIDTH = 32, 11 | parameter DEPTH = 16 12 | )( 13 | input clk, 14 | input rst, 15 | 16 | input enq, 17 | input [WIDTH-1:0]din, 18 | input deq, 19 | output [WIDTH-1:0]dout, 20 | output empty, 21 | output full, 22 | output [$clog2(DEPTH)-1:0]filled 23 | ); 24 | reg [$clog2(DEPTH)-1:0]head = 0; 25 | reg [$clog2(DEPTH)-1:0]tail = 0; 26 | assign empty = head == tail; 27 | assign full = tail+1 == head; 28 | assign filled = (head - tail + DEPTH); 29 | 30 | reg [WIDTH-1:0]d[DEPTH-1:0]; 31 | 32 | assign dout = d[head]; 33 | 34 | always @ (posedge clk) begin 35 | if (rst) begin 36 | head <= 0; 37 | tail <= 0; 38 | d[0] <= 0; 39 | end else begin 40 | // ignore illegal requests 41 | if (enq & (!full | deq)) begin 42 | tail <= tail + 1; 43 | d[tail] <= din; 44 | end 45 | if (deq & !empty) begin 46 | head <= head + 1; 47 | end 48 | end 49 | end 50 | endmodule 51 | -------------------------------------------------------------------------------- /rtl/quasisoc/gpio/gpio.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : gpio.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2020.11.25 6 | * Last Modified Date: 2020.11.25 7 | */ 8 | `timescale 1ns / 1ps 9 | // pComputer LED/Switch IO 10 | 11 | module gpio 12 | ( 13 | input clk, 14 | input rst, 15 | input [3:0]a, 16 | input [31:0]d, 17 | input we, 18 | output reg [31:0]spo, 19 | 20 | input [1:0]btn, 21 | input [1:0]sw, 22 | output reg [3:0]led, 23 | 24 | output reg irq = 0 25 | ); 26 | 27 | wire [3:0]data = d[27:24]; 28 | 29 | 30 | reg [1:0]btn_r; 31 | reg [1:0]sw_r; 32 | always @ (posedge clk) begin 33 | btn_r <= btn; 34 | sw_r <= sw; 35 | end 36 | 37 | reg [3:0]led_r[3:0]; 38 | reg [3:0]count = 0; 39 | always @ (posedge clk) begin 40 | count <= count + 1; 41 | end 42 | genvar i; 43 | generate 44 | for(i = 0; i < 4; i = i + 1) begin 45 | always @ (posedge clk) begin 46 | if (led_r[i] > count) led[i] <= 1; 47 | else led[i] <= 0; 48 | end 49 | end 50 | endgenerate 51 | 52 | always @ (*) begin 53 | case (a) 54 | 0: spo = {31'b0, btn_r[0]}; 55 | 1: spo = {31'b0, btn_r[1]}; 56 | 4: spo = {31'b0, sw_r[0]}; 57 | 5: spo = {31'b0, sw_r[1]}; 58 | 6: spo = {28'b0, led_r[0]}; 59 | 7: spo = {28'b0, led_r[1]}; 60 | 8: spo = {28'b0, led_r[2]}; 61 | 9: spo = {28'b0, led_r[3]}; 62 | default: spo = 32'b0; 63 | endcase 64 | end 65 | 66 | always @ (posedge clk) begin 67 | if (rst) begin 68 | // medium dim light when begin 69 | led_r[0] <= 4'b0011; 70 | led_r[1] <= 4'b0011; 71 | led_r[2] <= 4'b0011; 72 | led_r[3] <= 4'b0011; 73 | end 74 | else if (we) begin 75 | case (a) 76 | 6: led_r[0] <= data[3:0]; 77 | 7: led_r[1] <= data[3:0]; 78 | 8: led_r[2] <= data[3:0]; 79 | 9: led_r[3] <= data[3:0]; 80 | default: ; 81 | endcase 82 | end 83 | end 84 | 85 | reg [3:0]inputs_reg; 86 | always @ (posedge clk) begin 87 | inputs_reg <= {btn_r, sw_r}; 88 | end 89 | always @ (posedge clk) begin 90 | if (rst) irq <= 0; 91 | else if ((inputs_reg != {btn_r, sw_r}) & irq == 0) irq <= 1; 92 | else irq <= 0; 93 | end 94 | 95 | endmodule 96 | -------------------------------------------------------------------------------- /rtl/quasisoc/hdmi/attributemap.v: -------------------------------------------------------------------------------- 1 | module attributemap ( 2 | input wire [7:0] attribute, 3 | output wire [23:0] fgrgb, 4 | output wire [23:0] bgrgb, 5 | output wire blink 6 | ); 7 | // See https://en.wikipedia.org/wiki/Video_Graphics_Array#Color_palette 8 | assign blink = attribute[7]; 9 | assign bgrgb = attribute[6:4] == 3'b000 ? 24'h000000 10 | : attribute[6:4] == 3'b001 ? 24'h0000AA 11 | : attribute[6:4] == 3'b010 ? 24'h00AA00 12 | : attribute[6:4] == 3'b011 ? 24'h00AAAA 13 | : attribute[6:4] == 3'b100 ? 24'hAA0000 14 | : attribute[6:4] == 3'b101 ? 24'hAA00AA 15 | : attribute[6:4] == 3'b110 ? 24'hAA5500 16 | : attribute[6:4] == 3'b111 ? 24'hAAAAAA 17 | : 24'h000000; 18 | 19 | assign fgrgb = attribute[3:0] == 4'h0 ? 24'h000000 20 | : attribute[3:0] == 4'h1 ? 24'h0000AA 21 | : attribute[3:0] == 4'h2 ? 24'h00AA00 22 | : attribute[3:0] == 4'h3 ? 24'h00AAAA 23 | : attribute[3:0] == 4'h4 ? 24'hAA0000 24 | : attribute[3:0] == 4'h5 ? 24'hAA00AA 25 | : attribute[3:0] == 4'h6 ? 24'hAA5500 26 | : attribute[3:0] == 4'h7 ? 24'hAAAAAA 27 | : attribute[3:0] == 4'h8 ? 24'h555555 28 | : attribute[3:0] == 4'h9 ? 24'h5555FF 29 | : attribute[3:0] == 4'hA ? 24'h55FF55 30 | : attribute[3:0] == 4'hB ? 24'h55FFFF 31 | : attribute[3:0] == 4'hC ? 24'hFF5555 32 | : attribute[3:0] == 4'hD ? 24'hFF55FF 33 | : attribute[3:0] == 4'hE ? 24'hFFFF55 34 | : attribute[3:0] == 4'hF ? 24'hFFFFFF 35 | : 24'h000000; 36 | 37 | endmodule 38 | -------------------------------------------------------------------------------- /rtl/quasisoc/hdmi/console.v: -------------------------------------------------------------------------------- 1 | module console # ( 2 | parameter BIT_WIDTH = 12, 3 | parameter BIT_HEIGHT = 11, 4 | parameter FONT_WIDTH = 8, 5 | parameter FONT_HEIGHT = 16 6 | ) ( 7 | input wire clk_pixel, 8 | input wire [7:0] codepoint, 9 | input wire [7:0] attribute, 10 | input wire [BIT_WIDTH-1:0] cx, 11 | input wire [BIT_HEIGHT-1:0] cy, 12 | output reg [23:0] rgb = 24'd0 13 | ); 14 | 15 | wire [127:0] glyph; 16 | glyphmap glyphmap(.codepoint(codepoint), .glyph(glyph)); 17 | 18 | wire [23:0] fgrgb, bgrgb; 19 | wire blink; 20 | attributemap attributemap(.attribute(attribute), .fgrgb(fgrgb), .bgrgb(bgrgb), .blink(blink)); 21 | 22 | reg [BIT_HEIGHT-1:0] prevcy = 0; 23 | reg [$clog2(FONT_HEIGHT)-1:0] vindex = 0; 24 | reg [$clog2(FONT_WIDTH)-1:0] hindex = 0; 25 | reg [5:0] blink_timer = 0; 26 | 27 | always @(posedge clk_pixel) 28 | begin 29 | if (cx == 0 && cy == 0) 30 | begin 31 | prevcy <= 0; 32 | vindex <= 0; 33 | hindex <= 0; 34 | blink_timer <= blink_timer + 1'b1; 35 | end 36 | else if (prevcy != cy) 37 | begin 38 | prevcy <= cy; 39 | vindex <= vindex == FONT_HEIGHT - 1 ? 1'b0 : vindex + 1'b1; 40 | hindex <= 0; 41 | end 42 | else 43 | begin 44 | hindex <= hindex == FONT_WIDTH - 1 ? 1'b0 : hindex + 1'b1; 45 | end 46 | 47 | if (blink && blink_timer[5]) 48 | rgb <= bgrgb; 49 | else 50 | rgb <= glyph[{~vindex, ~hindex}] ? fgrgb : bgrgb; 51 | end 52 | endmodule 53 | -------------------------------------------------------------------------------- /rtl/quasisoc/mm2wb.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : mm2wb.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2024.01.27 6 | * Last Modified Date: 2024.01.27 7 | */ 8 | `timescale 1ns / 1ps 9 | `default_nettype wire 10 | 11 | module mm2wb 12 | #( 13 | // TODO: this probably only work for 32-bit 14 | parameter ADDRLEN = 32, 15 | parameter DATALEN = 32 16 | ) 17 | ( 18 | input clk, 19 | input rst, 20 | 21 | // CPU bus is fixed 32-bit 22 | input [31:0]a, 23 | input [31:0]d, 24 | input we, 25 | input rd, 26 | output reg [31:0]spo, 27 | output ready, 28 | 29 | output reg wb_cyc, 30 | output reg wb_we, 31 | output reg wb_stb, 32 | output reg [ADDRLEN-1:0]wb_addr, 33 | output reg [DATALEN-1:0]wb_dat_o, 34 | output [DATALEN/8-1:0]wb_sel, 35 | input [DATALEN-1:0]wb_dat_i, 36 | input wb_stall, // stall may suddenly assert! 37 | input wb_ack, 38 | 39 | output reg irq = 0 40 | ); 41 | assign wb_sel = 4'b1111; 42 | 43 | reg we_reg = 0; 44 | reg ready_reg = 1; 45 | 46 | localparam IDLE = 0; 47 | localparam DESTALL = 1; 48 | localparam BEGIN = 2; 49 | reg [1:0]state = IDLE; 50 | 51 | // UberDDR3 wb doens't use wb_cyc 52 | always @ (posedge clk) begin 53 | if (rst) begin 54 | state <= IDLE; 55 | wb_cyc <= 0; 56 | wb_stb <= 0; 57 | wb_we <= 0; 58 | we_reg <= 0; 59 | ready_reg <= 1; 60 | wb_addr <= 0; 61 | wb_dat_o <= 0; 62 | spo <= 0; 63 | end else if (state == IDLE & (rd | we)) begin 64 | if (!wb_stall) begin 65 | state <= BEGIN; 66 | wb_cyc <= 1; 67 | wb_stb <= 1; 68 | wb_we <= we; 69 | end else begin 70 | state <= DESTALL; 71 | end 72 | we_reg <= we; 73 | ready_reg <= 0; 74 | wb_addr <= a; 75 | wb_dat_o <= d; 76 | end else if (state == DESTALL & !wb_stall) begin 77 | state <= BEGIN; 78 | wb_cyc <= 1; 79 | wb_stb <= 1; 80 | wb_we <= we_reg; 81 | end else if (state == BEGIN) begin 82 | if (wb_stall) begin // come across a stall right in the head 83 | state <= DESTALL; 84 | end 85 | wb_stb <= 0; 86 | wb_we <= 0; 87 | if (wb_ack) begin 88 | wb_cyc <= 0; 89 | we_reg <= 0; 90 | ready_reg <= 1; 91 | if (!we_reg) 92 | spo <= wb_dat_i; 93 | state <= IDLE; 94 | end 95 | end 96 | end 97 | 98 | assign ready = ready_reg & !(we | rd); 99 | endmodule 100 | -------------------------------------------------------------------------------- /rtl/quasisoc/ps2/ps2.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : ps2.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.04.26 6 | * Last Modified Date: 2021.04.26 7 | */ 8 | `timescale 1ns / 1ps 9 | `include "quasi.vh" 10 | 11 | module ps2 12 | ( 13 | input clk, 14 | input rst, 15 | 16 | //input [2:0]a, 17 | //input [31:0]d, 18 | //input we, 19 | output [31:0]spo, 20 | 21 | output reg irq = 0, 22 | 23 | input kclk, 24 | input kdata 25 | ); 26 | 27 | wire [31:0]keycodeout; 28 | wire newkeypress; 29 | ps2_driver ps2_driver_inst( 30 | .clk(clk), 31 | .rst(rst), 32 | .kclk(kclk), 33 | .kdata(kdata), 34 | .keycodeout(keycodeout), 35 | .newkeypress(newkeypress) 36 | ); 37 | 38 | reg [31:0]keycode; 39 | reg newkeypress_old; 40 | always @ (posedge clk) begin 41 | if (rst) begin 42 | newkeypress_old <= 0; 43 | keycode <= 0; 44 | irq <= 0; 45 | end else begin 46 | newkeypress_old <= newkeypress; 47 | if (newkeypress & !newkeypress_old) begin 48 | keycode <= keycodeout; 49 | irq <= 1; 50 | end else irq <= 0; 51 | end 52 | end 53 | assign spo = keycode; 54 | endmodule 55 | -------------------------------------------------------------------------------- /rtl/quasisoc/sdram/sdram_br.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : sdram_br.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2024.05.26 6 | * Last Modified Date: 2024.05.26 7 | */ 8 | `timescale 1ns / 1ps 9 | `default_nettype wire 10 | 11 | // a: 12 | // 0x1000 13 | // 0x1004 14 | // 15 | // data_address (DATA_WIDTH=8): 16 | // 0x1000 -> 0x1000, 0x1001, 0x1002, 0x1003 17 | // 0x1004 -> 0x1004, ... 18 | // 19 | // data_address (DATA_WIDTH=16): 20 | // 0x1000 -> 0x500, 0x501 21 | // 0x1004 -> 0x502, 0x503 22 | // 23 | // LSB(7:0) at low address 24 | // ONLY 16-bit TESTED FOR NOW! 25 | 26 | module sdram_br #( 27 | parameter DATA_WIDTH = 16 28 | ) ( 29 | input clk, 30 | input rst, 31 | 32 | input [31:0]a, // as convention, a is 32-bit aligned 33 | input [31:0]d, 34 | input we, 35 | input rd, 36 | output reg [31:0]spo, 37 | output ready, 38 | 39 | output reg [1:0]command, 40 | output reg [31:0]data_address, 41 | output reg [31:0]data_write, // abuse the 32-bit bus a little bit 42 | input [DATA_WIDTH-1:0]data_read, 43 | input data_read_valid, 44 | input data_write_done 45 | ); 46 | reg we_reg = 0; 47 | reg ready_reg = 1; 48 | reg [5:0]cnt = 0; 49 | 50 | localparam CNT = 32 / DATA_WIDTH; // 16-bit case: 2 51 | localparam ASHIFT = $clog2(CNT); // 16-bit case: 1 52 | localparam IDLE = 0; 53 | localparam BEGIN = 1; 54 | reg state = IDLE; 55 | 56 | always @ (posedge clk) begin 57 | if (rst) begin 58 | state <= IDLE; 59 | command <= 2'b00; 60 | we_reg <= 0; 61 | ready_reg <= 1; 62 | data_address <= 0; 63 | data_write <= 0; 64 | spo <= 0; 65 | cnt <= 0; 66 | end else if (state == IDLE & (rd | we)) begin 67 | state <= BEGIN; 68 | command <= we ? 2'b01 : 2'b10; 69 | data_address <= {{ASHIFT{1'b0}}, a[31:ASHIFT]}; 70 | data_write <= we ? d : 0; 71 | we_reg <= we; 72 | ready_reg <= 0; 73 | cnt <= 0; 74 | end else if (state == BEGIN) begin 75 | spo <= we_reg ? 0 : {data_read, spo[31:32-DATA_WIDTH]}; 76 | if (we_reg & data_write_done) begin 77 | data_write <= {{DATA_WIDTH{1'b0}}, data_write[31:DATA_WIDTH]}; 78 | cnt <= cnt + 1; 79 | if (cnt == CNT - 1) begin 80 | state <= IDLE; 81 | we_reg <= 0; 82 | ready_reg <= 1; 83 | command <= 2'b00; 84 | end 85 | end else if (data_read_valid) begin 86 | state <= IDLE; 87 | ready_reg <= 1; 88 | command <= 2'b00; 89 | end 90 | end 91 | end 92 | 93 | assign ready = ready_reg & !(we | rd); 94 | endmodule 95 | -------------------------------------------------------------------------------- /rtl/quasisoc/simple_dp_ram.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : simple_ram.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2020.11.26 6 | * Last Modified Date: 2020.11.26 7 | */ 8 | `timescale 1ns / 1ps 9 | module simple_dp_ram 10 | #( 11 | parameter WIDTH = 32, 12 | parameter DEPTH = 1, 13 | parameter INIT = "/dev/null" 14 | ) 15 | ( 16 | input clk1, 17 | input [DEPTH-1:0]a1, 18 | input [WIDTH-1:0]d1, 19 | input we1, 20 | 21 | input clk2, 22 | input [DEPTH-1:0]a2, 23 | input rd2, 24 | output reg [WIDTH-1:0]spo2, 25 | output ready 26 | ); 27 | 28 | reg [WIDTH-1:0]mem[(2**DEPTH)-1:0]; 29 | initial $readmemh(INIT, mem); 30 | 31 | assign ready = ~(we1 | rd2); 32 | 33 | always @ (posedge clk1) begin 34 | if (we1) mem[a1] <= d1; 35 | end 36 | 37 | always @(posedge clk2) begin 38 | spo2 <= mem[a2]; 39 | end 40 | 41 | endmodule 42 | -------------------------------------------------------------------------------- /rtl/quasisoc/simple_ram.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : simple_ram.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2020.11.26 6 | * Last Modified Date: 2020.11.26 7 | */ 8 | `timescale 1ns / 1ps 9 | module simple_ram 10 | #( 11 | parameter WIDTH = 32, 12 | parameter DEPTH = 1, 13 | parameter WEB = 0, 14 | parameter INIT = "/dev/null" 15 | ) 16 | ( 17 | input clk, 18 | input [DEPTH-1:0]a, 19 | input [WIDTH-1:0]d, 20 | input we, 21 | input [3:0]web, 22 | input rd, 23 | output reg [WIDTH-1:0]spo, 24 | output ready 25 | ); 26 | 27 | reg [WIDTH-1:0]mem[(2**DEPTH)-1:0]; 28 | initial $readmemh(INIT, mem); 29 | 30 | assign ready = ~(rd | (WEB ? |web : we)); 31 | 32 | always @ (posedge clk) begin 33 | if (WEB) begin 34 | if (web[0]) mem[a][7:0] <= d[7:0]; 35 | if (web[1]) mem[a][15:8] <= d[15:8]; 36 | if (web[2]) mem[a][23:16] <= d[23:16]; 37 | if (web[3]) mem[a][31:24] <= d[31:24]; 38 | end else begin 39 | if (we) begin 40 | mem[a] <= d; 41 | end 42 | end 43 | //spo <= d; 44 | spo <= mem[a]; 45 | end 46 | endmodule 47 | -------------------------------------------------------------------------------- /rtl/quasisoc/simple_rom.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : simple_rom.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2020.11.25 6 | * Last Modified Date: 2020.11.26 7 | */ 8 | `timescale 1ns / 1ps 9 | module simple_rom 10 | #( 11 | parameter WIDTH = 32, 12 | parameter DEPTH = 1, 13 | parameter INIT = "/home/petergu/MyHome/pComputer/pCPU/null.dat" 14 | ) 15 | ( 16 | input [DEPTH-1:0]a, 17 | output reg [WIDTH-1:0]spo 18 | ); 19 | 20 | reg [WIDTH-1:0]mem[(2**DEPTH)-1:0]; 21 | initial $readmemh(INIT, mem); 22 | 23 | always @ (a) begin 24 | spo = mem[a]; 25 | end 26 | endmodule 27 | -------------------------------------------------------------------------------- /rtl/quasisoc/uart/baud_rate_gen.v: -------------------------------------------------------------------------------- 1 | // this is copied from github 2 | /* 3 | * Hacky baud rate generator to divide a 50MHz clock into a 115200 baud 4 | * rx/tx pair where the rx clcken oversamples by 16x. 5 | */ 6 | `include "quasi.vh" 7 | 8 | module baud_rate_gen 9 | #( 10 | parameter CLOCK_FREQ = 0, 11 | parameter BAUD_RATE = 0, 12 | parameter SAMPLE_MULTIPLIER = 16 13 | ) 14 | ( 15 | input wire clk, 16 | input rst, 17 | output wire rxclk_en, 18 | output wire txclk_en 19 | ); 20 | 21 | parameter RX_ACC_MAX = CLOCK_FREQ / (BAUD_RATE * SAMPLE_MULTIPLIER) + 1; 22 | parameter TX_ACC_MAX = CLOCK_FREQ / BAUD_RATE; 23 | parameter RX_ACC_WIDTH = 20; 24 | parameter TX_ACC_WIDTH = 20; 25 | //parameter RX_ACC_WIDTH = $clog2(RX_ACC_MAX); 26 | //parameter TX_ACC_WIDTH = $clog2(TX_ACC_MAX); 27 | reg [RX_ACC_WIDTH - 1:0] rx_acc = 0; 28 | reg [TX_ACC_WIDTH - 1:0] tx_acc = 0; 29 | 30 | assign rxclk_en = (rx_acc == 0); 31 | assign txclk_en = (tx_acc == 0); 32 | 33 | always @(posedge clk) begin 34 | if (rst) rx_acc <= 1; 35 | else if (rx_acc == RX_ACC_MAX[RX_ACC_WIDTH - 1:0]) 36 | rx_acc <= 0; 37 | else 38 | rx_acc <= rx_acc + 1; 39 | end 40 | 41 | always @(posedge clk) begin 42 | if (rst) tx_acc <= 1; 43 | else if (tx_acc == TX_ACC_MAX[TX_ACC_WIDTH - 1:0]) 44 | tx_acc <= 0; 45 | else 46 | tx_acc <= tx_acc + 1; 47 | end 48 | 49 | endmodule 50 | -------------------------------------------------------------------------------- /rtl/quasisoc/uart/uartreset.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : uartreset.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.04.25 6 | * Last Modified Date: 2021.10.17 7 | */ 8 | 9 | // generate reset signal when a certain character is 10 | // sent via UART several times 11 | // with this and serialboot, everything on the board 12 | // can be controlled by computer w/o pressing buttons 13 | 14 | module uartreset #( 15 | parameter RESET_CHARACTER = 82, // "R" 16 | parameter RESET_COUNT = 10 17 | )( 18 | input clk, 19 | 20 | (*mark_debug = "true"*) input [7:0]uart_data, 21 | (*mark_debug = "true"*) input uart_ready, 22 | 23 | (*mark_debug = "true"*) output uart_rst 24 | ); 25 | reg [7:0]count = 0; 26 | reg uart_rst_reg = 0; 27 | always @ (posedge clk) begin 28 | if (uart_ready) begin 29 | if (uart_data == RESET_CHARACTER) begin 30 | if (count >= RESET_COUNT) begin 31 | uart_rst_reg <= 1; 32 | //count <= 0; 33 | end else count <= count + 1; 34 | end else begin 35 | count <= 0; 36 | uart_rst_reg <= 0; 37 | end 38 | end 39 | end 40 | assign uart_rst = uart_rst_reg; 41 | endmodule 42 | -------------------------------------------------------------------------------- /rtl/quasisoc/uart/uartsim.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : uartsimu.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.01.24 6 | * Last Modified Date: 2023.02.18 7 | */ 8 | `timescale 1ns / 1ps 9 | // pComputer UART 10 | // a better version (arbitary input clk freq, fifo, ...) 11 | // TODO: fifo? fifo w/ uartboot? 12 | // 13 | // write 0x00: transmit data -- (tx fifo enqueue) 14 | // read 0x00: received data -- (first data in rx fifo) 15 | // write 0x01: begin receiving -- (rx fifo dequeue, ignore empty) 16 | // read 0x01: new data received? -- (rx fifo empty?) 17 | // read 0x02: transmit done? -- (tx fifo full?) 18 | // 0x03: 19 | // rxnew/rxdata: real-time, extra fifo required in serialboot 20 | // *need to x4 these addresses in assembly! 21 | `include "quasi.vh" 22 | 23 | module uart_sim 24 | ( 25 | input clk, 26 | input rst, 27 | 28 | input rx, 29 | input rxsim_en, 30 | input [7:0]rxsim_data, 31 | output reg tx = 1, 32 | 33 | input [2:0]a, 34 | input [31:0]d, 35 | input we, 36 | output reg [31:0]spo, 37 | 38 | output reg irq = 0, 39 | 40 | output reg rxnew = 0, // not supported in sim 41 | output reg [7:0]rxdata = 0 // not supported in sim 42 | ); 43 | 44 | wire [7:0]data = d[31:24]; 45 | 46 | reg [7:0]data_rx = 0; 47 | reg rx_new = 0; 48 | 49 | always @ (*) begin 50 | if (a == 3'b000) spo = {data_rx, 24'b0}; 51 | else if (a == 3'b001) spo = {7'b0, rx_new, 24'b0}; 52 | else if (a == 3'b010) spo = {7'b0, 1'b1, 24'b0}; 53 | else spo = 32'b0; 54 | end 55 | 56 | always @ (posedge clk) begin 57 | if (we & (a == 3'b000)) begin 58 | $write("%c", data); 59 | $fflush(); 60 | end 61 | // we assume input is not very fast 62 | if (we & (a == 3'b001)) begin 63 | rx_new <= 0; 64 | end else if (rxsim_en) begin 65 | rx_new <= 1; 66 | data_rx <= rxsim_data; 67 | end 68 | end 69 | endmodule 70 | -------------------------------------------------------------------------------- /rtl/quasisoc/vt100/vt100_top.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : vt100_top.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2023.05.23 6 | * Last Modified Date: 2023.05.23 7 | */ 8 | // top module for standalone VT100 operation 9 | 10 | `timescale 1ns / 1ps 11 | 12 | module vt100_top 13 | #( 14 | parameter CLOCK_FREQ = 62500000, 15 | parameter BAUD_RATE = 115200 16 | ) 17 | ( 18 | input sysclk, 19 | 20 | input [1:0]sw, 21 | 22 | input rx, 23 | 24 | output tx, 25 | input tx_up, 26 | 27 | 28 | output [2:0] TMDSp, 29 | output [2:0] TMDSn, 30 | output TMDSp_clock, 31 | output TMDSn_clock 32 | ); 33 | assign tx = tx_up; 34 | 35 | wire clk; 36 | wire clk_mem; 37 | wire clk_2x; 38 | wire clk_hdmi_25; 39 | wire clk_hdmi_250; 40 | clock_wizard clock_wizard_inst( 41 | .clk_in1(sysclk), 42 | .clk_main(clk), 43 | .clk_mem(clk_mem), 44 | .clk_hdmi_25(clk_hdmi_25), 45 | .clk_hdmi_250(clk_hdmi_250), 46 | .clk_hdmi_50(clk_2x) 47 | ); 48 | 49 | wire [1:0]sw_d; 50 | debounce #(.N(2)) debounce_inst_0( 51 | .clk(clk), 52 | .i_btn(sw), 53 | .o_state(sw_d) 54 | ); 55 | 56 | wire rst = sw_d[0]; 57 | 58 | wire [11:0]fb_a; 59 | wire [15:0]fb_d; 60 | wire fb_we; 61 | 62 | vt100 #( 63 | .CLOCK_FREQ(CLOCK_FREQ), 64 | .BAUD_RATE(BAUD_RATE) 65 | ) vt100_inst ( 66 | .clk(clk), 67 | .rst(rst), 68 | .rx(rx), 69 | .fb_a(fb_a), 70 | .fb_d(fb_d), 71 | .fb_we(fb_we) 72 | ); 73 | 74 | mkrvidor4000_top #( 75 | .FBEXT_ENABLE(1) 76 | ) hdmi_inst ( 77 | .clk(clk), 78 | .clk_2x(clk_2x), 79 | .clk_pix(clk_hdmi_25), 80 | .clk_tmds(clk_hdmi_250), 81 | 82 | .fb_a(fb_a), 83 | .fb_d(fb_d), 84 | .fb_we(fb_we), 85 | 86 | .TMDSp(TMDSp), 87 | .TMDSn(TMDSn), 88 | .TMDSp_clock(TMDSp_clock), 89 | .TMDSn_clock(TMDSn_clock) 90 | ); 91 | 92 | endmodule 93 | -------------------------------------------------------------------------------- /sim/debounce_simu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module debounce_simu(); 4 | reg clk; 5 | reg btn; 6 | 7 | wire o_state; 8 | debounce debounce_inst 9 | ( 10 | .clk(clk), 11 | .i_btn(btn), 12 | .o_state(o_state) 13 | ); 14 | 15 | initial begin 16 | clk = 0; 17 | forever #5 clk = ~clk; 18 | end 19 | initial begin 20 | btn = 0; 21 | #10 22 | btn = 1; 23 | #10 24 | btn = 0; 25 | #10 26 | btn = 1; 27 | #200 28 | btn = 0; 29 | #200 30 | $finish; 31 | end 32 | endmodule 33 | -------------------------------------------------------------------------------- /sim/iv_simu.v: -------------------------------------------------------------------------------- 1 | /** 2 | * File : iv_simu.v 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2023.02.18 6 | * Last Modified Date: 2023.02.18 7 | */ 8 | // iverilog "interactive" simulation 9 | `timescale 1ns / 1ns 10 | `define SIMULATION 11 | 12 | module top_simu (); 13 | reg clk = 0; 14 | reg [1:0]sw = 0; 15 | reg [1:0]btn = 0; 16 | wire [3:0]led; 17 | 18 | wire tx; 19 | reg rx = 1; 20 | 21 | quasi_main #( 22 | ) quasisoc_inst 23 | ( 24 | .sysclk(clk), 25 | .btn(btn), 26 | .led(led), 27 | .sw(sw), 28 | 29 | .uart_rx(rx), 30 | .uart_tx(tx) 31 | ); 32 | 33 | initial begin 34 | clk = 0; 35 | forever #5 clk = ~clk; 36 | end 37 | 38 | initial begin 39 | $dumpfile("wave.vcd"); 40 | $dumpvars(0, quasisoc_inst); 41 | sw = 2'b01; 42 | btn = 2'b11; 43 | #4000 44 | sw = 2'b00; 45 | btn = 2'b00; 46 | 47 | #2000000.0; 48 | $finish; 49 | end 50 | endmodule 51 | -------------------------------------------------------------------------------- /sim/mem_simu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // memory module simu 3 | `define SIMULATION 4 | 5 | module mem_simu(); 6 | reg clk = 0; 7 | reg clk_mem = 0; 8 | wire psram_ce; 9 | wire psram_mosi; 10 | wire psram_miso; 11 | wire psram_sio2; 12 | wire psram_sio3; 13 | wire psram_sclk; 14 | 15 | reg rst; 16 | reg burst_en; 17 | reg [7:0]burst_length; 18 | reg [31:0]a; 19 | reg [31:0]d; 20 | reg we = 0; 21 | reg rd = 0; 22 | wire [31:0]spo; 23 | wire ready; 24 | 25 | memory_controller_burst memory_controller_burst_inst 26 | ( 27 | .rst(rst), 28 | .clk(clk), 29 | .clk_mem(clk_mem), 30 | 31 | .burst_en(burst_en), 32 | .burst_length(burst_length), 33 | 34 | .a(a), 35 | .d(d), 36 | .we(we), 37 | .rd(rd), 38 | .spo(spo), 39 | .ready(ready), 40 | 41 | .psram_ce(psram_ce), 42 | .psram_mosi(psram_mosi), 43 | .psram_miso(psram_miso), 44 | .psram_sio2(psram_sio2), 45 | .psram_sio3(psram_sio3), 46 | .psram_sclk(psram_sclk) 47 | ); 48 | 49 | initial begin 50 | clk = 0; 51 | forever #5 clk = ~clk; 52 | end 53 | initial begin 54 | clk_mem = 0; 55 | forever #2.5 clk_mem = ~clk_mem; 56 | end 57 | 58 | initial begin 59 | #5 60 | burst_en = 0; 61 | burst_length = 0; 62 | a = 0; 63 | d = 0; 64 | we = 0; 65 | rd = 0; 66 | rst = 1; 67 | #20 68 | rst = 0; 69 | #2000 70 | burst_en = 1; 71 | burst_length = 5; 72 | a = 32'h2000abcd; 73 | d = 32'hdeadbeef; 74 | we = 0; 75 | rd = 1; 76 | #10 77 | burst_en = 0; 78 | burst_length = 0; 79 | a = 0; 80 | d = 0; 81 | we = 0; 82 | rd = 0; 83 | 84 | #4000 85 | burst_en = 1; 86 | burst_length = 7; 87 | a = 32'h2000abcd; 88 | d = 32'hdeadbeef; 89 | we = 1; 90 | rd = 0; 91 | #10 92 | burst_en = 0; 93 | burst_length = 0; 94 | a = 0; 95 | d = 0; 96 | we = 0; 97 | rd = 0; 98 | #4000 99 | burst_en = 0; 100 | burst_length = 0; 101 | a = 32'h2000abcd; 102 | d = 32'hdeadbeef; 103 | we = 1; 104 | rd = 0; 105 | #10 106 | we = 0; 107 | #4000 108 | $finish; 109 | end 110 | 111 | endmodule 112 | -------------------------------------------------------------------------------- /sim/quasi.vh: -------------------------------------------------------------------------------- 1 | //`define SIMULATION 2 | // CPU features 3 | `define RV32M 4 | `define RV32A 5 | `define IRQ_EN 6 | `define MMU_EN 7 | //`define NOARB 8 | 9 | `ifdef SIMULATION 10 | `define GPIO_EN 11 | `define UART_EN 12 | // `define CACHE_EN 13 | // `define MEM_SIMU_EN 14 | // `define SERIALBOOT_EN 15 | // `define UART_RST_EN 16 | `else 17 | // peripheral features 18 | //`define GPIO_EN 19 | `define UART_EN 20 | `define DDR_EN 21 | //`define PSRAM_EN 22 | //`define CACHE_EN 23 | `define SDCARD_EN 24 | //`define CH375B_EN 25 | //`define VIDEO_EN 26 | //`define LCD_EN 27 | //`define PS2_EN 28 | //`define ETH_EN 29 | 30 | //`define SERIALBOOT_EN 31 | //`define UART_RST_EN 32 | 33 | //`define AXI_GPIO_TEST 34 | `endif 35 | 36 | 37 | -------------------------------------------------------------------------------- /sim/sim_main.cpp: -------------------------------------------------------------------------------- 1 | #include "Vquasi_main.h" 2 | #include "verilated.h" 3 | #include "fcntl.h" 4 | #include "termios.h" 5 | #include "unistd.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main (int argc, char* argv[]) 12 | { 13 | Verilated::commandArgs(argc, argv); 14 | Vquasi_main *top = new Vquasi_main; 15 | 16 | int timeout = 3600; 17 | if (argc == 2) 18 | timeout = atoi(argv[1]); 19 | 20 | int i = 0; 21 | int j = 0; 22 | top->sw = 1; 23 | 24 | char buf; 25 | fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); 26 | struct termios raw; 27 | tcgetattr(STDIN_FILENO, &raw); 28 | raw.c_lflag &= ~(ECHO | ICANON); 29 | tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); 30 | 31 | time_t start = time(0); 32 | unsigned long start_sec = (unsigned long) start; 33 | while(1) { 34 | if (top->uart_rxsim_en == 1) top->uart_rxsim_en = 0; 35 | if (j == 20) { 36 | j = 0; 37 | int input = read(0, &buf, 1); 38 | if (input > 0) { 39 | //printf("You said: %c\n", buf); 40 | top->uart_rxsim_en = 1; 41 | top->uart_rxsim_data = buf; 42 | } 43 | } 44 | else j++; 45 | 46 | if (i < 100) { 47 | i++; 48 | } 49 | if (i == 100) { 50 | top->sw = 0; 51 | } 52 | top->sysclk = 0; 53 | top->eval(); 54 | top->sysclk = 1; 55 | top->eval(); 56 | time_t now = time(0); 57 | unsigned long now_sec = (unsigned long) now; 58 | if (now_sec - start_sec > timeout) 59 | break; 60 | } 61 | top->final(); 62 | delete top; 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /software/Makefile: -------------------------------------------------------------------------------- 1 | run_tests: 2 | make -C tests && sudo bash uartboot.sh ./tests/firmware/firmware.bin 3 | run_coremark: 4 | make -C coremark && sudo bash uartboot.sh ./coremark/coremark.bin 5 | run_renderer: 6 | make -C pingo_renderer && sudo bash uartboot.sh ./pingo_renderer/sdboot.bin 7 | -------------------------------------------------------------------------------- /software/binpatch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import subprocess 4 | 5 | binfile = sys.argv[1] 6 | elffile = sys.argv[2] 7 | status, output = subprocess.getstatusoutput("riscv32-unknown-elf-readelf -S " + elffile + " | grep ' \\.bss ' | awk '{print $6}'"); 8 | try: 9 | bss_length = int(output, base=16) 10 | except ValueError: 11 | print('BSS not found!') 12 | sys.exit() 13 | 14 | 15 | with open(binfile, 'ab') as f: 16 | f.write(b'\x00' * bss_length) 17 | print('binpatch done') 18 | 19 | -------------------------------------------------------------------------------- /software/coremark/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | coremark.bin 6 | coremark.dump 7 | coremark -------------------------------------------------------------------------------- /software/coremark/Makefile: -------------------------------------------------------------------------------- 1 | RISCV_ARCH := rv32im 2 | RISCV_ABI := ilp32 3 | RISCV_MCMODEL := medlow 4 | C_SRCS := \ 5 | core_list_join.c \ 6 | core_main.c \ 7 | core_matrix.c \ 8 | core_state.c \ 9 | core_util.c \ 10 | core_portme.c 11 | CFLAGS := -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4 12 | 13 | all: 14 | riscv32-unknown-elf-gcc $(CFLAGS) -march=rv32i -mabi=ilp32 -mcmodel=medlow -nostdlib sdboot.S newlib/crt0.S newlib/syscall.c mmio_basic.c timer.c $(C_SRCS) -o coremark.elf -T linker.ld -lc -lgcc 15 | riscv32-unknown-elf-objcopy -O binary coremark.elf coremark.bin 16 | 17 | clean: 18 | -rm coremark.bin coremark.elf 19 | 20 | -------------------------------------------------------------------------------- /software/coremark/README.md: -------------------------------------------------------------------------------- 1 | # this coremark port is copied and modified from tinyriscv 2 | 由于coremark程序编译出来的bin文件将近30KB,因此需要将link.lds文件里的flash加到到30KB或以上,RAM加大到10KB或以上。 3 | -------------------------------------------------------------------------------- /software/coremark/core_portme.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "coremark.h" 4 | #include "timer.h" 5 | 6 | // aclint timer 10MHz 7 | #define CPU_FREQ_HZ 10000000 8 | 9 | #if VALIDATION_RUN 10 | volatile ee_s32 seed1_volatile=0x3415; 11 | volatile ee_s32 seed2_volatile=0x3415; 12 | volatile ee_s32 seed3_volatile=0x66; 13 | #endif 14 | 15 | #if PERFORMANCE_RUN 16 | volatile ee_s32 seed1_volatile=0x0; 17 | volatile ee_s32 seed2_volatile=0x0; 18 | volatile ee_s32 seed3_volatile=0x66; 19 | #endif 20 | 21 | #if PROFILE_RUN 22 | volatile ee_s32 seed1_volatile=0x8; 23 | volatile ee_s32 seed2_volatile=0x8; 24 | volatile ee_s32 seed3_volatile=0x8; 25 | #endif 26 | 27 | volatile ee_s32 seed4_volatile=ITERATIONS; 28 | volatile ee_s32 seed5_volatile=0; 29 | 30 | static CORE_TICKS t0, t1; 31 | 32 | void start_time(void) 33 | { 34 | t0 = get_timer_ticks(); 35 | printf("t0: %u\r\n", t0); 36 | /*t0 = get_cycle_value();*/ 37 | } 38 | 39 | void stop_time(void) 40 | { 41 | t1 = get_timer_ticks(); 42 | printf("t1: %u\r\n", t1); 43 | /*t1 = get_cycle_value();*/ 44 | } 45 | 46 | CORE_TICKS get_time(void) 47 | { 48 | return t1 - t0; 49 | } 50 | 51 | secs_ret time_in_secs(CORE_TICKS ticks) 52 | { 53 | // scale timer down to avoid uint64_t -> double conversion in RV32 54 | int scale = 256; 55 | uint32_t delta = ticks / scale; 56 | uint32_t freq = CPU_FREQ_HZ / scale; 57 | return delta / (double)freq; 58 | } 59 | 60 | void portable_init(core_portable *p, int *argc, char *argv[]) 61 | { 62 | printf("portable init\r\n"); 63 | /*volatile int* c_en = (int*)0x7fffff00;*/ 64 | /**c_en = 1;*/ 65 | /*printf("cache up\r\n");*/ 66 | } 67 | -------------------------------------------------------------------------------- /software/coremark/core_portme.h: -------------------------------------------------------------------------------- 1 | //Bob: put some macro here such that the IDE SDK do not need to specify the macro specially 2 | #define FLAGS_STR "-O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4" 3 | #define PERFORMANCE_RUN 1 4 | #define ITERATIONS 40 5 | //#define CORE_DEBUG 6 | 7 | #ifndef FESDK_CORE_PORTME_H 8 | #define FESDK_CORE_PORTME_H 9 | 10 | #include 11 | #include 12 | 13 | #define HAS_FLOAT 0 14 | #define HAS_TIME_H 1 15 | #define USE_CLOCK 1 16 | #define HAS_STDIO 1 17 | #define HAS_PRINTF 1 18 | #define SEED_METHOD SEED_VOLATILE 19 | #define CORE_TICKS uint32_t 20 | #define ee_u8 uint8_t 21 | #define ee_u16 uint16_t 22 | #define ee_u32 uint32_t 23 | #define ee_s16 int16_t 24 | #define ee_s32 int32_t 25 | #define ee_ptr_int uintptr_t 26 | #define ee_size_t size_t 27 | #define COMPILER_FLAGS FLAGS_STR 28 | 29 | #define align_mem(x) (void *)(((ee_ptr_int)(x) + sizeof(ee_u32) - 1) & -sizeof(ee_u32)) 30 | 31 | #ifdef __GNUC__ 32 | # define COMPILER_VERSION "GCC"__VERSION__ 33 | #else 34 | # error 35 | #endif 36 | 37 | #define MEM_METHOD MEM_STATIC 38 | #define MEM_LOCATION "STATIC" 39 | 40 | #define MAIN_HAS_NOARGC 0 41 | #define MAIN_HAS_NORETURN 0 42 | 43 | #define MULTITHREAD 1 44 | #define USE_PTHREAD 0 45 | #define USE_FORK 0 46 | #define USE_SOCKET 0 47 | 48 | #define default_num_contexts MULTITHREAD 49 | 50 | typedef int core_portable; 51 | void portable_init(core_portable *p, int *argc, char *argv[]); 52 | static void portable_fini(core_portable *p) {} 53 | 54 | #if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN) 55 | #if (TOTAL_DATA_SIZE==1200) 56 | #define PROFILE_RUN 1 57 | #elif (TOTAL_DATA_SIZE==2000) 58 | #define PERFORMANCE_RUN 1 59 | #else 60 | #define VALIDATION_RUN 1 61 | #endif 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /software/coremark/mmio_basic.c: -------------------------------------------------------------------------------- 1 | #include "mmio_basic.h" 2 | volatile int* uart_tx = (int*) 0x93000000; 3 | volatile int* uart_tx_done = (int*) 0x93000008; 4 | volatile int* uart_rx_reset = (int*) 0x93000004; 5 | volatile int* uart_rx_new = (int*) 0x93000004; 6 | volatile int* uart_rx_data = (int*) 0x93000000; 7 | 8 | volatile int* psram_base = (int*) 0x20000000; 9 | 10 | volatile int* distram_base = (int*) 0x10000000; 11 | 12 | volatile int* video_base = (int*) 0x94000000; 13 | 14 | volatile int* sd_cache_base = (int*) 0x96000000; 15 | volatile int* sd_address = (int*) 0x96001000; 16 | volatile int* sd_do_read = (int*) 0x96001004; 17 | volatile int* sd_do_write = (int*) 0x96001008; 18 | volatile int* sd_ncd = (int*) 0x96002000; 19 | volatile int* sd_ready = (int*) 0x96002010; 20 | volatile int* sd_cache_dirty = (int*) 0x96002014; 21 | 22 | volatile int* gpio_ctrl = (int*) 0x92000000; 23 | 24 | volatile int* interrupt_ctrl = (int*) 0x98000000; 25 | 26 | volatile int* uart_dma_ctrl = (int*) 0x99000000; 27 | 28 | int video_x = 0; 29 | int video_y = 0; 30 | 31 | char uart_getchar() 32 | { 33 | /**uart_rx_reset = 1;*/ 34 | while(! *uart_rx_new); 35 | char c = *uart_rx_data; 36 | *uart_rx_reset = 1; 37 | return c; 38 | /*return *uart_rx_data;*/ 39 | } 40 | void uart_putchar(char c) 41 | { 42 | if (c == '\n') uart_putchar('\r'); 43 | while(! *uart_tx_done); 44 | *uart_tx = c; 45 | while(! *uart_tx_done); 46 | } 47 | void hdmi_putchar(char c) 48 | { 49 | if (c == '\r') video_x = 0; 50 | else if (c == '\n') { 51 | if (video_y == 29) video_y = 0; 52 | else video_y++; 53 | } 54 | else { 55 | video_base[video_y * 80 + video_x] = c + 0x0100; 56 | if (video_x == 79) { 57 | video_x = 0; 58 | if (video_y == 29) video_y = 0; 59 | else video_y++; 60 | } 61 | else video_x++; 62 | } 63 | } 64 | 65 | void uart_putstr(const char* str) 66 | { 67 | int n = 0; 68 | while(str[n]) uart_putchar(str[n++]); 69 | } 70 | 71 | -------------------------------------------------------------------------------- /software/coremark/mmio_basic.h: -------------------------------------------------------------------------------- 1 | // pComputer basic MMIO library 2 | #ifndef MMIO_BASIC_H 3 | #define MMIO_BASIC_H 4 | extern volatile int* uart_tx; 5 | extern volatile int* uart_tx_done; 6 | extern volatile int* uart_rx_reset; 7 | extern volatile int* uart_rx_new; 8 | extern volatile int* uart_rx_data; 9 | 10 | extern volatile int* psram_base; 11 | 12 | extern volatile int* video_base; 13 | 14 | extern volatile int* distram_base; 15 | 16 | extern volatile int* sd_cache_base; 17 | extern volatile int* sd_address; 18 | extern volatile int* sd_do_read; 19 | extern volatile int* sd_do_write; 20 | extern volatile int* sd_ncd; 21 | extern volatile int* sd_ready; 22 | extern volatile int* sd_cache_dirty; 23 | 24 | extern volatile int* gpio_ctrl; 25 | 26 | extern volatile int* interrupt_ctrl; 27 | 28 | extern volatile int* uart_dma_ctrl; 29 | 30 | char uart_getchar(); 31 | void uart_putchar(char c); 32 | void uart_putstr(const char* str); 33 | void hdmi_putchar(char c); 34 | #endif 35 | -------------------------------------------------------------------------------- /software/coremark/newlib/crt0.S: -------------------------------------------------------------------------------- 1 | .section .text.start 2 | nop 3 | -------------------------------------------------------------------------------- /software/coremark/sdboot.S: -------------------------------------------------------------------------------- 1 | .section .text.boot 2 | 3 | # entry point 4 | sd_start: 5 | la a0, 0x92000000 6 | li a1, 0 7 | sw a1, 24(a0) 8 | sw a1, 28(a0) 9 | sw a1, 32(a0) 10 | sw a1, 36(a0) 11 | 12 | # stack 13 | la sp, 0x101efffc 14 | j main 15 | # never here 16 | j end 17 | end: 18 | la a0, 0x92000000 19 | li a1, 1 20 | #sw a1, 24(a0) 21 | sw a1, 28(a0) 22 | #sw a1, 32(a0) 23 | sw a1, 36(a0) 24 | j end 25 | -------------------------------------------------------------------------------- /software/coremark/timer.c: -------------------------------------------------------------------------------- 1 | /** 2 | * File : timer.c 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.06.22 6 | * Last Modified Date: 2021.06.22 7 | */ 8 | #include "timer.h" 9 | #include "stdint.h" 10 | #include 11 | #include 12 | volatile int* timer_ctrl = (int*) 0x9b00bff8; 13 | /*volatile int* timel_addr = (int*) 0x9b000000;*/ 14 | /*volatile int* timeh_addr = (int*) 0x9b000004;*/ 15 | /*volatile int* timecmp_addr = (int*) 0x9b000008;*/ 16 | /*volatile int* time_irq_mode_addr = (int*) 0x9b00000c;*/ 17 | 18 | uint32_t get_timer_ticks() 19 | { 20 | uint64_t timel = timer_ctrl[0]; 21 | uint64_t timeh = timer_ctrl[1]; 22 | uint64_t result = timel + (timeh << 32); 23 | /*return result;*/ 24 | return timer_ctrl[0]; 25 | } 26 | -------------------------------------------------------------------------------- /software/coremark/timer.h: -------------------------------------------------------------------------------- 1 | /** 2 | * File : timer.h 3 | * License : GPL-3.0-or-later 4 | * Author : Peter Gu 5 | * Date : 2021.06.22 6 | * Last Modified Date: 2021.06.22 7 | */ 8 | #ifndef TIMER_H 9 | #define TIMER_H 10 | extern volatile int* timer_ctrl; 11 | #include "stdint.h" 12 | uint32_t get_timer_ticks(); 13 | #endif 14 | -------------------------------------------------------------------------------- /software/kernel/Image: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/software/kernel/Image -------------------------------------------------------------------------------- /software/kernel/quasi.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | / { 4 | #address-cells = <0x02>; 5 | #size-cells = <0x02>; 6 | compatible = "riscv-virtio"; 7 | model = "riscv-virtio,qemu"; 8 | interrupt-parent = "&cpu0inc"; 9 | 10 | chosen { 11 | bootargs = "earlycon console=ttyUL0 root=/dev/ram"; 12 | stdout-path = "/soc/uartlite@4000000"; 13 | /*bootargs = "earlycon console=ttyS0 root=/dev/ram";*/ 14 | /*stdout-path = "/soc/uart@40000000";*/ 15 | }; 16 | 17 | memory@20001000 { 18 | device_type = "memory"; 19 | reg = <0x00 0x20001000 0x00 0x00600000>; 20 | }; 21 | 22 | cpus { 23 | #address-cells = <0x01>; 24 | #size-cells = <0x00>; 25 | timebase-frequency = <0x989680>; 26 | 27 | cpu@0 { 28 | phandle = <0x01>; 29 | device_type = "cpu"; 30 | reg = <0x00>; 31 | status = "okay"; 32 | compatible = "riscv"; 33 | riscv,isa = "rv32ima"; 34 | //mmu-type = "riscv,sv32"; 35 | 36 | cpu0inc: interrupt-controller { 37 | #interrupt-cells = <0x01>; 38 | #address-cells = <0x01>; 39 | interrupt-controller; 40 | compatible = "riscv,cpu-intc"; 41 | //phandle = <0x02>; 42 | }; 43 | }; 44 | 45 | cpu-map { 46 | 47 | cluster0 { 48 | 49 | core0 { 50 | cpu = <0x01>; 51 | }; 52 | }; 53 | }; 54 | }; 55 | 56 | soc { 57 | #address-cells = <0x02>; 58 | #size-cells = <0x02>; 59 | compatible = "simple-bus"; 60 | ranges; 61 | 62 | /* 63 | uart@40000000 { 64 | //interrupts = <0x0a>; 65 | //interrupt-parent = <0x03>; 66 | clock-frequency = <0x384000>; 67 | reg = <0x00 0x40000000 0x00 0x100>; 68 | compatible = "ns16550"; 69 | }; 70 | */ 71 | 72 | uartlite@4000000 { 73 | clock-frequency = <0x384000>; 74 | //interrupts = <0 59 4>; 75 | //interrupt-parent = <0x03>; 76 | compatible = "xlnx,xps-uartlite-1.00.a"; 77 | reg = <0x00 0x4000000 0x00 0x10000>; 78 | clock = <10000000>; 79 | }; 80 | 81 | clint@9b000000 { 82 | //interrupt-parent = <0x03>; 83 | //interrupts-extended = <&cpu0inc 0x03 &cpu0inc 0x07>; 84 | interrupts-extended = <&cpu0inc 0x07>; 85 | reg = <0x00 0x9b000000 0x00 0x10000>; 86 | compatible = "riscv,clint0"; 87 | }; 88 | 89 | 90 | /*uart@80000000 { // dummy*/ 91 | /*[>interrupts = <0x0a>;<]*/ 92 | /*[>interrupt-parent = <0x03>;<]*/ 93 | /*clock-frequency = <0x384000>;*/ 94 | /*reg = <0x00 0x80000000 0x00 0x100>;*/ 95 | /*compatible = "ns16550";*/ 96 | /*};*/ 97 | }; 98 | }; 99 | -------------------------------------------------------------------------------- /software/kernelboot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # File : uartboot.sh 3 | # License : GPL-3.0-or-later 4 | # Author : Peter Gu 5 | # Date : 2021.04.24 6 | # Last Modified Date: 2021.04.24 7 | 8 | if [ -z $1 ]; then 9 | echo "please specify kernel" 10 | exit 0 11 | fi 12 | if [ -z $2 ]; then 13 | echo "please specify dtb" 14 | exit 0 15 | fi 16 | 17 | for i in `seq 0 9`; do 18 | if [ -e /dev/ttyUSB$i ]; then 19 | echo "reset board ..." 20 | echo 'RRRRRRRRRRR' > /dev/ttyUSB$i 21 | sync 22 | sleep 2 23 | echo 'Hope SD boot has finished' 24 | sleep 0.1 25 | echo "boot ..." 26 | echo 'x' > /dev/ttyUSB$i 27 | sync 28 | sleep 0.1 29 | echo "dump kernel to /dev/ttyUSB$i ..." 30 | xxd -p $1 > /dev/ttyUSB$i 31 | echo ' ' > /dev/ttyUSB$i 32 | sync 33 | 34 | sleep 0.1 35 | echo 'x' > /dev/ttyUSB$i 36 | sync 37 | sleep 0.1 38 | 39 | echo "dump dtb to /dev/ttyUSB$i ..." 40 | xxd -p $2 > /dev/ttyUSB$i 41 | for j in `seq 1 80`; do 42 | echo '00000000' > /dev/ttyUSB$i 43 | done 44 | sync 45 | sleep 0.1 46 | echo ' ' > /dev/ttyUSB$i 47 | sync 48 | echo "done. " 49 | exit 0 50 | fi 51 | done 52 | echo 'no ttyUSB device found!' 53 | -------------------------------------------------------------------------------- /software/mmukernel/Image: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/software/mmukernel/Image -------------------------------------------------------------------------------- /software/mmukernel/mmu.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | / { 4 | #address-cells = <0x02>; 5 | #size-cells = <0x02>; 6 | compatible = "riscv-virtio"; 7 | model = "riscv-virtio,qemu"; 8 | 9 | chosen { 10 | //bootargs = "earlycon=sbi console=ttyUL0"; 11 | stdout-path = "/soc/quasisoc_uart@93000000"; 12 | }; 13 | 14 | memory@20000000 { 15 | device_type = "memory"; 16 | reg = <0x00 0x20000000 0x00 0x4000000>; 17 | }; 18 | /* 19 | memory@20400000 { 20 | device_type = "memory"; 21 | reg = <0x00 0x20400000 0x00 0x8000000>; 22 | }; 23 | */ 24 | 25 | cpus { 26 | #address-cells = <0x01>; 27 | #size-cells = <0x00>; 28 | timebase-frequency = <10000000>; 29 | 30 | cpu@0 { 31 | phandle = <0x01>; 32 | device_type = "cpu"; 33 | reg = <0x00>; 34 | status = "okay"; 35 | compatible = "riscv"; 36 | riscv,isa = "rv32imafdcsuh"; 37 | mmu-type = "riscv,sv32"; 38 | 39 | interrupt-controller { 40 | #interrupt-cells = <0x01>; 41 | interrupt-controller; 42 | compatible = "riscv,cpu-intc"; 43 | phandle = <0x02>; 44 | }; 45 | }; 46 | 47 | cpu-map { 48 | 49 | cluster0 { 50 | 51 | core0 { 52 | cpu = <0x01>; 53 | }; 54 | }; 55 | }; 56 | }; 57 | 58 | soc { 59 | #address-cells = <0x02>; 60 | #size-cells = <0x02>; 61 | compatible = "simple-bus"; 62 | ranges; 63 | 64 | quasisoc_uart@93000000 { 65 | compatible = "quasisoc,uart-0.1"; 66 | reg = <0x00 0x93000000 0x00 0x100>; 67 | }; 68 | 69 | /* 70 | uart@10000000 { 71 | interrupts = <0x0a>; 72 | interrupt-parent = <0x03>; 73 | clock-frequency = "\08@"; 74 | reg = <0x00 0x10000000 0x00 0x100>; 75 | compatible = "ns16550a"; 76 | }; 77 | 78 | plic@c000000 { 79 | phandle = <0x03>; 80 | riscv,ndev = <0x35>; 81 | reg = <0x00 0xc000000 0x00 0x600000>; 82 | interrupts-extended = <0x02 0x0b 0x02 0x09>; 83 | interrupt-controller; 84 | compatible = "sifive,plic-1.0.0\0riscv,plic0"; 85 | #interrupt-cells = <0x01>; 86 | }; 87 | 88 | clint@9b000000 { 89 | interrupts-extended = <0x02 0x03 0x02 0x07>; 90 | reg = <0x00 0x9b000000 0x00 0x10000>; 91 | compatible = "riscv,clint0"; 92 | }; 93 | */ 94 | }; 95 | }; 96 | -------------------------------------------------------------------------------- /software/mmukernelboot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # File : uartboot.sh 3 | # License : GPL-3.0-or-later 4 | # Author : Peter Gu 5 | # Date : 2021.04.24 6 | # Last Modified Date: 2021.04.24 7 | 8 | if [ -z $1 ]; then 9 | echo "please specify kernel" 10 | exit 0 11 | fi 12 | if [ -z $2 ]; then 13 | echo "please specify dtb" 14 | exit 0 15 | fi 16 | if [ -z $3 ]; then 17 | echo "please specify sbi" 18 | exit 0 19 | fi 20 | 21 | for i in `seq 0 9`; do 22 | if [ -e /dev/ttyUSB$i ]; then 23 | echo "reset board ..." 24 | echo 'RRRRRRRRRRR' > /dev/ttyUSB$i 25 | sync 26 | sleep 2 27 | echo 'Hope SD boot has finished' 28 | sleep 0.1 29 | echo "boot ..." 30 | echo 'x' > /dev/ttyUSB$i 31 | sync 32 | sleep 0.1 33 | 34 | echo "dump sbi to /dev/ttyUSB$i ..." 35 | xxd -p $3 > /dev/ttyUSB$i 36 | echo ' ' > /dev/ttyUSB$i 37 | sync 38 | 39 | sleep 0.1 40 | echo 'x' > /dev/ttyUSB$i 41 | sync 42 | sleep 0.1 43 | 44 | echo "dump dtb to /dev/ttyUSB$i ..." 45 | xxd -p $2 > /dev/ttyUSB$i 46 | echo ' ' > /dev/ttyUSB$i 47 | sync 48 | 49 | sleep 0.1 50 | echo 'x' > /dev/ttyUSB$i 51 | sync 52 | sleep 0.1 53 | 54 | echo "dump kernel to /dev/ttyUSB$i ..." 55 | xxd -p $1 > /dev/ttyUSB$i 56 | for j in `seq 1 80`; do 57 | echo '00000000' > /dev/ttyUSB$i 58 | done 59 | sync 60 | 61 | sleep 0.1 62 | echo ' ' > /dev/ttyUSB$i 63 | sync 64 | echo "done. " 65 | exit 0 66 | fi 67 | done 68 | echo 'no ttyUSB device found!' 69 | -------------------------------------------------------------------------------- /software/newlib/crt0.S: -------------------------------------------------------------------------------- 1 | .section .text.start 2 | nop 3 | -------------------------------------------------------------------------------- /software/pingo_renderer/Makefile: -------------------------------------------------------------------------------- 1 | #RISCV = /opt/riscv32ima/bin/riscv32-unknown-linux-gnu- 2 | RISCVDIR= /opt/riscv32i 3 | RISCV = riscv32-unknown-elf- 4 | AS = $(RISCV)as 5 | ASFLAGS = -march=rv32im -mabi=ilp32 6 | LD = $(RISCV)ld 7 | #LDFLAGS = -m elf32lriscv --nostdlib 8 | LDFLAGS = -m elf32lriscv 9 | CC = $(RISCV)gcc 10 | CPP = $(RISCV)g++ 11 | CC_L_F = -march=rv32i -mabi=ilp32 -nostdlib -mstrict-align -O0 -static 12 | CFLAGS = -march=rv32im -mabi=ilp32 -mstrict-align -O0 -static 13 | CPPFLAGS= $(CFLAGS) -nostdlib 14 | OBJCOPY = $(RISCV)objcopy 15 | 16 | all: sdboot.bin 17 | 18 | %.bin: %.elf 19 | $(OBJCOPY) -O binary $*.elf $*.bin 20 | python3 ../binpatch.py $*.bin $*.elf 21 | 22 | sdboot.elf: 23 | (cd pingo; bash manualmake.sh; cd ..) && $(CC) $(CC_L_F) -fPIC -g -lc -lgcc ../newlib/crt0.S ../newlib/syscall.c sdboot.S sdboot.c pingo/*.o -o $@ -fPIE -pie -T linker_sdboot.ld -lm -lc -lgcc 24 | 25 | 26 | clean: 27 | -rm -f *.elf 28 | -rm -f *.bin 29 | -rm -f *.o 30 | -------------------------------------------------------------------------------- /software/pingo_renderer/linker_sdboot.ld: -------------------------------------------------------------------------------- 1 | /* Script for -z combreloc: combine and sort reloc sections */ 2 | /* Copyright (C) 2014-2018 Free Software Foundation, Inc. 3 | Copyright (C) 2019 ETH Zürich and University of Bologna 4 | Copying and distribution of this script, with or without modification, 5 | are permitted in any medium without royalty provided the copyright 6 | notice and this notice are preserved. */ 7 | 8 | /* This linker script is derived from the default linker script of the RISC-V 9 | gcc compiler. We have made a few changes to make it suitable for linking bare 10 | metal programs. These are mostly removing dynamic linking related sections and 11 | putting sections into our memory regions. */ 12 | 13 | SECTIONS 14 | { 15 | __heap_size = DEFINED(__heap_size) ? __heap_size : 0x1000; 16 | 17 | . = 0x20000000; 18 | .text : { *(.text.boot) } 19 | .text : { *(.text) } 20 | .data : { *(.data) } 21 | .bss : { *(.bss) } 22 | .heap : 23 | { 24 | PROVIDE(__heap_start = .); 25 | . = __heap_size; 26 | PROVIDE(__heap_end = .); 27 | } 28 | _edata = .; PROVIDE (edata = .); 29 | __global_pointer$ = 0x0; 30 | _end = .; PROVIDE (end = .); 31 | } 32 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/.gitignore: -------------------------------------------------------------------------------- 1 | Pingo.pro.user 2 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/Makefile.RV: -------------------------------------------------------------------------------- 1 | # varaibles are exported 2 | CC = $(RISCV)gcc 3 | CC_L_F = -march=rv32i -mabi=ilp32 -O0 -fPIC -g 4 | 5 | test: test.c 6 | $(CC) $(CC_L_F) $^ -o $@ -fPIE -T linker_user.ld -nostdlib 7 | 8 | #test: test.c test2.c 9 | #$(CC) $(CC_L_F) $^ -o $@ -fPIE -Ttext=0x20000000 10 | 11 | clean: 12 | -rm -rf test 13 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/Pingo.pro: -------------------------------------------------------------------------------- 1 | CONFIG += console 2 | CONFIG += c++11 3 | 4 | QT += gui 5 | 6 | DEFINES += QT_DEPRECATED_WARNINGS 7 | 8 | ;LIBS += -lgdi32 9 | 10 | # Default rules for deployment. 11 | qnx: target.path = /tmp/$${TARGET}/bin 12 | !isEmpty(target.path): INSTALLS += target 13 | 14 | HEADERS += \ 15 | example/consolebackend.h \ 16 | example/cube.h \ 17 | example/pingo_mesh.h \ 18 | example/teapot.h \ 19 | example/viking.h \ 20 | example/windowbackend.h \ 21 | math/mat3.h \ 22 | math/mat4.h \ 23 | math/types.h \ 24 | math/vec2.h \ 25 | math/vec3.h \ 26 | math/vec4.h \ 27 | render/backend.h \ 28 | render/depth.h \ 29 | render/material.h \ 30 | render/mesh.h \ 31 | render/object.h \ 32 | render/pixel.h \ 33 | render/rasterizer.h \ 34 | render/renderable.h \ 35 | render/renderer.h \ 36 | render/scene.h \ 37 | render/sprite.h \ 38 | render/texture.h 39 | 40 | SOURCES += \ 41 | example/consolebackend.c \ 42 | example/cube.c \ 43 | example/main.c \ 44 | example/pingo_mesh.c \ 45 | example/teapot.c \ 46 | example/viking.c \ 47 | example/windowbackend.c \ 48 | math/mat3.c \ 49 | math/mat4.c \ 50 | math/vec2.c \ 51 | math/vec3.c \ 52 | math/vec4.c \ 53 | render/depth.c \ 54 | render/material.c \ 55 | render/mesh.c \ 56 | render/object.c \ 57 | render/pixel.c \ 58 | render/rasterizer.c \ 59 | render/renderable.c \ 60 | render/renderer.c \ 61 | render/scene.c \ 62 | render/sprite.c \ 63 | render/texture.c 64 | 65 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/README.md: -------------------------------------------------------------------------------- 1 | # pingo 2 | 3 | Pingo is a low level 2D/3D graphics library. It uses no dynamic memory and provides a simple backend interface to implement for your ebedded platform. The graphical backend can just provide a framebuffer on whch to write on but can also intercept the draw calls and customize the rendering. 4 | 5 | The example can be compiled and run on Windows with MinGW 8. 6 | 7 | #### An example with texture and per-triangle shading 8 | ![Example](/example/viking.png) 9 | #### The beautiful low poly model has been gently provided by [Nigel Goh](https://www.artstation.com/artwork/9OzxO) 10 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/software/pingo_renderer/pingo/example/console.png -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/consolebackend.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../render/backend.h" 4 | #include "../math/vec2.h" 5 | 6 | typedef struct ConsoleBackend { 7 | BackEnd backend; 8 | } ConsoleBackend; 9 | 10 | void console_backend_init(ConsoleBackend * t, Vec2i size, void* memchunk); 11 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/cube.c: -------------------------------------------------------------------------------- 1 | #include "cube.h" 2 | 3 | Vec3f ver[36] = { 4 | {-0.5, +0.5, -0.5},{+0.5, -0.5, -0.5},{-0.5, -0.5, -0.5}, 5 | {-0.5, +0.5, -0.5},{+0.5, +0.5, -0.5},{+0.5, -0.5, -0.5}, 6 | {-0.5, -0.5, +0.5},{+0.5, -0.5, +0.5},{-0.5, +0.5, +0.5}, 7 | {-0.5, +0.5, +0.5},{+0.5, -0.5, +0.5},{+0.5, +0.5, +0.5}, 8 | 9 | {+0.5, -0.5, -0.5},{-0.5, -0.5, +0.5},{-0.5, -0.5, -0.5}, 10 | {+0.5, -0.5, -0.5},{+0.5, -0.5, +0.5},{-0.5, -0.5, +0.5}, 11 | {+0.5, +0.5, -0.5},{-0.5, +0.5, -0.5},{-0.5, +0.5, +0.5}, 12 | {-0.5, +0.5, +0.5},{+0.5, +0.5, +0.5},{+0.5, +0.5, -0.5}, 13 | 14 | {-0.5, +0.5, -0.5},{-0.5, -0.5, -0.5},{-0.5, -0.5, +0.5}, 15 | {-0.5, -0.5, +0.5},{-0.5, +0.5, +0.5},{-0.5, +0.5, -0.5}, 16 | {+0.5, -0.5, -0.5},{+0.5, +0.5, -0.5},{+0.5, -0.5, +0.5}, 17 | {+0.5, +0.5, +0.5},{+0.5, -0.5, +0.5},{+0.5, +0.5, -0.5} 18 | }; 19 | 20 | Vec2f tex[36] = { 21 | {0.0, 1.0},{1.0, 0.0},{0.0, 0.0}, 22 | {0.0, 1.0},{1.0, 1.0},{1.0, 0.0}, 23 | {1.0, 1.0},{1.0, 0.0},{0.0, 1.0}, 24 | {1.0, 0.0},{0.0, 1.0},{1.0, 1.0}, 25 | 26 | {1.0, 0.0},{0.0, 1.0},{0.0, 0.0}, 27 | {1.0, 0.0},{1.0, 1.0},{0.0, 1.0}, 28 | {1.0, 0.0},{0.0, 0.0},{0.0, 1.0}, 29 | {0.0, 1.0},{1.0, 1.0},{1.0, 0.0}, 30 | 31 | {1.0, 0.0},{0.0, 0.0},{0.0, 1.0}, 32 | {0.0, 1.0},{1.0, 1.0},{1.0, 0.0}, 33 | {0.0, 0.0},{1.0, 0.0},{0.0, 1.0}, 34 | {1.0, 1.0},{0.0, 1.0},{1.0, 0.0} 35 | 36 | }; 37 | 38 | uint16_t i[36] = { 39 | 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 40 | 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35 41 | }; 42 | 43 | 44 | Mesh mesh_cube = { 45 | .indexes_count = 36, 46 | .pos_indices = &i[0], 47 | .positions = &ver[0], 48 | .textCoord = &tex[0] 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/cube.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../render/mesh.h" 4 | 5 | extern Mesh mesh_cube; 6 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/memorybackend.c: -------------------------------------------------------------------------------- 1 | 2 | #include "memorybackend.h" 3 | 4 | #include "../render/renderer.h" 5 | #include "../render/texture.h" 6 | #include "../render/pixel.h" 7 | #include "../render/depth.h" 8 | 9 | 10 | void memoryBackendinit( Renderer * ren, BackEnd * backEnd, Vec4i _rect) { 11 | 12 | } 13 | 14 | void memoryBackendbeforeRender( Renderer * ren, BackEnd * backEnd) { 15 | } 16 | 17 | void memoryBackendafterRender( Renderer * ren, BackEnd * backEnd) { 18 | 19 | } 20 | 21 | Pixel * memoryBackendgetFrameBuffer( Renderer * ren, BackEnd * backEnd) { 22 | return ((MemoryBackend *) backEnd) -> frameBuffer; 23 | } 24 | 25 | Depth * memoryBackendgetZetaBuffer( Renderer * ren, BackEnd * backEnd) { 26 | return ((MemoryBackend *) backEnd) -> zetaBuffer; 27 | } 28 | 29 | void memoryBackendInit( MemoryBackend * this, Pixel * buf, Vec2i size) { 30 | 31 | this->backend.init = &memoryBackendinit; 32 | this->backend.beforeRender = &memoryBackendbeforeRender; 33 | this->backend.afterRender = &memoryBackendafterRender; 34 | this->backend.getFrameBuffer = &memoryBackendgetFrameBuffer; 35 | this->backend.getZetaBuffer = &memoryBackendgetZetaBuffer; 36 | 37 | this -> zetaBuffer = malloc(size.x*size.y*sizeof (Depth)); 38 | this -> frameBuffer = buf; 39 | } 40 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/memorybackend.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../render/backend.h" 4 | #include "../math/vec2.h" 5 | 6 | typedef struct Pixel Pixel; 7 | typedef struct Depth Depth; 8 | 9 | typedef struct { 10 | BackEnd backend; 11 | Depth * zetaBuffer; 12 | Pixel * frameBuffer; 13 | Vec2i size; 14 | } MemoryBackend; 15 | 16 | void memoryBackendInit(MemoryBackend * ths, Pixel * buf, Vec2i size); 17 | 18 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/pingo_mesh.h: -------------------------------------------------------------------------------- 1 | #include "../render/mesh.h" 2 | 3 | extern Mesh pingo_mesh; 4 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/shading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/software/pingo_renderer/pingo/example/shading.png -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/teapot.h: -------------------------------------------------------------------------------- 1 | #include "../render/mesh.h" 2 | 3 | extern Mesh mesh_teapot; 4 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/texture.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/software/pingo_renderer/pingo/example/texture.data -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/viking.h: -------------------------------------------------------------------------------- 1 | #include "../render/mesh.h" 2 | 3 | extern Mesh viking_mesh; 4 | 5 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/viking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/regymm/quasiSoC/ef83d1693bb6c9ca592c1f89120ca6ac080621d8/software/pingo_renderer/pingo/example/viking.png -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/example/windowbackend.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file: windowbackend.h 3 | * @author Federico Devigili - Alpitronic 4 | * 5 | * @section LICENSE 6 | * 7 | * 8 | * @section DESCRIPTION 9 | * A backend for the renderer which creates a Window windows and renders in it 10 | * 11 | */ 12 | #ifdef WIN32 13 | #pragma once 14 | 15 | struct Renderer; 16 | 17 | #include "../render/backend.h" 18 | #include "../math/vec2.h" 19 | 20 | typedef struct Pixel Pixel; 21 | 22 | /** 23 | * @brief Struct extending BackEnd interface for rendering on Win32 24 | */ 25 | typedef struct { 26 | BackEnd backend; 27 | Vec2i size; 28 | } WindowBackEnd; 29 | 30 | /** 31 | * @brief Initialize a debug overlay over a Windows window, used as emulator of the hardware. 32 | * @param Pointer to the WindowBackEnd structure to initialize 33 | * @param Position of the overlay 34 | * @param Size of the overlay 35 | */ 36 | void windowBackEndInit(WindowBackEnd * thiss, Vec2i size); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/mat3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "types.h" 3 | #include "vec2.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | 10 | typedef struct Mat3 { 11 | F_TYPE elements[9]; 12 | } Mat3; 13 | 14 | /* Returns identity 15 | |1|0|x| 16 | |0|1|y| 17 | |0|0|1| 18 | */ 19 | extern Mat3 mat3Identity(); 20 | 21 | /* Builds a clean translation matrix with x and y translation along relative axes 22 | |1|0|x| 23 | |0|1|y| 24 | |0|0|1| 25 | */ 26 | extern Mat3 mat3Translate(Vec2f l); 27 | 28 | /* Builds a clean rotation matrix of Θ angle 29 | | c(Θ) | -s(Θ) | 0 | 30 | | s(Θ) | c(Θ) | 0 | 31 | | 0 | 0 | 1 | 32 | */ 33 | extern Mat3 mat3Rotate(float theta); 34 | 35 | 36 | /* Builds a clean scale matrix of x, y scaling factors 37 | | x | 0 | 0 | 38 | | 0 | y | 0 | 39 | | 0 | 0 | 1 | 40 | */ 41 | extern Mat3 mat3Scale(Vec2f s); 42 | 43 | //Multiply 2 component vector b 3x3 matrix 44 | extern Vec2f mat3Multiply(Vec2f * v, Mat3 * t); 45 | 46 | //Multiply 3x3 matrix with 3x3 matrix (v*t) 47 | extern Mat3 mat3MultiplyM( Mat3 *v, Mat3 *t); 48 | 49 | //Calculate homogeneous inverse of matrix 50 | extern Mat3 mat3Inverse( Mat3 *v ); 51 | 52 | /* Calculate a complete matrix transformation with translation rotation and scale working as expected 53 | * Rotation and scaled are applied in reference to the provided origin 54 | */ 55 | extern Mat3 mat3Complete( Vec2f origin, Vec2f translation, Vec2f scale, float rotation ); 56 | 57 | //Calculate determinant of matrix 58 | extern F_TYPE mat3Determinant(Mat3 * m); 59 | 60 | //If a matrix has only translation some optimization can be done during rendering. 61 | extern int mat3IsOnlyTranslation(Mat3 *m); 62 | 63 | //If a matrix has only translation and doubles the size some optimization can be done during rendering. 64 | extern int mat3IsOnlyTranslationDoubled(Mat3 *m); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/mat4.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | #include "vec2.h" 5 | #include "vec3.h" 6 | #include "vec4.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct Mat4 { 13 | F_TYPE elements[16]; 14 | } Mat4; 15 | 16 | Mat4 mat4Identity(); 17 | Mat4 mat4Translate(Vec3f l); 18 | 19 | Mat4 mat4RotateX(F_TYPE phi); 20 | Mat4 mat4RotateY(F_TYPE phi); 21 | Mat4 mat4RotateZ(F_TYPE phi); 22 | 23 | Vec2f mat4MultiplyVec2(Vec2f *v, Mat4 *t); 24 | Vec3f mat4MultiplyVec3(Vec3f *v, Mat4 *t); 25 | 26 | Vec4f mat4MultiplyVec4(Vec4f *v, Mat4 *t); 27 | Vec4f mat4MultiplyVec4in( Vec4f *v, Mat4 *t ); 28 | 29 | Mat4 mat4MultiplyM( Mat4 * m1, Mat4 * m2); 30 | Mat4 mat4Inverse(Mat4 * mat); 31 | Mat4 mat4Scale(Vec3f s); 32 | 33 | Mat4 mat4Perspective(float near, float far, float aspect, float fov); 34 | Mat4 mat4Perspective(float near, float far, float aspect, float fov ); 35 | 36 | float mat4NearFromProjection(Mat4 mat); 37 | float mat4FarFromProjection(Mat4 mat); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * @brief I_TYPE is the integer type used in the math libraries, change to the desired size 5 | */ 6 | typedef int I_TYPE; 7 | 8 | /** 9 | * @brief F_TYPE is the floating point type used in the math libraries, change to the desired precision 10 | */ 11 | typedef float F_TYPE; 12 | 13 | 14 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/vec2.c: -------------------------------------------------------------------------------- 1 | #include "vec2.h" 2 | 3 | Vec2i vector2ISum(Vec2i l, Vec2i r) 4 | { 5 | return (Vec2i){l.x+r.x,l.y+r.y}; 6 | } 7 | 8 | Vec2f vecItoF(Vec2i v) 9 | { 10 | return (Vec2f){v.x,v.y}; 11 | } 12 | 13 | Vec2i vecFtoI(Vec2f v) 14 | { 15 | return (Vec2i){v.x,v.y}; 16 | } 17 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/vec2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef struct Vec2i { 10 | I_TYPE x; 11 | I_TYPE y; 12 | } Vec2i; 13 | 14 | typedef struct { 15 | F_TYPE x; 16 | F_TYPE y; 17 | } Vec2f; 18 | 19 | extern Vec2i vector2ISum(Vec2i l, Vec2i r); 20 | 21 | extern Vec2f vecItoF(Vec2i v); 22 | 23 | extern Vec2i vecFtoI(Vec2f v); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/vec3.c: -------------------------------------------------------------------------------- 1 | #include "vec3.h" 2 | #include 3 | 4 | Vec3f vec3fmul(Vec3f a, float b) 5 | { 6 | a.x = a.x * b; 7 | a.y = a.y * b; 8 | a.z = a.z * b; 9 | 10 | return a; 11 | } 12 | 13 | Vec3f vec3fsumV(Vec3f a, Vec3f b) 14 | { 15 | a.x = a.x + b.x; 16 | a.y = a.y + b.y; 17 | a.z = a.z + b.z; 18 | 19 | return a; 20 | } 21 | 22 | Vec3f vec3fsubV(Vec3f a, Vec3f b) 23 | { 24 | a.x = a.x - b.x; 25 | a.y = a.y - b.y; 26 | a.z = a.z - b.z; 27 | 28 | return a; 29 | } 30 | 31 | Vec3f vec3fsum(Vec3f a, float b) 32 | { 33 | a.x = a.x + b; 34 | a.y = a.y + b; 35 | a.z = a.z + b; 36 | 37 | return a; 38 | } 39 | 40 | float vec3Dot(Vec3f a, Vec3f b) 41 | { 42 | return a.x * b.x + a.y * b.y + a.z * b.z; 43 | } 44 | 45 | Vec3f vec3f(float x, float y, float z) 46 | { 47 | return (Vec3f){x,y,z}; 48 | } 49 | 50 | Vec3f vec3Cross(Vec3f a, Vec3f b) 51 | { 52 | 53 | return (Vec3f) {a.y * b.z - b.y * a.z, 54 | a.z * b.x - b.z * a.x, 55 | a.x * b.y - b.x * a.y}; 56 | } 57 | 58 | Vec3f vec3Normalize(Vec3f v) 59 | { 60 | float sqrt = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); 61 | return (Vec3f){v.x / sqrt, v.y / sqrt, v.z / sqrt}; 62 | } 63 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/vec3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef struct Vec3i { 10 | I_TYPE x; 11 | I_TYPE y; 12 | I_TYPE z; 13 | } Vec3i; 14 | 15 | typedef struct Vec3f { 16 | F_TYPE x; 17 | F_TYPE y; 18 | F_TYPE z; 19 | } Vec3f; 20 | 21 | Vec3f vec3f(float,float,float); 22 | Vec3f vec3fmul(Vec3f,float); 23 | Vec3f vec3fsumV(Vec3f,Vec3f); 24 | Vec3f vec3fsubV(Vec3f,Vec3f); 25 | Vec3f vec3fsum(Vec3f,float); 26 | float vec3Dot(Vec3f,Vec3f); 27 | Vec3f vec3Cross(Vec3f,Vec3f); 28 | Vec3f vec3Normalize(Vec3f); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/vec4.c: -------------------------------------------------------------------------------- 1 | #include "vec4.h" 2 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/math/vec4.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef struct Vec4i { 10 | I_TYPE x; 11 | I_TYPE y; 12 | I_TYPE z; 13 | I_TYPE w; 14 | } Vec4i; 15 | 16 | typedef struct Vec4f { 17 | F_TYPE x; 18 | F_TYPE y; 19 | F_TYPE z; 20 | F_TYPE w; 21 | } Vec4f; 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/backend.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../math/vec2.h" 4 | #include "../math/vec4.h" 5 | 6 | /** 7 | * Privdes a common interface to multiple graphical backends 8 | */ 9 | 10 | typedef struct Renderer Renderer; 11 | typedef struct Pixel Pixel; 12 | typedef struct Depth Depth; 13 | typedef struct Texture Texture; 14 | 15 | typedef struct BackEnd { 16 | //Called on initialization and re-initialization 17 | void (*init)(Renderer *, struct BackEnd *, Vec4i rect); 18 | 19 | //Called before starting rendering 20 | void (*beforeRender)(Renderer *, struct BackEnd * ); 21 | 22 | //Called after having finished a render 23 | void (*afterRender)(Renderer *, struct BackEnd * ); 24 | 25 | //Should return the address of the buffer (height*width*sizeof(Pixel)) 26 | Pixel * (*getFrameBuffer)(Renderer *, struct BackEnd * ); 27 | 28 | //Handle backend specific final framebuffer draw (can apply lighting in a different way if needed) 29 | void (*drawPixel)(Texture * f, Vec2i pos, Pixel color, float illumination); 30 | 31 | //Should return the address of the buffer (height*width*sizeof(Pixel)) 32 | Depth * (*getZetaBuffer)(Renderer *, struct BackEnd * ); 33 | } BackEnd; 34 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/depth.c: -------------------------------------------------------------------------------- 1 | #include "depth.h" 2 | 3 | #ifdef ZBUFFER32 4 | void depth_write (Depth * d, int idx, float value) { 5 | d[idx].d = (uint32_t)(value * (float)UINT32_MAX); 6 | } 7 | 8 | bool depth_check(Depth * d, int idx, float value){ 9 | return (uint32_t)(value * (float)UINT32_MAX) < d[idx].d; 10 | } 11 | #endif 12 | 13 | #ifdef ZBUFFER16 14 | void depth_write (Depth * d, int idx, float value) { 15 | d[idx].d = (uint16_t)(value * UINT16_MAX); 16 | } 17 | 18 | bool depth_check(Depth * d, int idx, float value){ 19 | return (uint16_t)(value * UINT16_MAX) < d[idx].d; 20 | } 21 | #endif 22 | 23 | #ifdef ZBUFFER8 24 | void depth_write (Depth * d, int idx, float value) { 25 | d[idx].d = (uint8_t)(value * UINT8_MAX); 26 | } 27 | 28 | bool depth_check(Depth * d, int idx, float value){ 29 | return (uint8_t)(value * UINT8_MAX) > d[idx].d; 30 | } 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/depth.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define ZBUFFER16 // [ZBUFFER32 | ZBUFFER16 | ZBUFFER8] 7 | 8 | #ifdef ZBUFFER32 9 | typedef struct Depth { 10 | uint32_t d; 11 | } Depth; 12 | #endif 13 | 14 | #ifdef ZBUFFER16 15 | typedef struct Depth { 16 | uint16_t d; 17 | } Depth; 18 | #endif 19 | 20 | #ifdef ZBUFFER8 21 | typedef struct Depth { 22 | uint8_t d; 23 | } Depth; 24 | #endif 25 | 26 | void depth_write(Depth * d, int idx, float value); 27 | bool depth_check(Depth * d, int idx, float value); 28 | 29 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/material.c: -------------------------------------------------------------------------------- 1 | #include "material.h" 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/material.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "texture.h" 4 | 5 | typedef struct Material { 6 | Texture * texture; 7 | } Material; 8 | 9 | 10 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/mesh.c: -------------------------------------------------------------------------------- 1 | #include "mesh.h" 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/mesh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../math/vec3.h" 6 | 7 | #include "material.h" 8 | 9 | typedef struct Mesh { 10 | int indexes_count; 11 | uint16_t * pos_indices; 12 | uint16_t * tex_indices; 13 | Vec3f * positions; 14 | Vec2f * textCoord; 15 | } Mesh; 16 | 17 | 18 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/object.c: -------------------------------------------------------------------------------- 1 | #include "object.h" 2 | 3 | 4 | Renderable object_as_renderable(Object * object) 5 | { 6 | return (Renderable){.renderableType = RENDERABLE_OBJECT, .impl = object}; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/object.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../math/mat4.h" 4 | 5 | #include "mesh.h" 6 | #include "renderable.h" 7 | #include "scene.h" 8 | 9 | typedef struct Object { 10 | Mesh * mesh; 11 | Mat4 transform; 12 | Material * material; 13 | } Object; 14 | 15 | Renderable object_as_renderable(Object * object); 16 | 17 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/pixel.c: -------------------------------------------------------------------------------- 1 | #include "pixel.h" 2 | 3 | uint32_t intFromRGBA(uint8_t r,uint8_t g,uint8_t b,uint8_t a) { 4 | uint32_t ret = r | g<<8 | b<<16 | a<<24; 5 | return ret; 6 | } 7 | 8 | #ifdef UINT8 9 | 10 | extern Pixel pixelRandom() { 11 | return (Pixel){(uint8_t)rand()}; 12 | } 13 | 14 | uint8_t pixelToUInt8(Pixel * p) 15 | { 16 | return p->g; 17 | } 18 | 19 | 20 | extern Pixel pixelFromUInt8( uint8_t g){ 21 | return (Pixel){g}; 22 | } 23 | 24 | extern Pixel pixelMul(Pixel p, float f) 25 | { 26 | return (Pixel){p.g*f}; 27 | } 28 | 29 | uint32_t pixelToRGBA(Pixel * p) 30 | { 31 | uint8_t g = p->g; 32 | uint32_t a = g | g<<8 | g<<16; 33 | return a; 34 | } 35 | 36 | extern Pixel pixelFromRGBA( uint8_t r, uint8_t g, uint8_t b, uint8_t a) 37 | { 38 | return (Pixel){((r + g + b) / 3)}; 39 | } 40 | #endif 41 | 42 | #ifdef RGB888 43 | extern Pixel pixelRandom() { 44 | return (Pixel){(uint8_t)rand(),(uint8_t)rand(),(uint8_t)rand()}; 45 | } 46 | 47 | uint32_t pixelToRGBA(Pixel * p) 48 | { 49 | uint8_t g = p->g; 50 | uint32_t a = p->r | p->g <<8 | p->b<<16| 255<<24; 51 | return a; 52 | } 53 | #endif 54 | 55 | #ifdef RGBA8888 56 | extern Pixel pixelRandom() { 57 | return (Pixel){(uint8_t)rand(),(uint8_t)rand(),(uint8_t)rand(),255}; 58 | } 59 | 60 | extern Pixel pixelFromUInt8( uint8_t g){ 61 | return (Pixel){g,g,g, 255}; 62 | } 63 | extern uint8_t pixelToUInt8( Pixel * p){ 64 | return (p->r + p->g + p->b) / 3; 65 | } 66 | 67 | extern uint32_t pixelToRGBA( Pixel * p){ 68 | return intFromRGBA(p->b,p->g,p->r,p->a); 69 | } 70 | 71 | extern Pixel pixelFromRGBA( uint8_t r, uint8_t g, uint8_t b, uint8_t a){ 72 | return (Pixel){r,g,b,a}; 73 | } 74 | 75 | extern Pixel pixelMul(Pixel p, float f) 76 | { 77 | return (Pixel){p.r*f,p.g*f,p.b*f,p.a}; 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/pixel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | //What format to use: 11 | // [ UINT8 | RGB565 | RGBA8888 | RGB888 ] 12 | //#ifdef WIN32 13 | #define UINT8 14 | //#else 15 | //#define UINT8 16 | //#endif 17 | //Formats definitions: 18 | #ifdef UINT8 19 | typedef struct Pixel { 20 | uint8_t g; 21 | }Pixel; 22 | #define PIXELBLACK (Pixel){0} 23 | #define PIXELWHITE (Pixel){255} 24 | #endif 25 | 26 | #ifdef RGB565 27 | typedef struct Pixel { 28 | uint8_t red:5; 29 | uint8_t green:6; 30 | uint8_t blue:5; 31 | }Pixel; 32 | #define PIXELBLACK (Pixel){0} 33 | #define PIXELWHITE (Pixel){255} 34 | #endif 35 | 36 | #ifdef RGB888 37 | typedef struct Pixel { 38 | uint8_t r; 39 | uint8_t g; 40 | uint8_t b; 41 | } Pixel; 42 | 43 | #define PIXELBLACK (Pixel){0,0,0} 44 | #define PIXELWHITE (Pixel){255,255,255} 45 | #endif 46 | 47 | #ifdef RGBA8888 48 | typedef struct Pixel { 49 | uint8_t r; 50 | uint8_t g; 51 | uint8_t b; 52 | uint8_t a; 53 | } Pixel; 54 | 55 | #define PIXELBLACK (Pixel){0,0,0,255} 56 | #define PIXELWHITE (Pixel){255,255,255,255} 57 | #endif 58 | 59 | //Interface 60 | extern Pixel pixelRandom(); 61 | extern Pixel pixelFromUInt8( uint8_t); 62 | extern uint8_t pixelToUInt8( Pixel *); 63 | extern uint32_t pixelToRGBA( Pixel *); 64 | extern Pixel pixelFromRGBA( uint8_t r, uint8_t g, uint8_t b, uint8_t a); 65 | extern Pixel pixelMul( Pixel p, float f); 66 | 67 | #ifdef __cplusplus 68 | } 69 | #endif 70 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/rasterizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "texture.h" 4 | #include "sprite.h" 5 | #include "renderer.h" 6 | 7 | /** 8 | * Defines the type of filtering used when textures are resized and rotated 9 | * by a transformation. Nearest filtering just take 1 texture sample in the 10 | * single pixel which the source coordinate is tranformed to. 11 | * Bilinear filtering takes 4 samples on the source texture to compute a 12 | * weighted average of those 4 values based on the distance of the input 13 | * point. 14 | * Anisotropic filtering takes 4/16 samples from the source image 15 | * distributed uniformly over the area occupied by the destination pixel on 16 | * the source image and makes an average of those values. 17 | */ 18 | 19 | #define FILTERING_NEAREST 20 | //#define FILTERING_BILINEAR 21 | //#define FILTERING_ANISOTROPIC 22 | //#define FILTERING_ANISOTROPICX2 23 | 24 | int rasterizer_draw_pixel_perfect(Vec2i off, Renderer *r, Texture * src); 25 | 26 | int rasterizer_draw_pixel_perfect_doubled(Vec2i off, Renderer *r, Texture * src); 27 | 28 | int rasterizer_draw_transformed(Mat4 t, Renderer *r, Texture * src); 29 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/renderable.c: -------------------------------------------------------------------------------- 1 | #include "renderable.h" 2 | #include "renderer.h" 3 | 4 | int (*renderingFunctions[RENDERABLE_COUNT])(Mat4 transform, Renderer *, Renderable); 5 | 6 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/renderable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../math/mat4.h" 4 | 5 | typedef struct Renderer Renderer; 6 | 7 | typedef enum { 8 | RENDERABLE_SCENE =0, 9 | RENDERABLE_SPRITE, 10 | RENDERABLE_OBJECT, 11 | RENDERABLE_COUNT, 12 | } RenderableType; 13 | 14 | typedef struct { 15 | RenderableType renderableType; 16 | void * impl; 17 | } Renderable; 18 | 19 | extern int (*renderingFunctions[RENDERABLE_COUNT])(Mat4 transform, Renderer *, Renderable); 20 | 21 | 22 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "texture.h" 4 | #include "renderable.h" 5 | #include "pixel.h" 6 | #include "../math/vec4.h" 7 | 8 | typedef struct Scene Scene; 9 | typedef struct BackEnd BackEnd; 10 | 11 | typedef struct Renderer{ 12 | Vec4i camera; 13 | Scene * scene; 14 | 15 | Texture frameBuffer; 16 | Pixel clearColor; 17 | int clear; 18 | 19 | Mat4 camera_projection; 20 | Mat4 camera_view; 21 | 22 | BackEnd * backEnd; 23 | 24 | } Renderer; 25 | 26 | extern int rendererRender(Renderer *); 27 | 28 | extern int rendererInit(Renderer *, Vec2i size, struct BackEnd * backEnd); 29 | 30 | extern int rendererSetScene(Renderer *r, Scene *s); 31 | 32 | extern int rendererSetCamera(Renderer *r, Vec4i camera); 33 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/scene.c: -------------------------------------------------------------------------------- 1 | #include "scene.h" 2 | #include "renderable.h" 3 | 4 | int sceneAddRenderable(Scene * scene, Renderable renderable) 5 | { 6 | if (scene->numberOfRenderables >= MAX_SCENE_RENDERABLES) { 7 | return 1; //Too many renderables in this scene 8 | } 9 | 10 | scene->renderables[scene->numberOfRenderables++] = renderable; 11 | return 0; 12 | } 13 | 14 | int sceneInit(Scene * s) 15 | { 16 | s->transform = mat4Identity(); 17 | s->numberOfRenderables = 0; 18 | s->visible = 1; 19 | 20 | return 0; 21 | } 22 | 23 | 24 | extern Renderable sceneAsRenderable(Scene * scene) { 25 | return (Renderable){.renderableType = RENDERABLE_SCENE, .impl = scene}; 26 | } 27 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/scene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "renderable.h" 5 | #include "../math/mat3.h" 6 | #include "../math/mat4.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #define MAX_SCENE_RENDERABLES 32 13 | 14 | typedef struct Scene { 15 | uint8_t numberOfRenderables; 16 | Renderable renderables[MAX_SCENE_RENDERABLES]; 17 | Mat4 transform; 18 | uint8_t visible; 19 | } Scene; 20 | 21 | extern int sceneInit(Scene * s); 22 | extern int sceneAddRenderable(Scene * scene, Renderable renderable); 23 | 24 | extern Renderable sceneAsRenderable(Scene * scene); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/sprite.c: -------------------------------------------------------------------------------- 1 | #include "sprite.h" 2 | #include "../math/mat3.h" 3 | 4 | int spriteInit(Sprite *s, Texture f, Mat4 t) 5 | { 6 | if (f.frameBuffer == 0) 7 | return 1; 8 | 9 | s->frame = f; 10 | s->t = t; 11 | 12 | return 0; 13 | } 14 | 15 | Renderable spriteAsRenderable(Sprite * s) { 16 | return (Renderable){ .renderableType = RENDERABLE_SPRITE, .impl = s}; 17 | } 18 | 19 | int spriteRandomize(Sprite * s) 20 | { 21 | 22 | for (int x = 0; x < s->frame.size.x; x++ ) { 23 | for (int y = 0; y < s->frame.size.y; y++ ) { 24 | 25 | texture_draw(&s->frame,(Vec2i){x,y},pixelRandom()); 26 | } 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/sprite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "texture.h" 4 | #include "renderable.h" 5 | #include "../math/mat4.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct Sprite { 12 | Mat4 t; 13 | Texture frame; 14 | } Sprite; 15 | 16 | extern int spriteInit( Sprite * s, Texture f, Mat4 t); 17 | extern int spriteRandomize( Sprite * s); 18 | extern Renderable spriteAsRenderable( Sprite * s); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/texture.c: -------------------------------------------------------------------------------- 1 | #include "texture.h" 2 | #include "math.h" 3 | 4 | int texture_init( Texture *f, Vec2i size, Pixel *buf ) 5 | { 6 | if(size.x * size.y == 0) 7 | return 1; // 0 sized rect 8 | 9 | if(buf == 0) 10 | return 2; // null ptr buffer 11 | 12 | f->frameBuffer = (Pixel *)buf; 13 | f->size = size; 14 | 15 | return 0; 16 | } 17 | 18 | /*#ifdef WIN32*/ 19 | /*void texture_draw(Texture *f, Vec2i pos, Pixel color)*/ 20 | /*{*/ 21 | /*f->frameBuffer[pos.x + pos.y * f->size.x] = color;*/ 22 | /*}*/ 23 | /*#endif*/ 24 | void texture_draw(Texture *f, Vec2i pos, Pixel color) 25 | { 26 | f->frameBuffer[pos.x + pos.y * f->size.x] = color; 27 | } 28 | 29 | Pixel texture_read(Texture *f, Vec2i pos) 30 | { 31 | return f->frameBuffer[pos.x + pos.y * f->size.x]; 32 | } 33 | 34 | Pixel texture_readF(Texture *f, Vec2f pos) 35 | { 36 | uint16_t x = (uint16_t)(pos.x * f->size.x) % f->size.x; 37 | uint16_t y = (uint16_t)(pos.y * f->size.y) % f->size.x; 38 | uint32_t index = x + y * f->size.x; 39 | Pixel value = f->frameBuffer[index]; 40 | return value; 41 | } 42 | 43 | Pixel texture_read_bilinear(Texture *f, Vec2f pos) 44 | { 45 | float kX = fmodf(pos.x, 1.0f); 46 | int lowX = floorf(pos.x); 47 | int higX = lowX + 1; 48 | 49 | float kY = fmodf(pos.y, 1.0f); 50 | int lowY = floorf(pos.y); 51 | int higY = lowY + 1; 52 | 53 | float p1 = f->frameBuffer[lowX + lowY * f->size.x].g; 54 | float p2 = f->frameBuffer[higX + lowY * f->size.x].g; 55 | float p3 = f->frameBuffer[lowX + higY * f->size.x].g; 56 | float p4 = f->frameBuffer[higX + higY * f->size.x].g; 57 | 58 | Pixel out ={ 59 | ((p1 * (1.0f - kX) + p2 * (kX)) * (1.0 - kY)) 60 | + 61 | ((p3 * (1.0f - kX) + p4 * (kX)) * (kY)) 62 | }; 63 | return out; 64 | } 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/render/texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "pixel.h" 4 | #include "renderable.h" 5 | #include "../math/vec2.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct Texture { 12 | Vec2i size; 13 | Pixel * frameBuffer; 14 | } Texture; 15 | 16 | extern int texture_init( Texture * f, Vec2i size, Pixel *); 17 | 18 | extern Renderable texture_as_renderable( Texture * s); 19 | 20 | extern void texture_draw(Texture * f, Vec2i pos, Pixel color); 21 | 22 | extern Pixel texture_read(Texture * f, Vec2i pos); 23 | 24 | extern Pixel texture_readF(Texture * f, Vec2f pos); 25 | 26 | extern Pixel texture_read_bilinear(Texture *f, Vec2f pos); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /software/pingo_renderer/pingo/sftrdr_main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //extern "C" int sftrdr_main(); 3 | int sftrdr_main(); 4 | -------------------------------------------------------------------------------- /software/pingo_renderer/sdboot.S: -------------------------------------------------------------------------------- 1 | .section .text.boot 2 | 3 | # C functions 4 | .globl sd_c_start 5 | 6 | # ASM functions 7 | .globl isr_asm 8 | .globl csrr_mstatus 9 | .globl csrw_mstatus 10 | .globl csrr_mie 11 | .globl csrw_mie 12 | .globl csrr_mtvec 13 | .globl csrw_mtvec 14 | .globl csrr_mcause 15 | .globl csrw_mcause 16 | .globl csrr_mscratch 17 | .globl csrw_mscratch 18 | .globl csrr_mepc 19 | .globl csrw_mepc 20 | 21 | .globl syscall_asm 22 | 23 | .globl crit_enter 24 | .globl crit_leave 25 | 26 | .globl sd_test_asm 27 | 28 | .equ REGS_SAVE_ADDR, 0x10000000 29 | 30 | # entry point 31 | sd_start: 32 | la a0, 0x92000000 33 | li a1, 0 34 | sw a1, 24(a0) 35 | sw a1, 28(a0) 36 | sw a1, 32(a0) 37 | sw a1, 36(a0) 38 | 39 | # kernel stack at 1MB 40 | la sp, 0x200ffffc 41 | j sd_c_start 42 | # never here 43 | j end 44 | end: 45 | la a0, 0x92000000 46 | li a1, 1 47 | #sw a1, 24(a0) 48 | sw a1, 28(a0) 49 | #sw a1, 32(a0) 50 | sw a1, 36(a0) 51 | j end 52 | 53 | -------------------------------------------------------------------------------- /software/ssbi/Makefile: -------------------------------------------------------------------------------- 1 | all: sbi.bin 2 | 3 | sbi.bin: 4 | riscv32-unknown-elf-gcc $(CFLAGS) -march=rv32ima_zicsr -mabi=ilp32 -mstrict-align -O0 -static -nostdlib sbi.S sbi.c -o sbi.elf -T linker.ld -lc -lgcc 5 | riscv32-unknown-elf-objcopy -O binary sbi.elf sbi.bin 6 | 7 | clean: 8 | -rm sbi.elf sbi.bin 9 | -------------------------------------------------------------------------------- /software/ssbi/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | SECTIONS 3 | { 4 | . = 0x20001000; 5 | .text : { _start = .; *(.text.boot) } 6 | .text : { *(.text) } 7 | .data : { *(.data) } 8 | .bss : { 9 | _bss_start = . ; 10 | *(.bss*) 11 | *(.sbss*) 12 | . = ALIGN(8) ; 13 | . += 4096 ; 14 | _sp = . - 16; 15 | } 16 | . = ALIGN(4); 17 | _end = . ; 18 | } 19 | -------------------------------------------------------------------------------- /software/tests/firmware/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | SECTIONS 3 | { 4 | . = 0x20001000; 5 | /*. = 0xf0000000;*/ 6 | .text : { _start = .; *(.text) } 7 | .data : { *(.data) } 8 | } 9 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2015, The Regents of the University of California (Regents). 2 | All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. Neither the name of the Regents nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 16 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 17 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 18 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 | 20 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 23 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 24 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/README: -------------------------------------------------------------------------------- 1 | Tests from https://github.com/riscv/riscv-tests/tree/master/isa/rv32ui 2 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/addi.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # addi.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test addi instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_IMM_OP( 2, addi, 0x00000000, 0x00000000, 0x000 ); 21 | TEST_IMM_OP( 3, addi, 0x00000002, 0x00000001, 0x001 ); 22 | TEST_IMM_OP( 4, addi, 0x0000000a, 0x00000003, 0x007 ); 23 | 24 | TEST_IMM_OP( 5, addi, 0xfffff800, 0x00000000, 0x800 ); 25 | TEST_IMM_OP( 6, addi, 0x80000000, 0x80000000, 0x000 ); 26 | TEST_IMM_OP( 7, addi, 0x7ffff800, 0x80000000, 0x800 ); 27 | 28 | TEST_IMM_OP( 8, addi, 0x000007ff, 0x00000000, 0x7ff ); 29 | TEST_IMM_OP( 9, addi, 0x7fffffff, 0x7fffffff, 0x000 ); 30 | TEST_IMM_OP( 10, addi, 0x800007fe, 0x7fffffff, 0x7ff ); 31 | 32 | TEST_IMM_OP( 11, addi, 0x800007ff, 0x80000000, 0x7ff ); 33 | TEST_IMM_OP( 12, addi, 0x7ffff7ff, 0x7fffffff, 0x800 ); 34 | 35 | TEST_IMM_OP( 13, addi, 0xffffffff, 0x00000000, 0xfff ); 36 | TEST_IMM_OP( 14, addi, 0x00000000, 0xffffffff, 0x001 ); 37 | TEST_IMM_OP( 15, addi, 0xfffffffe, 0xffffffff, 0xfff ); 38 | 39 | TEST_IMM_OP( 16, addi, 0x80000000, 0x7fffffff, 0x001 ); 40 | 41 | #------------------------------------------------------------- 42 | # Source/Destination tests 43 | #------------------------------------------------------------- 44 | 45 | TEST_IMM_SRC1_EQ_DEST( 17, addi, 24, 13, 11 ); 46 | 47 | #------------------------------------------------------------- 48 | # Bypassing tests 49 | #------------------------------------------------------------- 50 | 51 | TEST_IMM_DEST_BYPASS( 18, 0, addi, 24, 13, 11 ); 52 | TEST_IMM_DEST_BYPASS( 19, 1, addi, 23, 13, 10 ); 53 | TEST_IMM_DEST_BYPASS( 20, 2, addi, 22, 13, 9 ); 54 | 55 | TEST_IMM_SRC1_BYPASS( 21, 0, addi, 24, 13, 11 ); 56 | TEST_IMM_SRC1_BYPASS( 22, 1, addi, 23, 13, 10 ); 57 | TEST_IMM_SRC1_BYPASS( 23, 2, addi, 22, 13, 9 ); 58 | 59 | TEST_IMM_ZEROSRC1( 24, addi, 32, 32 ); 60 | TEST_IMM_ZERODEST( 25, addi, 33, 50 ); 61 | 62 | TEST_PASSFAIL 63 | 64 | RVTEST_CODE_END 65 | 66 | .data 67 | RVTEST_DATA_BEGIN 68 | 69 | TEST_DATA 70 | 71 | RVTEST_DATA_END 72 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amoadd_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amoadd_w.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amoadd.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amoadd.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0x000000007ffff800, lw a5, 0(a3)) 25 | 26 | # try again after a cache miss 27 | TEST_CASE(4, a4, 0x000000007ffff800, \ 28 | li a1, 0xffffffff80000000; \ 29 | amoadd.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0xfffffffffffff800, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amoand_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amoand.w.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amoand.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amoand.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3)) 25 | 26 | # try again after a cache miss 27 | TEST_CASE(4, a4, 0xffffffff80000000, \ 28 | li a1, 0x0000000080000000; \ 29 | amoand.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0xffffffff80000000, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amomax_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amomax_d.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amomax.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amomax.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3)) 25 | 26 | TEST_CASE(4, a4, 0, \ 27 | li a1, 1; \ 28 | sw x0, 0(a3); \ 29 | amomax.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 1, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amomaxu_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amomaxu_d.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amomaxu.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amomaxu.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3)) 25 | 26 | TEST_CASE(4, a4, 0, \ 27 | li a1, 0xffffffffffffffff; \ 28 | sw x0, 0(a3); \ 29 | amomaxu.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0xffffffffffffffff, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amomin_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amomin_d.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amomin.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amomin.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3)) 25 | 26 | TEST_CASE(4, a4, 0, \ 27 | li a1, 0xffffffffffffffff; \ 28 | sw x0, 0(a3); \ 29 | amomin.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0xffffffffffffffff, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amominu_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amominu_d.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amominu.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amominu.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0xffffffff80000000, lw a5, 0(a3)) 25 | 26 | TEST_CASE(4, a4, 0, \ 27 | li a1, 0xffffffffffffffff; \ 28 | sw x0, 0(a3); \ 29 | amominu.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | 50 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amoor_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amoor.w.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amoor.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amoor.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3)) 25 | 26 | # try again after a cache miss 27 | TEST_CASE(4, a4, 0xfffffffffffff800, \ 28 | li a1, 1; \ 29 | amoor.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0xfffffffffffff801, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amoswap_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amoswap_w.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amoswap.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amoswap.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0xfffffffffffff800, lw a5, 0(a3)) 25 | 26 | # try again after a cache miss 27 | TEST_CASE(4, a4, 0xfffffffffffff800, \ 28 | li a1, 0x0000000080000000; \ 29 | amoswap.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0xffffffff80000000, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/amoxor_w.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # amoxor_w.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test amoxor.w instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a4, 0xffffffff80000000, \ 17 | li a0, 0xffffffff80000000; \ 18 | li a1, 0xfffffffffffff800; \ 19 | la a3, amo_operand; \ 20 | sw a0, 0(a3); \ 21 | amoxor.w a4, a1, 0(a3); \ 22 | ) 23 | 24 | TEST_CASE(3, a5, 0x7ffff800, lw a5, 0(a3)) 25 | 26 | # try again after a cache miss 27 | TEST_CASE(4, a4, 0x7ffff800, \ 28 | li a1, 0xc0000001; \ 29 | amoxor.w a4, a1, 0(a3); \ 30 | ) 31 | 32 | TEST_CASE(5, a5, 0xffffffffbffff801, lw a5, 0(a3)) 33 | 34 | TEST_PASSFAIL 35 | 36 | RVTEST_CODE_END 37 | 38 | .data 39 | RVTEST_DATA_BEGIN 40 | 41 | TEST_DATA 42 | 43 | RVTEST_DATA_END 44 | 45 | .bss 46 | .align 3 47 | amo_operand: 48 | .dword 0 49 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/andi.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # andi.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test andi instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Logical tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_IMM_OP( 2, andi, 0xff00ff00, 0xff00ff00, 0xf0f ); 21 | TEST_IMM_OP( 3, andi, 0x000000f0, 0x0ff00ff0, 0x0f0 ); 22 | TEST_IMM_OP( 4, andi, 0x0000000f, 0x00ff00ff, 0x70f ); 23 | TEST_IMM_OP( 5, andi, 0x00000000, 0xf00ff00f, 0x0f0 ); 24 | 25 | #------------------------------------------------------------- 26 | # Source/Destination tests 27 | #------------------------------------------------------------- 28 | 29 | TEST_IMM_SRC1_EQ_DEST( 6, andi, 0x00000000, 0xff00ff00, 0x0f0 ); 30 | 31 | #------------------------------------------------------------- 32 | # Bypassing tests 33 | #------------------------------------------------------------- 34 | 35 | TEST_IMM_DEST_BYPASS( 7, 0, andi, 0x00000700, 0x0ff00ff0, 0x70f ); 36 | TEST_IMM_DEST_BYPASS( 8, 1, andi, 0x000000f0, 0x00ff00ff, 0x0f0 ); 37 | TEST_IMM_DEST_BYPASS( 9, 2, andi, 0xf00ff00f, 0xf00ff00f, 0xf0f ); 38 | 39 | TEST_IMM_SRC1_BYPASS( 10, 0, andi, 0x00000700, 0x0ff00ff0, 0x70f ); 40 | TEST_IMM_SRC1_BYPASS( 11, 1, andi, 0x000000f0, 0x00ff00ff, 0x0f0 ); 41 | TEST_IMM_SRC1_BYPASS( 12, 2, andi, 0x0000000f, 0xf00ff00f, 0x70f ); 42 | 43 | TEST_IMM_ZEROSRC1( 13, andi, 0, 0x0f0 ); 44 | TEST_IMM_ZERODEST( 14, andi, 0x00ff00ff, 0x70f ); 45 | 46 | TEST_PASSFAIL 47 | 48 | RVTEST_CODE_END 49 | 50 | .data 51 | RVTEST_DATA_BEGIN 52 | 53 | TEST_DATA 54 | 55 | RVTEST_DATA_END 56 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/auipc.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # auipc.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test auipc instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | TEST_CASE(2, a0, 10000, \ 17 | .align 3; \ 18 | lla a0, 1f + 10000; \ 19 | jal a1, 1f; \ 20 | 1: sub a0, a0, a1; \ 21 | ) 22 | 23 | TEST_CASE(3, a0, -10000, \ 24 | .align 3; \ 25 | lla a0, 1f - 10000; \ 26 | jal a1, 1f; \ 27 | 1: sub a0, a0, a1; \ 28 | ) 29 | 30 | TEST_PASSFAIL 31 | 32 | RVTEST_CODE_END 33 | 34 | .data 35 | RVTEST_DATA_BEGIN 36 | 37 | TEST_DATA 38 | 39 | RVTEST_DATA_END 40 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/beq.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # beq.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test beq instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Branch tests 18 | #------------------------------------------------------------- 19 | 20 | # Each test checks both forward and backward branches 21 | 22 | TEST_BR2_OP_TAKEN( 2, beq, 0, 0 ); 23 | TEST_BR2_OP_TAKEN( 3, beq, 1, 1 ); 24 | TEST_BR2_OP_TAKEN( 4, beq, -1, -1 ); 25 | 26 | TEST_BR2_OP_NOTTAKEN( 5, beq, 0, 1 ); 27 | TEST_BR2_OP_NOTTAKEN( 6, beq, 1, 0 ); 28 | TEST_BR2_OP_NOTTAKEN( 7, beq, -1, 1 ); 29 | TEST_BR2_OP_NOTTAKEN( 8, beq, 1, -1 ); 30 | 31 | #------------------------------------------------------------- 32 | # Bypassing tests 33 | #------------------------------------------------------------- 34 | 35 | TEST_BR2_SRC12_BYPASS( 9, 0, 0, beq, 0, -1 ); 36 | TEST_BR2_SRC12_BYPASS( 10, 0, 1, beq, 0, -1 ); 37 | TEST_BR2_SRC12_BYPASS( 11, 0, 2, beq, 0, -1 ); 38 | TEST_BR2_SRC12_BYPASS( 12, 1, 0, beq, 0, -1 ); 39 | TEST_BR2_SRC12_BYPASS( 13, 1, 1, beq, 0, -1 ); 40 | TEST_BR2_SRC12_BYPASS( 14, 2, 0, beq, 0, -1 ); 41 | 42 | TEST_BR2_SRC12_BYPASS( 15, 0, 0, beq, 0, -1 ); 43 | TEST_BR2_SRC12_BYPASS( 16, 0, 1, beq, 0, -1 ); 44 | TEST_BR2_SRC12_BYPASS( 17, 0, 2, beq, 0, -1 ); 45 | TEST_BR2_SRC12_BYPASS( 18, 1, 0, beq, 0, -1 ); 46 | TEST_BR2_SRC12_BYPASS( 19, 1, 1, beq, 0, -1 ); 47 | TEST_BR2_SRC12_BYPASS( 20, 2, 0, beq, 0, -1 ); 48 | 49 | #------------------------------------------------------------- 50 | # Test delay slot instructions not executed nor bypassed 51 | #------------------------------------------------------------- 52 | 53 | TEST_CASE( 21, x1, 3, \ 54 | li x1, 1; \ 55 | beq x0, x0, 1f; \ 56 | addi x1, x1, 1; \ 57 | addi x1, x1, 1; \ 58 | addi x1, x1, 1; \ 59 | addi x1, x1, 1; \ 60 | 1: addi x1, x1, 1; \ 61 | addi x1, x1, 1; \ 62 | ) 63 | 64 | TEST_PASSFAIL 65 | 66 | RVTEST_CODE_END 67 | 68 | .data 69 | RVTEST_DATA_BEGIN 70 | 71 | TEST_DATA 72 | 73 | RVTEST_DATA_END 74 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/bge.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # bge.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test bge instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Branch tests 18 | #------------------------------------------------------------- 19 | 20 | # Each test checks both forward and backward branches 21 | 22 | TEST_BR2_OP_TAKEN( 2, bge, 0, 0 ); 23 | TEST_BR2_OP_TAKEN( 3, bge, 1, 1 ); 24 | TEST_BR2_OP_TAKEN( 4, bge, -1, -1 ); 25 | TEST_BR2_OP_TAKEN( 5, bge, 1, 0 ); 26 | TEST_BR2_OP_TAKEN( 6, bge, 1, -1 ); 27 | TEST_BR2_OP_TAKEN( 7, bge, -1, -2 ); 28 | 29 | TEST_BR2_OP_NOTTAKEN( 8, bge, 0, 1 ); 30 | TEST_BR2_OP_NOTTAKEN( 9, bge, -1, 1 ); 31 | TEST_BR2_OP_NOTTAKEN( 10, bge, -2, -1 ); 32 | TEST_BR2_OP_NOTTAKEN( 11, bge, -2, 1 ); 33 | 34 | #------------------------------------------------------------- 35 | # Bypassing tests 36 | #------------------------------------------------------------- 37 | 38 | TEST_BR2_SRC12_BYPASS( 12, 0, 0, bge, -1, 0 ); 39 | TEST_BR2_SRC12_BYPASS( 13, 0, 1, bge, -1, 0 ); 40 | TEST_BR2_SRC12_BYPASS( 14, 0, 2, bge, -1, 0 ); 41 | TEST_BR2_SRC12_BYPASS( 15, 1, 0, bge, -1, 0 ); 42 | TEST_BR2_SRC12_BYPASS( 16, 1, 1, bge, -1, 0 ); 43 | TEST_BR2_SRC12_BYPASS( 17, 2, 0, bge, -1, 0 ); 44 | 45 | TEST_BR2_SRC12_BYPASS( 18, 0, 0, bge, -1, 0 ); 46 | TEST_BR2_SRC12_BYPASS( 19, 0, 1, bge, -1, 0 ); 47 | TEST_BR2_SRC12_BYPASS( 20, 0, 2, bge, -1, 0 ); 48 | TEST_BR2_SRC12_BYPASS( 21, 1, 0, bge, -1, 0 ); 49 | TEST_BR2_SRC12_BYPASS( 22, 1, 1, bge, -1, 0 ); 50 | TEST_BR2_SRC12_BYPASS( 23, 2, 0, bge, -1, 0 ); 51 | 52 | #------------------------------------------------------------- 53 | # Test delay slot instructions not executed nor bypassed 54 | #------------------------------------------------------------- 55 | 56 | TEST_CASE( 24, x1, 3, \ 57 | li x1, 1; \ 58 | bge x1, x0, 1f; \ 59 | addi x1, x1, 1; \ 60 | addi x1, x1, 1; \ 61 | addi x1, x1, 1; \ 62 | addi x1, x1, 1; \ 63 | 1: addi x1, x1, 1; \ 64 | addi x1, x1, 1; \ 65 | ) 66 | 67 | TEST_PASSFAIL 68 | 69 | RVTEST_CODE_END 70 | 71 | .data 72 | RVTEST_DATA_BEGIN 73 | 74 | TEST_DATA 75 | 76 | RVTEST_DATA_END 77 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/blt.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # blt.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test blt instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Branch tests 18 | #------------------------------------------------------------- 19 | 20 | # Each test checks both forward and backward branches 21 | 22 | TEST_BR2_OP_TAKEN( 2, blt, 0, 1 ); 23 | TEST_BR2_OP_TAKEN( 3, blt, -1, 1 ); 24 | TEST_BR2_OP_TAKEN( 4, blt, -2, -1 ); 25 | 26 | TEST_BR2_OP_NOTTAKEN( 5, blt, 1, 0 ); 27 | TEST_BR2_OP_NOTTAKEN( 6, blt, 1, -1 ); 28 | TEST_BR2_OP_NOTTAKEN( 7, blt, -1, -2 ); 29 | TEST_BR2_OP_NOTTAKEN( 8, blt, 1, -2 ); 30 | 31 | #------------------------------------------------------------- 32 | # Bypassing tests 33 | #------------------------------------------------------------- 34 | 35 | TEST_BR2_SRC12_BYPASS( 9, 0, 0, blt, 0, -1 ); 36 | TEST_BR2_SRC12_BYPASS( 10, 0, 1, blt, 0, -1 ); 37 | TEST_BR2_SRC12_BYPASS( 11, 0, 2, blt, 0, -1 ); 38 | TEST_BR2_SRC12_BYPASS( 12, 1, 0, blt, 0, -1 ); 39 | TEST_BR2_SRC12_BYPASS( 13, 1, 1, blt, 0, -1 ); 40 | TEST_BR2_SRC12_BYPASS( 14, 2, 0, blt, 0, -1 ); 41 | 42 | TEST_BR2_SRC12_BYPASS( 15, 0, 0, blt, 0, -1 ); 43 | TEST_BR2_SRC12_BYPASS( 16, 0, 1, blt, 0, -1 ); 44 | TEST_BR2_SRC12_BYPASS( 17, 0, 2, blt, 0, -1 ); 45 | TEST_BR2_SRC12_BYPASS( 18, 1, 0, blt, 0, -1 ); 46 | TEST_BR2_SRC12_BYPASS( 19, 1, 1, blt, 0, -1 ); 47 | TEST_BR2_SRC12_BYPASS( 20, 2, 0, blt, 0, -1 ); 48 | 49 | #------------------------------------------------------------- 50 | # Test delay slot instructions not executed nor bypassed 51 | #------------------------------------------------------------- 52 | 53 | TEST_CASE( 21, x1, 3, \ 54 | li x1, 1; \ 55 | blt x0, x1, 1f; \ 56 | addi x1, x1, 1; \ 57 | addi x1, x1, 1; \ 58 | addi x1, x1, 1; \ 59 | addi x1, x1, 1; \ 60 | 1: addi x1, x1, 1; \ 61 | addi x1, x1, 1; \ 62 | ) 63 | 64 | TEST_PASSFAIL 65 | 66 | RVTEST_CODE_END 67 | 68 | .data 69 | RVTEST_DATA_BEGIN 70 | 71 | TEST_DATA 72 | 73 | RVTEST_DATA_END 74 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/bne.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # bne.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test bne instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Branch tests 18 | #------------------------------------------------------------- 19 | 20 | # Each test checks both forward and backward branches 21 | 22 | TEST_BR2_OP_TAKEN( 2, bne, 0, 1 ); 23 | TEST_BR2_OP_TAKEN( 3, bne, 1, 0 ); 24 | TEST_BR2_OP_TAKEN( 4, bne, -1, 1 ); 25 | TEST_BR2_OP_TAKEN( 5, bne, 1, -1 ); 26 | 27 | TEST_BR2_OP_NOTTAKEN( 6, bne, 0, 0 ); 28 | TEST_BR2_OP_NOTTAKEN( 7, bne, 1, 1 ); 29 | TEST_BR2_OP_NOTTAKEN( 8, bne, -1, -1 ); 30 | 31 | #------------------------------------------------------------- 32 | # Bypassing tests 33 | #------------------------------------------------------------- 34 | 35 | TEST_BR2_SRC12_BYPASS( 9, 0, 0, bne, 0, 0 ); 36 | TEST_BR2_SRC12_BYPASS( 10, 0, 1, bne, 0, 0 ); 37 | TEST_BR2_SRC12_BYPASS( 11, 0, 2, bne, 0, 0 ); 38 | TEST_BR2_SRC12_BYPASS( 12, 1, 0, bne, 0, 0 ); 39 | TEST_BR2_SRC12_BYPASS( 13, 1, 1, bne, 0, 0 ); 40 | TEST_BR2_SRC12_BYPASS( 14, 2, 0, bne, 0, 0 ); 41 | 42 | TEST_BR2_SRC12_BYPASS( 15, 0, 0, bne, 0, 0 ); 43 | TEST_BR2_SRC12_BYPASS( 16, 0, 1, bne, 0, 0 ); 44 | TEST_BR2_SRC12_BYPASS( 17, 0, 2, bne, 0, 0 ); 45 | TEST_BR2_SRC12_BYPASS( 18, 1, 0, bne, 0, 0 ); 46 | TEST_BR2_SRC12_BYPASS( 19, 1, 1, bne, 0, 0 ); 47 | TEST_BR2_SRC12_BYPASS( 20, 2, 0, bne, 0, 0 ); 48 | 49 | #------------------------------------------------------------- 50 | # Test delay slot instructions not executed nor bypassed 51 | #------------------------------------------------------------- 52 | 53 | TEST_CASE( 21, x1, 3, \ 54 | li x1, 1; \ 55 | bne x1, x0, 1f; \ 56 | addi x1, x1, 1; \ 57 | addi x1, x1, 1; \ 58 | addi x1, x1, 1; \ 59 | addi x1, x1, 1; \ 60 | 1: addi x1, x1, 1; \ 61 | addi x1, x1, 1; \ 62 | ) 63 | 64 | TEST_PASSFAIL 65 | 66 | RVTEST_CODE_END 67 | 68 | .data 69 | RVTEST_DATA_BEGIN 70 | 71 | TEST_DATA 72 | 73 | RVTEST_DATA_END 74 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/div.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # div.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test div instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_RR_OP( 2, div, 3, 20, 6 ); # OK 21 | TEST_RR_OP( 3, div, -3, -20, 6 ); # OK 22 | TEST_RR_OP( 4, div, -3, 20, -6 ); # OK 23 | TEST_RR_OP( 5, div, 3, -20, -6 ); # OK 24 | 25 | TEST_RR_OP( 6, div, -1<<31, -1<<31, 1 ); # this failed 26 | TEST_RR_OP( 7, div, -1<<31, -1<<31, -1 ); # failed 27 | 28 | #TEST_RR_OP( 8, div, -1, -1<<31, 0 ) # failed 29 | TEST_RR_OP( 9, div, -1, 1, 0 ); # OK 30 | TEST_RR_OP(10, div, -1, 0, 0 ); # OK 31 | 32 | TEST_PASSFAIL 33 | 34 | RVTEST_CODE_END 35 | 36 | .data 37 | RVTEST_DATA_BEGIN 38 | 39 | TEST_DATA 40 | 41 | RVTEST_DATA_END 42 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/divu.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # divu.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test divu instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_RR_OP( 2, divu, 3, 20, 6 ); 21 | TEST_RR_OP( 3, divu, 715827879, -20, 6 ); 22 | TEST_RR_OP( 4, divu, 0, 20, -6 ); 23 | TEST_RR_OP( 5, divu, 0, -20, -6 ); 24 | 25 | TEST_RR_OP( 6, divu, -1<<31, -1<<31, 1 ); 26 | TEST_RR_OP( 7, divu, 0, -1<<31, -1 ); 27 | 28 | TEST_RR_OP( 8, divu, -1, -1<<31, 0 ); 29 | TEST_RR_OP( 9, divu, -1, 1, 0 ); 30 | TEST_RR_OP(10, divu, -1, 0, 0 ); 31 | 32 | TEST_PASSFAIL 33 | 34 | RVTEST_CODE_END 35 | 36 | .data 37 | RVTEST_DATA_BEGIN 38 | 39 | TEST_DATA 40 | 41 | RVTEST_DATA_END 42 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/j.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # j.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test j instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Test basic 18 | #------------------------------------------------------------- 19 | 20 | li TESTNUM, 2; 21 | j test_2; 22 | j fail; 23 | test_2: 24 | 25 | #------------------------------------------------------------- 26 | # Test delay slot instructions not executed nor bypassed 27 | #------------------------------------------------------------- 28 | 29 | TEST_CASE( 3, x1, 3, \ 30 | li x1, 1; \ 31 | j 1f; \ 32 | addi x1, x1, 1; \ 33 | addi x1, x1, 1; \ 34 | addi x1, x1, 1; \ 35 | addi x1, x1, 1; \ 36 | 1: addi x1, x1, 1; \ 37 | addi x1, x1, 1; \ 38 | ) 39 | 40 | TEST_PASSFAIL 41 | 42 | RVTEST_CODE_END 43 | 44 | .data 45 | RVTEST_DATA_BEGIN 46 | 47 | TEST_DATA 48 | 49 | RVTEST_DATA_END 50 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/jal.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # jal.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test jal instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | .option norvc 14 | 15 | RVTEST_RV32U 16 | RVTEST_CODE_BEGIN 17 | 18 | #------------------------------------------------------------- 19 | # Test 2: Basic test 20 | #------------------------------------------------------------- 21 | 22 | test_2: 23 | li TESTNUM, 2 24 | li ra, 0 25 | 26 | linkaddr_2: 27 | jal target_2 28 | nop 29 | nop 30 | 31 | j fail 32 | 33 | target_2: 34 | la x2, linkaddr_2 35 | addi x2, x2, 4 36 | bne x2, ra, fail 37 | 38 | #------------------------------------------------------------- 39 | # Test delay slot instructions not executed nor bypassed 40 | #------------------------------------------------------------- 41 | 42 | TEST_CASE( 3, x2, 3, \ 43 | li x2, 1; \ 44 | jal 1f; \ 45 | addi x2, x2, 1; \ 46 | addi x2, x2, 1; \ 47 | addi x2, x2, 1; \ 48 | addi x2, x2, 1; \ 49 | 1: addi x2, x2, 1; \ 50 | addi x2, x2, 1; \ 51 | ) 52 | 53 | TEST_PASSFAIL 54 | 55 | RVTEST_CODE_END 56 | 57 | .data 58 | RVTEST_DATA_BEGIN 59 | 60 | TEST_DATA 61 | 62 | RVTEST_DATA_END 63 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/jalr.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # jalr.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test jalr instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | .option norvc 14 | 15 | RVTEST_RV32U 16 | RVTEST_CODE_BEGIN 17 | 18 | #------------------------------------------------------------- 19 | # Test 2: Basic test 20 | #------------------------------------------------------------- 21 | 22 | test_2: 23 | li TESTNUM, 2 24 | li x31, 0 25 | la x2, target_2 26 | 27 | linkaddr_2: 28 | jalr x19, x2, 0 29 | nop 30 | nop 31 | 32 | j fail 33 | 34 | target_2: 35 | la x1, linkaddr_2 36 | addi x1, x1, 4 37 | bne x1, x19, fail 38 | 39 | #------------------------------------------------------------- 40 | # Test 3: Check r0 target and that r31 is not modified 41 | #------------------------------------------------------------- 42 | 43 | test_3: 44 | li TESTNUM, 3 45 | li x31, 0 46 | la x3, target_3 47 | 48 | linkaddr_3: 49 | jalr x0, x3, 0 50 | nop 51 | 52 | j fail 53 | 54 | target_3: 55 | bne x31, x0, fail 56 | 57 | #------------------------------------------------------------- 58 | # Bypassing tests 59 | #------------------------------------------------------------- 60 | 61 | TEST_JALR_SRC1_BYPASS( 4, 0, jalr ); 62 | TEST_JALR_SRC1_BYPASS( 5, 1, jalr ); 63 | TEST_JALR_SRC1_BYPASS( 6, 2, jalr ); 64 | 65 | #------------------------------------------------------------- 66 | # Test delay slot instructions not executed nor bypassed 67 | #------------------------------------------------------------- 68 | 69 | TEST_CASE( 7, x1, 4, \ 70 | li x1, 1; \ 71 | la x2, 1f; 72 | jalr x19, x2, -4; \ 73 | addi x1, x1, 1; \ 74 | addi x1, x1, 1; \ 75 | addi x1, x1, 1; \ 76 | addi x1, x1, 1; \ 77 | 1: addi x1, x1, 1; \ 78 | addi x1, x1, 1; \ 79 | ) 80 | 81 | TEST_PASSFAIL 82 | 83 | RVTEST_CODE_END 84 | 85 | .data 86 | RVTEST_DATA_BEGIN 87 | 88 | TEST_DATA 89 | 90 | RVTEST_DATA_END 91 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/lui.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # lui.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test lui instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Basic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_CASE( 2, x1, 0x00000000, lui x1, 0x00000 ); 21 | TEST_CASE( 3, x1, 0xfffff800, lui x1, 0xfffff;sra x1,x1,1); 22 | TEST_CASE( 4, x1, 0x000007ff, lui x1, 0x7ffff;sra x1,x1,20); 23 | TEST_CASE( 5, x1, 0xfffff800, lui x1, 0x80000;sra x1,x1,20); 24 | 25 | TEST_CASE( 6, x0, 0, lui x0, 0x80000 ); 26 | 27 | TEST_PASSFAIL 28 | 29 | RVTEST_CODE_END 30 | 31 | .data 32 | RVTEST_DATA_BEGIN 33 | 34 | TEST_DATA 35 | 36 | RVTEST_DATA_END 37 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/mcsr.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # mcsr.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test various M-mode CSRs. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32M 14 | RVTEST_CODE_BEGIN 15 | 16 | # Check that mcpuid reports the correct XLEN 17 | #if __riscv_xlen == 64 18 | TEST_CASE(2, a0, 0x2, csrr a0, misa; srl a0, a0, 62) 19 | #else 20 | TEST_CASE(2, a0, 0x1, csrr a0, misa; srl a0, a0, 30) 21 | #endif 22 | 23 | # Check that mhartid reports 0 24 | TEST_CASE(3, a0, 0x0, csrr a0, mhartid) 25 | 26 | # Check that reading the following CSRs doesn't cause an exception 27 | csrr a0, mimpid 28 | csrr a0, marchid 29 | csrr a0, mvendorid 30 | 31 | # Check that writing the following CSRs doesn't cause an exception 32 | li t0, 0 33 | csrs mtvec, t0 34 | csrs mepc, t0 35 | 36 | TEST_PASSFAIL 37 | 38 | RVTEST_CODE_END 39 | 40 | .data 41 | RVTEST_DATA_BEGIN 42 | 43 | TEST_DATA 44 | 45 | RVTEST_DATA_END 46 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/ori.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # ori.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test ori instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Logical tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_IMM_OP( 2, ori, 0xffffff0f, 0xff00ff00, 0xf0f ); 21 | TEST_IMM_OP( 3, ori, 0x0ff00ff0, 0x0ff00ff0, 0x0f0 ); 22 | TEST_IMM_OP( 4, ori, 0x00ff07ff, 0x00ff00ff, 0x70f ); 23 | TEST_IMM_OP( 5, ori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 ); 24 | 25 | #------------------------------------------------------------- 26 | # Source/Destination tests 27 | #------------------------------------------------------------- 28 | 29 | TEST_IMM_SRC1_EQ_DEST( 6, ori, 0xff00fff0, 0xff00ff00, 0x0f0 ); 30 | 31 | #------------------------------------------------------------- 32 | # Bypassing tests 33 | #------------------------------------------------------------- 34 | 35 | TEST_IMM_DEST_BYPASS( 7, 0, ori, 0x0ff00ff0, 0x0ff00ff0, 0x0f0 ); 36 | TEST_IMM_DEST_BYPASS( 8, 1, ori, 0x00ff07ff, 0x00ff00ff, 0x70f ); 37 | TEST_IMM_DEST_BYPASS( 9, 2, ori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 ); 38 | 39 | TEST_IMM_SRC1_BYPASS( 10, 0, ori, 0x0ff00ff0, 0x0ff00ff0, 0x0f0 ); 40 | TEST_IMM_SRC1_BYPASS( 11, 1, ori, 0xffffffff, 0x00ff00ff, 0xf0f ); 41 | TEST_IMM_SRC1_BYPASS( 12, 2, ori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 ); 42 | 43 | TEST_IMM_ZEROSRC1( 13, ori, 0x0f0, 0x0f0 ); 44 | TEST_IMM_ZERODEST( 14, ori, 0x00ff00ff, 0x70f ); 45 | 46 | TEST_PASSFAIL 47 | 48 | RVTEST_CODE_END 49 | 50 | .data 51 | RVTEST_DATA_BEGIN 52 | 53 | TEST_DATA 54 | 55 | RVTEST_DATA_END 56 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/rem.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # rem.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test rem instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_RR_OP( 2, rem, 2, 20, 6 ); # OK 21 | TEST_RR_OP( 3, rem, -2, -20, 6 ); # OK 22 | TEST_RR_OP( 4, rem, 2, 20, -6 ); # OK 23 | TEST_RR_OP( 5, rem, -2, -20, -6 ); # OK 24 | 25 | TEST_RR_OP( 6, rem, 0, -1<<31, 1 ); # ERROR 26 | TEST_RR_OP( 7, rem, 0, -1<<31, -1 ); # OK 27 | 28 | TEST_RR_OP( 8, rem, -1<<31, -1<<31, 0 ); # OK 29 | TEST_RR_OP( 9, rem, 1, 1, 0 ); # OK 30 | TEST_RR_OP(10, rem, 0, 0, 0 ); # OK 31 | 32 | TEST_PASSFAIL 33 | 34 | RVTEST_CODE_END 35 | 36 | .data 37 | RVTEST_DATA_BEGIN 38 | 39 | TEST_DATA 40 | 41 | RVTEST_DATA_END 42 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/remu.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # remu.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test remu instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_RR_OP( 2, remu, 2, 20, 6 ); 21 | TEST_RR_OP( 3, remu, 2, -20, 6 ); 22 | TEST_RR_OP( 4, remu, 20, 20, -6 ); 23 | TEST_RR_OP( 5, remu, -20, -20, -6 ); 24 | 25 | TEST_RR_OP( 6, remu, 0, -1<<31, 1 ); 26 | TEST_RR_OP( 7, remu, -1<<31, -1<<31, -1 ); 27 | 28 | TEST_RR_OP( 8, remu, -1<<31, -1<<31, 0 ); 29 | TEST_RR_OP( 9, remu, 1, 1, 0 ); 30 | TEST_RR_OP(10, remu, 0, 0, 0 ); 31 | 32 | TEST_PASSFAIL 33 | 34 | RVTEST_CODE_END 35 | 36 | .data 37 | RVTEST_DATA_BEGIN 38 | 39 | TEST_DATA 40 | 41 | RVTEST_DATA_END 42 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/simple.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # simple.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # This is the most basic self checking test. If your simulator does not 8 | # pass thiss then there is little chance that it will pass any of the 9 | # more complicated self checking tests. 10 | # 11 | 12 | #include "riscv_test.h" 13 | #include "test_macros.h" 14 | 15 | RVTEST_RV32U 16 | RVTEST_CODE_BEGIN 17 | 18 | RVTEST_PASS 19 | 20 | RVTEST_CODE_END 21 | 22 | .data 23 | RVTEST_DATA_BEGIN 24 | 25 | TEST_DATA 26 | 27 | RVTEST_DATA_END 28 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/slli.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # slli.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test slli instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_IMM_OP( 2, slli, 0x00000001, 0x00000001, 0 ); 21 | TEST_IMM_OP( 3, slli, 0x00000002, 0x00000001, 1 ); 22 | TEST_IMM_OP( 4, slli, 0x00000080, 0x00000001, 7 ); 23 | TEST_IMM_OP( 5, slli, 0x00004000, 0x00000001, 14 ); 24 | TEST_IMM_OP( 6, slli, 0x80000000, 0x00000001, 31 ); 25 | 26 | TEST_IMM_OP( 7, slli, 0xffffffff, 0xffffffff, 0 ); 27 | TEST_IMM_OP( 8, slli, 0xfffffffe, 0xffffffff, 1 ); 28 | TEST_IMM_OP( 9, slli, 0xffffff80, 0xffffffff, 7 ); 29 | TEST_IMM_OP( 10, slli, 0xffffc000, 0xffffffff, 14 ); 30 | TEST_IMM_OP( 11, slli, 0x80000000, 0xffffffff, 31 ); 31 | 32 | TEST_IMM_OP( 12, slli, 0x21212121, 0x21212121, 0 ); 33 | TEST_IMM_OP( 13, slli, 0x42424242, 0x21212121, 1 ); 34 | TEST_IMM_OP( 14, slli, 0x90909080, 0x21212121, 7 ); 35 | TEST_IMM_OP( 15, slli, 0x48484000, 0x21212121, 14 ); 36 | TEST_IMM_OP( 16, slli, 0x80000000, 0x21212121, 31 ); 37 | 38 | #------------------------------------------------------------- 39 | # Source/Destination tests 40 | #------------------------------------------------------------- 41 | 42 | TEST_IMM_SRC1_EQ_DEST( 17, slli, 0x00000080, 0x00000001, 7 ); 43 | 44 | #------------------------------------------------------------- 45 | # Bypassing tests 46 | #------------------------------------------------------------- 47 | 48 | TEST_IMM_DEST_BYPASS( 18, 0, slli, 0x00000080, 0x00000001, 7 ); 49 | TEST_IMM_DEST_BYPASS( 19, 1, slli, 0x00004000, 0x00000001, 14 ); 50 | TEST_IMM_DEST_BYPASS( 20, 2, slli, 0x80000000, 0x00000001, 31 ); 51 | 52 | TEST_IMM_SRC1_BYPASS( 21, 0, slli, 0x00000080, 0x00000001, 7 ); 53 | TEST_IMM_SRC1_BYPASS( 22, 1, slli, 0x00004000, 0x00000001, 14 ); 54 | TEST_IMM_SRC1_BYPASS( 23, 2, slli, 0x80000000, 0x00000001, 31 ); 55 | 56 | TEST_IMM_ZEROSRC1( 24, slli, 0, 31 ); 57 | TEST_IMM_ZERODEST( 25, slli, 33, 20 ); 58 | 59 | TEST_PASSFAIL 60 | 61 | RVTEST_CODE_END 62 | 63 | .data 64 | RVTEST_DATA_BEGIN 65 | 66 | TEST_DATA 67 | 68 | RVTEST_DATA_END 69 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/slti.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # slti.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test slti instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | #define RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_IMM_OP( 2, slti, 0, 0x00000000, 0x000 ); 21 | TEST_IMM_OP( 3, slti, 0, 0x00000001, 0x001 ); 22 | TEST_IMM_OP( 4, slti, 1, 0x00000003, 0x007 ); 23 | TEST_IMM_OP( 5, slti, 0, 0x00000007, 0x003 ); 24 | 25 | TEST_IMM_OP( 6, slti, 0, 0x00000000, 0x800 ); 26 | TEST_IMM_OP( 7, slti, 1, 0x80000000, 0x000 ); 27 | TEST_IMM_OP( 8, slti, 1, 0x80000000, 0x800 ); 28 | 29 | TEST_IMM_OP( 9, slti, 1, 0x00000000, 0x7ff ); 30 | TEST_IMM_OP( 10, slti, 0, 0x7fffffff, 0x000 ); 31 | TEST_IMM_OP( 11, slti, 0, 0x7fffffff, 0x7ff ); 32 | 33 | TEST_IMM_OP( 12, slti, 1, 0x80000000, 0x7ff ); 34 | TEST_IMM_OP( 13, slti, 0, 0x7fffffff, 0x800 ); 35 | 36 | TEST_IMM_OP( 14, slti, 0, 0x00000000, 0xfff ); 37 | TEST_IMM_OP( 15, slti, 1, 0xffffffff, 0x001 ); 38 | TEST_IMM_OP( 16, slti, 0, 0xffffffff, 0xfff ); 39 | 40 | #------------------------------------------------------------- 41 | # Source/Destination tests 42 | #------------------------------------------------------------- 43 | 44 | TEST_IMM_SRC1_EQ_DEST( 17, sltiu, 1, 11, 13 ); 45 | 46 | #------------------------------------------------------------- 47 | # Bypassing tests 48 | #------------------------------------------------------------- 49 | 50 | TEST_IMM_DEST_BYPASS( 18, 0, slti, 0, 15, 10 ); 51 | TEST_IMM_DEST_BYPASS( 19, 1, slti, 1, 10, 16 ); 52 | TEST_IMM_DEST_BYPASS( 20, 2, slti, 0, 16, 9 ); 53 | 54 | TEST_IMM_SRC1_BYPASS( 21, 0, slti, 1, 11, 15 ); 55 | TEST_IMM_SRC1_BYPASS( 22, 1, slti, 0, 17, 8 ); 56 | TEST_IMM_SRC1_BYPASS( 23, 2, slti, 1, 12, 14 ); 57 | 58 | TEST_IMM_ZEROSRC1( 24, slti, 0, 0xfff ); 59 | TEST_IMM_ZERODEST( 25, slti, 0x00ff00ff, 0xfff ); 60 | 61 | TEST_PASSFAIL 62 | 63 | RVTEST_CODE_END 64 | 65 | .data 66 | RVTEST_DATA_BEGIN 67 | 68 | TEST_DATA 69 | 70 | RVTEST_DATA_END 71 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/sltiu.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #include "riscv_test.h" 4 | #include "test_macros.h" 5 | #define RVTEST_RV32U 6 | 7 | RVTEST_CODE_BEGIN 8 | 9 | #------------------------------------------------------------- 10 | # Arithmetic tests 11 | #------------------------------------------------------------- 12 | 13 | TEST_IMM_OP( 2, sltiu, 0, 0x0000000000000000, 0x000 ); 14 | TEST_IMM_OP( 3, sltiu, 0, 0x0000000000000001, 0x001 ); 15 | TEST_IMM_OP( 4, sltiu, 1, 0x0000000000000003, 0x007 ); 16 | TEST_IMM_OP( 5, sltiu, 0, 0x0000000000000007, 0x003 ); 17 | 18 | TEST_IMM_OP( 6, sltiu, 1, 0x0000000000000000, 0x800 ); 19 | TEST_IMM_OP( 7, sltiu, 0, 0xffffffff80000000, 0x000 ); 20 | TEST_IMM_OP( 8, sltiu, 1, 0xffffffff80000000, 0x800 ); 21 | 22 | TEST_IMM_OP( 9, sltiu, 1, 0x0000000000000000, 0x7ff ); 23 | TEST_IMM_OP( 10, sltiu, 0, 0x000000007fffffff, 0x000 ); 24 | TEST_IMM_OP( 11, sltiu, 0, 0x000000007fffffff, 0x7ff ); 25 | 26 | TEST_IMM_OP( 12, sltiu, 0, 0xffffffff80000000, 0x7ff ); 27 | TEST_IMM_OP( 13, sltiu, 1, 0x000000007fffffff, 0x800 ); 28 | 29 | TEST_IMM_OP( 14, sltiu, 1, 0x0000000000000000, 0xfff ); 30 | TEST_IMM_OP( 15, sltiu, 0, 0xffffffffffffffff, 0x001 ); 31 | TEST_IMM_OP( 16, sltiu, 0, 0xffffffffffffffff, 0xfff ); 32 | 33 | #------------------------------------------------------------- 34 | # Source/Destination tests 35 | #------------------------------------------------------------- 36 | 37 | TEST_IMM_SRC1_EQ_DEST( 17, sltiu, 1, 11, 13 ); 38 | 39 | #------------------------------------------------------------- 40 | # Bypassing tests 41 | #------------------------------------------------------------- 42 | 43 | TEST_IMM_DEST_BYPASS( 18, 0, sltiu, 0, 15, 10 ); 44 | TEST_IMM_DEST_BYPASS( 19, 1, sltiu, 1, 10, 16 ); 45 | TEST_IMM_DEST_BYPASS( 20, 2, sltiu, 0, 16, 9 ); 46 | 47 | TEST_IMM_SRC1_BYPASS( 21, 0, sltiu, 1, 11, 15 ); 48 | TEST_IMM_SRC1_BYPASS( 22, 1, sltiu, 0, 17, 8 ); 49 | TEST_IMM_SRC1_BYPASS( 23, 2, sltiu, 1, 12, 14 ); 50 | 51 | TEST_IMM_ZEROSRC1( 24, sltiu, 1, 0xfff ); 52 | TEST_IMM_ZERODEST( 25, sltiu, 0x00ff00ff, 0xfff ); 53 | 54 | TEST_PASSFAIL 55 | 56 | RVTEST_CODE_END 57 | 58 | .data 59 | RVTEST_DATA_BEGIN 60 | 61 | TEST_DATA 62 | 63 | RVTEST_DATA_END 64 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/srai.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # srai.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test srai instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Arithmetic tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_IMM_OP( 2, srai, 0x00000000, 0x00000000, 0 ); 21 | TEST_IMM_OP( 3, srai, 0xc0000000, 0x80000000, 1 ); 22 | TEST_IMM_OP( 4, srai, 0xff000000, 0x80000000, 7 ); 23 | TEST_IMM_OP( 5, srai, 0xfffe0000, 0x80000000, 14 ); 24 | TEST_IMM_OP( 6, srai, 0xffffffff, 0x80000001, 31 ); 25 | 26 | TEST_IMM_OP( 7, srai, 0x7fffffff, 0x7fffffff, 0 ); 27 | TEST_IMM_OP( 8, srai, 0x3fffffff, 0x7fffffff, 1 ); 28 | TEST_IMM_OP( 9, srai, 0x00ffffff, 0x7fffffff, 7 ); 29 | TEST_IMM_OP( 10, srai, 0x0001ffff, 0x7fffffff, 14 ); 30 | TEST_IMM_OP( 11, srai, 0x00000000, 0x7fffffff, 31 ); 31 | 32 | TEST_IMM_OP( 12, srai, 0x81818181, 0x81818181, 0 ); 33 | TEST_IMM_OP( 13, srai, 0xc0c0c0c0, 0x81818181, 1 ); 34 | TEST_IMM_OP( 14, srai, 0xff030303, 0x81818181, 7 ); 35 | TEST_IMM_OP( 15, srai, 0xfffe0606, 0x81818181, 14 ); 36 | TEST_IMM_OP( 16, srai, 0xffffffff, 0x81818181, 31 ); 37 | 38 | #------------------------------------------------------------- 39 | # Source/Destination tests 40 | #------------------------------------------------------------- 41 | 42 | TEST_IMM_SRC1_EQ_DEST( 17, srai, 0xff000000, 0x80000000, 7 ); 43 | 44 | #------------------------------------------------------------- 45 | # Bypassing tests 46 | #------------------------------------------------------------- 47 | 48 | TEST_IMM_DEST_BYPASS( 18, 0, srai, 0xff000000, 0x80000000, 7 ); 49 | TEST_IMM_DEST_BYPASS( 19, 1, srai, 0xfffe0000, 0x80000000, 14 ); 50 | TEST_IMM_DEST_BYPASS( 20, 2, srai, 0xffffffff, 0x80000001, 31 ); 51 | 52 | TEST_IMM_SRC1_BYPASS( 21, 0, srai, 0xff000000, 0x80000000, 7 ); 53 | TEST_IMM_SRC1_BYPASS( 22, 1, srai, 0xfffe0000, 0x80000000, 14 ); 54 | TEST_IMM_SRC1_BYPASS( 23, 2, srai, 0xffffffff, 0x80000001, 31 ); 55 | 56 | TEST_IMM_ZEROSRC1( 24, srai, 0, 31 ); 57 | TEST_IMM_ZERODEST( 25, srai, 33, 20 ); 58 | # 59 | TEST_PASSFAIL 60 | 61 | RVTEST_CODE_END 62 | 63 | .data 64 | RVTEST_DATA_BEGIN 65 | 66 | TEST_DATA 67 | 68 | RVTEST_DATA_END 69 | -------------------------------------------------------------------------------- /software/tests/riscv_tests/xori.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #***************************************************************************** 4 | # xori.S 5 | #----------------------------------------------------------------------------- 6 | # 7 | # Test xori instruction. 8 | # 9 | 10 | #include "riscv_test.h" 11 | #include "test_macros.h" 12 | 13 | RVTEST_RV32U 14 | RVTEST_CODE_BEGIN 15 | 16 | #------------------------------------------------------------- 17 | # Logical tests 18 | #------------------------------------------------------------- 19 | 20 | TEST_IMM_OP( 2, xori, 0xff00f00f, 0x00ff0f00, 0xf0f ); 21 | TEST_IMM_OP( 3, xori, 0x0ff00f00, 0x0ff00ff0, 0x0f0 ); 22 | TEST_IMM_OP( 4, xori, 0x00ff0ff0, 0x00ff08ff, 0x70f ); 23 | TEST_IMM_OP( 5, xori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 ); 24 | 25 | #------------------------------------------------------------- 26 | # Source/Destination tests 27 | #------------------------------------------------------------- 28 | 29 | TEST_IMM_SRC1_EQ_DEST( 6, xori, 0xff00f00f, 0xff00f700, 0x70f ); 30 | 31 | #------------------------------------------------------------- 32 | # Bypassing tests 33 | #------------------------------------------------------------- 34 | 35 | TEST_IMM_DEST_BYPASS( 7, 0, xori, 0x0ff00f00, 0x0ff00ff0, 0x0f0 ); 36 | TEST_IMM_DEST_BYPASS( 8, 1, xori, 0x00ff0ff0, 0x00ff08ff, 0x70f ); 37 | TEST_IMM_DEST_BYPASS( 9, 2, xori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 ); 38 | 39 | TEST_IMM_SRC1_BYPASS( 10, 0, xori, 0x0ff00f00, 0x0ff00ff0, 0x0f0 ); 40 | TEST_IMM_SRC1_BYPASS( 11, 1, xori, 0x00ff0ff0, 0x00ff0fff, 0x00f ); 41 | TEST_IMM_SRC1_BYPASS( 12, 2, xori, 0xf00ff0ff, 0xf00ff00f, 0x0f0 ); 42 | 43 | TEST_IMM_ZEROSRC1( 13, xori, 0x0f0, 0x0f0 ); 44 | TEST_IMM_ZERODEST( 14, xori, 0x00ff00ff, 0x70f ); 45 | 46 | TEST_PASSFAIL 47 | 48 | RVTEST_CODE_END 49 | 50 | .data 51 | RVTEST_DATA_BEGIN 52 | 53 | TEST_DATA 54 | 55 | RVTEST_DATA_END 56 | -------------------------------------------------------------------------------- /software/uartboot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # File : uartboot.sh 3 | # License : GPL-3.0-or-later 4 | # Author : Peter Gu 5 | # Date : 2021.04.24 6 | # Last Modified Date: 2021.04.24 7 | 8 | if [ -z $1 ]; then 9 | echo "please specify target file" 10 | exit 0 11 | fi 12 | 13 | for i in `seq 0 9`; do 14 | if [ -e /dev/ttyUSB$i ]; then 15 | echo "reset board ..." 16 | echo 'RRRRRRRRRRR' > /dev/ttyUSB$i 17 | sync 18 | sleep 2 19 | echo 'Hope SD boot has finished' 20 | sleep 0.1 21 | echo "boot ..." 22 | echo 'x' > /dev/ttyUSB$9 23 | sync 24 | sleep 0.1 25 | echo "dump to /dev/ttyUSB$i ..." 26 | xxd -p $1 > /dev/ttyUSB$i 27 | echo ' ' > /dev/ttyUSB$i 28 | sync 29 | echo "done. " 30 | exit 0 31 | fi 32 | done 33 | echo 'no ttyUSB device found!' 34 | --------------------------------------------------------------------------------