├── LICENSE ├── README.md ├── Vivado Files ├── Cmod-S7-25-Master.xdc ├── run_vivado.tcl └── rv32i_soc.mcs ├── rtl ├── fwb_master.v ├── rv32i_alu.v ├── rv32i_basereg.v ├── rv32i_core.v ├── rv32i_csr.v ├── rv32i_decoder.v ├── rv32i_fetch.v ├── rv32i_forwarding.v ├── rv32i_header.vh ├── rv32i_memoryaccess.v └── rv32i_writeback.v └── test ├── entry.s ├── extra ├── add.s ├── addi.s ├── and.s ├── andi.s ├── auipc.s ├── beq.s ├── bge.s ├── bgeu.s ├── blt.s ├── bltu.s ├── bne.s ├── branch_hazard.s ├── csr_op.s ├── data_hazard.s ├── demo1.c ├── exceptions.s ├── helloworld.s ├── instret.s ├── interrupts.s ├── jal.s ├── jalr.s ├── lb.s ├── lbu.s ├── lh.s ├── lhu.s ├── lui.s ├── lw.s ├── no_hazard.s ├── or.s ├── ori.s ├── sb.s ├── sh.s ├── sll.s ├── slli.s ├── slt.s ├── slti.s ├── sltiu.s ├── sltu.s ├── sra.s ├── srai.s ├── srl.s ├── srli.s ├── sub.s ├── sw.s ├── test_gpio.c ├── test_hygro.c ├── test_hygro.c_backup ├── test_i2c.c ├── test_lcd.c ├── test_rtc.c_fpga ├── test_timer.c ├── test_uart.c ├── test_ultrasonic.c_fpga ├── ultrasonic_sensor.c ├── xor.s └── xori.s ├── freertos ├── FreeRTOSConfig.h ├── freertos.c ├── freertos_old.c ├── freertos_risc_v_chip_specific_extensions.h ├── main_blinky.c ├── mobile_app.aia └── mobile_app.apk ├── lib ├── clint.c ├── gpio.c ├── hygro_pmod.c ├── i2c.c ├── lcd.c ├── printf.c ├── rv32i.h ├── uart.c └── ultrasonic_sensor.c ├── rv32i_core.sby ├── rv32i_linkerscript.ld ├── rv32i_soc.v ├── rv32i_soc_TB.v ├── test.sh ├── wave.do └── wave.gtkw /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Angelo Jacobo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Vivado Files/Cmod-S7-25-Master.xdc: -------------------------------------------------------------------------------- 1 | ## To use it in a project: 2 | ## - uncomment the lines corresponding to used pins 3 | ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project 4 | 5 | ## 12 MHz System Clock 6 | set_property -dict {PACKAGE_PIN M9 IOSTANDARD LVCMOS33} [get_ports i_clk] 7 | create_clock -period 83.330 -name sys_clk_pin -waveform {0.000 41.660} -add [get_ports i_clk] 8 | 9 | ## Push Buttons 10 | set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33} [get_ports { i_rst }]; 11 | 12 | 13 | #set_property -dict { PACKAGE_PIN L12 IOSTANDARD LVCMOS33 } [get_ports { uart_tx }]; #IO_L6N_T0_D08_VREF_14 Sch=uart_rxd_out 14 | #set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { uart_rx }]; #IO_L5N_T0_D07_14 Sch=uart_txd_in 15 | 16 | 17 | set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { i2c_scl }]; #IO_L5P_T0_34 Sch=pio[40] 18 | set_property -dict { PACKAGE_PIN A2 IOSTANDARD LVCMOS33 } [get_ports { i2c_sda }]; #IO_L2N_T0_34 Sch=pio[41] 19 | 20 | set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { uart_tx }]; #IO_L2P_T0_34 Sch=pio[42] 21 | set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { uart_rx }]; #IO_L4N_T0_34 Sch=pio[43] 22 | 23 | set_property -dict { PACKAGE_PIN L1 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[0] }]; #IO_L18N_T2_34 Sch=pio[01] 24 | set_property -dict { PACKAGE_PIN M4 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[1] }]; #IO_L19P_T3_34 Sch=pio[02] 25 | set_property -dict { PACKAGE_PIN M3 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[2] }]; #IO_L19N_T3_VREF_34 Sch=pio[03] 26 | set_property -dict { PACKAGE_PIN N2 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[3] }]; #IO_L20P_T3_34 Sch=pio[04] 27 | set_property -dict { PACKAGE_PIN M2 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[4] }]; #IO_L20N_T3_34 Sch=pio[05] 28 | set_property -dict { PACKAGE_PIN P3 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[5] }]; #IO_L21P_T3_DQS_34 Sch=pio[06] 29 | set_property -dict { PACKAGE_PIN N3 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[6] }]; #IO_L21N_T3_DQS_34 Sch=pio[07] 30 | set_property -dict { PACKAGE_PIN P1 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[7] }]; #IO_L22P_T3_34 Sch=pio[08] 31 | 32 | set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[8] }]; #IO_L8P_T1_34 Sch=led[1] 33 | set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[9] }]; #IO_L16P_T2_34 Sch=led[2] 34 | set_property -dict { PACKAGE_PIN J1 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[10] }]; #IO_L16N_T2_34 Sch=led[3] 35 | set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { gpio_pins[11] }]; #IO_L8N_T1_34 Sch=led[4] 36 | 37 | set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] 38 | set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design] 39 | set_property CONFIG_MODE SPIx4 [current_design] 40 | -------------------------------------------------------------------------------- /Vivado Files/run_vivado.tcl: -------------------------------------------------------------------------------- 1 | # run_vivado.tcl 2 | # NOTE: typical usage would be "vivado -mode tcl -source run_vivado.tcl" 3 | # 4 | # STEP#0: define output directory area. 5 | # 6 | set outputDir ./runs 7 | file delete -force ./runs 8 | file mkdir $outputDir 9 | # 10 | # STEP#1: setup design sources and constraints 11 | # 12 | read_verilog [ glob ../rtl/*.v ] 13 | read_verilog ../test/rv32i_soc.v 14 | read_mem ../test/memory.mem 15 | read_xdc ./Cmod-S7-25-Master.xdc 16 | # 17 | # STEP#2: run synthesis, report utilization and timing estimates, write checkpoint design 18 | # 19 | synth_design -top rv32i_soc -part xc7s25csga225-1 20 | # 21 | # STEP#3: run placement and logic optimzation, report utilization and timing estimates, write checkpoint design 22 | # 23 | opt_design 24 | place_design 25 | phys_opt_design 26 | # 27 | # STEP#4: run router, report actual utilization and timing, write checkpoint design, run drc, write verilog and xdc out 28 | # 29 | route_design 30 | # 31 | # STEP#5: generate a bitstream 32 | # 33 | write_bitstream -force $outputDir/rv32i_soc.bit 34 | 35 | # Connect to the Digilent Cable on localhost:3121 36 | open_hw_manager 37 | connect_hw_server -url localhost:3121 38 | current_hw_target [get_hw_targets */xilinx_tcf/Digilent/210376AC734EA] 39 | open_hw_target 40 | 41 | # Program and Refresh the XC7K325T Device 42 | 43 | current_hw_device [lindex [get_hw_devices] 0] 44 | refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0] 45 | set_property PROGRAM.FILE {./runs/rv32i_soc.bit} [lindex [get_hw_devices] 0] 46 | 47 | program_hw_devices [lindex [get_hw_devices] 0] 48 | refresh_hw_device [lindex [get_hw_devices] 0] 49 | quit 50 | 51 | 52 | -------------------------------------------------------------------------------- /rtl/rv32i_basereg.v: -------------------------------------------------------------------------------- 1 | //regfile controller for the 32 integer base registers 2 | 3 | `timescale 1ns / 1ps 4 | `default_nettype none 5 | 6 | module rv32i_basereg 7 | ( 8 | input wire i_clk, 9 | input wire i_ce_read, //clock enable for reading from basereg [STAGE 2] 10 | input wire[4:0] i_rs1_addr, //source register 1 address 11 | input wire[4:0] i_rs2_addr, //source register 2 address 12 | input wire[4:0] i_rd_addr, //destination register address 13 | input wire[31:0] i_rd, //data to be written to destination register 14 | input wire i_wr, //write enable 15 | output wire[31:0] o_rs1, //source register 1 value 16 | output wire[31:0] o_rs2 //source register 2 value 17 | ); 18 | 19 | reg[4:0] rs1_addr_q, rs2_addr_q; 20 | reg[31:0] base_regfile[31:1]; //base register file (base_regfile[0] is hardwired to zero) 21 | wire write_to_basereg; 22 | 23 | always @(posedge i_clk) begin 24 | if(write_to_basereg) begin //only write to register if stage 5 is previously enabled (output of stage 5[WRITEBACK] is registered so delayed by 1 clk) 25 | base_regfile[i_rd_addr] <= i_rd; //synchronous write 26 | end 27 | if(i_ce_read) begin //only read the register if stage 2 is enabled [DECODE] 28 | rs1_addr_q <= i_rs1_addr; //synchronous read 29 | rs2_addr_q <= i_rs2_addr; //synchronous read 30 | end 31 | end 32 | 33 | assign write_to_basereg = i_wr && i_rd_addr!=0; //no need to write to basereg 0 (hardwired to zero) 34 | assign o_rs1 = rs1_addr_q==0? 0: base_regfile[rs1_addr_q]; // if regfile is about to be written at the same time we read it 35 | assign o_rs2 = rs2_addr_q==0? 0: base_regfile[rs2_addr_q]; //then return the next value to be written to that address 36 | 37 | endmodule 38 | 39 | -------------------------------------------------------------------------------- /rtl/rv32i_fetch.v: -------------------------------------------------------------------------------- 1 | /* The rv32i_fetch module is primarily for fetching instructions from the memory 2 | and prepare them for the decode stage of the pipeline. The module is responsible 3 | for managing the Program Counter (PC), fetching instructions, and controlling 4 | the pipeline. Below are the key functions of the rv32i_fetch module: 5 | - Program Counter (PC) management: The module maintains a Program Counter (PC) 6 | that holds the address of the current instruction in memory. The PC is 7 | initialized at the reset vector address (specified by the parameter PC_RESET), 8 | and it is incremented or updated based on the instruction flow control, 9 | such as branches, jumps, or traps. 10 | - Instruction fetching: The module fetches the instruction from memory based on 11 | the current PC value. It sends a request for a new instruction (o_stb_inst) 12 | when the fetch stage is enabled (ce), and waits for an acknowledgment 13 | (i_ack_inst) from the memory. The fetched instruction (i_inst) is then sent 14 | to the pipeline (o_inst). 15 | - Pipeline control: The rv32i_fetch module manages the pipeline by controlling 16 | clock enable (o_ce) signals for the next stage. It can stall the fetch stage 17 | (stall_fetch) when the next stages are stalled (i_stall), a requested 18 | instruction has not yet been acknowledged, or when there is no request for a 19 | new instruction. Moreover, it can create pipeline bubbles when the PC needs 20 | to be changed, disabling clock enable signals for the next stages, ensuring 21 | no instructions are executed during this period. 22 | - PC control: The module updates the PC based on the control signals received 23 | from other stages in the pipeline. It can update the PC with a new address 24 | (i_writeback_next_pc) when handling traps, or with the address of a taken 25 | branch or jump (i_alu_next_pc). The fetch stage can be stalled during this 26 | process to prevent instructions from being executed in the pipeline. 27 | - Handling stalls and flushes: The rv32i_fetch module can stall the fetch 28 | stage based on different conditions and store the current PC and instruction 29 | values. When the stall condition is resolved, it can return to the stored 30 | values and continue fetching instructions. The module can also flush the 31 | fetch stage when required (i_flush), disabling the clock enable signal 32 | for the next stage, effectively clearing any pending instructions. 33 | */ 34 | `timescale 1ns / 1ps 35 | `default_nettype none 36 | `include "rv32i_header.vh" 37 | 38 | module rv32i_fetch #(parameter PC_RESET = 32'h00_00_00_00) ( 39 | input wire i_clk,i_rst_n, 40 | output reg[31:0] o_iaddr, //instruction memory address 41 | output reg[31:0] o_pc, //PC value of current instruction 42 | input wire[31:0] i_inst, // retrieved instruction from Memory 43 | output reg[31:0] o_inst, // instruction sent to pipeline 44 | output wire o_stb_inst, // request for instruction 45 | input wire i_ack_inst, //ack (high if new instruction is now on the bus) 46 | // PC Control 47 | input wire i_writeback_change_pc, //high when PC needs to change when going to trap or returning from trap 48 | input wire[31:0] i_writeback_next_pc, //next PC due to trap 49 | input wire i_alu_change_pc, //high when PC needs to change for taken branches and jumps 50 | input wire[31:0] i_alu_next_pc, //next PC due to branch or jump 51 | /// Pipeline Control /// 52 | output reg o_ce, // output clk enable for pipeline stalling of next stage 53 | input wire i_stall, //stall logic for whole pipeline 54 | input wire i_flush //flush this stage 55 | ); 56 | 57 | reg[31:0] iaddr_d, prev_pc, stalled_inst, stalled_pc; 58 | reg ce, ce_d; 59 | reg stall_fetch; 60 | reg stall_q; 61 | //stall this stage when: 62 | //- next stages are stalled 63 | //- you have request but no ack yeti 64 | //- you dont have a request at all (no request then no instruction to execute for this stage) 65 | wire stall_bit = stall_fetch || i_stall || (o_stb_inst && !i_ack_inst) || !o_stb_inst; 66 | assign o_stb_inst = ce; //request for new instruction if this stage is enabled 67 | 68 | //ce logic for fetch stage 69 | always @(posedge i_clk, negedge i_rst_n) begin 70 | if(!i_rst_n) ce <= 0; 71 | else if((i_alu_change_pc || i_writeback_change_pc) && !(i_stall || stall_fetch)) ce <= 0; //do pipeline bubble when need to change pc so that next stages will be disabled 72 | else ce <= 1; //and will not execute the instructions already inside the pipeline 73 | end 74 | 75 | 76 | 77 | always @(posedge i_clk, negedge i_rst_n) begin 78 | if(!i_rst_n) begin 79 | o_ce <= 0; 80 | o_iaddr <= PC_RESET; 81 | prev_pc <= PC_RESET; 82 | stalled_inst <= 0; 83 | o_pc <= 0; 84 | end 85 | else begin 86 | if((ce && !stall_bit) || (stall_bit && !o_ce && ce) || i_writeback_change_pc) begin //update registers only if this stage is enabled and next stages are not stalled 87 | o_iaddr <= iaddr_d; 88 | o_pc <= stall_q? stalled_pc:prev_pc; 89 | o_inst <= stall_q? stalled_inst:i_inst; 90 | end 91 | if(i_flush && !stall_bit) begin //flush this stage(only when not stalled) so that clock-enable of next stage is disabled at next clock cycle 92 | o_ce <= 0; 93 | end 94 | else if(!stall_bit) begin //clock-enable will change only when not stalled 95 | o_ce <= ce_d; 96 | end 97 | //if this stage is stalled but next stage is not, disable 98 | //clock enable of next stage at next clock cycle (pipeline bubble) 99 | else if(stall_bit && !i_stall) o_ce <= 0; 100 | 101 | 102 | stall_q <= i_stall || stall_fetch; //raise stall when any of 5 stages is stalled 103 | 104 | //store both instruction and PC before stalling so that we can 105 | //come back to these values when we need to return from stall 106 | if(stall_bit && !stall_q) begin 107 | stalled_pc <= prev_pc; 108 | stalled_inst <= i_inst; 109 | end 110 | prev_pc <= o_iaddr; //this is the first delay to align the PC to the pipeline 111 | end 112 | end 113 | // logic for PC and pipeline clock_enable control 114 | always @* begin 115 | iaddr_d = 0; 116 | ce_d = 0; 117 | stall_fetch = i_stall; //stall when retrieving instructions need wait time 118 | //prepare next PC when changing pc, then do a pipeline bubble 119 | //to disable the ce of next stage 120 | if(i_writeback_change_pc) begin 121 | iaddr_d = i_writeback_next_pc; 122 | ce_d = 0; 123 | end 124 | else if(i_alu_change_pc) begin 125 | iaddr_d = i_alu_next_pc; 126 | ce_d = 0; 127 | end 128 | else begin 129 | iaddr_d = o_iaddr + 32'd4; 130 | ce_d = ce; 131 | end 132 | end 133 | 134 | endmodule 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /rtl/rv32i_forwarding.v: -------------------------------------------------------------------------------- 1 | /*The rv32i_forwarding module is responsible for handling data hazards in the 2 | pipelined processor by implementing operand forwarding. Data hazards occur 3 | when a register value is about to be overwritten by previous instructions that 4 | are still in the pipeline and have not yet been written to the base register. 5 | Operand forwarding resolves this issue by either stalling the pipeline until 6 | the base register is updated (less efficient) or forwarding the updated operand 7 | value directly from the pipeline stage where it is currently being computed. Key 8 | functionalities of the rv32i_forwarding module include: 9 | - Forwarding rs1 and rs2 operands: The module initially sets the output values 10 | o_rs1 and o_rs2 to their original values from the base register (i_rs1_orig 11 | and i_rs2_orig). It then checks for any data hazards by comparing the register 12 | addresses of the operands (i_decoder_rs1_addr_q and i_decoder_rs2_addr_q) with 13 | the destination register addresses in the pipeline stages (i_alu_rd_addr and 14 | i_memoryaccess_rd_addr). 15 | - Operand forwarding for rs1:If the next value of rs1 is in stage 4 (Memory Access), 16 | and the Memory Access stage is enabled and if the next value of rs1 comes from a 17 | load or CSR instruction (i.e., rd is not valid at stage 4), the module stalls the 18 | ALU stage by asserting o_alu_force_stall. Otherwise, the module forwards the value 19 | of rd from stage 4 (i_alu_rd) to o_rs1. If the next value of rs1 is in stage 5 20 | (Writeback), and the Writeback stage is enabled, the module forwards the value of 21 | rd from stage 5 (i_writeback_rd) to o_rs1. 22 | - Operand forwarding for rs2: If the next value of rs2 is in stage 4 (Memory Access), 23 | and the Memory Access stage is enabled and if the next value of rs2 comes from a 24 | load or CSR instruction (i.e., rd is not yet valid at stage 4), the module stalls 25 | the ALU stage by asserting o_alu_force_stall. Otherwise, the module forwards the 26 | value of rd from stage 4 (i_alu_rd) to o_rs2. If the next value of rs2 is in stage 27 | 5 (Writeback), and the Writeback stage is enabled, the module forwards the value 28 | of rd from stage 5 (i_writeback_rd) to o_rs2. 29 | - Handling zero register (x0) forwarding: The module ensures that no operation 30 | forwarding is performed when the register address is zero, as this register is 31 | hardwired to zero. If either i_decoder_rs1_addr_q or i_decoder_rs2_addr_q is zero, 32 | the corresponding output register (o_rs1 or o_rs2) is set to zero. By implementing 33 | operand forwarding, the rv32i_forwarding module helps to mitigate data hazards, 34 | ensuring the correct execution of instructions and improving the overall efficiency 35 | of the RV32I pipelined processor. 36 | */ 37 | 38 | `timescale 1ns / 1ps 39 | `default_nettype none 40 | `include "rv32i_header.vh" 41 | 42 | module rv32i_forwarding ( 43 | input wire[31:0] i_rs1_orig, //current rs1 value saved in basereg 44 | input wire[31:0] i_rs2_orig, //current rs2 value saved in basereg 45 | input wire[4:0] i_decoder_rs1_addr_q, //address of operand rs1 used in ALU stage 46 | input wire[4:0] i_decoder_rs2_addr_q, //address of operand rs2 used in ALU stage 47 | output reg o_alu_force_stall, //high to force ALU stage to stall 48 | output reg[31:0] o_rs1, //rs1 value with Operand Forwarding 49 | output reg[31:0] o_rs2, //rs2 value with Operand Forwarding 50 | // Stage 4 [MEMORYACCESS] 51 | input wire[4:0] i_alu_rd_addr, //destination register address 52 | input wire i_alu_wr_rd, //high if rd_addr will be written 53 | input wire i_alu_rd_valid, //high if rd is already valid at this stage (not LOAD nor CSR instruction) 54 | input wire[31:0] i_alu_rd, //rd value in stage 4 55 | input wire i_memoryaccess_ce, //high if stage 4 is enabled 56 | // Stage 5 [WRITEBACK] 57 | input wire[4:0] i_memoryaccess_rd_addr, //destination register address 58 | input wire i_memoryaccess_wr_rd, //high if rd_addr will be written 59 | input wire[31:0] i_writeback_rd, //rd value in stage 5 60 | input wire i_writeback_ce //high if stage 4 is enabled 61 | ); 62 | 63 | always @* begin 64 | o_rs1 = i_rs1_orig; //original value from basereg 65 | o_rs2 = i_rs2_orig; //original value from basereg 66 | o_alu_force_stall = 0; 67 | 68 | // Data Hazard = Register value is about to be overwritten by previous instructions but are still on the pipeline and are not yet written to basereg. 69 | // The solution to make sure the updated value of rs1 or rs2 is used is to either stall the pipeline until the basereg is updated (very inefficient) or use Operand Forwarding 70 | 71 | // Operand Forwarding for rs1 72 | if((i_decoder_rs1_addr_q == i_alu_rd_addr) && i_alu_wr_rd && i_memoryaccess_ce) begin //next value of rs1 is currently on stage 4 73 | if(!i_alu_rd_valid) begin //if next value of rs1 comes from load or CSR instruction then we must stall from ALU stage and wait until 74 | o_alu_force_stall = 1; //stage 4(Memoryaccess) becomes disabled, which means next value of rs1 is already at stage 5 75 | end 76 | o_rs1 = i_alu_rd; 77 | end 78 | else if((i_decoder_rs1_addr_q == i_memoryaccess_rd_addr) && i_memoryaccess_wr_rd && i_writeback_ce) begin //next value of rs1 is currently on stage 5 79 | o_rs1 = i_writeback_rd; 80 | end 81 | 82 | // Operand Forwarding for rs2 83 | if((i_decoder_rs2_addr_q == i_alu_rd_addr) && i_alu_wr_rd && i_memoryaccess_ce) begin //next value of rs2 is currently on stage 4 84 | if(!i_alu_rd_valid) begin //if next value of rs2 comes from load or CSR instruction(rd is only available at stage 5) then we must stall from ALU stage and wait until 85 | o_alu_force_stall = 1; //stage 4(Memoryaccess) becomes disabled (which implicitly means that next value of rs2 is already at stage 5) 86 | end 87 | o_rs2 = i_alu_rd; 88 | end 89 | else if((i_decoder_rs2_addr_q == i_memoryaccess_rd_addr) && i_memoryaccess_wr_rd && i_writeback_ce) begin //next value of rs2 is currently on stage 5 90 | o_rs2 = i_writeback_rd; 91 | end 92 | 93 | // No operation forwarding necessary when addr is zero since that address is hardwired to zero 94 | if(i_decoder_rs1_addr_q == 0) o_rs1 = 0; 95 | if(i_decoder_rs2_addr_q == 0) o_rs2 = 0; 96 | end 97 | 98 | endmodule 99 | -------------------------------------------------------------------------------- /rtl/rv32i_header.vh: -------------------------------------------------------------------------------- 1 | `define ALU_WIDTH 14 2 | `define ADD 0 3 | `define SUB 1 4 | `define SLT 2 5 | `define SLTU 3 6 | `define XOR 4 7 | `define OR 5 8 | `define AND 6 9 | `define SLL 7 10 | `define SRL 8 11 | `define SRA 9 12 | `define EQ 10 13 | `define NEQ 11 14 | `define GE 12 15 | `define GEU 13 16 | 17 | `define OPCODE_WIDTH 11 18 | `define RTYPE 0 19 | `define ITYPE 1 20 | `define LOAD 2 21 | `define STORE 3 22 | `define BRANCH 4 23 | `define JAL 5 24 | `define JALR 6 25 | `define LUI 7 26 | `define AUIPC 8 27 | `define SYSTEM 9 28 | `define FENCE 10 29 | 30 | `define EXCEPTION_WIDTH 4 31 | `define ILLEGAL 0 32 | `define ECALL 1 33 | `define EBREAK 2 34 | `define MRET 3 35 | 36 | `define OPCODE_RTYPE 7'b0110011 37 | `define OPCODE_ITYPE 7'b0010011 38 | `define OPCODE_LOAD 7'b0000011 39 | `define OPCODE_STORE 7'b0100011 40 | `define OPCODE_BRANCH 7'b1100011 41 | `define OPCODE_JAL 7'b1101111 42 | `define OPCODE_JALR 7'b1100111 43 | `define OPCODE_LUI 7'b0110111 44 | `define OPCODE_AUIPC 7'b0010111 45 | `define OPCODE_SYSTEM 7'b1110011 46 | `define OPCODE_FENCE 7'b0001111 47 | 48 | `define FUNCT3_ADD 3'b000 49 | `define FUNCT3_SLT 3'b010 50 | `define FUNCT3_SLTU 3'b011 51 | `define FUNCT3_XOR 3'b100 52 | `define FUNCT3_OR 3'b110 53 | `define FUNCT3_AND 3'b111 54 | `define FUNCT3_SLL 3'b001 55 | `define FUNCT3_SRA 3'b101 56 | `define FUNCT3_EQ 3'b000 57 | `define FUNCT3_NEQ 3'b001 58 | `define FUNCT3_LT 3'b100 59 | `define FUNCT3_GE 3'b101 60 | `define FUNCT3_LTU 3'b110 61 | `define FUNCT3_GEU 3'b111 62 | 63 | -------------------------------------------------------------------------------- /rtl/rv32i_writeback.v: -------------------------------------------------------------------------------- 1 | /* The rv32i_writeback module serves as the writeback stage of the pipelined 2 | processor. This stage is responsible for determining the next value of the 3 | program counter (PC), writing data back to the destination register, and 4 | handling trap-related operations (interrupts and exceptions). In addition, 5 | the module manages pipeline control, such as stalling and flushing previous 6 | stages. Key functionalities of the rv32i_writeback module include: 7 | - Determining the next value of the program counter (PC) and updating the 8 | o_next_pc register: If an interrupt or exception is detected, the module 9 | sets the PC to the trap address (i_trap_address) and asserts the o_change_pc 10 | signal. If the processor is returning from a trap, the module sets the PC to 11 | the return address (i_return_address) and asserts the o_change_pc signal. In 12 | normal operation, the PC value from the previous stage (i_pc) is passed through. 13 | - Handling writeback to destination registers: The module writes data back to the 14 | destination register based on the opcode and funct3 fields of the instruction: 15 | If the instruction is a load operation, the data from the memory (i_data_load) 16 | is written back. If the instruction is a CSR write operation, the CSR value 17 | (i_csr_out) is written back. In other cases, the data is computed at the ALU 18 | stage (i_rd) and is written back. The o_wr_rd signal is set based on the i_wr_rd 19 | input and the current pipeline control state (i_ce and o_stall). The destination 20 | register address (o_rd_addr) is passed through from the i_rd_addr input. 21 | - Trap-handler control: The module handles interrupts and exceptions by checking the 22 | i_go_to_trap and i_return_from_trap input signals. When the processor goes to a 23 | trap, the o_next_pc register is set to the trap address (i_trap_address) and the 24 | pipeline is flushed. When the processor returns from a trap, the o_next_pc register 25 | is set to the return address (i_return_address) and the pipeline is flushed. 26 | - Pipeline control: The module can stall the pipeline by asserting the o_stall signal 27 | when necessary. It can also flush the current stage and previous stages by asserting 28 | the o_flush signal based on the state of the pipeline and trap-related operations. 29 | */ 30 | 31 | //logic controller for the next PC and rd value [WRITEBACK STAGE] 32 | 33 | `timescale 1ns / 1ps 34 | `default_nettype none 35 | `include "rv32i_header.vh" 36 | 37 | module rv32i_writeback ( 38 | input wire[2:0] i_funct3, //function type 39 | input wire[31:0] i_data_load, //data to be loaded to base reg 40 | input wire[31:0] i_csr_out, //CSR value to be loaded to basereg 41 | input wire i_opcode_load, 42 | input wire i_opcode_system, 43 | // Basereg Control 44 | input wire i_wr_rd, //write rd to basereg if enabled (from previous stage) 45 | output reg o_wr_rd, //write rd to the base reg if enabled 46 | input wire[4:0] i_rd_addr, //address for destination register (from previous stage) 47 | output reg[4:0] o_rd_addr, //address for destination register 48 | input wire[31:0] i_rd, //value to be written back to destination register (from previous stage) 49 | output reg[31:0] o_rd, //value to be written back to destination register 50 | // PC Control 51 | input wire[31:0] i_pc, // pc value (from previous stage) 52 | output reg[31:0] o_next_pc, //new pc value 53 | output reg o_change_pc, //high if PC needs to jump 54 | // Trap-Handler 55 | input wire i_go_to_trap, //high before going to trap (if exception/interrupt detected) 56 | input wire i_return_from_trap, //high before returning from trap (via mret) 57 | input wire[31:0] i_return_address, //mepc CSR 58 | input wire[31:0] i_trap_address, //mtvec CSR 59 | /// Pipeline Control /// 60 | input wire i_ce, // input clk enable for pipeline stalling of this stage 61 | output reg o_stall, //informs pipeline to stall 62 | output reg o_flush //flush previous stages 63 | ); 64 | // 65 | //determine next value of pc and o_rd 66 | always @* begin 67 | o_stall = 0; //stall when this stage needs wait time 68 | o_flush = 0; //flush this stage along with previous stages when changing PC 69 | o_wr_rd = i_wr_rd && i_ce && !o_stall; 70 | o_rd_addr = i_rd_addr; 71 | o_rd = 0; 72 | o_next_pc = 0; 73 | o_change_pc = 0; 74 | 75 | if(i_go_to_trap) begin 76 | o_change_pc = 1; //change PC only when ce of this stage is high (o_change_pc is valid) 77 | o_next_pc = i_trap_address; //interrupt or exception detected so go to trap address (mtvec value) 78 | o_flush = i_ce; 79 | o_wr_rd = 0; 80 | end 81 | 82 | else if(i_return_from_trap) begin 83 | o_change_pc = 1; //change PC only when ce of this stage is high (o_change_pc is valid) 84 | o_next_pc = i_return_address; //return from trap via mret (mepc value) 85 | o_flush = i_ce; 86 | o_wr_rd = 0; 87 | end 88 | 89 | else begin //normal operation 90 | if(i_opcode_load) o_rd = i_data_load; //load data from memory to basereg 91 | else if(i_opcode_system && i_funct3!=0) begin //CSR write 92 | o_rd = i_csr_out; 93 | end 94 | else o_rd = i_rd; //rd value is already computed at ALU stage 95 | end 96 | 97 | end 98 | endmodule 99 | -------------------------------------------------------------------------------- /test/entry.s: -------------------------------------------------------------------------------- 1 | .section .text 2 | .global _start 3 | 4 | _start: 5 | 6 | # Start-up sequence: 7 | # 1. Initialize all base registers to zero 8 | # 2. Set-up stack and global pointer. The stack pointer is loaded with the highest ram address (defined by the linker as __stack_pointer). 9 | # 3. Set-up the trap and exception vector (MTVEC). 10 | # 4. Clear the .bss section to zero. It uses the symbols __bss_start and __bss_end (defined by linker) to obtain the address range that should be set to zero. 11 | # 5. (NOT NEEDED)Initialize the .data section. This section is defined in the linker script with different VMA (Virtual address) and LMA (Load address) since 12 | # it has to be loaded to Flash, but used from RAM when the execution starts. To make sure that all C code can use the initialized data within the .data section, 13 | # it has to be copied over from Flash to RAM by the startup code. 14 | # 6. Set-up call to main function 15 | # 7. Set-up exit routine 16 | 17 | # Initialize base registers to zero 18 | li x0, 0 19 | li x1, 0 20 | li x2, 0 21 | li x3, 0 22 | li x4, 0 23 | li x5, 0 24 | li x6, 0 25 | li x7, 0 26 | li x8, 0 27 | li x9, 0 28 | li x10, 0 29 | li x11, 0 30 | li x12, 0 31 | li x13, 0 32 | li x14, 0 33 | li x15, 0 34 | li x16, 0 35 | li x17, 0 36 | li x18, 0 37 | li x19, 0 38 | li x20, 0 39 | li x21, 0 40 | li x22, 0 41 | li x23, 0 42 | li x24, 0 43 | li x25, 0 44 | li x26, 0 45 | li x27, 0 46 | li x28, 0 47 | li x29, 0 48 | li x30, 0 49 | li x31, 0 50 | 51 | # Set-up stack pointer 52 | la sp, __stack_pointer 53 | 54 | # Set-up global pointer 55 | la gp, __global_pointer$ 56 | 57 | # Set-up trap vector 58 | csrw mtvec, zero 59 | csrw mie, zero 60 | csrw mstatus, zero 61 | csrw mip, zero 62 | 63 | # Clear BSS section 64 | la x14, __bss_start 65 | la x15, __bss_end 66 | 67 | clear_bss_loop: # store zero starting from __bss_start(included) to __bss_end(excluded) 68 | bge x14, x15, clear_bss_end 69 | sw zero, 0(x14) 70 | addi x14, x14, 4 71 | j clear_bss_loop 72 | clear_bss_end: 73 | 74 | # Call main function 75 | jal main 76 | 77 | # Exit program (RISC-V test pass code) 78 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 79 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 80 | ebreak 81 | 82 | 83 | 84 | /* 85 | Stack pointer (SP) is a pointer that points to the top of the stack in a program's memory. 86 | The stack is a region of memory used for storing local variables, function call frames, and 87 | other temporary data. The stack grows downwards, which means that the stack pointer points to 88 | the last used memory location on the stack. As new items are added to the stack, the stack 89 | pointer is decremented to point to the new top of the stack. 90 | 91 | On the other hand, a global pointer (GP) is a pointer that points to a region of memory containing 92 | global variables. Global variables are variables that are accessible from anywhere in the program. 93 | The global pointer is usually set to point to the start of the global variable region (BSS section), 94 | and it remains fixed throughout the execution of the program. 95 | */ 96 | 97 | 98 | -------------------------------------------------------------------------------- /test/extra/add.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ADD 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 + 150 = 250 (positive answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 150 # set x2 to 150 (0x00000096) 22 | add x3, x1, x2 # add x1(100) to x2(150), x3=250 (0x000000FA) 23 | 24 | # -150 + 100 = -50 (negative answer) 25 | li x4, -150 # set x4 to -150 (FFFFFF6A) 26 | add x5, x4, x1 # add x4(-150) to x1(100), x5=-50 (0xFFFFFFCE) 27 | 28 | # -150 + 150 = 0 (zero answer) 29 | add x6, x4, x2 # add x4(-150) to x2(150), x6=0 (0x00000000) 30 | 31 | # store result to x0 32 | add x0, x1, x2 # x0 must be hardcoded to 0 33 | 34 | # self-check 35 | li x7, 250 # set x7 to 250 (expected value for x3) 36 | beqz x7, fail0 # make sure x7 has value 37 | li x8, -50 # set x8 to -50 (expected value for x5) 38 | beqz x8, fail0 # make sure x8 has value 39 | bne x7, x3, fail1 # 40 | bne x8, x5, fail2 #branch to fail if not equal to expected value 41 | bne x0, x6, fail3 # 42 | bnez x0, fail4 # 43 | 44 | 45 | ### END OF TEST CODE ### 46 | 47 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 48 | pass: 49 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 50 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 51 | ebreak 52 | 53 | fail0: 54 | li a0, 1 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail1: 59 | li a0, 2 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail2: 64 | li a0, 4 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | fail3: 69 | li a0, 6 # fail code 70 | li a7, 93 # reached end of code 71 | ebreak 72 | 73 | fail4: 74 | li a0, 8 # fail code 75 | li a7, 93 # reached end of code 76 | ebreak 77 | 78 | # ----------------------------------------- 79 | # Data section. Note starts at 0x1000, as 80 | # set by DATAADDR variable in rv_asm.bat. 81 | # ----------------------------------------- 82 | .data 83 | 84 | # Data section 85 | data: 86 | 87 | -------------------------------------------------------------------------------- /test/extra/addi.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ADDI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 + (150) = 250 (positive answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | addi x2, x1, 150 # addi x1(100) to 150, x2=250 (0x000000FA) 22 | 23 | # 100 + (-150) = -50 (negative answer) 24 | addi x3, x1, -150 # addi x1(100) to -150, x3=-50 (0xFFFFFFCE) 25 | 26 | # -150 + (150) = 0 (zero answer) 27 | li x4, -150 # set x4 to -150 (FFFFFF6A) 28 | addi x5, x4, 150 # addi x4(-150) to 150, x5=0 (0x00000000) 29 | 30 | # self-check 31 | li x6, 250 # set x6 to 250 (expected value for x2) 32 | beqz x6, fail0 # make sure x6 has value 33 | li x7, -50 # set x7 to -50 (expected value for x3) 34 | beqz x7, fail0 # make sure x7 has value 35 | bne x6, x2, fail1 # 36 | bne x7, x3, fail2 # branch to fail if not equal to expected value 37 | bnez x5, fail3 # 38 | 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | # ----------------------------------------- 69 | # Data section. Note starts at 0x1000, as 70 | # set by DATAADDR variable in rv_asm.bat. 71 | # ----------------------------------------- 72 | .data 73 | 74 | # Data section 75 | data: 76 | 77 | -------------------------------------------------------------------------------- /test/extra/and.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR AND 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 & 150 = 4 (nonzero answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 150 # set x2 to 150 (0x00000096) 22 | and x3, x1, x2 # and x1(100) to x2(150), x3=4 (0x00000004) 23 | 24 | # 100 & 0 = 0 (zero answer) 25 | and x4, x1, x0 # and x1(100) to x0(0), x4=0 (0x00000000) 26 | 27 | #self-check 28 | li x5, 4 # set x5 to 4 (expected value for x3) 29 | beqz x5, fail0 # make sure x5 has value 30 | bne x3, x5, fail1 # 31 | bnez x4, fail2 # branch to fail if not equal to expected value 32 | 33 | ### END OF TEST CODE ### 34 | 35 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 36 | pass: 37 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 38 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 39 | ebreak 40 | 41 | fail0: 42 | li a0, 1 # fail code 43 | li a7, 93 # reached end of code 44 | ebreak 45 | 46 | fail1: 47 | li a0, 2 # fail code 48 | li a7, 93 # reached end of code 49 | ebreak 50 | 51 | fail2: 52 | li a0, 4 # fail code 53 | li a7, 93 # reached end of code 54 | ebreak 55 | 56 | # ----------------------------------------- 57 | # Data section. Note starts at 0x1000, as 58 | # set by DATAADDR variable in rv_asm.bat. 59 | # ----------------------------------------- 60 | .data 61 | 62 | # Data section 63 | data: 64 | 65 | -------------------------------------------------------------------------------- /test/extra/andi.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ANDI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 & 150 = 4 (nonzero answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | andi x2, x1, 150 # and x1(100) to 150, x2=4 (0x00000004) 22 | 23 | # 100 & 0 = 0 (zero answer) 24 | andi x3, x1, 0 # and x1(100) to 0, x3=0 (0x00000000) 25 | 26 | #self-check 27 | li x4, 4 # set x4 to 4 (expected value for x2) 28 | beqz x4, fail0 # make sure x5 has value 29 | bne x2, x4, fail1 # 30 | bnez x3, fail2 # branch to fail if not equal to expected value 31 | 32 | ### END OF TEST CODE ### 33 | 34 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 35 | pass: 36 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 37 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 38 | ebreak 39 | 40 | fail0: 41 | li a0, 1 # fail code 42 | li a7, 93 # reached end of code 43 | ebreak 44 | 45 | fail1: 46 | li a0, 2 # fail code 47 | li a7, 93 # reached end of code 48 | ebreak 49 | 50 | fail2: 51 | li a0, 4 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | # ----------------------------------------- 56 | # Data section. Note starts at 0x1000, as 57 | # set by DATAADDR variable in rv_asm.bat. 58 | # ----------------------------------------- 59 | .data 60 | 61 | # Data section 62 | data: 63 | 64 | -------------------------------------------------------------------------------- /test/extra/auipc.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR AUIPC 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | nop # no operation 19 | nop # no operation 20 | auipc x1, 0xABCDE # load 0xABCDE to upper immediate of x1 the add PC (0xABCDE008) 21 | 22 | # self-check 23 | li x2, 0 # 24 | addi x2, x2, 0xAB # 25 | slli x2, x2, 8 # 26 | addi x2, x2, 0xCD # 27 | slli x2, x2, 8 # 28 | addi x2, x2, 0xE0 # 29 | sll x2, x2, 8 # 30 | addi x2, x2, 8 # x2 = 0xABCDE008 31 | 32 | beqz x2, fail0 # make sure x2 has value 33 | bne x1, x2, fail1 # branch to fail if not equal to expected value 34 | 35 | ### END OF TEST CODE ### 36 | 37 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 38 | pass: 39 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 40 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 41 | ebreak 42 | 43 | fail0: 44 | li a0, 1 # fail code 45 | li a7, 93 # reached end of code 46 | ebreak 47 | 48 | fail1: 49 | li a0, 2 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | # ----------------------------------------- 54 | # Data section. Note starts at 0x1000, as 55 | # set by DATAADDR variable in rv_asm.bat. 56 | # ----------------------------------------- 57 | .data 58 | 59 | # Data section 60 | data: 61 | 62 | -------------------------------------------------------------------------------- /test/extra/beq.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR BEQ 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | li x1, 100 # set x1 to 100 (0x00000064) 20 | li x2, 100 # set x2 to 100 (0x00000064) 21 | 22 | beq x1, x0, fail0 # make sure x1 has value 23 | beq x1, x2, pass # if x1 equas x2, branch to pass 24 | j fail1 # jump to fail 25 | 26 | ### END OF TEST CODE ### 27 | 28 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 29 | pass: 30 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 31 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 32 | ebreak 33 | 34 | fail0: 35 | li a0, 1 # fail code 36 | li a7, 93 # reached end of code 37 | ebreak 38 | 39 | fail1: 40 | li a0, 2 # fail code 41 | li a7, 93 # reached end of code 42 | ebreak 43 | 44 | 45 | # ----------------------------------------- 46 | # Data section. Note starts at 0x1000, as 47 | # set by DATAADDR variable in rv_asm.bat. 48 | # ----------------------------------------- 49 | .data 50 | 51 | # Data section 52 | data: 53 | 54 | -------------------------------------------------------------------------------- /test/extra/bge.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR BGE 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # compare positive numbers 20 | li x1, 50 # set x1 to 50 (0x00000032) 21 | li x2, 100 # set x2 to 100 (0x00000064) 22 | 23 | beq x1, x0, fail0 # make sure x1 has value 24 | bge x2, x1, branch1 # if x2 >= x1, branch to branch1 25 | j fail1 # jump to fail 26 | 27 | branch1: 28 | bge x1, x2, fail1 # if x1 >= x2, branch to fail 29 | 30 | # compare signed numbers 31 | li x3, -50 # set x3 to -50 (0xFFFFFFCE) 32 | bge x3, x1, fail2 # if x3 >= x1, branch to fail 33 | 34 | # compare equal numbers 35 | bge x3, x3, pass # if x3 >= x3, branch to pass 36 | j fail3 # jump to fail 37 | 38 | 39 | ### END OF TEST CODE ### 40 | 41 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 42 | pass: 43 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 44 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 45 | ebreak 46 | 47 | fail0: 48 | li a0, 1 # fail code 49 | li a7, 93 # reached end of code 50 | ebreak 51 | 52 | fail1: 53 | li a0, 2 # fail code 54 | li a7, 93 # reached end of code 55 | ebreak 56 | 57 | fail2: 58 | li a0, 4 # fail code 59 | li a7, 93 # reached end of code 60 | ebreak 61 | 62 | fail3: 63 | li a0, 6 # fail code 64 | li a7, 93 # reached end of code 65 | ebreak 66 | 67 | 68 | # ----------------------------------------- 69 | # Data section. Note starts at 0x1000, as 70 | # set by DATAADDR variable in rv_asm.bat. 71 | # ----------------------------------------- 72 | .data 73 | 74 | # Data section 75 | data: 76 | 77 | -------------------------------------------------------------------------------- /test/extra/bgeu.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR BGEU 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # compare positive numbers 20 | li x1, 50 # set x1 to 50 (0x00000032) 21 | li x2, 100 # set x2 to 100 (0x00000064) 22 | 23 | beq x1, x0, fail0 # make sure x1 has value 24 | bgeu x2, x1, branch1 # if x2 >= x1, branch to branch1 25 | j fail1 # jump to fail 26 | 27 | branch1: 28 | bgeu x1, x2, fail1 # if x1 >= x2, branch to fail 29 | 30 | # compare signed numbers 31 | li x3, -50 # set x3 to -50 (0xFFFFFFCE) 32 | bgeu x1, x3, fail2 # if x1 >= x3, branch to fail 33 | 34 | # compare equal numbers 35 | bgeu x3, x3, pass # if x3 >= x3, branch to pass 36 | j fail3 # jump to fail 37 | 38 | 39 | ### END OF TEST CODE ### 40 | 41 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 42 | pass: 43 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 44 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 45 | ebreak 46 | 47 | fail0: 48 | li a0, 1 # fail code 49 | li a7, 93 # reached end of code 50 | ebreak 51 | 52 | fail1: 53 | li a0, 2 # fail code 54 | li a7, 93 # reached end of code 55 | ebreak 56 | 57 | fail2: 58 | li a0, 4 # fail code 59 | li a7, 93 # reached end of code 60 | ebreak 61 | 62 | fail3: 63 | li a0, 6 # fail code 64 | li a7, 93 # reached end of code 65 | ebreak 66 | 67 | 68 | # ----------------------------------------- 69 | # Data section. Note starts at 0x1000, as 70 | # set by DATAADDR variable in rv_asm.bat. 71 | # ----------------------------------------- 72 | .data 73 | 74 | # Data section 75 | data: 76 | 77 | -------------------------------------------------------------------------------- /test/extra/blt.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR BLT 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # compare positive numbers 20 | li x1, 50 # set x1 to 50 (0x00000032) 21 | li x2, 100 # set x2 to 100 (0x00000064) 22 | 23 | beq x1, x0, fail0 # make sure x1 has value 24 | blt x1, x2, branch1 # if x1 < x2, branch to branch1 25 | j fail1 # jump to fail 26 | 27 | branch1: 28 | blt x2, x1, fail1 # if x2 < x1, branch to fail 29 | 30 | # compare signed numbers 31 | li x3, -50 # set x3 to -50 (0xFFFFFFCE) 32 | blt x1, x3, fail2 # if x3 < x1, branch to fail 33 | 34 | # compare equal numbers 35 | blt x3, x3, fail3 36 | 37 | ### END OF TEST CODE ### 38 | 39 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 40 | pass: 41 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 42 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 43 | ebreak 44 | 45 | fail0: 46 | li a0, 1 # fail code 47 | li a7, 93 # reached end of code 48 | ebreak 49 | 50 | fail1: 51 | li a0, 2 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | fail2: 56 | li a0, 4 # fail code 57 | li a7, 93 # reached end of code 58 | ebreak 59 | 60 | fail3: 61 | li a0, 6 # fail code 62 | li a7, 93 # reached end of code 63 | ebreak 64 | 65 | 66 | # ----------------------------------------- 67 | # Data section. Note starts at 0x1000, as 68 | # set by DATAADDR variable in rv_asm.bat. 69 | # ----------------------------------------- 70 | .data 71 | 72 | # Data section 73 | data: 74 | 75 | -------------------------------------------------------------------------------- /test/extra/bltu.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR BLTU 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # compare positive numbers 20 | li x1, 50 # set x1 to 50 (0x00000032) 21 | li x2, 100 # set x2 to 100 (0x00000064) 22 | 23 | beq x1, x0, fail0 # make sure x1 has value 24 | bltu x1, x2, branch1 # if x1 < x2, branch to branch1 25 | j fail1 # jump to fail 26 | 27 | branch1: 28 | bltu x2, x1, fail1 # if x2 < x1, branch to fail 29 | 30 | # compare signed numbers 31 | li x3, -50 # set x3 to -50 (0xFFFFFFCE) 32 | bltu x3, x1, fail2 # if x3 < x1 (unsigned), branch to fail 33 | 34 | # compare equal numbers 35 | bltu x3, x3, fail3 # if x3 < x3, branch to fail 36 | 37 | ### END OF TEST CODE ### 38 | 39 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 40 | pass: 41 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 42 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 43 | ebreak 44 | 45 | fail0: 46 | li a0, 1 # fail code 47 | li a7, 93 # reached end of code 48 | ebreak 49 | 50 | fail1: 51 | li a0, 2 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | fail2: 56 | li a0, 4 # fail code 57 | li a7, 93 # reached end of code 58 | ebreak 59 | 60 | fail3: 61 | li a0, 6 # fail code 62 | li a7, 93 # reached end of code 63 | ebreak 64 | 65 | 66 | # ----------------------------------------- 67 | # Data section. Note starts at 0x1000, as 68 | # set by DATAADDR variable in rv_asm.bat. 69 | # ----------------------------------------- 70 | .data 71 | 72 | # Data section 73 | data: 74 | 75 | -------------------------------------------------------------------------------- /test/extra/bne.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR BNE 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | li x1, 100 # set x1 to 100 (0x00000064) 20 | li x2, 100 # set x2 to 100 (0x00000064) 21 | 22 | beq x1, x0, fail0 # make sure x1 has value 23 | bne x1, x2, fail1 # if x1 not equal to x2, branch to fail 24 | 25 | 26 | ### END OF TEST CODE ### 27 | 28 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 29 | pass: 30 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 31 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 32 | ebreak 33 | 34 | fail0: 35 | li a0, 1 # fail code 36 | li a7, 93 # reached end of code 37 | ebreak 38 | 39 | fail1: 40 | li a0, 2 # fail code 41 | li a7, 93 # reached end of code 42 | ebreak 43 | 44 | 45 | # ----------------------------------------- 46 | # Data section. Note starts at 0x1000, as 47 | # set by DATAADDR variable in rv_asm.bat. 48 | # ----------------------------------------- 49 | .data 50 | 51 | # Data section 52 | data: 53 | 54 | -------------------------------------------------------------------------------- /test/extra/branch_hazard.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ADD 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 + 150 = 250 (positive answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | nop 22 | nop 23 | nop 24 | nop 25 | nop 26 | nop 27 | li x2, 150 # set x2 to 150 (0x00000096) 28 | nop 29 | nop 30 | nop 31 | nop 32 | nop 33 | nop 34 | add x3, x1, x2 # add x1(100) to x2(150), x3=250 (0x000000FA) 35 | nop 36 | nop 37 | nop 38 | nop 39 | nop 40 | nop 41 | j pass 42 | ### END OF TEST CODE ### 43 | 44 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 45 | 46 | fail: 47 | li a0, 2 # set a0 (x10) to 0 to indicate a pass code 48 | nop 49 | nop 50 | nop 51 | nop 52 | nop 53 | nop 54 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 55 | nop 56 | nop 57 | nop 58 | nop 59 | nop 60 | nop 61 | ebreak 62 | pass: 63 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 64 | nop 65 | nop 66 | nop 67 | nop 68 | nop 69 | nop 70 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 71 | nop 72 | nop 73 | nop 74 | nop 75 | nop 76 | nop 77 | ebreak 78 | 79 | 80 | 81 | 82 | # ----------------------------------------- 83 | # Data section. Note starts at 0x1000, as 84 | # set by DATAADDR variable in rv_asm.bat. 85 | # ----------------------------------------- 86 | .data 87 | 88 | # Data section 89 | data: 90 | 91 | -------------------------------------------------------------------------------- /test/extra/csr_op.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR CSR instructions (CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI) 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 200 # set x2 to 200 (0x000000C8) 22 | li x3, 0x10000000 # set x3 to 0x10000000 23 | 24 | # Test CSRRW 25 | csrrw x4, mtvec, x2 # set mtvec to value of x2 (0x000000C8) and set x4 to current value of mtvec (0x00000064) 26 | 27 | # Test CSRRS 28 | csrrs x5, mtvec, x3 # set bits in mtvec based on x3 (0x000000C8 | 0x10000000 = 0x100000C8) and set x5 to current value of mtvec (0x000000C8) 29 | 30 | # Test CSRRC 31 | csrrc x6, mtvec, x2 # clear bits in mtvec based on x2 (0x100000C8 & ~(0x000000C8) = 0x10000000) and set x6 to current value of mtvec (0x100000C8) 32 | 33 | # Test CSRRWI 34 | csrrwi x7, mtvec, 0b10101 # set mtvec to value of 0b10101 (0x00000015) and set x7 to current value of mtvec (0x10000000) 35 | 36 | # Test CSRRSI 37 | csrrsi x8, mtvec, 0b01010 # set bits in mtvec based on the imm (0x00000015 | 0x0000000a = 0x0000001F) and set x8 to current value of mtvec (0x00000015) 38 | 39 | # Test CSRRCI 40 | csrrci x9, mtvec, 0b10000 # clear bits in mtvec based on the imm (0x0000001F & ~0x00000010 = 0x0000000F) and set x9 to current value of mtvec (0x0000001F) 41 | 42 | csrr x11, mtvec # set x11 to current value of mtvec (0x0000000F) 43 | 44 | # self-test 45 | beqz x2, fail0 # make sure x1 has value 46 | bne x5, x2, fail1 # failed on csrrw 47 | li x12, 0x100000C8 48 | beqz x12, fail0 # make sure x12 has value 49 | bne x6, x12, fail2 # failed on csrrs 50 | li x12, 0x10000000 51 | beqz x12, fail0 # make sure x12 has value 52 | bne x12, x7, fail3 #failed on csrrc 53 | li x12, 0x00000015 54 | beqz x12, fail0 # make sure x12 has value 55 | bne x12, x8, fail4 # failed on csrrwi 56 | li x12, 0x0000001F 57 | beqz x12, fail0 # make sure x12 has value 58 | bne x12, x9, fail5 # failed on csrrsi 59 | li x12, 0x0000000F 60 | beqz x12, fail0 # make sure x12 has value 61 | bne x12, x11, fail6 # failed on csrrsi 62 | 63 | 64 | 65 | 66 | ### END OF TEST CODE ### 67 | 68 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 69 | pass: 70 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 71 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 72 | ebreak 73 | 74 | fail0: 75 | li a0, 1 # fail code 76 | li a7, 93 # reached end of code 77 | ebreak 78 | 79 | fail1: 80 | li a0, 2 # fail code 81 | li a7, 93 # reached end of code 82 | ebreak 83 | 84 | fail2: 85 | li a0, 4 # fail code 86 | li a7, 93 # reached end of code 87 | ebreak 88 | 89 | fail3: 90 | li a0, 6 # fail code 91 | li a7, 93 # reached end of code 92 | ebreak 93 | 94 | fail4: 95 | li a0, 8 # fail code 96 | li a7, 93 # reached end of code 97 | ebreak 98 | 99 | fail5: 100 | li a0, 10 # fail code 101 | li a7, 93 # reached end of code 102 | ebreak 103 | 104 | fail6: 105 | li a0, 12 # fail code 106 | li a7, 93 # reached end of code 107 | ebreak 108 | 109 | 110 | # ----------------------------------------- 111 | # Data section. Note starts at 0x1000, as 112 | # set by DATAADDR variable in rv_asm.bat. 113 | # ----------------------------------------- 114 | .data 115 | 116 | # Data section 117 | data: 118 | 119 | -------------------------------------------------------------------------------- /test/extra/data_hazard.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ADD 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 1 NOP margin between dependent instructions 20 | 21 | li x1, 100 # set x1 to 100 (0x00000064) 22 | li x2, 150 # set x2 to 150 (0x00000096) 23 | add x3, x1, x2 # add x1(100) to x2(150), x3=250 (0x000000FA) 24 | nop 25 | nop 26 | nop 27 | nop 28 | nop 29 | nop 30 | li x4, 0xFA # set x4 to 0xFA (expected value for x3) 31 | nop 32 | nop 33 | nop 34 | nop 35 | nop 36 | nop 37 | beqz x4, fail0 # make sure x4 has value 38 | nop 39 | nop 40 | nop 41 | nop 42 | nop 43 | nop 44 | bne x3, x4, fail1 # branch to fail if not equal to expected value 45 | 46 | # 2 NOP margin between dependent instructions 47 | li x1, 100 # set x1 to 100 (0x00000064) 48 | li x2, 150 # set x2 to 150 (0x00000096) 49 | nop 50 | nop 51 | add x3, x1, x2 # add x1(100) to x2(150), x3=250 (0x000000FA) 52 | nop 53 | nop 54 | nop 55 | nop 56 | nop 57 | nop 58 | bne x3, x4, fail2 # branch to fail if not equal to expected value 59 | 60 | # 3 NOP margin between dependent instructions 61 | li x1, 100 # set x1 to 100 (0x00000064) 62 | li x2, 150 # set x2 to 150 (0x00000096) 63 | nop 64 | nop 65 | nop 66 | add x3, x1, x2 # add x1(100) to x2(150), x3=250 (0x000000FA) 67 | nop 68 | nop 69 | nop 70 | nop 71 | nop 72 | nop 73 | bne x3, x4, fail3 # branch to fail if not equal to expected value 74 | 75 | ### END OF TEST CODE ### 76 | pass: 77 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 78 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 79 | ebreak 80 | 81 | fail0: 82 | li a0, 1 # fail code 83 | li a7, 93 # reached end of code 84 | ebreak 85 | 86 | fail1: 87 | li a0, 2 # fail code 88 | li a7, 93 # reached end of code 89 | ebreak 90 | 91 | fail2: 92 | li a0, 4 # fail code 93 | li a7, 93 # reached end of code 94 | ebreak 95 | 96 | fail3: 97 | li a0, 6 # fail code 98 | li a7, 93 # reached end of code 99 | ebreak 100 | 101 | 102 | 103 | 104 | # ----------------------------------------- 105 | # Data section. Note starts at 0x1000, as 106 | # set by DATAADDR variable in rv_asm.bat. 107 | # ----------------------------------------- 108 | .data 109 | 110 | # Data section 111 | data: 112 | 113 | -------------------------------------------------------------------------------- /test/extra/demo1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | LCD_Init(); // Initialize LCD module with I2C address = 0x4E 6 | 7 | while(1){ 8 | LCD_Set_Cursor(1, 1); //set cursor to row 1 col 1 9 | LCD_Write_String("Demonstration #1"); 10 | LCD_Set_Cursor(2, 1); //set cursor to row 2 col 1 11 | LCD_Write_String("Hello World!!!"); 12 | } 13 | return 0; 14 | } 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/extra/exceptions.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR EXCEPTIONS (MISALIGNED LOAD, MISALIGNED STORE, EBREAK, ECALL) 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | nop 20 | nop 21 | nop 22 | nop 23 | fence 24 | fence 25 | nop 26 | nop 27 | 28 | 29 | # misaligned load address exception 30 | lla x1, trap_address_1 # set x1 to trap_address 31 | csrw mtvec, x1 # set mtvec to trap_address 32 | 33 | li x2, 0x1008 # set x2 to 0x1008 34 | lw x3, 2(x2) # load word from data mem address 0x100a to x3 (misaligned load address) 35 | j fail1 # go to fail if no exception is raised 36 | 37 | trap_address_1: 38 | fence 39 | nop 40 | csrr x4, mcause # set x4 to mcause value 41 | csrr x7, mtval # set x7 to mtval (address of misaligned address) 42 | li x5, 0x00000004 # set x5 to 0x00000004 (expected mcause value for load addr misaligned) 43 | li x8, 0x100a # set x8 to 0x100a (value of mtval or the misaligned address) 44 | beqz x5, fail0 # make sure x5 has value 45 | beqz x8, fail0 # make sure x5 has value 46 | bne x4, x5, fail2 # go to fail if mcause is wrong 47 | bne x7, x8, fail9 # go to fail if mtval is wrong 48 | 49 | 50 | # misaligned store address exception 51 | li x6, 0 # set x6 to 0 (counter) 52 | lla x1, trap_address_2 # set x1 to trap_address 53 | csrw mtvec, x1 # set mtvec to trap_address 54 | 55 | fence 56 | sh x1, 1(x2) # store halfword from x1 to data mem address 0x1009 (misaligned store address) 57 | j fail3 # go to fail if no exception is raised 58 | 59 | trap_address_2: 60 | fence 61 | nop 62 | csrr x4, mcause # set x4 to mcause value 63 | csrr x7, mtval # set x7 to mtval (address of misaligned address) 64 | li x5, 0x00000006 # set x5 to 0x00000006 (expected mcause value for store addr misaligned) 65 | li x8, 0x1009 # set x8 to 0x100a (value of mtval or the misaligned address) 66 | beqz x5, fail0 # make sure x5 has value 67 | beqz x8, fail0 # make sure x5 has value 68 | bne x4, x5, fail4 # go to fail if mcause is wrong 69 | bne x7, x8, fail9 # go to fail if mtval is wrong 70 | 71 | addi x6, x6, 1 # increment x6 72 | beq x6, x5, escape_loop # escape from loop when x6 reaches 6 73 | mret # test mret 74 | 75 | 76 | escape_loop: 77 | # ebreak exception 78 | lla x1, trap_address_3 # set x1 to trap_address 79 | csrw mtvec, x1 # set mtvec to trap_address 80 | nop 81 | fence 82 | nop 83 | fence 84 | 85 | ebreak 86 | j fail5 # go to fail if no exception raised 87 | 88 | trap_address_3: 89 | fence 90 | nop 91 | csrr x4, mcause # set x4 to mcause value 92 | li x5, 0x00000003 # set x5 to 0x0000000b (expected mcause value for ebreak) 93 | beqz x5, fail0 # make sure x5 has value 94 | bne x4, x5, fail6 # go to fail if mcause is wrong 95 | 96 | 97 | #ecall exception 98 | lla x1, trap_address_4 # set x1 to trap_address 99 | csrw mtvec, x1 # set mtvec to trap_address 100 | nop 101 | fence 102 | nop 103 | fence 104 | 105 | ecall 106 | j fail7 # go to fail if no exception raised 107 | 108 | trap_address_4: 109 | fence 110 | nop 111 | csrr x4, mcause # set x4 to mcause value 112 | li x5, 0x0000000b # set x5 to 0x0000000b (expected mcause value for ebreak) 113 | beqz x5, fail0 # make sure x5 has value 114 | bne x4, x5, fail8 # go to fail if mcause is wrong 115 | 116 | li x1, 0x1000 # set x1 to trap_address 117 | csrw mtvec, x1 # set mtvec to trap_address 118 | 119 | ### END OF TEST CODE ### 120 | 121 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 122 | pass: 123 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 124 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 125 | ebreak 126 | 127 | fail0: 128 | li a0, 1 # fail code 129 | li a7, 93 # reached end of code 130 | ebreak 131 | 132 | fail1: 133 | li a0, 2 # fail code 134 | li a7, 93 # reached end of code 135 | ebreak 136 | 137 | fail2: 138 | li a0, 4 # fail code 139 | li a7, 93 # reached end of code 140 | ebreak 141 | 142 | fail3: 143 | li a0, 6 # fail code 144 | li a7, 93 # reached end of code 145 | ebreak 146 | 147 | fail4: 148 | li a0, 8 # fail code 149 | li a7, 93 # reached end of code 150 | ebreak 151 | 152 | fail5: 153 | li a0, 10 # fail code 154 | li a7, 93 # reached end of code 155 | ebreak 156 | 157 | fail6: 158 | li a0, 12 # fail code 159 | li a7, 93 # reached end of code 160 | ebreak 161 | 162 | fail7: 163 | li a0, 14 # fail code 164 | li a7, 93 # reached end of code 165 | ebreak 166 | 167 | fail8: 168 | li a0, 16 # fail code 169 | li a7, 93 # reached end of code 170 | ebreak 171 | 172 | fail9: 173 | li a0, 18 # fail code 174 | li a7, 93 # reached end of code 175 | ebreak 176 | 177 | 178 | # ----------------------------------------- 179 | # Data section. Note starts at 0x1000, as 180 | # set by DATAADDR variable in rv_asm.bat. 181 | # ----------------------------------------- 182 | .data 183 | 184 | # Data section 185 | data: 186 | 187 | 188 | -------------------------------------------------------------------------------- /test/extra/helloworld.s: -------------------------------------------------------------------------------- 1 | # 2 | # Display String via UART TX model of ISS 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | .equ UART_TX_DATA_ADDR, 8052 18 | .equ UART_TX_BUSY_ADDR, 8056 19 | 20 | ### TEST CODE STARTS HERE ### 21 | la x1, data # set x1 to address of data (0x00001000) 22 | li x2, UART_TX_DATA_ADDR # set x2 to address of UART_TX_DATA_ADDR 23 | li x3, UART_TX_BUSY_ADDR # set x3 to address of UART_TX_BUSY_ADDR 24 | 25 | ready: 26 | lb x4, 0(x3) # load TX_BUSY 27 | bnez x4, ready # branch if UART is busy 28 | 29 | print_char: 30 | lbu x5, 0(x1) # load the character stored in data to x5 31 | sb x5, 0(x2) # store character from x5 to x2 (UART_TX_DATA_ADDR) 32 | beqz x5, exit # branch to exit if character is 0 33 | addi x1, x1, 1 # increment x1 (address of data) by 1 34 | j ready # jump to label ready 35 | 36 | 37 | ### END OF TEST CODE ### 38 | 39 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 40 | exit: 41 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 42 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 43 | ebreak 44 | 45 | # ----------------------------------------- 46 | # Data section. Note starts at 0x1000, as 47 | # set by DATAADDR variable in rv_asm.bat. 48 | # ----------------------------------------- 49 | .data 50 | 51 | # Data section 52 | data: 53 | .string "Hello World!" 54 | 55 | 56 | -------------------------------------------------------------------------------- /test/extra/instret.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ADD 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | nop 20 | fence 21 | nop 22 | fence 23 | nop 24 | 25 | csrr x1, minstret # save retired instructions (5) to x1 26 | li x2, 4 # set x2 to 5 (expected value fot rdinstret) 27 | beqz x2, fail0 # make sure x2 has value 28 | bne x1, x2, fail1 # branch to fail 29 | 30 | 31 | ### END OF TEST CODE ### 32 | 33 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 34 | pass: 35 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 36 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 37 | ebreak 38 | 39 | fail0: 40 | li a0, 1 # fail code 41 | li a7, 93 # reached end of code 42 | ebreak 43 | 44 | fail1: 45 | li a0, 2 # fail code 46 | li a7, 93 # reached end of code 47 | ebreak 48 | 49 | 50 | # ----------------------------------------- 51 | # Data section. Note starts at 0x1000, as 52 | # set by DATAADDR variable in rv_asm.bat. 53 | # ----------------------------------------- 54 | .data 55 | 56 | # Data section 57 | data: 58 | 59 | -------------------------------------------------------------------------------- /test/extra/interrupts.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR INTERRUPTS (EXTERNAL, SOFTWARE, TIMER) 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | .equ MTIME_BASE_ADDRESS, 0x80000000 18 | .equ MTIMECMP_BASE_ADDRESS, 0x80000008 19 | .equ MSIP_BASE_ADDRESS, 0x80000010 20 | 21 | ### TEST CODE STARTS HERE ### 22 | 23 | # initial interrupt configuration 24 | li x1, 0b00001000 25 | csrw mstatus, x1 # set MIE (Machine Interrupt Enable) in mstatus 26 | li x1, 0b100010001000 # 27 | csrw mie, x1 # set MEIE(Machine External Interrupt Enable),MTIE(Machine Timer Interrupt Enable), and MSIE(Machine Software Interrupt Enable) in mie 28 | lla x1, interrupt_handler # 29 | csrw mtvec, x1 # set mtvec (trap_address) to interrupt_handler 30 | 31 | 32 | # Test software interrupt 33 | li x2, MSIP_BASE_ADDRESS 34 | li x3, 1 35 | sw x3, 0(x2) # store 1 (enable) to MSIP_BASE_ADDRESS 36 | 37 | 38 | # Test timer interrupt 39 | la x1, MTIME_BASE_ADDRESS # 40 | lw x2, 0(x1) # load current value of mtime (in millisecs) 41 | addi x2, x2, 3 # add 3 in current mtime (3 millisec) 42 | la x3, MTIMECMP_BASE_ADDRESS 43 | sw x2, 0(x3) # store the compare value (plus 3 millisec in current time) 44 | sw x0, 4(x3) # load 0 to second half 45 | 46 | loop: # wait until the software or timer interrupt fires (immediate) 47 | nop 48 | j loop 49 | 50 | 51 | 52 | interrupt_handler: 53 | # determine cause of interrupt 54 | csrr x2, mcause # save mcause to x2 55 | li x3, 0x8000000b # mcause for external interrupt 56 | li x4, 0x80000003 # mcause for software interrupt 57 | li x5, 0x80000007 # mcause for timer interrupt 58 | beqz x3, fail0 # make sure x3 has value 59 | beqz x4, fail0 # make sure x4 has value 60 | beqz x5, fail0 # make sure x5 has value 61 | beq x2, x4, check_software_interrupt # cause if software interrupt 62 | beq x2, x5, check_timer_interrupt # cause is timer interrupt 63 | mret 64 | 65 | 66 | 67 | check_software_interrupt: 68 | # disable software interrrupt 69 | li x2, MSIP_BASE_ADDRESS 70 | sw x0, 0(x2) # store 0 (disable) to MSIP_BASE_ADDRESS 71 | li x10, 1 # save 1 to x10 after software interrupt 72 | mret 73 | 74 | check_timer_interrupt: 75 | # disable timer interrupt by resetting mtimecmp 76 | li x2, -1 77 | la x3, MTIMECMP_BASE_ADDRESS 78 | sw x2, 0(x3) # set MTIMECMP_BASE_ADDRESS to all 1s 79 | li x11, 1 # save 1 to x11 after timer interrupt 80 | 81 | li x15, 1 82 | bne x10, x15, fail0 # software interrupt did not fired 83 | bne x11, x15, fail1 # timer interrupt did not fired 84 | 85 | 86 | 87 | ### END OF TEST CODE ### 88 | 89 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 90 | pass: 91 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 92 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 93 | ebreak 94 | 95 | fail0: 96 | li a0, 1 # fail code 97 | li a7, 93 # reached end of code 98 | ebreak 99 | 100 | fail1: 101 | li a0, 2 # fail code 102 | li a7, 93 # reached end of code 103 | ebreak 104 | 105 | 106 | 107 | # ----------------------------------------- 108 | # Data section. Note starts at 0x1000, as 109 | # set by DATAADDR variable in rv_asm.bat. 110 | # ----------------------------------------- 111 | .data 112 | 113 | # Data section 114 | data: 115 | 116 | 117 | -------------------------------------------------------------------------------- /test/extra/jal.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR JAL 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # jump 20 | nop # no operation 21 | nop # no operation 22 | jal x1, jump1 # jump to jump1 then store next PC to x1 , x1=x1_val 23 | x1_val: 24 | j fail1 # jump to fail 25 | nop # no operation 26 | nop # no operation 27 | 28 | jump1: 29 | nop # no operation 30 | nop # no operation 31 | jal x2, jump2 # jump to jump2 then store next PC to x2, x2=x2_val 32 | x2_val: 33 | jal fail2 # jump to fail 34 | nop # no operation 35 | nop # no operation 36 | 37 | jump2: 38 | lla x3, x1_val # load address of x1_val to x3(expected value for x1) 39 | beqz x3, fail0 # make sure x3 has value 40 | lla x4, x2_val # load address of x2_val to x4 (expected value for x2) 41 | beqz x4, fail0 # make sure x4 has value 42 | bne x1, x3, fail3 # 43 | bne x2, x4, fail4 # branch to fail if not equal to expected value 44 | 45 | 46 | ### END OF TEST CODE ### 47 | 48 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 49 | pass: 50 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 51 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 52 | ebreak 53 | 54 | fail0: 55 | li a0, 1 # fail code 56 | li a7, 93 # reached end of code 57 | ebreak 58 | 59 | fail1: 60 | li a0, 2 # fail code 61 | li a7, 93 # reached end of code 62 | ebreak 63 | 64 | fail2: 65 | li a0, 4 # fail code 66 | li a7, 93 # reached end of code 67 | ebreak 68 | 69 | fail3: 70 | li a0, 6 # fail code 71 | li a7, 93 # reached end of code 72 | ebreak 73 | 74 | fail4: 75 | li a0, 8 # fail code 76 | li a7, 93 # reached end of code 77 | ebreak 78 | 79 | # ----------------------------------------- 80 | # Data section. Note starts at 0x1000, as 81 | # set by DATAADDR variable in rv_asm.bat. 82 | # ----------------------------------------- 83 | .data 84 | 85 | # Data section 86 | data: 87 | 88 | -------------------------------------------------------------------------------- /test/extra/jalr.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR JALR 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # jump register 20 | nop # no operation 21 | nop # no operation 22 | lla x1, jump1 # load address of jump1 to x1, x1=jump1 23 | jalr x2, 0(x1) # jump to address stored in x1 (jump1) then store next PC to x2 , x2=x2_val 24 | x2_val: 25 | j fail1 # jump to fail 26 | nop # no operation 27 | nop # no operation 28 | 29 | jump1: 30 | nop # no operation 31 | nop # no operation 32 | jalr x3, 24(x1) # jump to address stored in x1 plus 24 then store next PC to x3, x3=x3_val 33 | x3_val: 34 | jal fail2 # jump to fail 35 | nop # no operation 36 | nop # no operation 37 | 38 | jump2: 39 | lla x4, x2_val # load address of x2_val to x4(expected value for x2) 40 | beqz x4, fail0 # make sure x4 has value 41 | lla x5, x3_val # load address of x3_val to x5(expected value for x3) 42 | beqz x5, fail0 # make sure x5 has value 43 | bne x2, x4, fail3 # 44 | bne x3, x5, fail4 # branch to fail if not equal to expected value 45 | 46 | 47 | ### END OF TEST CODE ### 48 | 49 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 50 | pass: 51 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 52 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 53 | ebreak 54 | 55 | fail0: 56 | li a0, 1 # fail code 57 | li a7, 93 # reached end of code 58 | ebreak 59 | 60 | 61 | fail1: 62 | li a0, 2 # fail code 63 | li a7, 93 # reached end of code 64 | ebreak 65 | 66 | fail2: 67 | li a0, 4 # fail code 68 | li a7, 93 # reached end of code 69 | ebreak 70 | 71 | fail3: 72 | li a0, 6 # fail code 73 | li a7, 93 # reached end of code 74 | ebreak 75 | 76 | fail4: 77 | li a0, 8 # fail code 78 | li a7, 93 # reached end of code 79 | ebreak 80 | 81 | 82 | # ----------------------------------------- 83 | # Data section. Note starts at 0x1000, as 84 | # set by DATAADDR variable in rv_asm.bat. 85 | # ----------------------------------------- 86 | .data 87 | 88 | # Data section 89 | data: 90 | 91 | -------------------------------------------------------------------------------- /test/extra/lb.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR LB 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | # load byte with zero imm 19 | lla x1, data # set x1 to data 20 | addi x1,x1, 8 # set x1 to data + 8 21 | lb x2, 0(x1) # load byte from address data + 8 to x2, x2=0x00000077 22 | 23 | # load byte with positive imm 24 | lb x3, 11(x1) # load byte from address to x3, x3=0xFFFFFFAB 25 | 26 | # load byte with negative imm 27 | lb x4, -6(x1) # load byte from address 0x1002 to x4, x4=0x00000034 28 | 29 | #self-check 30 | li x5, 0x077 # set x5 to 0x77 (expected value for x2) 31 | beqz x5, fail0 # make sure has x5 has value 32 | li x6, -85 # set x6 to -85 (0xFFFFFFAB) (expected value for x3) 33 | beqz x6, fail0 # make sure has x6 has value 34 | li x7, 0x034 # set x7 to 0x034 (expected value for x4) 35 | beqz x7, fail0 # make sure x7 has value 36 | bne x2, x5, fail1 # 37 | bne x3, x6, fail2 # branch to fail if not equal to expected value 38 | bne x4, x7, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | 69 | # ----------------------------------------- 70 | # Data section. Note starts at 0x1000, as 71 | # set by DATAADDR variable in rv_asm.bat. 72 | # ----------------------------------------- 73 | .data 74 | data: 75 | # Data section 76 | .word 0x12345678 #1000 77 | .word 0 #1004 78 | .word 0x11335577 #1008 79 | .word 0 #100C 80 | .word 0xABCDEF19 #1010 81 | -------------------------------------------------------------------------------- /test/extra/lbu.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR LBU 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | # load byte unsigned with zero imm 19 | lla x1, data # set x1 to data 20 | addi x1,x1, 8 # set x1 to data + 8 21 | lbu x2, 0(x1) # load byte from address 0x1008 to x2, x2=0x00000077 22 | 23 | # load byte unsigned with positive imm 24 | lbu x3, 11(x1) # load byte from address 0x1013 to x3, x3=0x000000AB 25 | 26 | # load byte unsigned with negative imm (not signed extended) 27 | lbu x4, -6(x1) # load byte from address 0x1002 to x4, x4=0x00000034 28 | 29 | #self-check 30 | li x5, 0x077 # set x5 to 0x077 (expected value for x2) 31 | beqz x5, fail0 # make sure x5 has value 32 | li x6, 0x0AB # set x6 to 0x0AB (expected value for x3) 33 | beqz x6, fail0 # make sure x6 has value 34 | li x7, 0x034 # set x7 to 0x034 (expected value for x4) 35 | beqz x7, fail0 # make sure x7 has value 36 | bne x2, x5, fail1 # 37 | bne x3, x6, fail2 # branch to fail if not equal to expected value 38 | bne x4, x7, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | 69 | # ----------------------------------------- 70 | # Data section. Note starts at 0x1000, as 71 | # set by DATAADDR variable in rv_asm.bat. 72 | # ----------------------------------------- 73 | .data 74 | data: 75 | # Data section 76 | .word 0x12345678 #1000 77 | .word 0 #1004 78 | .word 0x11335577 #1008 79 | .word 0 #100C 80 | .word 0xABCDEF19 #1010 81 | -------------------------------------------------------------------------------- /test/extra/lh.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR LH 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | # load halfword with zero imm 19 | lla x1, data # set x1 to data 20 | addi x1,x1, 8 # set x1 to data + 8 21 | lh x2, 0(x1) # load halfword from address 0x1008 to x2, x2=0x00005577 22 | 23 | # load halfword with positive imm 24 | lh x3, 10(x1) # load halfword from address 0x1012 to x3, x3=0xFFFFABCD 25 | 26 | # load halfword with negative imm 27 | lh x4, -6(x1) # load byte from address 0x1002 to x4, x4=0x00001234 28 | 29 | #self-check 30 | li x5, 0x5577 # set x5 to 0x5577 (expected value for x2) 31 | beqz x5, fail0 # make sure x5 has value 32 | li x6, -21555 # set x6 to -21555 (0xFFFFABCD) (expected value for x3) 33 | beqz x6, fail0 # make sure x6 has value 34 | li x7, 0x1234 # set x7 to 0x1234 (expected value for x4) 35 | beqz x7, fail0 # make sure x7 has value 36 | bne x2, x5, fail1 # 37 | bne x3, x6, fail2 # branch to fail if not equal to expected value 38 | bne x4, x7, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | 69 | # ----------------------------------------- 70 | # Data section. Note starts at 0x1000, as 71 | # set by DATAADDR variable in rv_asm.bat. 72 | # ----------------------------------------- 73 | .data 74 | data: 75 | # Data section 76 | .word 0x12345678 #1000 77 | .word 0 #1004 78 | .word 0x11335577 #1008 79 | .word 0 #100C 80 | .word 0xABCDEF19 #1010 81 | -------------------------------------------------------------------------------- /test/extra/lhu.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR LHU 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | # load halfword unsigned with zero imm 19 | lla x1, data # set x1 to data 20 | addi x1,x1, 8 # set x1 to data + 8 21 | lhu x2, 0(x1) # load halfword from address 0x1008 to x2, x2=0x00005577 22 | 23 | # load halfword unsigned with positive imm 24 | lhu x3, 10(x1) # load halfword from address 0x1012 to x3, x3=0x0000ABCD 25 | 26 | # load halfword unsigned with negative imm 27 | lhu x4, -6(x1) # load byte from address 0x1002 to x4, x4=0x00001234 28 | 29 | #self-check 30 | li x5, 0x5577 # set x5 to 0x5577 (expected value for x2) 31 | beqz x5, fail0 # make sure x5 has value 32 | li x6, 0xABCD # set x6 to 0xABCD (0x0000ABCD) (expected value for x3) 33 | beqz x6, fail0 # make sure x6 has value 34 | li x7, 0x1234 # set x7 to 0x1234 (expected value for x4) 35 | beqz x7, fail0 # make sure x7 has value 36 | bne x2, x5, fail1 # 37 | bne x3, x6, fail2 # branch to fail if not equal to expected value 38 | bne x4, x7, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | 69 | # ----------------------------------------- 70 | # Data section. Note starts at 0x1000, as 71 | # set by DATAADDR variable in rv_asm.bat. 72 | # ----------------------------------------- 73 | .data 74 | data: 75 | # Data section 76 | .word 0x12345678 #1000 77 | .word 0 #1004 78 | .word 0x11335577 #1008 79 | .word 0 #100C 80 | .word 0xABCDEF19 #1010 81 | -------------------------------------------------------------------------------- /test/extra/lui.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR LUI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | lui x1, 0xABCDE # load 0xABCDE to upper immediate of x1 (0xABCDE000) 20 | 21 | # self-check 22 | li x2, 0 # 23 | addi x2, x2, 0xAB # 24 | slli x2, x2, 8 # 25 | addi x2, x2, 0xCD # 26 | slli x2, x2, 8 # 27 | addi x2, x2, 0xE0 # 28 | sll x2, x2, 8 # x2 = 0xABCDE000 29 | 30 | beqz x2, fail0 # make sure x2 has value 31 | bne x1, x2, fail1 # branch to fail if not equal to expected value 32 | 33 | ### END OF TEST CODE ### 34 | 35 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 36 | pass: 37 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 38 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 39 | ebreak 40 | 41 | fail0: 42 | li a0, 1 # fail code 43 | li a7, 93 # reached end of code 44 | ebreak 45 | 46 | fail1: 47 | li a0, 2 # fail code 48 | li a7, 93 # reached end of code 49 | ebreak 50 | 51 | # ----------------------------------------- 52 | # Data section. Note starts at 0x1000, as 53 | # set by DATAADDR variable in rv_asm.bat. 54 | # ----------------------------------------- 55 | .data 56 | 57 | # Data section 58 | data: 59 | 60 | -------------------------------------------------------------------------------- /test/extra/lw.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR LW 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | # load word with zero imm 19 | lla x1, data # set x1 to data 20 | addi x1,x1, 8 # set x1 to data + 8 21 | lw x2, 0(x1) # load word from address data to x2, x2=0x11335577 22 | 23 | # load word with positive imm 24 | lw x3, 8(x1) # load word from address 0x1010 to x3, x3=0xABCDEF19 25 | 26 | # load halfword with negative imm 27 | lw x4, -8(x1) # load word from address 0x1000 to x4, x4=0x12345678 28 | 29 | #self-check 30 | li x5, 0x11335577 # set x5 to 0x11335577 (expected value for x2) 31 | beqz x5, fail0 # make sure x5 has value 32 | li x6, 0xABCDEF19 # set x6 to 0xABCDEF19 (0xFFFFABCD) (expected value for x3) 33 | beqz x6, fail0 # make sure x6 has value 34 | li x7, 0x12345678 # set x7 to 0x12345678 (expected value for x4) 35 | beqz x7, fail0 # make sure x7 has value 36 | bne x2, x5, fail1 # 37 | bne x3, x6, fail2 # branch to fail if not equal to expected value 38 | bne x4, x7, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | 69 | # ----------------------------------------- 70 | # Data section. Note starts at 0x1000, as 71 | # set by DATAADDR variable in rv_asm.bat. 72 | # ----------------------------------------- 73 | .data 74 | data: 75 | # Data section 76 | .word 0x12345678 77 | .word 0 78 | .word 0x11335577 79 | .word 0 80 | .word 0xABCDEF19 81 | -------------------------------------------------------------------------------- /test/extra/no_hazard.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ADD 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 + 150 = 250 (positive answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | nop 22 | nop 23 | nop 24 | nop 25 | nop 26 | nop 27 | li x2, 150 # set x2 to 150 (0x00000096) 28 | nop 29 | nop 30 | nop 31 | nop 32 | nop 33 | nop 34 | add x3, x1, x2 # add x1(100) to x2(150), x3=250 (0x000000FA) 35 | nop 36 | nop 37 | nop 38 | nop 39 | nop 40 | nop 41 | ### END OF TEST CODE ### 42 | 43 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | nop 46 | nop 47 | nop 48 | nop 49 | nop 50 | nop 51 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 52 | nop 53 | nop 54 | nop 55 | nop 56 | nop 57 | nop 58 | ebreak 59 | 60 | # ----------------------------------------- 61 | # Data section. Note starts at 0x1000, as 62 | # set by DATAADDR variable in rv_asm.bat. 63 | # ----------------------------------------- 64 | .data 65 | 66 | # Data section 67 | data: 68 | 69 | -------------------------------------------------------------------------------- /test/extra/or.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR OR 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 | 150 = 246 (nonzero answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 150 # set x2 to 150 (0x00000096) 22 | or x3, x1, x2 # or x1(100) to x2(150), x3=246 (0x000000F6) 23 | 24 | # -2048 | 2047 = -1 (all ones) 25 | li x4, -2048 # set x4 to -2048 (0xFFFFF800) 26 | li x5, 2047 # set x5 to 2047 (0x000007FF) 27 | or x6, x4, x5 # or x4(-2048) to x5(2047), x6=-1 (0xFFFFFFFF) 28 | 29 | #self-check 30 | li x7, 246 # set x7 to 246 (expected value for x3) 31 | beqz x7, fail0 # make sure x7 has value 32 | li x8, -1 # set x8 to -1 (expected value for x6) 33 | beqz x8, fail0 # make sure x8 has value 34 | bne x3, x7, fail1 # 35 | bne x6, x8, fail2 # branch to fail if not equal to expected value 36 | 37 | ### END OF TEST CODE ### 38 | 39 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 40 | pass: 41 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 42 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 43 | ebreak 44 | 45 | fail0: 46 | li a0, 1 # fail code 47 | li a7, 93 # reached end of code 48 | ebreak 49 | 50 | fail1: 51 | li a0, 2 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | fail2: 56 | li a0, 4 # fail code 57 | li a7, 93 # reached end of code 58 | ebreak 59 | 60 | # ----------------------------------------- 61 | # Data section. Note starts at 0x1000, as 62 | # set by DATAADDR variable in rv_asm.bat. 63 | # ----------------------------------------- 64 | .data 65 | 66 | # Data section 67 | data: 68 | 69 | -------------------------------------------------------------------------------- /test/extra/ori.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR ORI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 | 150 = 246 (nonzero answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | ori x2, x1, 150 # ori x1(100) to 150, x2=246 (0x000000F6) 22 | 23 | # -2048 | 2047 = -1 (all ones) 24 | li x3, -2048 # set x3 to -2048 (0xFFFFF800) 25 | ori x4, x3, 2047 # ori x3(-2048) to 2047, x4=-1 (0xFFFFFFFF) 26 | 27 | #self-check 28 | li x5, 246 # set x5 to 246 (expected value for x2) 29 | beqz x5, fail0 # make sure x5 has value 30 | li x6, -1 # set x6 to -1 (expected value for x4) 31 | beqz x6, fail0 # make sure x6 has value 32 | bne x2, x5, fail1 # 33 | bne x4, x6, fail2 # branch to fail if not equal to expected value 34 | 35 | ### END OF TEST CODE ### 36 | 37 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 38 | pass: 39 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 40 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 41 | ebreak 42 | 43 | fail0: 44 | li a0, 1 # fail code 45 | li a7, 93 # reached end of code 46 | ebreak 47 | 48 | fail1: 49 | li a0, 2 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail2: 54 | li a0, 4 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | # ----------------------------------------- 59 | # Data section. Note starts at 0x1000, as 60 | # set by DATAADDR variable in rv_asm.bat. 61 | # ----------------------------------------- 62 | .data 63 | 64 | # Data section 65 | data: 66 | 67 | -------------------------------------------------------------------------------- /test/extra/sb.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SB 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # store byte with zero immediate 20 | li x1, 0x12345678 # set x1 to 0x12345678 21 | li x2, 0x1008 # set x2 to 0x1008 22 | sb x1, 0(x2) # store byte from x1 (0x12345678) to 0x1008, mem_byte(0x1008)=0x78 23 | 24 | # store byte with positive immediate 25 | li x3, 0xAABBCCDD # set x3 to 0xAABBCCDD 26 | sb x3, 1(x2) # store byte from x3 (0xAABBCCDD) to 0x1009, mem_byte(0x1009)=0xDD 27 | 28 | #store byte with negative immediate 29 | sb x3, -4(x2) # store byte from x3(0xAABBCCDD) to 0x1004, mem_byte(0x1004)=0xDD 30 | 31 | # self-check 32 | li x4, 0x78 # set x4 to 0x78 (expected value for mem_byte(0x1008) 33 | beqz x4, fail0 # make sure x4 has value 34 | li x5, 0xDD # set x5 to 0xDD (expected value for mem_byte(0x1009) and mem_byte(0x1004) ) 35 | beqz x5, fail0 # make sure x5 has value 36 | lbu x6, 0(x2) # load byte from address 0x1008 to x6 (0x78) 37 | lbu x7, 1(x2) # load byte from address 0x1009 to x7 (0xDD) 38 | lbu x8, -4(x2) # load byte from address 0x1004 to x8 (0xDD) 39 | bne x6, x4, fail1 # 40 | bne x7, x5, fail2 # branch to fail if not equal to expected value 41 | bne x8, x5, fail3 # 42 | 43 | 44 | 45 | ### END OF TEST CODE ### 46 | 47 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 48 | pass: 49 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 50 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 51 | ebreak 52 | 53 | fail0: 54 | li a0, 1 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail1: 59 | li a0, 2 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail2: 64 | li a0, 4 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | fail3: 69 | li a0, 6 # fail code 70 | li a7, 93 # reached end of code 71 | ebreak 72 | 73 | # ----------------------------------------- 74 | # Data section. Note starts at 0x1000, as 75 | # set by DATAADDR variable in rv_asm.bat. 76 | # ----------------------------------------- 77 | .data 78 | 79 | # Data section 80 | data: 81 | 82 | -------------------------------------------------------------------------------- /test/extra/sh.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SH 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # store halfword with zero immediate 20 | li x1, 0x12345678 # set x1 to 0x12345678 21 | li x2, 0x1008 # set x2 to 0x1008 22 | sh x1, 0(x2) # store halfword from x1 (0x12345678) to 0x1008, mem_hw(0x1008)=0x5678 23 | 24 | # store halfword with positive immediate 25 | li x3, 0xAABBCCDD # set x3 to 0xAABBCCDD 26 | sh x3, 2(x2) # store halfword from x3 (0xAABBCCDD) to 0x100a, mem_hw(0x100a)=0xCCDD 27 | 28 | #store halfword with negative immediate 29 | sh x3, -4(x2) # store halfword from x3(0xAABBCCDD) to 0x1004, mem_hw(0x1004)=0xCCDD 30 | 31 | # self-check 32 | li x4, 0x5678 # set x4 to 0x5678 (expected value for mem_hw(0x1008) 33 | beqz x4, fail0 # make sure x4 has value 34 | li x5, 0xCCDD # set x5 to 0xCCDD (expected value for mem_hw(0x100a) and mem_hw(0x1004) ) 35 | beqz x5, fail0 # make sure x5 has value 36 | lhu x6, 0(x2) # load halfword from address 0x1008 to x6 (0x5678) 37 | lhu x7, 2(x2) # load halfword from address 0x100a to x7 (0xCCDD) 38 | lhu x8, -4(x2) # load halfword from address 0x1004 to x8 (0xCCDD) 39 | bne x6, x4, fail1 # 40 | bne x7, x5, fail2 # branch to fail if not equal to expected value 41 | bne x8, x5, fail3 # 42 | 43 | 44 | 45 | ### END OF TEST CODE ### 46 | 47 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 48 | pass: 49 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 50 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 51 | ebreak 52 | 53 | fail0: 54 | li a0, 1 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail1: 59 | li a0, 2 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail2: 64 | li a0, 4 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | fail3: 69 | li a0, 6 # fail code 70 | li a7, 93 # reached end of code 71 | ebreak 72 | 73 | # ----------------------------------------- 74 | # Data section. Note starts at 0x1000, as 75 | # set by DATAADDR variable in rv_asm.bat. 76 | # ----------------------------------------- 77 | .data 78 | 79 | # Data section 80 | data: 81 | 82 | -------------------------------------------------------------------------------- /test/extra/sll.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SLL 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | 20 | # 50 << 5 = 1600 (shift to nonzero value) 21 | li x1, 50 # set x1 to 50 (0x00000032) 22 | li x2, 5 # set x2 to 5 (0x00000005) 23 | sll x3, x1, x2 # shift left x1(50) by x2(5), x3=1600 (0x00000640) 24 | 25 | # 50 << 31 = 0 (shift to zero) 26 | li x4, 31 # set x4 to 31 (0x0000001F) 27 | sll x5, x1, x4 # shift left x1(50) by x4(31), x5=0 (0x00000000) 28 | 29 | # 50 << 2021 = 1600 (truncate to 5 bits before shifting) 30 | li x6, 2021 # set x6 to 2021 (0x000007E5) 31 | sll x7, x1, x6 # shift left x1(50) by 5 (truncate x6(2021) to 5 bits first), x7=1600 (0x00000640) 32 | 33 | #self-check 34 | li x8, 1600 # set x8 to 1600 (expected value for x3 and x7) 35 | beqz x8, fail0 # make sure x8 has value 36 | bne x3, x8, fail1 # 37 | bnez x5, fail2 # branch to fail if not equal to expected value 38 | bne x7, x8, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | # ----------------------------------------- 69 | # Data section. Note starts at 0x1000, as 70 | # set by DATAADDR variable in rv_asm.bat. 71 | # ----------------------------------------- 72 | .data 73 | 74 | # Data section 75 | data: 76 | 77 | -------------------------------------------------------------------------------- /test/extra/slli.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SLLI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | 20 | # 50 << 5 = 1600 (shift to nonzero value) 21 | li x1, 50 # set x1 to 50 (0x00000032) 22 | slli x2, x1, 5 # shift left x1(50) by 5, x2=1600 (0x00000640) 23 | 24 | # 50 << 31 = 0 (shift to zero) 25 | slli x3, x1, 31 # shift left x1(50) by 31, x3=0 (0x00000000) 26 | 27 | #self-check 28 | li x4, 1600 # set x4 to 1600 (expected value for x2) 29 | beqz x4, fail0 # make sure x4 has value 30 | bne x2, x4, fail1 # 31 | bnez x3, fail2 # branch to fail if not equal to expected value 32 | 33 | 34 | ### END OF TEST CODE ### 35 | 36 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 37 | pass: 38 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 39 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 40 | ebreak 41 | 42 | fail0: 43 | li a0, 1 # fail code 44 | li a7, 93 # reached end of code 45 | ebreak 46 | 47 | fail1: 48 | li a0, 2 # fail code 49 | li a7, 93 # reached end of code 50 | ebreak 51 | 52 | fail2: 53 | li a0, 4 # fail code 54 | li a7, 93 # reached end of code 55 | ebreak 56 | 57 | 58 | # ----------------------------------------- 59 | # Data section. Note starts at 0x1000, as 60 | # set by DATAADDR variable in rv_asm.bat. 61 | # ----------------------------------------- 62 | .data 63 | 64 | # Data section 65 | data: 66 | 67 | -------------------------------------------------------------------------------- /test/extra/slt.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SLT 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # set 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 150 # set x2 to 150 (0x00000096) 22 | slt x3, x1, x2 # x1 < x2 ? , x3=1 23 | 24 | # not set 25 | slt x4, x2, x1 # x2 < x1 ? , x4=0 26 | 27 | # signed number (set) 28 | li x5, -100 # set x5 to -100 (0xFFFFFF9C) 29 | li x6, -150 # set x6 to -150 (0xFFFFFF6A) 30 | slt x7, x6, x5 # x6 < x5 ? , x7=1 31 | 32 | # signed number (not set) 33 | slt x8, x5, x6 # x5 < x6 ? , x8=0 34 | 35 | #self-check 36 | beqz x3, fail1 # 37 | bnez x4, fail2 # branch to fail if not equal to expected value 38 | beqz x7, fail3 # 39 | bnez x8, fail4 # 40 | 41 | 42 | ### END OF TEST CODE ### 43 | 44 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 45 | pass: 46 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 47 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 48 | ebreak 49 | 50 | fail1: 51 | li a0, 2 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | fail2: 56 | li a0, 4 # fail code 57 | li a7, 93 # reached end of code 58 | ebreak 59 | 60 | fail3: 61 | li a0, 6 # fail code 62 | li a7, 93 # reached end of code 63 | ebreak 64 | 65 | fail4: 66 | li a0, 8 # fail code 67 | li a7, 93 # reached end of code 68 | ebreak 69 | 70 | # ----------------------------------------- 71 | # Data section. Note starts at 0x1000, as 72 | # set by DATAADDR variable in rv_asm.bat. 73 | # ----------------------------------------- 74 | .data 75 | 76 | # Data section 77 | data: 78 | 79 | -------------------------------------------------------------------------------- /test/extra/slti.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SLTI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # set 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | slti x2, x1, 150 # x1 < 150 ? , x2=1 22 | 23 | # not set 24 | slti x3, x1, 50 # x1 < 50 ? , x3=0 25 | 26 | # signed number (set) 27 | li x4, -150 # set x4 to -150 (0xFFFFFF6A) 28 | slti x5, x4, -100 # x4 < -100 ? , x5=1 29 | 30 | # signed number (not set) 31 | slt x6, x4, -200 # x4 < -200 ? , x6=0 32 | 33 | #self-check 34 | beqz x2, fail1 # 35 | bnez x3, fail2 # branch to fail if not equal to expected value 36 | beqz x5, fail3 # 37 | bnez x6, fail4 # 38 | 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail1: 49 | li a0, 2 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail2: 54 | li a0, 4 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail3: 59 | li a0, 6 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail4: 64 | li a0, 8 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | # ----------------------------------------- 69 | # Data section. Note starts at 0x1000, as 70 | # set by DATAADDR variable in rv_asm.bat. 71 | # ----------------------------------------- 72 | .data 73 | 74 | # Data section 75 | data: 76 | 77 | -------------------------------------------------------------------------------- /test/extra/sltiu.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SLTIU 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # set 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | sltiu x2, x1, 150 # unsigned(x1) < unsigned(150) ? , x2=1 22 | 23 | # not set 24 | sltiu x3, x1, 50 # unsigned(x1) < unsigned(50) ? , x3=0 25 | 26 | # signed number (set) 27 | li x4, -150 # set x4 to -150 (0xFFFFFF6A) 28 | sltiu x5, x4, -100 # unsigned(x4) < unsigned(-100) ? , x5=1 29 | 30 | # signed number (not set) 31 | sltiu x6, x4, -200 # unsigned(x4) < unsigned(-200) ? , x6=0 32 | 33 | #signed and unsigned 34 | sltiu x7, x1, -100 # unsigned(x1) < unisgned(-100)? , x7=1 35 | 36 | #self-check 37 | beqz x2, fail1 # 38 | bnez x3, fail2 # 39 | beqz x5, fail3 # branch to fail if not equal to expected value 40 | bnez x6, fail4 # 41 | beqz x7, fail5 # 42 | 43 | 44 | ### END OF TEST CODE ### 45 | 46 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 47 | pass: 48 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 49 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 50 | ebreak 51 | 52 | fail1: 53 | li a0, 2 # fail code 54 | li a7, 93 # reached end of code 55 | ebreak 56 | 57 | fail2: 58 | li a0, 4 # fail code 59 | li a7, 93 # reached end of code 60 | ebreak 61 | 62 | fail3: 63 | li a0, 6 # fail code 64 | li a7, 93 # reached end of code 65 | ebreak 66 | 67 | fail4: 68 | li a0, 8 # fail code 69 | li a7, 93 # reached end of code 70 | ebreak 71 | 72 | fail5: 73 | li a0, 10 # fail code 74 | li a7, 93 # reached end of code 75 | ebreak 76 | 77 | # ----------------------------------------- 78 | # Data section. Note starts at 0x1000, as 79 | # set by DATAADDR variable in rv_asm.bat. 80 | # ----------------------------------------- 81 | .data 82 | 83 | # Data section 84 | data: 85 | 86 | -------------------------------------------------------------------------------- /test/extra/sltu.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SLTU 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # set 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 150 # set x2 to 150 (0x00000096) 22 | sltu x3, x1, x2 # unsigned(x1) < unsigned(x2) ? , x3=1 23 | 24 | # not set 25 | sltu x4, x2, x1 # unsigned(x2) < unsigned(x1) ? , x4=0 26 | 27 | # signed number (set) 28 | li x5, -100 # set x5 to -100 (0xFFFFFF9C) 29 | li x6, -150 # set x6 to -150 (0xFFFFFF6A) 30 | sltu x7, x6, x5 # unsigned(x6) < unsigned(x5) ? , x7=1 31 | 32 | # signed number (not set) 33 | sltu x8, x5, x6 # unsigned(x5) < unsigned(x6) ? , x8=0 34 | 35 | #signed and unsigned 36 | sltu x9, x2, x6 # unsigned(x2) < unisgned(x6)? , x9=1 37 | 38 | #self-check 39 | beqz x3, fail1 # 40 | bnez x4, fail2 # 41 | beqz x7, fail3 # branch to fail if not equal to expected value 42 | bnez x8, fail4 # 43 | beqz x9, fail5 # 44 | 45 | 46 | ### END OF TEST CODE ### 47 | 48 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 49 | pass: 50 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 51 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 52 | ebreak 53 | 54 | fail1: 55 | li a0, 2 # fail code 56 | li a7, 93 # reached end of code 57 | ebreak 58 | 59 | fail2: 60 | li a0, 4 # fail code 61 | li a7, 93 # reached end of code 62 | ebreak 63 | 64 | fail3: 65 | li a0, 6 # fail code 66 | li a7, 93 # reached end of code 67 | ebreak 68 | 69 | fail4: 70 | li a0, 8 # fail code 71 | li a7, 93 # reached end of code 72 | ebreak 73 | 74 | fail5: 75 | li a0, 10 # fail code 76 | li a7, 93 # reached end of code 77 | ebreak 78 | 79 | # ----------------------------------------- 80 | # Data section. Note starts at 0x1000, as 81 | # set by DATAADDR variable in rv_asm.bat. 82 | # ----------------------------------------- 83 | .data 84 | 85 | # Data section 86 | data: 87 | 88 | -------------------------------------------------------------------------------- /test/extra/sra.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SRA 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | 20 | # 1024 >>> 5 = 32 (shift positive number) 21 | li x1, 1024 # set x1 to 1024 (0x00000400) 22 | li x2, 5 # set x2 to 5 (0x00000005) 23 | sra x3, x1, x2 # shift right arithmetic x1(1024) by x2(5), x3=32 (0x00000020) 24 | 25 | # -1024 >>> 5 = -32 (shift negative number) 26 | li x4, -1024 # set x4 to -1024 (0xFFFFFC00) 27 | sra x5, x4, x2 # shift right arithmetic x4(-1024) by x2(5), x5=-32 (0xFFFFFFE0) 28 | 29 | # -1024 >>> 2021 = -32 (truncate to 5 bits before shifting) 30 | li x6, 2021 # set x6 to 2021 (0x000007E5) 31 | sra x7, x4, x6 # shift right x4(-1024) by 5 (truncate x6(2021) to 5 bits first), x7=-32 (0xFFFFFFE0) 32 | 33 | #self-check 34 | li x8, 32 # set x8 to 32 (expected value for x3) 35 | beqz x8, fail0 # make sure x8 has value 36 | li x9, -32 # set x9 to -32 (expected value for x5 and x7) 37 | beqz x9, fail0 # make sure x9 has value 38 | bne x3, x8, fail1 # 39 | bne x5, x9, fail2 # branch to fail if not equal to expected value 40 | bne x7, x9, fail3 # 41 | 42 | ### END OF TEST CODE ### 43 | 44 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 45 | pass: 46 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 47 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 48 | ebreak 49 | 50 | fail0: 51 | li a0, 1 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | fail1: 56 | li a0, 2 # fail code 57 | li a7, 93 # reached end of code 58 | ebreak 59 | 60 | fail2: 61 | li a0, 4 # fail code 62 | li a7, 93 # reached end of code 63 | ebreak 64 | 65 | fail3: 66 | li a0, 6 # fail code 67 | li a7, 93 # reached end of code 68 | ebreak 69 | 70 | # ----------------------------------------- 71 | # Data section. Note starts at 0x1000, as 72 | # set by DATAADDR variable in rv_asm.bat. 73 | # ----------------------------------------- 74 | .data 75 | 76 | # Data section 77 | data: 78 | 79 | -------------------------------------------------------------------------------- /test/extra/srai.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SRAI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | 20 | # 1024 >>> 5 = 32 (shift positive number) 21 | li x1, 1024 # set x1 to 1024 (0x00000400) 22 | srai x2, x1, 5 # shift right arithmetic x1(1024) by 5, x2=32 (0x00000020) 23 | 24 | # -1024 >>> 5 = -32 (shift negative number) 25 | li x3, -1024 # set x3 to -1024 (0xFFFFFC00) 26 | srai x4, x3, 5 # shift right arithmetic x3(-1024) by 5, x4=-32 (0xFFFFFFE0) 27 | 28 | 29 | #self-check 30 | li x5, 32 # set x5 to 32 (expected value for x2) 31 | beqz x5, fail0 # make sure x5 has value 32 | li x6, -32 # set x6 to -32 (expected value for x4) 33 | beqz x6, fail0 # make sure x6 has value 34 | bne x2, x5, fail1 # 35 | bne x4, x6, fail2 # branch to fail if not equal to expected value 36 | 37 | ### END OF TEST CODE ### 38 | 39 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 40 | pass: 41 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 42 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 43 | ebreak 44 | 45 | fail0: 46 | li a0, 1 # fail code 47 | li a7, 93 # reached end of code 48 | ebreak 49 | 50 | fail1: 51 | li a0, 2 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | fail2: 56 | li a0, 4 # fail code 57 | li a7, 93 # reached end of code 58 | ebreak 59 | 60 | 61 | # ----------------------------------------- 62 | # Data section. Note starts at 0x1000, as 63 | # set by DATAADDR variable in rv_asm.bat. 64 | # ----------------------------------------- 65 | .data 66 | 67 | # Data section 68 | data: 69 | 70 | -------------------------------------------------------------------------------- /test/extra/srl.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SRL 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | 20 | # 1024 >> 5 = 32 (shift to nonzero value) 21 | li x1, 1024 # set x1 to 1024 (0x00000400) 22 | li x2, 5 # set x2 to 5 (0x00000005) 23 | srl x3, x1, x2 # shift right logical x1(1024) by x2(5), x3=32 (0x00000020) 24 | 25 | # 1024 >> 11 = 0 (shift to zero) 26 | li x4, 11 # set x4 to 11 (0x0000000B) 27 | srl x5, x1, x4 # shift right x1(1024) by x4(11), x5=0 (0x00000000) 28 | 29 | # 1024 >> 2021 = 32 (truncate to 5 bits before shifting) 30 | li x6, 2021 # set x6 to 2021 (0x000007E5) 31 | srl x7, x1, x6 # shift right x1(1024) by 5 (truncate x6(2021) to 5 bits first), x7=32 (0x00000020) 32 | 33 | # -1024 >> 23 = 511 (shift negative number logically) 34 | li x8, -1024 # set x8 to -1024 (0xFFFFFC00) 35 | li x9, 23 # set x9 to 23 (0x00000017) 36 | srl x11, x8, x9 # shift right logical x8(-1024) by x9(23), x11=511 (0x000001FF) 37 | 38 | #self-check 39 | li x12, 32 # set x12 to 32 (expected value for x3 and x7) 40 | beqz x12, fail0 # make sure x12 has value 41 | li x13, 511 # set x13 to 511 (expected value for x11) 42 | beqz x13, fail0 # make sure x13 has value 43 | bne x3, x12, fail1 # 44 | bnez x5, fail2 # branch to fail if not equal to expected value 45 | bne x7, x12, fail3 # 46 | bne x11, x13, fail4 # 47 | 48 | ### END OF TEST CODE ### 49 | 50 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 51 | pass: 52 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 53 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 54 | ebreak 55 | 56 | fail0: 57 | li a0, 1 # fail code 58 | li a7, 93 # reached end of code 59 | ebreak 60 | 61 | fail1: 62 | li a0, 2 # fail code 63 | li a7, 93 # reached end of code 64 | ebreak 65 | 66 | fail2: 67 | li a0, 4 # fail code 68 | li a7, 93 # reached end of code 69 | ebreak 70 | 71 | fail3: 72 | li a0, 6 # fail code 73 | li a7, 93 # reached end of code 74 | ebreak 75 | 76 | fail4: 77 | li a0, 8 # fail code 78 | li a7, 93 # reached end of code 79 | ebreak 80 | 81 | # ----------------------------------------- 82 | # Data section. Note starts at 0x1000, as 83 | # set by DATAADDR variable in rv_asm.bat. 84 | # ----------------------------------------- 85 | .data 86 | 87 | # Data section 88 | data: 89 | 90 | -------------------------------------------------------------------------------- /test/extra/srli.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SRLI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | 20 | # 1024 >> 5 = 32 (shift to nonzero value) 21 | li x1, 1024 # set x1 to 1024 (0x00000400) 22 | srli x2, x1, 5 # shift right logical x1(1024) by 5, x2=32 (0x00000020) 23 | 24 | # 1024 >> 11 = 0 (shift to zero) 25 | srli x3, x1, 11 # shift right logical x1(1024) by 11, x3=0 (0x00000000) 26 | 27 | # -1024 >> 23 = 511 (shift negative number logically) 28 | li x4, -1024 # set x4 to -1024 (0xFFFFFC00) 29 | srli x5, x4, 23 # shift right logical x4(-1024) by 23, x5=511 (0x000001FF) 30 | 31 | #self-check 32 | li x6, 32 # set x6 to 32 (expected value for x2) 33 | beqz x6, fail0 # make sure x6 has value 34 | li x7, 511 # set x7 to 511 (expected value for x5) 35 | beqz x7, fail0 # make sure x7 has value 36 | bne x2, x6, fail1 # 37 | bnez x3, fail2 # branch to fail if not equal to expected value 38 | bne x5, x7, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | # ----------------------------------------- 69 | # Data section. Note starts at 0x1000, as 70 | # set by DATAADDR variable in rv_asm.bat. 71 | # ----------------------------------------- 72 | .data 73 | 74 | # Data section 75 | data: 76 | 77 | -------------------------------------------------------------------------------- /test/extra/sub.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SUB 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 150 - 100 = 50 (positive answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 150 # set x2 to 150 (0x00000096) 22 | sub x3, x2, x1 # subtract x2(150) to x1(100), x3=50 (0x00000032) 23 | 24 | # 100 - 150 = -50 (negative answer) 25 | sub x4, x1, x2 # subtract x1(100) to x2(150), x4=-50 (0xFFFFFFCE) 26 | 27 | # 0 - (-100) = 100 (negative of negative) 28 | li x5, -100 # set x5 to -100 (0xFFFFFF9C) 29 | sub x6, x0, x5 # subtract x0(0) to x5(-100), x6=100 (0x00000064) 30 | 31 | #self-check 32 | li x7, 50 # set x7 to 50 (expected value for x3) 33 | beqz x7, fail0 # make sure x7 has value 34 | li x8, -50 # set x8 to -50 (expected value for x4) 35 | beqz x8, fail0 # make sure x8 has value 36 | bne x7, x3, fail1 # 37 | bne x8, x4, fail2 # branch to fail if not equal to expected value 38 | bne x1, x6, fail3 # 39 | 40 | ### END OF TEST CODE ### 41 | 42 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 43 | pass: 44 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 45 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 46 | ebreak 47 | 48 | fail0: 49 | li a0, 1 # fail code 50 | li a7, 93 # reached end of code 51 | ebreak 52 | 53 | fail1: 54 | li a0, 2 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail2: 59 | li a0, 4 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail3: 64 | li a0, 6 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | # ----------------------------------------- 69 | # Data section. Note starts at 0x1000, as 70 | # set by DATAADDR variable in rv_asm.bat. 71 | # ----------------------------------------- 72 | .data 73 | 74 | # Data section 75 | data: 76 | 77 | -------------------------------------------------------------------------------- /test/extra/sw.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR SW 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # store word with zero immediate 20 | li x1, 0x12345678 # set x1 to 0x12345678 21 | li x2, 0x1008 # set x2 to 0x1008 22 | sw x1, 0(x2) # store word from x1 (0x12345678) to 0x1008, mem(0x1008)=0x12345678 23 | 24 | # store word with positive immediate 25 | li x3, 0xAABBCCDD # set x3 to 0xAABBCCDD 26 | sw x3, 4(x2) # store word from x3 (0xAABBCCDD) to 0x100C, mem(0x100C)=0xAABBCCDD 27 | 28 | #store word with negative immediate 29 | sw x3, -4(x2) # store word from x3(0xAABBCCDD) to 0x1004, mem(0x1004)=0xAABBCCDD 30 | 31 | # self-check 32 | li x4, 0x12345678 # set x4 to 0x12345678 (expected value for mem(0x1008) 33 | beqz x4, fail0 # make sure x4 has value 34 | li x5, 0xAABBCCDD # set x5 to 0xAABBCCDD (expected value for mem(0x100C) and mem(0x1004) ) 35 | beqz x5, fail0 # make sure x5 has value 36 | lw x6, 0(x2) # load word from address 0x1008 to x6 (0x12345678) 37 | lw x7, 4(x2) # load word from address 0x100C to x7 (0xAABBCCDD) 38 | lw x8, -4(x2) # load word from address 0x1004 to x8 (0xAABBCCDD) 39 | bne x6, x4, fail1 # 40 | bne x7, x5, fail2 # branch to fail if not equal to expected value 41 | bne x8, x5, fail3 # 42 | 43 | 44 | 45 | ### END OF TEST CODE ### 46 | 47 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 48 | pass: 49 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 50 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 51 | ebreak 52 | 53 | fail0: 54 | li a0, 1 # fail code 55 | li a7, 93 # reached end of code 56 | ebreak 57 | 58 | fail1: 59 | li a0, 2 # fail code 60 | li a7, 93 # reached end of code 61 | ebreak 62 | 63 | fail2: 64 | li a0, 4 # fail code 65 | li a7, 93 # reached end of code 66 | ebreak 67 | 68 | fail3: 69 | li a0, 6 # fail code 70 | li a7, 93 # reached end of code 71 | ebreak 72 | 73 | # ----------------------------------------- 74 | # Data section. Note starts at 0x1000, as 75 | # set by DATAADDR variable in rv_asm.bat. 76 | # ----------------------------------------- 77 | .data 78 | 79 | # Data section 80 | data: 81 | 82 | -------------------------------------------------------------------------------- /test/extra/test_gpio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | int counter = 0; 6 | gpio_write_pin(10, 1); //write to a specific GPIO pin (automatically set pin to write mode) 7 | delay_ticks(100); //after 100 cpu clock ticks 8 | gpio_write_pin(10, 0); //write to a specific GPIO pin (automatically set pin to write mode) 9 | delay_ticks(100); //after 100 cpu clock ticks 10 | gpio_write_pin(10, 1); //write to a specific GPIO pin (automatically set pin to write mode) 11 | delay_ticks(100); //after 100 cpu clock ticks 12 | /*while(1)*/{ 13 | toggle_gpio(5); //toggle a specific GPIO pin (automatically set pin to write mode) 14 | delay_ticks(100); //after 100 cpu clock ticks 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/extra/test_hygro.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(){ 6 | uart_print("Start HygroPMOD....\n"); 7 | 8 | // Capture and print temperature and humidity data 2x per second 9 | int val; 10 | char msg[5]; //max of 5 chars 11 | 12 | while(1){ 13 | hygroi2c_begin(); 14 | val = (int) hygroi2c_getTemperature(); 15 | itoa(val, msg, 10); 16 | uart_print("\nTemperature: "); 17 | uart_print(msg); 18 | 19 | val = (int) hygroi2c_getHumidity(); 20 | itoa(val, msg, 10); 21 | uart_print("\nHumidity: "); 22 | uart_print(msg); 23 | delay_ms(1000); // 1 sample per second (temp + humidity) maximum 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/extra/test_hygro.c_backup: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | char sample[10]; 6 | uart_print("Start HygroPMOD....\n"); 7 | sprintf_(sample, "%x", 0x96); 8 | uart_print(sample); 9 | uart_print("\n"); 10 | // Capture and print temperature and humidity data 2x per second 11 | int val_temp, val_hum; 12 | char msg[20];//max of 5 chars 13 | int buffer_full; 14 | char rx_data; 15 | int rd_pin; 16 | /*while(1)*/{ 17 | hygroi2c_begin(); 18 | val_temp = (int)hygroi2c_getTemperature(); 19 | sprintf_(msg, "%d", val_temp); 20 | //uart_print("\nTemperature: "); 21 | uart_print(msg); 22 | uart_print(";"); 23 | 24 | val_hum = (int)hygroi2c_getHumidity(); 25 | sprintf_(msg, "%d", val_hum); 26 | //uart_print("\nHumidity: "); 27 | uart_print(msg); 28 | uart_print(";"); 29 | if(val_temp<=35) { 30 | uart_print("a"); 31 | uart_print(";"); 32 | } 33 | else { 34 | uart_print("b"); 35 | uart_print(";"); 36 | } 37 | 38 | /*buffer_full = uart_rx_buffer_full(); //check if read buffer is full and data can be read 39 | if(buffer_full){ 40 | rx_data = uart_read(); //read data from buffer (make sure to check first if rx buffer is full) 41 | } 42 | if(rx_data == 'c'){ 43 | toggle_gpio(8); //toggle a specific GPIO pin (automatically set pin to write mode) 44 | toggle_gpio(9); //toggle a specific GPIO pin (automatically set pin to write mode) 45 | toggle_gpio(10); //toggle a specific GPIO pin (automatically set pin to write mode) 46 | toggle_gpio(11); //toggle a specific GPIO pin (automatically set pin to write mode) 47 | rx_data = 0; 48 | }*/ 49 | rd_pin = gpio_read_pin(0); 50 | if(rd_pin){ 51 | gpio_write_pin(8, 1); //write to a specific GPIO pin (automatically set pin to write mode) 52 | gpio_write_pin(9, 1); //write to a specific GPIO pin (automatically set pin to write mode) 53 | gpio_write_pin(10, 1); //write to a specific GPIO pin (automatically set pin to write mode) 54 | gpio_write_pin(11, 1); //write to a specific GPIO pin (automatically set pin to write mode) 55 | } 56 | else{ 57 | gpio_write_pin(8, 0); //write to a specific GPIO pin (automatically set pin to write mode) 58 | gpio_write_pin(9, 0); //write to a specific GPIO pin (automatically set pin to write mode) 59 | gpio_write_pin(10, 0); //write to a specific GPIO pin (automatically set pin to write mode) 60 | gpio_write_pin(11, 0); //write to a specific GPIO pin (automatically set pin to write mode) 61 | } 62 | 63 | delay_ms(1000); // 1 sample per second (temp + humidity) maximum 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /test/extra/test_i2c.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | i2c_write_address(0xaa); 6 | i2c_write_byte('A'); 7 | i2c_write_byte('Z'); 8 | i2c_stop(); 9 | return 0; 10 | 11 | 12 | /* I2C Address Finder 13 | uart_print("\n\nSTART THE I2C ADDRES FINDER\n\n"); 14 | int address; 15 | uint8_t ack; 16 | for(address=1; address<128; address++){ 17 | ack = i2c_write_address(address<<1); //rightmost bit is 0(write) 18 | i2c_stop(); //make sure to stop before accessing new address slave 19 | if(ack){ 20 | uart_print("\nFound the address:"); 21 | //char str_address[20]; 22 | // sprintf(str_address,"%d",address); 23 | //uart_print(str_address); 24 | uart_print("\n\n\n\n"); 25 | } 26 | else{ 27 | uart_print("\nWRONG:"); 28 | //char str_address[20]; 29 | //sprintf(str_address,"%d",address); 30 | //uart_print(str_address); 31 | } 32 | } 33 | 34 | return 0; 35 | */ 36 | } 37 | 38 | -------------------------------------------------------------------------------- /test/extra/test_lcd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | 6 | uart_print("INITIALIZING LCD MODULE.....\n"); 7 | LCD_Init(0x4E); // Initialize LCD module with I2C address = 0x4E 8 | uart_print("INITIALIZING DONE!\n\n"); 9 | 10 | LCD_Set_Cursor(1, 1); 11 | LCD_Write_String(" Angelo Jacobo"); 12 | LCD_Set_Cursor(2, 1); 13 | LCD_Write_String("BSECE-4A"); 14 | //while(1){ 15 | //} 16 | 17 | return 1; 18 | } 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /test/extra/test_rtc.c_fpga: -------------------------------------------------------------------------------- 1 | /* 2 | * PIC18F4550 interfacing with RTC DS1307 3 | * http://www.electronicwings.com 4 | */ 5 | 6 | 7 | #include 8 | #include 9 | 10 | #define RTC_I2C_ADDR 0x68 11 | 12 | 13 | char sec,min,hour; 14 | char Day,Date,Month,Year; 15 | 16 | 17 | 18 | int RTC_Clock_Write(char Sec, char Min, char Hour, char AM_PM) /* function for clock */ 19 | { 20 | int ack; 21 | Hour = Hour | (1<<6); /* set to 12-hour mode*/ 22 | Hour = Hour | (AM_PM<<5); /* whether it is AM or PM */ 23 | ack = i2c_write_address(RTC_I2C_ADDR<<1); // start i2c by writing slave address (returns slave ack) 24 | i2c_write_byte(0); /* write 0 location for sec value */ 25 | i2c_write_byte(Sec); /* write second value on 00 location */ 26 | i2c_write_byte(Min); /* write min value on 01 location */ 27 | i2c_write_byte(Hour); /* write hour value on 02 location */ 28 | i2c_stop(); // stop current i2c transaction 29 | return ack; 30 | } 31 | 32 | int RTC_Calendar_Write(char day, char date, char month, char year) /* function for calendar */ 33 | { 34 | int ack; 35 | ack = i2c_write_address(RTC_I2C_ADDR<<1);/* start I2C comm. with device slave address */ 36 | i2c_write_byte(3); /* write on 3 location for day value */ 37 | i2c_write_byte(day); /* write day value on 03 location */ 38 | i2c_write_byte(date); /* write date value on 04 location */ 39 | i2c_write_byte(month); /* write month value on 05 location */ 40 | i2c_write_byte(year); /* write year value on 06 location */ 41 | i2c_stop(); 42 | return ack; 43 | } 44 | 45 | 46 | 47 | int RTC_Read_Clock(char read_clock_address) 48 | { 49 | int ack; 50 | char msg[20]; 51 | ack = i2c_write_address(RTC_I2C_ADDR<<1); 52 | i2c_write_byte(read_clock_address); /* address from where time needs to be read*/ 53 | i2c_stop(); 54 | i2c_write_address((RTC_I2C_ADDR<<1)|0x1); 55 | sec = i2c_read_byte(); /*read data and send ack for continuous reading*/ 56 | min = i2c_read_byte(); /*read data and send ack for continuous reading*/ 57 | hour= i2c_read_byte(); /*read data and send nack for indicating stop reading*/ 58 | i2c_stop(); 59 | return ack; 60 | } 61 | 62 | int RTC_Read_Calendar(char read_calendar_address) 63 | { 64 | int ack; 65 | ack = i2c_write_address(RTC_I2C_ADDR<<1); 66 | i2c_write_byte(read_calendar_address); /* address from where time needs to be read*/ 67 | i2c_stop(); 68 | i2c_write_address((RTC_I2C_ADDR<<1)|0x1); 69 | Day = i2c_read_byte(); /*read data and send ack for continuous reading*/ 70 | Date = i2c_read_byte(); /*read data and send ack for continuous reading*/ 71 | Month = i2c_read_byte(); /*read data and send ack for continuous reading*/ 72 | Year = i2c_read_byte(); /*read data and send nack for indicating stop reading*/ 73 | i2c_stop(); 74 | return ack; 75 | } 76 | 77 | void main() 78 | { 79 | 80 | char secs[10],mins[10],hours[10]; 81 | char date[10],month[10],year[10]; 82 | char Clock_type = 0x06; 83 | char AM_PM = 0x05; 84 | char days[7] = {'S','M','T','W','t','F','s'}; 85 | int ack; 86 | 87 | LCD_Init(); /*initialize LCD16x2*/ 88 | LCD_Set_Cursor(1, 1); 89 | LCD_Write_String(" Angelo Jacobo"); 90 | LCD_Set_Cursor(2, 1); 91 | LCD_Write_String("BSECE-4A"); 92 | delay_ms(1000); 93 | LCD_Clear(); 94 | delay_ms(10); 95 | 96 | ack = RTC_Clock_Write(0x30, 0x15, 0x10, 0); /* function for clock */ 97 | if(ack){ 98 | uart_print("RTC_Clock_Write() SUCCESS\n"); 99 | } 100 | else { 101 | uart_print("RTC_Clock_Write() FAILED\n"); 102 | } 103 | 104 | ack = RTC_Calendar_Write(0x6, 0x01, 0x04, 0x23); /* function for calendar */ 105 | if(ack){ 106 | uart_print("RTC_Calendar_Write() SUCCESS\n"); 107 | } 108 | else { 109 | uart_print("RTC_Calendar_Write() FAILED\n"); 110 | } 111 | 112 | while(1) 113 | { 114 | RTC_Read_Clock(0); /*gives second,minute and hour*/ 115 | if(hour & (1< 2 | #include 3 | 4 | int finish; 5 | 6 | 7 | void __attribute__((interrupt)) trap_handler(void) { 8 | mtime_set_timecmp(-1); 9 | finish = 1; 10 | } 11 | int main() { 12 | trap_handler_setup(trap_handler); //configure MTVEC to call "trap_handler" and initially disable all interrupts 13 | csr_set(MSTATUS, 1< 2 | #include 3 | 4 | int main() { 5 | uart_print("Angelo Jacobo"); 6 | return 0; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/extra/test_ultrasonic.c_fpga: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int main(){ 6 | int trig_pin = 0; 7 | int echo_pin = 1; 8 | int pulse_duration_us; 9 | int distance_cm; 10 | char string[16]; //max of 16 chars 11 | 12 | gpio_set_mode_pin(trig_pin, 1); //set mode setting of a single GPIO pin(read = 0, write = 1) 13 | gpio_set_mode_pin(echo_pin, 0); //set mode setting of a single GPIO pin(read = 0, write = 1) 14 | uart_print("Start Ultrasonic Sensor\n\n"); 15 | 16 | /*while(1)*/ { 17 | // set trig_pin for 10us 18 | gpio_write_pin(trig_pin, 0); //write to a specific GPIO pin (automatically set pin to write mode) 19 | delay_us(2); // delay function based on microseconds 20 | gpio_write_pin(trig_pin, 1); //write to a specific GPIO pin (automatically set pin to write mode) 21 | delay_us(10); // delay function based on microseconds 22 | gpio_write_pin(trig_pin, 0); //write to a specific GPIO pin (automatically set pin to write mode) 23 | 24 | pulse_duration_us = gpio_pulse_duration_us(echo_pin, 1); //measure how long will be the high pulse 25 | distance_cm = pulse_duration_us*(0.034/2); 26 | 27 | //convert distance_cm to string 28 | sprintf_(string,"%d",distance_cm); 29 | uart_print("Distance (cm): "); 30 | uart_print(string); 31 | uart_print("\n"); 32 | } 33 | 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /test/extra/ultrasonic_sensor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | int trig_pin = 0; 6 | int echo_pin = 1; 7 | int pulse_duration_us; 8 | int distance_cm; 9 | char string[16]; //max of 16 chars 10 | 11 | gpio_set_mode_pin(trig_pin, 1); //set mode setting of a single GPIO pin(read = 0, write = 1) 12 | gpio_set_mode_pin(echo_pin, 0); //set mode setting of a single GPIO pin(read = 0, write = 1) 13 | uart_print("Start Ultrasonic Sensor\n\n"); 14 | 15 | while(1) { 16 | // set trig_pin for 10us 17 | gpio_write_pin(trig_pin, 0); //write to a specific GPIO pin (automatically set pin to write mode) 18 | delay_us(2); // delay function based on microseconds 19 | gpio_write_pin(trig_pin, 1); //write to a specific GPIO pin (automatically set pin to write mode) 20 | delay_us(10); // delay function based on microseconds 21 | gpio_write_pin(trig_pin, 0); //write to a specific GPIO pin (automatically set pin to write mode) 22 | 23 | pulse_duration_us = gpio_pulse_duration_us(echo_pin, 1); //measure how long will be the high pulse 24 | distance_cm = pulse_duration_us*(0.034/2); 25 | 26 | //convert distance_cm to string 27 | itoa(distance_cm, string, 10); 28 | uart_print("Distance (cm): "); 29 | uart_print(string); 30 | uart_print("\n"); 31 | } 32 | 33 | } 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /test/extra/xor.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR XOR 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 ^ 150 = 242 (nonzero answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | li x2, 150 # set x2 to 150 (0x00000096) 22 | xor x3, x1, x2 # xor x1(100) to x2(150), x3=242 (0x000000F2) 23 | 24 | # 100 ^ 100 = 0 (zero answer) 25 | xor x4, x1, x1 # xor x1(100) to x1(100), x4=0 (0x00000000) 26 | 27 | #self-check 28 | li x5, 242 # set x5 to 242 (expected value for x3) 29 | beqz x5, fail0 # make sure x5 has value 30 | bne x3, x5, fail1 # 31 | bnez x4, fail2 # branch to fail if not equal to expected value 32 | 33 | ### END OF TEST CODE ### 34 | 35 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 36 | pass: 37 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 38 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 39 | ebreak 40 | 41 | fail0: 42 | li a0, 1 # fail code 43 | li a7, 93 # reached end of code 44 | ebreak 45 | 46 | fail1: 47 | li a0, 2 # fail code 48 | li a7, 93 # reached end of code 49 | ebreak 50 | 51 | fail2: 52 | li a0, 4 # fail code 53 | li a7, 93 # reached end of code 54 | ebreak 55 | 56 | # ----------------------------------------- 57 | # Data section. Note starts at 0x1000, as 58 | # set by DATAADDR variable in rv_asm.bat. 59 | # ----------------------------------------- 60 | .data 61 | 62 | # Data section 63 | data: 64 | 65 | -------------------------------------------------------------------------------- /test/extra/xori.s: -------------------------------------------------------------------------------- 1 | # 2 | # TEST CODE FOR XORI 3 | # 4 | # ----------------------------------------- 5 | # Program section (known as text) 6 | # ----------------------------------------- 7 | .text 8 | 9 | # Start symbol (must be present), exported as a global symbol. 10 | _start: .global _start 11 | 12 | # Export main as a global symbol 13 | .global main 14 | 15 | # Label for entry point of test code 16 | main: 17 | ### TEST CODE STARTS HERE ### 18 | 19 | # 100 ^ 150 = 242 (nonzero answer) 20 | li x1, 100 # set x1 to 100 (0x00000064) 21 | xori x2, x1, 150 # xori x1(100) to 150, x2=242 (0x000000F2) 22 | 23 | # 100 ^ 100 = 0 (zero answer) 24 | xori x3, x1, 100 # xor x1(100) to 100, x3=0 (0x00000000) 25 | 26 | #self-check 27 | li x4, 242 # set x4 to 242 (expected value for x3) 28 | beqz x4, fail0 # make sure x4 has value 29 | bne x2, x4, fail1 # 30 | bnez x3, fail2 # branch to fail if not equal to expected value 31 | 32 | ### END OF TEST CODE ### 33 | 34 | # Exit test using RISC-V International's riscv-tests pass/fail criteria 35 | pass: 36 | li a0, 0 # set a0 (x10) to 0 to indicate a pass code 37 | li a7, 93 # set a7 (x17) to 93 (5dh) to indicate reached the end of the test 38 | ebreak 39 | 40 | fail0: 41 | li a0, 1 # fail code 42 | li a7, 93 # reached end of code 43 | ebreak 44 | 45 | fail1: 46 | li a0, 2 # fail code 47 | li a7, 93 # reached end of code 48 | ebreak 49 | 50 | fail2: 51 | li a0, 4 # fail code 52 | li a7, 93 # reached end of code 53 | ebreak 54 | 55 | # ----------------------------------------- 56 | # Data section. Note starts at 0x1000, as 57 | # set by DATAADDR variable in rv_asm.bat. 58 | # ----------------------------------------- 59 | .data 60 | 61 | # Data section 62 | data: 63 | 64 | -------------------------------------------------------------------------------- /test/freertos/FreeRTOSConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd. 3 | All rights reserved 4 | VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 5 | This file is part of the FreeRTOS distribution. 6 | FreeRTOS is free software; you can redistribute it and/or modify it under 7 | the terms of the GNU General Public License (version 2) as published by the 8 | Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. 9 | *************************************************************************** 10 | >>! NOTE: The modification to the GPL is included to allow you to !<< 11 | >>! distribute a combined work that includes FreeRTOS without being !<< 12 | >>! obliged to provide the source code for proprietary components !<< 13 | >>! outside of the FreeRTOS kernel. !<< 14 | *************************************************************************** 15 | FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 16 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 | FOR A PARTICULAR PURPOSE. Full license text is available on the following 18 | link: http://www.freertos.org/a00114.html 19 | *************************************************************************** 20 | * * 21 | * FreeRTOS provides completely free yet professionally developed, * 22 | * robust, strictly quality controlled, supported, and cross * 23 | * platform software that is more than just the market leader, it * 24 | * is the industry's de facto standard. * 25 | * * 26 | * Help yourself get started quickly while simultaneously helping * 27 | * to support the FreeRTOS project by purchasing a FreeRTOS * 28 | * tutorial book, reference manual, or both: * 29 | * http://www.FreeRTOS.org/Documentation * 30 | * * 31 | *************************************************************************** 32 | http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 33 | the FAQ page "My application does not run, what could be wrong?". Have you 34 | defined configASSERT()? 35 | http://www.FreeRTOS.org/support - In return for receiving this top quality 36 | embedded software for free we request you assist our global community by 37 | participating in the support forum. 38 | http://www.FreeRTOS.org/training - Investing in training allows your team to 39 | be as productive as possible as early as possible. Now you can receive 40 | FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 41 | Ltd, and the world's leading authority on the world's leading RTOS. 42 | http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 43 | including FreeRTOS+Trace - an indispensable productivity tool, a DOS 44 | compatible FAT file system, and our tiny thread aware UDP/IP stack. 45 | http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 46 | Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 47 | http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 48 | Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 49 | licenses offer ticketed support, indemnification and commercial middleware. 50 | http://www.SafeRTOS.com - High Integrity Systems also provide a safety 51 | engineered and independently SIL3 certified version for use in safety and 52 | mission critical applications that require provable dependability. 53 | 1 tab == 4 spaces! 54 | */ 55 | 56 | 57 | #ifndef FREERTOS_CONFIG_H 58 | #define FREERTOS_CONFIG_H 59 | 60 | //#include "clock_config.h" 61 | 62 | /*----------------------------------------------------------- 63 | * Application specific definitions. 64 | * 65 | * These definitions should be adjusted for your particular hardware and 66 | * application requirements. 67 | * 68 | * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE 69 | * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 70 | * 71 | * See http://www.freertos.org/a00110.html. 72 | *----------------------------------------------------------*/ 73 | 74 | /* See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html */ 75 | 76 | 77 | /****************************************************************************** 78 | * Modified for the RISC-V core: https://github.com/AngeloJacobo/RISC-V 79 | ******************************************************************************/ 80 | #define configMTIME_BASE_ADDRESS ( 0x80000000UL ) 81 | #define configMTIMECMP_BASE_ADDRESS ( 0x80000008UL ) 82 | 83 | #define configISR_STACK_SIZE_WORDS ( 128 ) 84 | 85 | #define configUSE_PREEMPTION 1 86 | #define configUSE_IDLE_HOOK 1 87 | #define configUSE_TICK_HOOK 1 88 | #define configCPU_CLOCK_HZ 12000000 //Frequency in Hz at which the internal clock that drives the peripheral used to generate the tick interrupt will be executing 89 | #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) // 90 | #define configMAX_PRIORITIES ( 5 ) //Each task is assigned a priority from 0 to ( configMAX_PRIORITIES - 1 ) 91 | #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) /* Can be as low as 60 but some of the demo tasks that use this constant require it to be higher. */ 92 | #define configSUPPORT_DYNAMIC_ALLOCATION 1 93 | #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 14*1024 ) ) //RAM length is set to 16K 94 | //You can make this configTOTAL_HEAP_SIZE as big as you want, the linker will issue an error when you’re running out of RAM. 95 | //https://www.freertos.org/FreeRTOS_Support_Forum_Archive/March_2015/freertos_How_to_configure_the_Total_Heap_Size_5a94a34cj.html 96 | #define configMAX_TASK_NAME_LEN ( 16 ) //The maximum permissible length of the descriptive name given to a task when the task is created. 97 | #define configUSE_TRACE_FACILITY 1 98 | #define configUSE_16_BIT_TICKS 0 //Defining configUSE_16_BIT_TICKS as 0 causes TickType_t to be defined (typedef'ed) as an unsigned 32bit type. 99 | #define configIDLE_SHOULD_YIELD 0 //Setting configIDLE_SHOULD_YIELD to 0 prevents the idle task from yielding processing time until the end of its time slice. This ensure all tasks at the idle priority are allocated an equal amount of processing time 100 | #define configUSE_MUTEXES 1 101 | #define configQUEUE_REGISTRY_SIZE 8 102 | #define configCHECK_FOR_STACK_OVERFLOW 2 103 | #define configUSE_RECURSIVE_MUTEXES 1 104 | #define configUSE_MALLOC_FAILED_HOOK 1 105 | #define configUSE_APPLICATION_TASK_TAG 0 106 | #define configUSE_COUNTING_SEMAPHORES 1 107 | #define configGENERATE_RUN_TIME_STATS 0 108 | #define configTASK_NOTIFICATION_ARRAY_ENTRIES 4 109 | #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 110 | 111 | /* Co-routine definitions. */ 112 | #define configUSE_CO_ROUTINES 0 113 | #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) 114 | 115 | /* Software timer definitions. */ 116 | #define configUSE_TIMERS 1 117 | #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) 118 | #define configTIMER_QUEUE_LENGTH 4 119 | #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) 120 | 121 | 122 | 123 | /* Set the following definitions to 1 to include the API function, or zero 124 | to exclude the API function. */ 125 | #define INCLUDE_vTaskPrioritySet 1 126 | #define INCLUDE_uxTaskPriorityGet 1 127 | #define INCLUDE_vTaskDelete 1 128 | #define INCLUDE_vTaskCleanUpResources 1 129 | #define INCLUDE_vTaskSuspend 1 130 | #define INCLUDE_vTaskDelayUntil 1 131 | #define INCLUDE_vTaskDelay 1 132 | #define INCLUDE_eTaskGetState 1 133 | #define INCLUDE_xTimerPendFunctionCall 1 134 | #define INCLUDE_xTaskAbortDelay 1 135 | #define INCLUDE_xTaskGetHandle 1 136 | #define INCLUDE_xSemaphoreGetMutexHolder 1 137 | 138 | 139 | /* Normal assert() semantics without relying on the provision of an assert.h 140 | header file. */ 141 | #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); } 142 | 143 | #endif /* FREERTOS_CONFIG_H */ 144 | -------------------------------------------------------------------------------- /test/freertos/freertos_risc_v_chip_specific_extensions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * FreeRTOS Kernel V10.3.1 3 | * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | * this software and associated documentation files (the "Software"), to deal in 7 | * the Software without restriction, including without limitation the rights to 8 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | * the Software, and to permit persons to whom the Software is furnished to do so, 10 | * subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in all 13 | * copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | * 22 | * http://www.FreeRTOS.org 23 | * http://aws.amazon.com/freertos 24 | * 25 | * 1 tab == 4 spaces! 26 | */ 27 | 28 | /* 29 | * The FreeRTOS kernel's RISC-V port is split between the the code that is 30 | * common across all currently supported RISC-V chips (implementations of the 31 | * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: 32 | * 33 | * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that 34 | * is common to all currently supported RISC-V chips. There is only one 35 | * portASM.S file because the same file is built for all RISC-V target chips. 36 | * 37 | * + Header files called freertos_risc_v_chip_specific_extensions.h contain the 38 | * code that tailors the FreeRTOS kernel's RISC-V port to a specific RISC-V 39 | * chip. There are multiple freertos_risc_v_chip_specific_extensions.h files 40 | * as there are multiple RISC-V chip implementations. 41 | * 42 | * !!!NOTE!!! 43 | * TAKE CARE TO INCLUDE THE CORRECT freertos_risc_v_chip_specific_extensions.h 44 | * HEADER FILE FOR THE CHIP IN USE. This is done using the assembler's (not the 45 | * compiler's!) include path. For example, if the chip in use includes a core 46 | * local interrupter (CLINT) and does not include any chip specific register 47 | * extensions then add the path below to the assembler's include path: 48 | * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions 49 | * 50 | */ 51 | 52 | /* 53 | * NEORV32 chip specific extensions 54 | */ 55 | 56 | 57 | #ifndef __FREERTOS_RISC_V_EXTENSIONS_H__ 58 | #define __FREERTOS_RISC_V_EXTENSIONS_H__ 59 | 60 | #define portasmHAS_SIFIVE_CLINT 0 61 | #define portasmHAS_MTIME 1 62 | #define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */ 63 | 64 | .macro portasmSAVE_ADDITIONAL_REGISTERS 65 | /* No additional registers to save, so this macro does nothing. */ 66 | .endm 67 | 68 | .macro portasmRESTORE_ADDITIONAL_REGISTERS 69 | /* No additional registers to restore, so this macro does nothing. */ 70 | .endm 71 | 72 | #endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */ 73 | 74 | 75 | -------------------------------------------------------------------------------- /test/freertos/mobile_app.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/RISC-V/b0ab05501abcb2a1bc882702d196dcbd1385be03/test/freertos/mobile_app.aia -------------------------------------------------------------------------------- /test/freertos/mobile_app.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AngeloJacobo/RISC-V/b0ab05501abcb2a1bc882702d196dcbd1385be03/test/freertos/mobile_app.apk -------------------------------------------------------------------------------- /test/lib/clint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | volatile uint32_t *mtime_low = (volatile uint32_t *) MTIME_BASE_ADDRESS; 6 | volatile uint32_t *mtime_hi = (volatile uint32_t *) (MTIME_BASE_ADDRESS + 4); 7 | volatile uint32_t *mtimecmp_low = (volatile uint32_t *) MTIMECMP_BASE_ADDRESS; 8 | volatile uint32_t *mtimecmp_hi = (volatile uint32_t *) (MTIMECMP_BASE_ADDRESS + 4); 9 | volatile uint32_t *software_interrupt = (volatile uint32_t *) MSIP_BASE_ADDRESS; 10 | 11 | // Set current system time. 12 | void mtime_set_time(uint64_t time) { 13 | 14 | union { 15 | uint64_t uint64; 16 | uint32_t uint32[sizeof(uint64_t)/sizeof(uint32_t)]; 17 | } time_union; 18 | 19 | time_union.uint64 = time; 20 | //set it up this way to not trigger false timer interrupt 21 | *mtime_low = 0; 22 | *mtime_hi = time_union.uint32[1]; 23 | *mtime_low = time_union.uint32[0]; 24 | 25 | } 26 | 27 | 28 | // Get current system time. 29 | uint64_t mtime_get_time(void) { 30 | 31 | union { 32 | uint64_t uint64; 33 | uint32_t uint32[sizeof(uint64_t)/sizeof(uint32_t)]; 34 | } time_union; 35 | 36 | 37 | time_union.uint32[0] = *mtime_low; 38 | time_union.uint32[1] = *mtime_hi; 39 | 40 | return time_union.uint64; 41 | } 42 | 43 | 44 | // Set compare time register (MTIMECMP) for generating interrupts. 45 | void mtime_set_timecmp(uint64_t timecmp) { 46 | 47 | union { 48 | uint64_t uint64; 49 | uint32_t uint32[sizeof(uint64_t)/sizeof(uint32_t)]; 50 | } timecmp_union; 51 | 52 | timecmp_union.uint64 = timecmp; 53 | 54 | *mtimecmp_low = -1; // prevent MTIMECMP from temporarily becoming smaller than the lesser of the old and new values 55 | *mtimecmp_hi = timecmp_union.uint32[1]; 56 | *mtimecmp_low = timecmp_union.uint32[0]; 57 | } 58 | 59 | 60 | // Get compare time register (MTIMECMP). 61 | uint64_t mtime_get_timecmp(void) { 62 | 63 | union { 64 | uint64_t uint64; 65 | uint32_t uint32[sizeof(uint64_t)/sizeof(uint32_t)]; 66 | } timecmp_union; 67 | 68 | timecmp_union.uint32[0] = *mtimecmp_low; 69 | timecmp_union.uint32[1] = *mtimecmp_hi; 70 | 71 | return timecmp_union.uint64; 72 | } 73 | 74 | //setup trap handler by setting MTVEC and initially disabling all interrupts 75 | //NOTE: trap handler function MUST HAVE ATTRIBUTE INTERRUPT 76 | void trap_handler_setup(void (*trap_handler)(void)) { //this is a pointer to a function with void arguments and returns void 77 | csr_write(MTVEC,(uint32_t) trap_handler); //store the address of the function to MTVEC (the input is a pointer which is simply an address) 78 | //disable all interrupts 79 | csr_write(MSTATUS, 0); 80 | csr_write(MIE, 0); 81 | csr_write(MIP, 0); 82 | } 83 | 84 | // trurn on software interrupt 85 | void enable_software_interrupt(void){ 86 | *software_interrupt = 1; 87 | } 88 | 89 | // turn off software interrupt 90 | void disable_software_interrupt(void){ 91 | *software_interrupt = 0; 92 | } 93 | 94 | 95 | // convert milliseconds input to cpu clock ticks 96 | uint64_t ms_to_cpu_ticks (uint64_t ms){ 97 | uint64_t cpu_clk_ticks = ms*(CPU_CLK_HZ/1000); 98 | return cpu_clk_ticks; 99 | } 100 | 101 | // convert milliseconds input to cpu clock ticks 102 | uint64_t us_to_cpu_ticks (uint64_t us){ 103 | uint64_t cpu_clk_ticks = us*(CPU_CLK_HZ/1000000); 104 | return cpu_clk_ticks; 105 | } 106 | 107 | // convert cpu clock ticks to us 108 | uint32_t cpu_ticks_to_us (uint64_t ticks){ 109 | uint32_t us = (ticks*1000000)/CPU_CLK_HZ; 110 | return us; 111 | } 112 | 113 | 114 | // delay function based on milliseconds 115 | void delay_ms(uint64_t ms) { 116 | uint64_t initial_time = mtime_get_time(); 117 | uint64_t ms_in_ticks = ms_to_cpu_ticks(ms); 118 | while ((initial_time + ms_in_ticks) > (uint64_t)mtime_get_time()){ //do nothing while delay has not yet passed 119 | } 120 | } 121 | 122 | // delay function based on microseconds 123 | void delay_us(uint64_t us) { 124 | uint64_t initial_time = mtime_get_time(); 125 | uint64_t us_in_ticks = us_to_cpu_ticks(us); 126 | while ((initial_time + us_in_ticks) > (uint64_t)mtime_get_time()){ //do nothing while delay has not yet passed 127 | } 128 | } 129 | 130 | // delay function based on cpu clock tick 131 | void delay_ticks(uint32_t ticks) { 132 | uint64_t initial_time = mtime_get_time(); 133 | while ((initial_time + ticks) > (uint64_t)mtime_get_time()){ //do nothing while delay has not yet passed 134 | } 135 | } 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /test/lib/gpio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | volatile uint32_t *gpio_mode_reg = (volatile uint32_t *) GPIO_MODE; 5 | volatile uint32_t *gpio_write_reg = (volatile uint32_t *) GPIO_WRITE; 6 | volatile uint32_t *gpio_read_reg = (volatile uint32_t *) GPIO_READ; 7 | 8 | //read mode setting of the GPIOs (read = 0, write = 1) 9 | uint32_t gpio_read_mode(){ 10 | return *gpio_mode_reg; 11 | } 12 | 13 | //set mode setting og the GPIOs (read = 0, write = 1) 14 | void gpio_set_mode(uint32_t mode){ 15 | *gpio_mode_reg = mode; 16 | } 17 | 18 | //write to GPIOs 19 | void gpio_write(uint32_t write){ 20 | *gpio_write_reg = write; 21 | } 22 | 23 | //read current write value of GPIOs 24 | uint32_t gpio_write_value(){ 25 | return *gpio_write_reg; 26 | } 27 | 28 | //read GPIO 29 | uint32_t gpio_read(){ 30 | return *gpio_read_reg; 31 | } 32 | 33 | //toggle a specific GPIO pin 34 | void toggle_gpio(uint32_t pin_number){ 35 | gpio_set_mode_pin(pin_number, 1); //set pin to write mode 36 | uint32_t value; 37 | value = gpio_write_value(); //read current write value 38 | gpio_write(value ^ (1< 25 | #include 26 | #include 27 | /* ------------------------------------------------------------ */ 28 | /* Procedure Definitions */ 29 | /* ------------------------------------------------------------ */ 30 | 31 | 32 | 33 | /* ------------------------------------------------------------ */ 34 | /* HYGROI2C::writeRegI2C 35 | ** 36 | ** Synopsis: 37 | ** writeRegI2C(bConfig); 38 | ** 39 | ** Parameters: 40 | ** uint8_t bReg - the register address to be written to 41 | ** uint16_t bVal - the bytes to be written 42 | ** 43 | ** Return Values: 44 | ** void 45 | ** 46 | ** Errors: 47 | ** none 48 | ** 49 | ** Description: 50 | ** This function writes to a register over I2C. 51 | ** 52 | */ 53 | uint8_t hygroi2c_writeRegI2C(uint8_t bReg, uint16_t bVal) 54 | { 55 | uint8_t ack; 56 | ack = i2c_write_address(HYGROI2C_I2C_ADDR<<1); // start i2c by writing slave address (returns slave ack) 57 | i2c_write_byte(bReg); // write to slave (returns slave ack) (after i2c_write_address()) 58 | i2c_write_byte((bVal>>8)&0xff); // send upper byte 59 | i2c_write_byte((bVal)&0xff); // send lower byte 60 | i2c_stop(); // stop current i2c transaction 61 | return ack; 62 | } 63 | 64 | /* ------------------------------------------------------------ */ 65 | /* HYGROI2C::readRegI2C 66 | ** 67 | ** Synopsis: 68 | ** readRegI2C(bReg, rVal, delay_ms); 69 | ** 70 | ** Parameters: 71 | ** uint8_t bReg - the register address to be written to 72 | ** uint16_t* rVal - the return location for the read bytes 73 | ** unsigned int delay_ms - the number of milliseconds required for the HYGRO to convert the desired data 74 | ** 75 | ** Return Values: 76 | ** bool success - whether valid data has been successfully captured 77 | ** 78 | ** Errors: 79 | ** failure on bad rVal pointer 80 | ** 81 | ** Description: 82 | ** This function reads a register over I2C. 83 | ** 84 | */ 85 | uint8_t hygroi2c_readRegI2C(uint8_t bReg, uint16_t *rVal, uint32_t delay_in_ms) 86 | { 87 | int n, i; 88 | uint8_t ack; 89 | char msg[20]; 90 | i2c_write_address(HYGROI2C_I2C_ADDR<<1); // start i2c by writing slave address (returns slave ack) 91 | i2c_write_byte(bReg); // write to slave (returns slave ack) (after i2c_write_address()) 92 | if (delay_in_ms > 0) 93 | delay_ms(delay_in_ms); // wait for conversion to complete 94 | i2c_stop(); // stop current i2c transaction 95 | 96 | 97 | ack = i2c_write_address(((HYGROI2C_I2C_ADDR<<1) | 0x01)); // start i2c by writing slave address (returns slave ack) 98 | //read two bytes from slave 99 | *rVal |= (uint16_t)i2c_read_byte(); //read a byte from the slave (after i2c_write_address()) 100 | *rVal <<= 8; 101 | *rVal |= (uint16_t)i2c_read_byte(); //read a byte from the slave (after i2c_write_address()) 102 | i2c_stop(); // stop current i2c transaction 103 | 104 | return ack; 105 | } 106 | 107 | 108 | /* ------------------------------------------------------------ */ 109 | /* HYGROI2C::begin 110 | ** 111 | ** Synopsis: 112 | ** myHYGROI2C.begin(); 113 | ** 114 | ** Parameters: 115 | ** 116 | ** Return Values: 117 | ** void 118 | ** 119 | ** Errors: 120 | ** 121 | ** Description: 122 | ** This function initializes the I2C interface #1 that is used to communicate with PmodAD2. 123 | ** 124 | */ 125 | void hygroi2c_begin() 126 | { 127 | uint8_t ack; 128 | delay_ms(15); 129 | ack = hygroi2c_writeRegI2C(HYGROI2C_CONFIG_REG, 0x00); // use non-sequential acquisition mode, all other config bits are default 130 | if(!ack){ 131 | //uart_print("hygroi2c_begin() FAILED\n"); 132 | } 133 | 134 | 135 | } 136 | 137 | /* ------------------------------------------------------------ */ 138 | /* HYGROI2C::getTemperature 139 | ** 140 | ** Synopsis: 141 | ** myHYGROI2C.getTemperature(); 142 | ** 143 | ** Parameters: 144 | ** 145 | ** Return Values: 146 | ** float deg_c - the temperature reading in degrees celsius 147 | ** 148 | ** Errors: - modify to manage read failures 149 | ** 150 | ** Description: 151 | ** This function captures a temperature reading from the Pmod HYGRO. 152 | ** 153 | */ 154 | float hygroi2c_getTemperature() 155 | { 156 | uint8_t ack; 157 | uint16_t raw_t; 158 | float deg_c; 159 | ack = hygroi2c_readRegI2C(HYGROI2C_TMP_REG, &raw_t, 7); // conversion time for temperature at 14 bit resolution is 6.5 ms 160 | deg_c = (float)raw_t / 0x10000; 161 | deg_c *= 165.0; 162 | deg_c -= 40.0; // conversion provided in reference manual 163 | return deg_c; 164 | } 165 | 166 | /* ------------------------------------------------------------ */ 167 | /* HYGROI2C::getHumidity 168 | ** 169 | ** Synopsis: 170 | ** HYGROI2C.getHumidity(); 171 | ** 172 | ** Parameters: 173 | ** 174 | ** Return Values: 175 | ** float per_rh - the humidity reading in percent relative humidity. 176 | ** 177 | ** Errors: - modify to manage read failures 178 | ** 179 | ** Description: 180 | ** This function captures a humidity reading from the Pmod HYGRO. 181 | ** 182 | */ 183 | float hygroi2c_getHumidity() { 184 | uint16_t raw_h; 185 | float per_rh; 186 | uint8_t ack; 187 | ack = hygroi2c_readRegI2C(HYGROI2C_HUM_REG, &raw_h, 7); // conversion time for humidity at 14 bit resolution is 6.35 ms 188 | per_rh = (float)raw_h / 0x10000; 189 | per_rh *= 100.0; // conversion provided in reference manual 190 | return per_rh; 191 | } 192 | 193 | /* ------------------------------------------------------------ */ 194 | /* HYGROI2C::tempF2C 195 | ** 196 | ** Synopsis: 197 | ** HYGROI2C.tempF2C(deg_f); 198 | ** 199 | ** Parameters: 200 | ** float deg_f - the temperature in degrees fahrenheit 201 | ** Return Values: 202 | ** float deg_c - the temperature in degrees celsius 203 | ** 204 | ** Errors: 205 | ** 206 | ** Description: 207 | ** This function converts a fahrenheit temperature to celsius 208 | ** 209 | */ 210 | float hygroi2c_tempF2C(float deg_f) 211 | { 212 | return (deg_f - 32) / 1.8; 213 | } 214 | 215 | /* ------------------------------------------------------------ */ 216 | /* HYGROI2C::tempC2F 217 | ** 218 | ** Synopsis: 219 | ** HYGROI2C.tempC2F(deg_c); 220 | ** 221 | ** Parameters: 222 | ** float deg_c - the temperature in degrees celsius 223 | ** Return Values: 224 | ** float deg_f - the temperature in degrees fahrenheit 225 | ** 226 | ** Errors: 227 | ** 228 | ** Description: 229 | ** This function converts a celsius temperature to fahrenheit 230 | ** 231 | */ 232 | float hygroi2c_tempC2F(float deg_c) 233 | { 234 | return deg_c * 1.8 + 32; 235 | } 236 | 237 | 238 | 239 | -------------------------------------------------------------------------------- /test/lib/i2c.c: -------------------------------------------------------------------------------- 1 | // [REPEATED START NOT SUPPORTED] 2 | #include 3 | #include 4 | 5 | volatile uint32_t *i2c_start = (volatile uint32_t *) I2C_START; 6 | volatile uint32_t *i2c_write = (volatile uint32_t *) I2C_WRITE; 7 | volatile uint32_t *i2c_busy = (volatile uint32_t *) I2C_BUSY; 8 | volatile uint32_t *i2c_halt = (volatile uint32_t *) I2C_STOP; 9 | volatile uint32_t *i2c_ack = (volatile uint32_t *) I2C_ACK; 10 | volatile uint32_t *i2c_read_ready = (volatile uint32_t *) I2C_READ_DATA_READY; 11 | volatile uint32_t *i2c_read = (volatile uint32_t *) I2C_READ; 12 | 13 | 14 | // start i2c by writing slave address (returns slave ack) 15 | uint8_t i2c_write_address(uint8_t addr){ 16 | uint8_t ack; 17 | while(*i2c_busy); //stay here if busy 18 | *i2c_start = addr; //write to i2c address of slave 19 | while(*i2c_busy); //wait until write is finished 20 | ack = *i2c_ack; //check if slave acknowledged 21 | return ack; 22 | } 23 | 24 | // stop current i2c transaction 25 | void i2c_stop(void){ 26 | while(*i2c_busy); 27 | *i2c_halt = 0x01; 28 | while(*i2c_busy); 29 | *i2c_halt = 0x00; //set it back to zero in preparation for next transaction 30 | delay_ticks(100); 31 | } 32 | 33 | uint8_t i2c_write_byte(uint8_t data){ 34 | uint8_t ack; 35 | while(*i2c_busy); //stay here if busy 36 | *i2c_write = data; //write data byte to slave 37 | while(*i2c_busy); //wait until write is finished 38 | ack = *i2c_ack; //check if slave acknowledged 39 | return ack; 40 | } 41 | 42 | uint8_t i2c_read_byte(){ //read a byte from the slave (after i2c_write_address()) 43 | uint8_t read_data; 44 | while(*i2c_busy); 45 | while(*i2c_read_ready == 0){ //while read data is not yet available 46 | } 47 | read_data = *i2c_read; //retrieve data 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /test/lib/lcd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | // Source: https://deepbluembedded.com/interfacing-i2c-lcd-16x2-tutorial-with-pic-microcontrollers-mplab-xc8/ 4 | 5 | unsigned char RS, i2c_add, BackLight_State = LCD_BACKLIGHT; 6 | 7 | void LCD_Init() //initialize LCD with proper routine 8 | { 9 | i2c_add = LCD_I2C_ADDR; 10 | IO_Expander_Write(0x00); 11 | delay_ms(30); 12 | LCD_CMD(0x03); 13 | delay_ms(5); 14 | LCD_CMD(0x03); 15 | delay_ms(5); 16 | LCD_CMD(0x03); 17 | delay_ms(5); 18 | LCD_CMD(LCD_RETURN_HOME); 19 | delay_ms(5); 20 | LCD_CMD(0x20 | (LCD_TYPE << 2)); 21 | delay_ms(50); 22 | LCD_CMD(LCD_TURN_ON); 23 | delay_ms(50); 24 | LCD_CMD(LCD_CLEAR); 25 | delay_ms(50); 26 | LCD_CMD(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME); 27 | delay_ms(50); 28 | } 29 | 30 | void IO_Expander_Write(unsigned char Data) 31 | { 32 | uint8_t addr_ack, data_ack; 33 | addr_ack = i2c_write_address(i2c_add<<1); 34 | data_ack = i2c_write_byte(Data | BackLight_State); 35 | i2c_stop(); 36 | } 37 | 38 | void LCD_Write_4Bit(unsigned char Nibble) 39 | { 40 | // Get The RS Value To LSB OF Data 41 | Nibble |= RS; 42 | IO_Expander_Write(Nibble | 0x04); 43 | IO_Expander_Write(Nibble & 0xFB); 44 | delay_ms(50); 45 | } 46 | 47 | void LCD_CMD(unsigned char CMD) 48 | { 49 | RS = 0; // Command Register Select 50 | LCD_Write_4Bit(CMD & 0xF0); 51 | LCD_Write_4Bit((CMD << 4) & 0xF0); 52 | } 53 | 54 | void LCD_Write_Char(char Data) 55 | { 56 | RS = 1; // Data Register Select 57 | LCD_Write_4Bit(Data & 0xF0); 58 | LCD_Write_4Bit((Data << 4) & 0xF0); 59 | } 60 | 61 | void LCD_Write_String(char* Str) //write string to LCD 62 | { 63 | for(int i=0; Str[i]!='\0'; i++) 64 | LCD_Write_Char(Str[i]); 65 | } 66 | 67 | void LCD_Set_Cursor(unsigned char ROW, unsigned char COL) //Set cursor where to start writing to LCD 68 | { 69 | switch(ROW) 70 | { 71 | case 2: 72 | LCD_CMD(0xC0 + COL-1); 73 | break; 74 | case 3: 75 | LCD_CMD(0x94 + COL-1); 76 | break; 77 | case 4: 78 | LCD_CMD(0xD4 + COL-1); 79 | break; 80 | // Case 1 81 | default: 82 | LCD_CMD(0x80 + COL-1); 83 | } 84 | } 85 | 86 | void Backlight(void) //turn on backlight (initially turned on) 87 | { 88 | BackLight_State = LCD_BACKLIGHT; 89 | IO_Expander_Write(0); 90 | } 91 | 92 | void noBacklight(void) //turn off backlight 93 | { 94 | BackLight_State = LCD_NOBACKLIGHT; 95 | IO_Expander_Write(0); 96 | } 97 | 98 | void LCD_SL(void) 99 | { 100 | LCD_CMD(0x18); 101 | delay_ms(40); 102 | } 103 | 104 | void LCD_SR(void) 105 | { 106 | LCD_CMD(0x1C); 107 | delay_ms(40); 108 | } 109 | 110 | void LCD_Clear(void) 111 | { 112 | LCD_CMD(0x01); 113 | delay_ms(40); 114 | } 115 | 116 | -------------------------------------------------------------------------------- /test/lib/uart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | volatile uint32_t *uart_tx_data = (volatile uint32_t *) UART_TX_DATA; 5 | volatile uint32_t *uart_tx_busy = (volatile uint32_t *) UART_TX_BUSY; 6 | volatile uint32_t *uart_rx_full = (volatile uint32_t *) UART_RX_BUFFER_FULL; 7 | volatile uint32_t *uart_rx_data = (volatile uint32_t *) UART_RX_DATA; 8 | 9 | // print characters serially via UART 10 | void uart_print(char *message) { 11 | int i = 0; 12 | while (message[i] != '\0') { 13 | while (*uart_tx_busy); // wait for UART to be ready 14 | *uart_tx_data = message[i]; 15 | i++; 16 | } 17 | } 18 | 19 | //check if read buffer is full and data can be read 20 | int uart_rx_buffer_full(){ 21 | int ready = *uart_rx_full; 22 | return ready; 23 | } 24 | 25 | //read data from buffer (make sure to check first if rx buffer is full) 26 | char uart_read(){ 27 | char read_data; 28 | read_data = *uart_rx_data; 29 | return read_data; 30 | } 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /test/lib/ultrasonic_sensor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // returns distance in cm detected by the ultrasonic sensor 5 | int ultrasonic_sensor_cm(int trig_pin, int echo_pin){ 6 | int pulse_duration_us; 7 | int distance_cm; 8 | 9 | gpio_set_mode_pin(trig_pin, 1); //set mode setting of a single GPIO pin(read = 0, write = 1) 10 | gpio_set_mode_pin(echo_pin, 0); //set mode setting of a single GPIO pin(read = 0, write = 1) 11 | 12 | // set trig_pin for 10us 13 | gpio_write_pin(trig_pin, 0); //write to a specific GPIO pin (automatically set pin to write mode) 14 | delay_us(2); // delay function based on microseconds 15 | gpio_write_pin(trig_pin, 1); //write to a specific GPIO pin (automatically set pin to write mode) 16 | delay_us(10); // delay function based on microseconds 17 | gpio_write_pin(trig_pin, 0); //write to a specific GPIO pin (automatically set pin to write mode) 18 | 19 | pulse_duration_us = gpio_pulse_duration_us(echo_pin, 1); //measure how long will be the high pulse 20 | distance_cm = pulse_duration_us*(0.034/2); 21 | return distance_cm; 22 | } 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /test/rv32i_core.sby: -------------------------------------------------------------------------------- 1 | [options] 2 | mode prove 3 | depth 3 4 | 5 | [engines] 6 | smtbmc 7 | 8 | [script] 9 | read -formal rv32i_forwarding.v 10 | read -formal rv32i_basereg.v 11 | read -formal rv32i_fetch.v 12 | read -formal rv32i_decoder.v 13 | read -formal rv32i_alu.v 14 | read -formal rv32i_memoryaccess.v 15 | read -formal rv32i_writeback.v 16 | read -formal rv32i_csr.v 17 | read -formal rv32i_core.v 18 | read -formal fwb_master.v 19 | # verific -import -flatten rv32i_core 20 | prep -top rv32i_core 21 | 22 | [files] 23 | ../rtl/rv32i_header.vh 24 | ../rtl/rv32i_forwarding.v 25 | ../rtl/rv32i_basereg.v 26 | ../rtl/rv32i_fetch.v 27 | ../rtl/rv32i_decoder.v 28 | ../rtl/rv32i_alu.v 29 | ../rtl/rv32i_memoryaccess.v 30 | ../rtl/rv32i_writeback.v 31 | ../rtl/rv32i_csr.v 32 | ../rtl/rv32i_core.v 33 | ../rtl/fwb_master.v 34 | 35 | -------------------------------------------------------------------------------- /test/rv32i_linkerscript.ld: -------------------------------------------------------------------------------- 1 | /* This is sourced from: https://github.com/stnolting/neorv32/blob/main/sw/common/neorv32.ld */ 2 | 3 | ENTRY(_start) 4 | 5 | /* Define the memory regions */ 6 | MEMORY 7 | { 8 | /* Define the ROM(read, executable) memory region for the program */ 9 | ROM (rx) : ORIGIN = 0, LENGTH = 64k 10 | 11 | /* Define the RAM(read,write,executable) memory region for the program */ 12 | RAM (rwx) : ORIGIN = 64k, LENGTH = 16k 13 | } 14 | 15 | 16 | SECTIONS 17 | { 18 | /* start section on WORD boundary */ 19 | . = ALIGN(4); 20 | 21 | /* Actual instructions */ 22 | .text : 23 | { 24 | PROVIDE(__text_start = .); 25 | PROVIDE(__textstart = .); 26 | 27 | PROVIDE_HIDDEN (__rela_iplt_start = .); 28 | *(.rela.iplt) 29 | PROVIDE_HIDDEN (__rela_iplt_end = .); 30 | 31 | *(.rela.plt) 32 | 33 | KEEP(*(.text.boot)); /* keep start-up code at the beginning of rom */ 34 | 35 | KEEP (*(SORT_NONE(.init))) 36 | 37 | *(.text.unlikely .text.*_unlikely .text.unlikely.*) 38 | *(.text.exit .text.exit.*) 39 | *(.text.startup .text.startup.*) 40 | *(.text.hot .text.hot.*) 41 | *(SORT(.text.sorted.*)) 42 | *(.text .stub .text.* .gnu.linkonce.t.*) 43 | /* .gnu.warning sections are handled specially by elf.em. */ 44 | *(.gnu.warning) 45 | 46 | KEEP (*(SORT_NONE(.fini))) 47 | 48 | /* We don't want to include the .ctor section from 49 | the crtend.o file until after the sorted ctors. 50 | The .ctor section from the crtend file contains the 51 | end of ctors marker and it must be last */ 52 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 53 | KEEP (*(SORT(.ctors.*))) 54 | KEEP (*(.ctors)) 55 | 56 | KEEP (*crtbegin.o(.dtors)) 57 | KEEP (*crtbegin?.o(.dtors)) 58 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 59 | KEEP (*(SORT(.dtors.*))) 60 | KEEP (*(.dtors)) 61 | 62 | /* finish section on WORD boundary */ 63 | . = ALIGN(4); 64 | 65 | PROVIDE (__etext = .); 66 | PROVIDE (_etext = .); 67 | PROVIDE (etext = .); 68 | } > ROM 69 | 70 | 71 | /* read-only data, appended to .text */ 72 | .rodata : 73 | { 74 | PROVIDE_HIDDEN (__init_array_start = .); 75 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 76 | KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) 77 | PROVIDE_HIDDEN (__init_array_end = .); 78 | 79 | PROVIDE_HIDDEN (__fini_array_start = .); 80 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 81 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 82 | PROVIDE_HIDDEN (__fini_array_end = .); 83 | 84 | *(.rodata .rodata.* .gnu.linkonce.r.*) 85 | *(.rodata1) 86 | 87 | /* finish section on WORD boundary */ 88 | . = ALIGN(4); 89 | } > ROM 90 | 91 | 92 | /* initialized read/write data, accessed in RAM, placed in ROM, copied during boot */ 93 | .data : 94 | { 95 | __DATA_BEGIN__ = .; 96 | __SDATA_BEGIN__ = .; 97 | *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) 98 | *(.data1) 99 | *(.data .data.* .gnu.linkonce.d.*) 100 | SORT(CONSTRUCTORS) 101 | 102 | *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) 103 | *(.dynamic) 104 | 105 | /* We want the small data sections together, so single-instruction offsets 106 | can access them all, and initialized data all before uninitialized, so 107 | we can shorten the on-disk segment size. */ 108 | 109 | *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) 110 | *(.sdata .sdata.* .gnu.linkonce.s.*) 111 | 112 | PROVIDE_HIDDEN (__tdata_start = .); 113 | *(.tdata .tdata.* .gnu.linkonce.td.*) 114 | 115 | 116 | /* finish section on WORD boundary */ 117 | . = ALIGN(4); 118 | 119 | _edata = .; PROVIDE (edata = .); 120 | . = .; 121 | 122 | } > RAM 123 | 124 | 125 | /* zero/non-initialized read/write data placed in RAM */ 126 | .bss (NOLOAD): 127 | { 128 | __bss_start = .; 129 | *(.dynsbss) 130 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 131 | *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) 132 | *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) 133 | *(.scommon) 134 | *(.dynbss) 135 | *(.bss .bss.* .gnu.linkonce.b.*) 136 | 137 | PROVIDE_HIDDEN (__preinit_array_start = .); 138 | KEEP (*(.preinit_array)) 139 | PROVIDE_HIDDEN (__preinit_array_end = .); 140 | 141 | *(COMMON) 142 | /* Align here to ensure that the .bss section occupies space up to 143 | _end. Align after .bss to ensure correct alignment even if the 144 | .bss section disappears because there are no input sections. 145 | FIXME: Why do we need it? When there is no .bss section, we do not 146 | pad the .data section. */ 147 | . = ALIGN(. != 0 ? 32 / 8 : 1); 148 | 149 | . = ALIGN(32 / 8); 150 | __bss_end = .; 151 | __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __bss_end - 0x800)); 152 | _end = .; PROVIDE (end = .); 153 | } > RAM 154 | 155 | 156 | 157 | 158 | /* Define symbols for start and end of each memory region */ 159 | __ram_start = ORIGIN(RAM); 160 | __ram_end = __ram_start + LENGTH(RAM); 161 | __rom_start = ORIGIN(ROM); 162 | __rom_end = __rom_start + LENGTH(ROM); 163 | 164 | /* Define the stack section */ 165 | __stack_pointer = __ram_end - 4; 166 | 167 | 168 | 169 | } 170 | -------------------------------------------------------------------------------- /test/wave.do: -------------------------------------------------------------------------------- 1 | onerror {resume} 2 | quietly virtual signal -install /rv32i_soc_TB/uut/m0 { (context /rv32i_soc_TB/uut/m0 )&{fetch_ce , decoder_ce , alu_ce , memoryaccess_ce , writeback_ce }} clock_enables 3 | quietly WaveActivateNextPane {} 0 4 | add wave -noupdate /rv32i_soc_TB/clk 5 | add wave -noupdate /rv32i_soc_TB/rst_n 6 | add wave -noupdate -divider {Core Interface} 7 | add wave -noupdate /rv32i_soc_TB/uut/m0/o_iaddr 8 | add wave -noupdate /rv32i_soc_TB/uut/m0/i_inst 9 | add wave -noupdate /rv32i_soc_TB/uut/m0/o_daddr 10 | add wave -noupdate /rv32i_soc_TB/uut/m0/i_din 11 | add wave -noupdate /rv32i_soc_TB/uut/m0/o_dout 12 | add wave -noupdate -radix binary /rv32i_soc_TB/uut/m0/o_wr_mask 13 | add wave -noupdate /rv32i_soc_TB/uut/m0/o_wr_en 14 | add wave -noupdate -divider {Core Registers} 15 | add wave -noupdate -radix binary /rv32i_soc_TB/uut/m0/stall 16 | add wave -noupdate /rv32i_soc_TB/uut/m0/m2/o_opcode 17 | add wave -noupdate /rv32i_soc_TB/uut/m0/m2/o_alu 18 | add wave -noupdate /rv32i_soc_TB/uut/m0/clock_enables 19 | add wave -noupdate /rv32i_soc_TB/uut/m0/alu_change_pc 20 | add wave -noupdate /rv32i_soc_TB/uut/m0/alu_next_pc 21 | add wave -noupdate /rv32i_soc_TB/uut/m0/writeback_change_pc 22 | add wave -noupdate /rv32i_soc_TB/uut/m0/writeback_next_pc 23 | add wave -noupdate -divider {Decoder Outputs} 24 | add wave -noupdate /rv32i_soc_TB/uut/m0/rs1 25 | add wave -noupdate /rv32i_soc_TB/uut/m0/rs2 26 | add wave -noupdate /rv32i_soc_TB/uut/m0/decoder_rs1_addr 27 | add wave -noupdate /rv32i_soc_TB/uut/m0/decoder_rs2_addr 28 | add wave -noupdate /rv32i_soc_TB/uut/m0/decoder_rd_addr 29 | add wave -noupdate /rv32i_soc_TB/uut/m0/m2/valid_opcode 30 | add wave -noupdate /rv32i_soc_TB/uut/m0/m2/illegal_shift 31 | add wave -noupdate -divider ALU 32 | add wave -noupdate /rv32i_soc_TB/uut/m0/rs1_orig 33 | add wave -noupdate /rv32i_soc_TB/uut/m0/rs2_orig 34 | add wave -noupdate /rv32i_soc_TB/uut/m0/m3/a 35 | add wave -noupdate /rv32i_soc_TB/uut/m0/m3/b 36 | add wave -noupdate /rv32i_soc_TB/uut/m0/m3/o_y 37 | add wave -noupdate -divider WriteBack 38 | add wave -noupdate /rv32i_soc_TB/uut/m0/m5/o_wr_rd 39 | add wave -noupdate -divider {Basereg and Memory} 40 | add wave -noupdate /rv32i_soc_TB/uut/m0/m0/base_regfile 41 | add wave -noupdate /rv32i_soc_TB/uut/m1/memory_regfile 42 | TreeUpdate [SetDefaultTree] 43 | WaveRestoreCursors {{Cursor 1} {236501 ps} 0} 44 | quietly wave cursor active 1 45 | configure wave -namecolwidth 243 46 | configure wave -valuecolwidth 100 47 | configure wave -justifyvalue left 48 | configure wave -signalnamewidth 1 49 | configure wave -snapdistance 10 50 | configure wave -datasetprefix 0 51 | configure wave -rowmargin 4 52 | configure wave -childrowmargin 2 53 | configure wave -gridoffset 0 54 | configure wave -gridperiod 1 55 | configure wave -griddelta 40 56 | configure wave -timeline 0 57 | configure wave -timelineunits ns 58 | update 59 | WaveRestoreZoom {218274 ps} {320091 ps} 60 | --------------------------------------------------------------------------------