├── .gitignore ├── .idea ├── .gitignore ├── dictionaries │ └── wuqin.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── Makefile ├── README.md ├── RISCV-CPU.iml ├── report ├── Overview.png ├── Overview.psd ├── Report.pdf └── Report.tex ├── src ├── block_ram.v ├── buffer_branch.v ├── buffer_write.v ├── cache_d.v ├── cache_i.v ├── cpu.v ├── ctrl_mem.v ├── ctrl_stall.v ├── define.v ├── fifo.v ├── hci.v ├── pipe_ex_mem.v ├── pipe_id_ex.v ├── pipe_if_id.v ├── pipe_mem_wb.v ├── ram.v ├── reg_file.v ├── reg_pc.v ├── riscv_top.v ├── stage_ex.v ├── stage_id.v ├── stage_if.v ├── stage_mem.v ├── testbench.v ├── uart.v ├── uart_baud_clk.v ├── uart_rx.v └── uart_tx.v └── test_tool ├── ctrl ├── build.sh ├── controller.cpp ├── listener.h └── run.sh ├── fpga_build.sh ├── fpga_run.sh ├── sim_build.sh ├── sim_run.sh ├── sys ├── io.h ├── memory.ld ├── rom.o └── rom.s └── testcase ├── array_test1.ans ├── array_test1.c ├── array_test1.in ├── array_test1.sim.c ├── array_test2.ans ├── array_test2.c ├── array_test2.in ├── basicopt1.ans ├── basicopt1.c ├── basicopt1.sim.c ├── bulgarian.ans ├── bulgarian.c ├── bulgarian.sim.c ├── expr.ans ├── expr.c ├── expr.sim.c ├── gcd.ans ├── gcd.c ├── gcd.sim.c ├── hanoi.ans ├── hanoi.c ├── hanoi.in ├── love.c ├── love.sim.c ├── lvalue2.ans ├── lvalue2.c ├── lvalue2.sim.c ├── magic.ans ├── magic.c ├── magic.sim.c ├── manyarguments.ans ├── manyarguments.c ├── manyarguments.sim.c ├── multiarray.ans ├── multiarray.c ├── multiarray.sim.c ├── pi.ans ├── pi.c ├── pi.sim.c ├── print_hello.ans ├── print_hello.c ├── print_hello.sim.c ├── qsort.ans ├── qsort.c ├── qsort.sim.c ├── queens.ans ├── queens.c ├── queens.sim.c ├── statement_test.ans ├── statement_test.c ├── statement_test.in ├── superloop.ans ├── superloop.c ├── superloop.in ├── tak.ans ├── tak.c ├── tak.in └── testsleep.c /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | data 3 | /.idea/edaphic/defines.xml 4 | *.aux 5 | *.log 6 | *.out 7 | *.swp 8 | /test_tool/ctrl/ctrl 9 | /test_tool/test/ 10 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /.idea/dictionaries/wuqin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | aluop 5 | alusel 6 | auipc 7 | bgeu 8 | bltu 9 | fpga 10 | jalr 11 | riscv 12 | slli 13 | slti 14 | sltiu 15 | sltu 16 | srai 17 | srli 18 | xori 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | out/sim: src/*.v 2 | iverilog -Isrc -Diverilog src/*.v -o out/testbench 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RISCV-CPU 2 | 3 | A RISC-V CPU with standard 5-stage pipeline, implemented in Verilog HDL 4 | 5 | ## Feature, Performance 6 | 7 | Please refer to the project report. 8 | 9 | ## Feature Progress 10 | 11 | For feature details, please refer to project report. 12 | 13 | Feature|Status 14 | ----|---- 15 | Simulation Correct Output|__Test OK__ 16 | FPGA Correct Output|__Test OK__ 17 | Data Forwarding|__Test OK__ 18 | IF Prefetch|__Test OK__ 19 | ICache (1-Cycle Hit)|__Test OK__ 20 | DCache (Write Back) (1-Cycle Hit)|__Test OK__ 21 | Write Buffer|__Test OK__ 22 | 2-bit BTB|__Test OK__ 23 | 24 | ## Timeline 25 | 26 | + 2019.11.12 Finish ori (as MIPS) (pass compilation) 27 | + 2019.11.20 ori (pass result check) 28 | + 2019.11.20 Change into RV32I (untested) 29 | + 2019.11.22 Reconstruct lots of code (untested) 30 | + 2019.11.22 ori (pass test) 31 | + 2019.11.22 Add OP_OP and OP_IMM (untested) 32 | + 2019.11.22 Add Data Forward (naive) (untested) 33 | + 2019.11.23 Data Forward (naive) (pass test) 34 | + 2019.11.23 OP_OP and OP_IMM (pass test) 35 | + 2019.11.23 Add JUMP and BRANCH (not pass compilation) 36 | + 2019.11.23 Add ctrl_stall (not pass compilation) 37 | + 2019.11.25 Add MEM (not pass compilation) 38 | + 2019.11.25 IF pass simple test 39 | + 2019.11.25 JAL seems passed 40 | + 2019.11.25 Single LOAD seems passed 41 | + 2019.11.26 Fix Data Forward with stall_mem 42 | + 2019.11.26 BRANCH with stall_id & stall_mem seems passed 43 | + 2019.11.26 Reconstruct ctrl_mem (untested) 44 | + 2019.11.26 Trivial Test pass 45 | + 2019.11.27 Pass many tests 46 | + 2019.11.28 Fix an issue in IF 47 | + 2019.11.28 Fix an issue in ctrl_stall 48 | + 2019.11.28 Add ICache (pass some tests, cannot pass some tests) 49 | + 2019.11.28 Fix several issues about data hazard 50 | + 2019.11.29 Fix an issue about data hazard (branch after load) 51 | + 2019.11.30 Fix an issue in stage_ex (store after load) 52 | + 2019.12.09 Fix some (maybe meaningless) bugs 53 | + 2019.12.11 Decrease time slack to 4.865ns (reconstruct branch) 54 | + 2019.12.12 Delay br one more cycle (not very useful) 55 | + 2019.12.25 Reconstruct cache and fix all inferring latch 56 | + 2019.12.26 Pass several tests on FPGA 57 | + 2019.12.27 Invalidate cache_i when resetting 58 | + 2019.12.27 Pass all tests on FPGA 59 | + 2019.12.27 Optimize some codes 60 | + 2019.12.28 Add an extra cycle to cache miss to reduce cycle time 61 | + 2019.12.28 Add IF-read ahead to mem_ctrl 62 | + 2019.12.28 Fix cache offset 63 | + 2019.12.29 Add DCache (pass some tests) 64 | + 2019.12.29 Reduce Time Slack & Pass tests on FPGA without input 65 | + 2019.12.29 DCache pass all tests on FPGA 66 | + 2019.12.29 Change mem_ctrl priority 67 | + 2019.12.30 Add Write Buffer (pass all tests on FPGA) 68 | + 2020.01.01 IF Read Ahead Interruptable 69 | + 2020.01.02 Add BTB (pass some test) 70 | + 2020.01.02 Interrupt IF-read head when IO (cannot pass print_hello, gcd and hanoi) 71 | + 2020.01.03 Pass All Tests 72 | + 2020.01.03 Remove unused code 73 | + 2020.01.03 Add project report 74 | 75 | ## Test on FPGA 76 | 77 | Test Name|Current 78 | ----|---- 79 | array_test1|0.000 80 | array_test2|0.016 81 | basicopt1|0.016 82 | bulgarian|1.313 (extra sleep) 83 | expr|0.031 84 | gcd|0.016 85 | hanoi|0.766 86 | lvalue2|0.016 87 | magic|0.031 88 | manyarguments|0.000 89 | multiarray|0.031 90 | pi|0.469 91 | qsort|3.500 (extra sleep) 92 | queens|0.563 93 | statement_test|0.016 94 | superloop|0.016 95 | tak|0.016 96 | love|138.3 97 | -------------------------------------------------------------------------------- /RISCV-CPU.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /report/Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wu-qing-157/RISCV-CPU/7a2897619837c8b03b7536d391d38ac7fa6e43ce/report/Overview.png -------------------------------------------------------------------------------- /report/Overview.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wu-qing-157/RISCV-CPU/7a2897619837c8b03b7536d391d38ac7fa6e43ce/report/Overview.psd -------------------------------------------------------------------------------- /report/Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wu-qing-157/RISCV-CPU/7a2897619837c8b03b7536d391d38ac7fa6e43ce/report/Report.pdf -------------------------------------------------------------------------------- /report/Report.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | \usepackage{xeCJK, indentfirst, geometry} 4 | \usepackage{hyperref} 5 | \usepackage{booktabs} 6 | 7 | \geometry{a4paper} 8 | 9 | %\setCJKmainfont{微软雅黑} 10 | 11 | \title{Project Report of RISCV-CPU} 12 | \author{Yi Gu} 13 | 14 | \begin{document} 15 | \maketitle 16 | 17 | \section{Summary} 18 | 19 | This project is a RISC-V CPU with five-stage pipeline, implemented in Verilog HDL. 20 | 21 | The CPU can be simulated by Icarus Verilog or Xilinx xsim, and can be implemented on Basys3 FPGA, using Xilinx vivado. 22 | 23 | The repository of this project may be found at: \url{https://github.com/wu-qing-157/RISCV-CPU}. 24 | 25 | \section{Design} 26 | 27 | \subsection{Project Overview} 28 | 29 | This project has a standard $5$-stage pipeline with some additional features, and the overview structure is shown in the below figure: 30 | 31 | \begin{center} 32 | \includegraphics[scale=0.7]{Overview.png} 33 | \end{center} 34 | 35 | Note: Red lines represent data flow controlled by clock. 36 | Lines with light color represent control flow. 37 | 38 | \subsection{Features} 39 | 40 | Main features implemented in this project are listed as below, with some of them described in later part of this section. 41 | 42 | \begin{table}[h] 43 | \centering 44 | \begin{tabular}{l l} 45 | \toprule 46 | Feature & Description\\ 47 | \midrule 48 | ISA & RV32I subset of RISC-V\\ 49 | Pipelining & Standard 5 stages\\ 50 | Data Forwarding & Complete forwarding paths\\ 51 | Cache & Direct mapping Instruction Cache \& Direct mapping Data Cache\\ 52 | Write Buffer & $1$-block $4$-byte Write Buffer\\ 53 | Branch Prediction & $2$-bit Branch Target Buffer\\ 54 | IF Prefetch & Prefetch during spare time of memory port\\ 55 | \bottomrule 56 | \end{tabular} 57 | \end{table} 58 | 59 | Details of some features are listed below: 60 | 61 | \begin{description} 62 | \item[Instruction Cache] 63 | A direct mapping I-Cache with size of $256 \times 4~\mathrm{bytes}$ is implemented. 64 | If cache hits, the data will be returned in the same cycle, 65 | while, otherwise, fetching of the instruction will be started from the next cycle. 66 | The slow behavior of cache-hit check and memory port is to blame for the additional cycle. 67 | The latency caused by the additional cycle is eliminated with \textit{IF Prefetch} described below. 68 | \item[Data Cache] 69 | A direct mapping D-Cache with size of $128 \times 4~\mathrm{bytes}$ is implemented. 70 | The write policy is a mixture of write back and write through, 71 | and in detail, $4$-byte store insructions use write back and other store instructions use write through. 72 | It is so arranged because of the large proportion of $4$-byte store instructions, 73 | and the $4$-byte block size due to limitation of units on FPGA. 74 | Similar as I-Cache, cache-hit data is returned in the same cycle, while cache-misses take an addtional cycle. 75 | \item[Write Buffer] 76 | A naive single-block $4$-byte write buffer is added for D-Cache. 77 | Data in write buffer will be flushed when memory port is not busy. 78 | \item[IF Prefetch] 79 | After an instruction is fetched, the next instruction will be pre-fetched. 80 | The prioity of the pre-fetching is lower than load needed by D-Cache, but higher than write buffer. 81 | Note that in this implementation, I-Cache-miss and D-Cache-miss takes $3$ unused cycles, 82 | the pre-fetching will also take advantage of these $3$ cycles, with exception described in next section. 83 | Note that \textit{IF Prefetch} will be interrupted by wrong branch predition (prefetching is meaningless), 84 | or branches predicted taken (cache-hit rate of the target instruction is very high). 85 | \end{description} 86 | 87 | \subsection{Performance} 88 | 89 | The implemented CPU can be run on FPGA with a frequency of $230~\mathrm{MHz}$. 90 | 91 | It can pass all tests on FPGA listed in the project repository. 92 | Note that it has some problems during simulation due to some issues in the given \textit{hci.v}. 93 | 94 | Some detailed performance quota are tested based on testcases in the project repository. 95 | 96 | \clearpage 97 | 98 | \begin{table}[h] 99 | \centering 100 | \begin{tabular}{l c c c c} 101 | \toprule 102 | Testname & Instructions & Cycles & CPI & FPGA Time (sec)\\ 103 | \midrule 104 | bulgarian & $872042$ & $955046$ & $1.095$ & - \\ 105 | pi & - & - & - & $0.469$ \\ 106 | magic & $661360$ & $723539$ & $1.094$ & $0.031$ \\ 107 | queens & $521577$ & $585617$ & $1.123$ & $0.563$ \\ 108 | love & - & - & - & $183.3$\\ 109 | \bottomrule 110 | \end{tabular} 111 | \end{table} 112 | 113 | \section{Thinkings} 114 | 115 | \begin{description} 116 | \item[Issues in given files] 117 | In the given files, there does exist lots of issues disturbing my finishing this project. 118 | When testing with simulation, some bytes written to IO port will be displayed twice or even four times. 119 | In order to check who is to blame, I need to check the huge wave grapth. 120 | Reading from IO port will cause last reading from memory port invalid, 121 | and the reading address one cycle after reading from IO port must have $1$ on its $17$-th bit 122 | to keep the IO reading valid. 123 | These two issues disturb me a lot when debugging my project on FPGA. 124 | I think as a course project, the above $3$ issues are supposed not happen, 125 | and we students should at least be informed. 126 | However, the assignment repository and TAs give me a bad feel. 127 | Addtionally, due to the issues mentioned above, 128 | the \textit{IF Prefetch} will be interrupted by a IO reading, and will be restarted after next IF reading. 129 | \item[The motivation for \textit{IF Prefetch} and \textit{Write Buffer}] 130 | The memory port on FPGA is completely different from RAM in modern computer, 131 | where the motivation for \textit{IF Prefetch} and \textit{Write Buffer} comes from. 132 | \textit{Write Buffer} dalays unimportant write behavior to gaps between reading, 133 | and \textit{IF Prefetch} makes full use of the actually unused cycles. 134 | Based on simulation tests, it's better to grant \textit{IF Prefetch} a higher priority than \textit{Write Buffer}. 135 | \item[The block size of Cache] 136 | Due to the limitation of units on FPGA, the way of memory access, 137 | and the proportion of $4$-byte load instructions, as well as the difficulties in implementation, 138 | $4$-byte block size is chosen for both I-Cache and D-Cache. 139 | \item[Mapping method of Cache and BTB] 140 | The performance on FPGA is not so good for me to choose 141 | fully-associated or set-associated. Actually, even implemented as direct mapping, 142 | I-Cache-hit and D-Cache-hit are the bottleneck of the performance. 143 | \item[Total size of Cache and BTB] 144 | Currently I have $256$ blocks for I-Cache, $128$ blocks for D-Cache, 145 | and $32$ blocks for BTB. 146 | As tested, the CPI performance can only increase by less than $0.5\%$ if I double any of it, 147 | so these $3$ figures are chosen. 148 | % \item[Annoying grading standard] 149 | % Also it seems inappropriate to include this part in a project report, 150 | % I still want to make complaints about the quite annoying grading standard. 151 | % The grading standard of this course project is neither given in time nor being paricular. 152 | % The standard was specified near the deadline, not granting us sufficient time to achieve some grades. 153 | % It was also vague on point assignments, which may cause dispute on final grading. 154 | % Besides that, TAs informed us of the bonus of presentation just during the week filled with final exams. 155 | % At least, it was too late. The presentation should not be assigned on last week, especially a busy week. 156 | % Also, the bonus of presentation is itself improper. 157 | % From my point of view, it should be either nonexistent or required to everyone, but may not be treated as a bonus. 158 | \end{description} 159 | 160 | \section{Acknowledgement} 161 | 162 | Special thanks would go to Yuan Yao and Zonghan Yang who discuss with me some features implemented in this project, 163 | and Haichen Dong who informed me of the issues in given files. 164 | Also, I would like to express my gratitude to TAs 165 | for providing codes for memory and IO ports (although with some issued). 166 | I also referenced the book \textit{自己动手写 CPU} and Zhou Fan's project at the very beginning of my own project. 167 | 168 | \section*{Reference} 169 | 170 | \begin{itemize} 171 | \item 雷思磊. \textit{自己动手写CPU}, 电子工业出版社, 2014 172 | \item Zhou Fan. RISC-V-CPU. \url{https://github.com/Evensgn/RISC-V-CPU} 173 | \end{itemize} 174 | \end{document} 175 | -------------------------------------------------------------------------------- /src/block_ram.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************************** 2 | * 3 | * Copyright (c) 2012, Brian Bennett 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are permitted 7 | * provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 10 | * and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other materials provided 13 | * with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 22 | * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * Various generic, inferred block ram descriptors. 25 | ***************************************************************************************************/ 26 | 27 | // Dual port RAM with synchronous read. Modified version of listing 12.4 in "FPGA Prototyping by 28 | // Verilog Examples," itself a modified version of XST 8.11 v_rams_11. 29 | module dual_port_ram_sync 30 | #( 31 | parameter ADDR_WIDTH = 6, 32 | parameter DATA_WIDTH = 8 33 | ) 34 | ( 35 | input wire clk, 36 | input wire we, 37 | input wire [ADDR_WIDTH-1:0] addr_a, 38 | input wire [ADDR_WIDTH-1:0] addr_b, 39 | input wire [DATA_WIDTH-1:0] din_a, 40 | output wire [DATA_WIDTH-1:0] dout_a, 41 | output wire [DATA_WIDTH-1:0] dout_b 42 | ); 43 | 44 | reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0]; 45 | reg [ADDR_WIDTH-1:0] q_addr_a; 46 | reg [ADDR_WIDTH-1:0] q_addr_b; 47 | 48 | always @(posedge clk) 49 | begin 50 | if (we) 51 | ram[addr_a] <= din_a; 52 | q_addr_a <= addr_a; 53 | q_addr_b <= addr_b; 54 | end 55 | 56 | assign dout_a = ram[q_addr_a]; 57 | assign dout_b = ram[q_addr_b]; 58 | 59 | endmodule 60 | 61 | // Single port RAM with synchronous read. 62 | module single_port_ram_sync 63 | #( 64 | parameter ADDR_WIDTH = 6, 65 | parameter DATA_WIDTH = 8 66 | ) 67 | ( 68 | input wire clk, 69 | input wire we, 70 | input wire [ADDR_WIDTH-1:0] addr_a, 71 | input wire [DATA_WIDTH-1:0] din_a, 72 | output wire [DATA_WIDTH-1:0] dout_a 73 | ); 74 | 75 | reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0]; 76 | reg [ADDR_WIDTH-1:0] q_addr_a; 77 | 78 | always @(posedge clk) 79 | begin 80 | if (we) 81 | ram[addr_a] <= din_a; 82 | q_addr_a <= addr_a; 83 | end 84 | 85 | assign dout_a = ram[q_addr_a]; 86 | 87 | // initialize ram content (for simulation) 88 | integer i; 89 | initial begin 90 | for (i=0;i<2**ADDR_WIDTH;i=i+1) begin 91 | ram[i] = 0; 92 | end 93 | $readmemh("test.data", ram); // add test.data to vivado project or specify a valid file path 94 | end 95 | 96 | endmodule 97 | 98 | -------------------------------------------------------------------------------- /src/buffer_branch.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module buffer_branch( 4 | input wire reset, 5 | input wire clock, 6 | 7 | input wire [`MemAddrBus] pc_i, 8 | output reg [`MemAddrBus] pc_o, 9 | output reg prediction, 10 | 11 | input wire update, 12 | input wire committed, 13 | input wire [`BTBAllBytes] current, 14 | input wire [`MemAddrBus] target 15 | ); 16 | 17 | reg [`BTBNum-1:0] btb_valid; 18 | reg [`BTBTagBus] btb_tag [`BTBNum-1:0]; 19 | reg [`MemAddrBus] btb_target [`BTBNum-1:0]; 20 | reg [1:0] btb_predictor [`BTBNum-1:0]; 21 | 22 | wire [`BTBBus] pc_index = pc_i[`BTBBus]; 23 | wire [`BTBTagBus] pc_tag = pc_i[`BTBTagBytes]; 24 | 25 | always @(*) begin 26 | if (reset) begin 27 | pc_o = 0; 28 | prediction = 0; 29 | end else if (btb_valid[pc_index] && btb_tag[pc_index] == pc_tag && btb_predictor[pc_index][1]) begin 30 | pc_o = btb_target[pc_index]; 31 | prediction = 1; 32 | end else begin 33 | pc_o = pc_i+4; 34 | prediction = 0; 35 | end 36 | end 37 | 38 | wire [`BTBBus] current_index = current[`BTBBus]; 39 | wire [`BTBTagBus] current_tag = current[`BTBTagBytes]; 40 | 41 | always @(posedge clock) begin 42 | if (reset) begin 43 | btb_valid <= 0; 44 | end else if (update) begin 45 | if (btb_valid[current_index] && btb_tag[current_index] == current_tag) begin 46 | if (committed && btb_predictor[current_index] != 3) 47 | btb_predictor[current_index] <= btb_predictor[current_index]+1; 48 | if (!committed && btb_predictor[current_index] != 0) 49 | btb_predictor[current_index] <= btb_predictor[current_index]-1; 50 | end else begin 51 | btb_valid[current_index] <= 1; 52 | btb_tag[current_index] <= current_tag; 53 | btb_target[current_index] <= target; 54 | btb_predictor[current_index] <= committed ? 2:1; 55 | end 56 | end 57 | end 58 | 59 | endmodule 60 | -------------------------------------------------------------------------------- /src/buffer_write.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module buffer_write( 4 | input wire clock, 5 | input wire reset, 6 | 7 | input wire write, 8 | output wire busy, 9 | input wire [2:0] length, 10 | input wire [`MemAddrBus] addr, 11 | input wire [`MemDataBus] data, 12 | 13 | input wire ram_busy, 14 | input wire ram_seccess, 15 | output wire ram_write, 16 | output wire [`MemAddrBus] ram_addr, 17 | output wire [`ByteBus] ram_data 18 | ); 19 | 20 | wire [`ByteBus] write_data[3:0]; 21 | assign write_data[0] = data[7:0]; 22 | assign write_data[1] = data[15:8]; 23 | assign write_data[2] = data[23:16]; 24 | assign write_data[3] = data[31:24]; 25 | 26 | reg working; 27 | reg [2:0] cur; 28 | 29 | assign ram_addr = addr+cur; 30 | assign ram_data = write_data[cur]; 31 | 32 | assign busy = write || working; 33 | assign ram_write = busy && !ram_busy; 34 | 35 | always @(posedge clock) begin 36 | if (reset) begin 37 | cur <= 0; 38 | working <= 0; 39 | end else if (write) begin 40 | if (cur+ram_seccess == length) begin 41 | cur <= 0; 42 | working <= 0; 43 | end else begin 44 | cur <= cur+ram_seccess; 45 | working <= 1; 46 | end 47 | end else if (ram_write) begin 48 | if (cur+ram_seccess == length) begin 49 | cur <= 0; 50 | working <= 0; 51 | end else begin 52 | cur <= cur+ram_seccess; 53 | end 54 | end 55 | end 56 | 57 | endmodule 58 | -------------------------------------------------------------------------------- /src/cache_d.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module cache_d( 4 | input wire clock, 5 | input wire reset, 6 | 7 | input wire ram_busy, 8 | input wire ram_ready, 9 | output reg ram_read, 10 | output reg [2:0] ram_length, 11 | output reg ram_signed, 12 | output reg [`MemAddrBus] ram_addr, 13 | input wire [`MemDataBus] ram_data, 14 | 15 | input wire buffer_busy, 16 | output reg buffer_write, 17 | output reg [2:0] buffer_length, 18 | output reg [`MemAddrBus] buffer_addr, 19 | output reg [`MemDataBus] buffer_data, 20 | 21 | input wire read, 22 | input wire write, 23 | output reg ready, 24 | input wire [2:0] length, 25 | input wire signed_, 26 | input wire [`MemAddrBus] addr, 27 | input wire [`MemDataBus] data_i, 28 | output reg [`MemDataBus] data_o 29 | ); 30 | 31 | reg [`DCacheNum-1:0] cache_valid, cache_dirty; 32 | reg [`DCacheTagBus] cache_tag [`DCacheNum-1:0]; 33 | reg [`MemDataBus] cache_data [`DCacheNum-1:0]; 34 | 35 | wire [`DCacheBus] addr_index = addr[`DCacheBus]; 36 | wire [`DCacheTagBytes] addr_tag = addr[`DCacheTagBytes]; 37 | wire [`MemDataBus] addr_data = cache_data[addr_index]; 38 | 39 | wire buffer_miss = !buffer_busy || addr[`DCacheAllBytes] != buffer_addr[`DCacheAllBytes]; 40 | 41 | reg to_read, to_write, to_flush; 42 | reg cache_write; 43 | 44 | always @(*) begin 45 | ready = 0; data_o = 0; 46 | cache_write = 0; 47 | to_read = 0; to_write = 0; to_flush = 0; 48 | if (reset) begin 49 | end else if (read) begin 50 | if (!addr[17] && cache_valid[addr_index] && cache_tag[addr_index] == addr_tag) begin 51 | ready = 1; 52 | if (length[0]) begin 53 | case (addr[1:0]) 54 | 0: data_o = {{24{signed_ && addr_data[7]}}, addr_data[7:0]}; 55 | 1: data_o = {{24{signed_ && addr_data[15]}}, addr_data[15:8]}; 56 | 2: data_o = {{24{signed_ && addr_data[23]}}, addr_data[23:16]}; 57 | default: data_o = {{24{signed_ && addr_data[31]}}, addr_data[31:24]}; 58 | endcase 59 | end else if (length[1]) begin 60 | if (addr[1]) data_o = {{16{signed_ && addr_data[15]}}, addr_data[15:0]}; 61 | else data_o = {{16{signed_ && addr_data[31]}}, addr_data[31:16]}; 62 | end else begin 63 | data_o = addr_data; 64 | end 65 | end else if (!length[2]) begin 66 | if (ram_ready) begin 67 | ready = 1; data_o = ram_data; 68 | end else begin 69 | to_read = 1; 70 | end 71 | end else begin 72 | if (ram_ready) begin 73 | ready = 1; data_o = ram_data; 74 | end else if (!cache_dirty[addr_index]) begin 75 | to_read = 1; 76 | end else if (!buffer_busy) begin 77 | to_read = 1; to_flush = cache_valid[addr_index]; 78 | end else if (buffer_addr[`DCacheAllBytes] == {cache_tag[addr_index], addr_index}/* && buffer_data == addr_data*/) begin 79 | to_read = 1; 80 | end 81 | end 82 | end else if (write) begin 83 | if (!addr[17] && cache_valid[addr_index] && cache_tag[addr_index] == addr_tag) begin 84 | ready = 1; cache_write = 1; 85 | end else if (!length[2]) begin 86 | if (!buffer_busy) begin 87 | ready = 1; to_write = 1; 88 | end 89 | end else begin 90 | if (!cache_dirty[addr_index]) begin 91 | ready = 1; cache_write = 1; 92 | end else if (!buffer_busy) begin 93 | ready = 1; to_flush = cache_valid[addr_index]; cache_write = 1; 94 | end 95 | end 96 | end 97 | end 98 | 99 | reg delay_read, update_cache; 100 | 101 | always @(posedge clock) begin 102 | delay_read <= to_read && buffer_miss; 103 | update_cache <= ram_length[2]; 104 | ram_length <= length; 105 | ram_addr <= addr; 106 | ram_signed <= signed_; 107 | end 108 | 109 | always @(*) begin 110 | ram_read = delay_read && !ram_busy; 111 | end 112 | 113 | always @(posedge clock) begin 114 | if (reset) begin 115 | buffer_write <= 0; 116 | buffer_length <= 0; 117 | buffer_addr <= 0; 118 | buffer_data <= 0; 119 | end else if (to_write || to_flush) begin 120 | buffer_write <= 1; 121 | buffer_length <= to_write ? length:to_flush ? 4:0; 122 | buffer_addr <= to_write ? addr:{cache_tag[addr_index], addr_index, 2'b0}; 123 | buffer_data <= to_write ? data_i:addr_data; 124 | end else begin 125 | buffer_write <= 0; 126 | end 127 | end 128 | 129 | always @(posedge clock) begin 130 | if (reset) begin 131 | cache_valid <= 0; 132 | cache_dirty <= 0; 133 | end else if (cache_write) begin 134 | cache_dirty[addr_index] <= 1; 135 | if (length[0]) begin 136 | case (addr[1:0]) 137 | 0: cache_data[addr_index][7:0] <= data_i; 138 | 1: cache_data[addr_index][15:8] <= data_i; 139 | 2: cache_data[addr_index][23:16] <= data_i; 140 | 3: cache_data[addr_index][31:24] <= data_i; 141 | endcase 142 | end else if (length[1]) begin 143 | if (addr[1]) cache_data[addr_index][31:16] <= data_i; 144 | else cache_data[addr_index][15:0] <= data_i; 145 | end else begin 146 | cache_valid[addr_index] <= 1; 147 | cache_tag[addr_index] <= addr_tag; 148 | cache_data[addr_index] <= data_i; 149 | end 150 | end else if (delay_read && ram_ready && update_cache) begin 151 | cache_valid[addr_index] <= 1; 152 | cache_dirty[addr_index] <= 0; 153 | cache_tag[addr_index] <= addr_tag; 154 | cache_data[addr_index] <= ram_data; 155 | end 156 | end 157 | 158 | endmodule 159 | -------------------------------------------------------------------------------- /src/cache_i.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module cache_i( 4 | input wire clock, 5 | input wire reset, 6 | 7 | input wire discard, 8 | 9 | input wire ram_busy, 10 | input wire ram_ready, 11 | input wire [`MemDataBus] ram_data, 12 | output reg ram_read, 13 | output reg [`MemAddrBus] ram_addr, 14 | 15 | input wire read, 16 | input wire [`MemAddrBus] addr, 17 | output reg ready, 18 | output reg [`MemDataBus] data 19 | ); 20 | 21 | reg miss; 22 | 23 | reg [`ICacheNum-1:0] cache_valid; 24 | reg [`ICacheTagBus] cache_tag [`ICacheNum-1:0]; 25 | reg [`MemDataBus] cache_data [`ICacheNum-1:0]; 26 | 27 | wire [`ICacheBus] addr_index = addr[`ICacheBus]; 28 | wire [`ICacheTagBytes] addr_tag = addr[`ICacheTagBytes]; 29 | 30 | reg [31:0] i; 31 | 32 | initial begin 33 | for (i = 0; i < `ICacheNum; i = i+1) cache_valid[i] = 0; 34 | end 35 | 36 | always @(*) begin 37 | if (reset || !read) begin 38 | ready = 0; data = 0; miss = 0; 39 | end else begin 40 | if (cache_valid[addr_index] && cache_tag[addr_index] == addr_tag) begin 41 | ready = 1; data = cache_data[addr_index]; miss = 0; 42 | end else if (ram_ready) begin 43 | ready = 1; data = ram_data; miss = 0; 44 | end else begin 45 | ready = 0; data = 0; miss = 1; 46 | end 47 | end 48 | end 49 | 50 | reg delay_read; 51 | 52 | always @(posedge clock) begin 53 | delay_read <= !reset && miss && !discard; 54 | ram_addr <= addr; 55 | end 56 | 57 | always @(*) begin 58 | ram_read = delay_read && !ram_busy; 59 | end 60 | 61 | always @(posedge clock) begin 62 | if (reset) begin 63 | cache_valid <= 0; 64 | end else if (ram_ready) begin 65 | cache_valid[addr_index] <= 1; 66 | cache_tag[addr_index] <= addr_tag; 67 | cache_data[addr_index] <= ram_data; 68 | end 69 | end 70 | 71 | endmodule 72 | -------------------------------------------------------------------------------- /src/cpu.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | // RISCV32I CPU top module 4 | // port modification allowed for debugging purposes 5 | 6 | module cpu( 7 | input wire clk_in, // system clock signal 8 | input wire rst_in, // reset signal 9 | input wire rdy_in, // TODO ready signal, pause cpu when low 10 | input wire [7:0] mem_din, // data input bus 11 | output wire [7:0] mem_dout, // data output bus 12 | output wire [31:0] mem_a, // address bus (only 17:0 is used) 13 | output wire mem_wr, // write/read signal (1 for write) 14 | output wire [31:0] dbgreg_dout // cpu register output (debugging demo) 15 | ); 16 | 17 | // implementation goes here 18 | 19 | // Specifications: 20 | // - Pause cpu(freeze pc, registers, etc.) when rdy_in is low 21 | // - Memory read takes 2 cycles(wait till next cycle), write takes 1 cycle(no need to wait) 22 | // - Memory is of size 128KB, with valid address ranging from 0x0 to 0x20000 23 | // - I/O port is mapped to address higher than 0x30000 (mem_a[17:16]==2'b11) 24 | // - 0x30000 read: read a byte from input 25 | // - 0x30000 write: write a byte to output (write 0x00 is ignored) 26 | // - 0x30004 read: read clocks passed since cpu starts (in dword, 4 bytes) 27 | // - 0x30004 write: indicates program stop (will output '\0' through uart tx) 28 | 29 | wire reset = rst_in || !rdy_in; 30 | assign dbgreg_dout = reset; 31 | 32 | wire ex_br, ex_br_inst, ex_br_error; 33 | wire [`MemAddrBus] ex_br_addr, ex_br_actual_addr; 34 | 35 | wire ctrl_stall_stall_if, ctrl_stall_stall_id, ctrl_stall_stall_ex, ctrl_stall_stall_mem; 36 | wire [`StallBus] ctrl_stall_stall; 37 | ctrl_stall ctrl_stall_( 38 | .reset(reset), 39 | .stall_if(ctrl_stall_stall_if), .stall_id(ctrl_stall_stall_id), 40 | .stall_ex(ctrl_stall_stall_ex), .stall_mem(ctrl_stall_stall_mem), 41 | .stall(ctrl_stall_stall) 42 | ); 43 | 44 | wire br = ex_br && !ctrl_stall_stall[3]; 45 | wire br_inst = ex_br_inst && !ctrl_stall_stall[3]; 46 | wire br_error = ex_br_error; 47 | 48 | wire [`MemAddrBus] reg_pc_pc_i; 49 | wire [`MemAddrBus] reg_pc_pc_o; 50 | reg_pc reg_pc_( 51 | .clock(clk_in), .reset(reset), .stall0(ctrl_stall_stall[0]), 52 | .br(br_error), .br_addr(ex_br_actual_addr), .pc_i(reg_pc_pc_i), .pc_o(reg_pc_pc_o) 53 | ); 54 | 55 | wire [`MemAddrBus] pipe_if_id_pc_i, pipe_if_id_pc_o; 56 | wire [`InstBus] pipe_if_id_inst_i, pipe_if_id_inst_o; 57 | wire pipe_if_id_prediction_i, pipe_if_id_prediction_o; 58 | pipe_if_id pipe_if_id_( 59 | .clock(clk_in), .reset(reset), .discard(br_error), .stall(ctrl_stall_stall[2:1]), 60 | .pc_i(pipe_if_id_pc_i), .inst_i(pipe_if_id_inst_i), 61 | .prediction_i(pipe_if_id_prediction_i), 62 | .pc_o(pipe_if_id_pc_o), .inst_o(pipe_if_id_inst_o), 63 | .prediction_o(pipe_if_id_prediction_o) 64 | ); 65 | 66 | wire [`AluSelBus] pipe_id_ex_alusel_i, pipe_id_ex_alusel_o; 67 | wire [`AluOpBus] pipe_id_ex_aluop_i, pipe_id_ex_aluop_o; 68 | wire [`RegBus] pipe_id_ex_op1_i, pipe_id_ex_op1_o; 69 | wire [`RegBus] pipe_id_ex_op2_i, pipe_id_ex_op2_o; 70 | wire [`RegBus] pipe_id_ex_link_addr_i, pipe_id_ex_link_addr_o; 71 | wire pipe_id_ex_write_i, pipe_id_ex_write_o; 72 | wire [`RegAddrBus] pipe_id_ex_regw_addr_i, pipe_id_ex_regw_addr_o; 73 | wire [`RegBus] pipe_id_ex_mem_offset_i, pipe_id_ex_mem_offset_o; 74 | wire [`MemAddrBus] pipe_id_ex_br_addr_i, pipe_id_ex_br_addr_o; 75 | wire [`MemAddrBus] pipe_id_ex_br_offset_i, pipe_id_ex_br_offset_o; 76 | wire pipe_id_ex_prediction_i, pipe_id_ex_prediction_o; 77 | wire [`MemAddrBus] pipe_id_ex_pc_i, pipe_id_ex_pc_o; 78 | wire pipe_id_ex_no_prediction_i, pipe_id_ex_no_prediction_o; 79 | pipe_id_ex pipe_id_ex_( 80 | .clock(clk_in), .reset(reset), .discard(br_error), .stall(ctrl_stall_stall[3:2]), 81 | .alusel_i(pipe_id_ex_alusel_i), .aluop_i(pipe_id_ex_aluop_i), 82 | .op1_i(pipe_id_ex_op1_i), .op2_i(pipe_id_ex_op2_i), .link_addr_i(pipe_id_ex_link_addr_i), 83 | .write_i(pipe_id_ex_write_i), .regw_addr_i(pipe_id_ex_regw_addr_i), 84 | .mem_offset_i(pipe_id_ex_mem_offset_i), 85 | .br_addr_i(pipe_id_ex_br_addr_i), .br_offset_i(pipe_id_ex_br_offset_i), 86 | .prediction_i(pipe_id_ex_prediction_i), .pc_i(pipe_id_ex_pc_i), 87 | .no_prediction_i(pipe_id_ex_no_prediction_i), 88 | .alusel_o(pipe_id_ex_alusel_o), .aluop_o(pipe_id_ex_aluop_o), 89 | .op1_o(pipe_id_ex_op1_o), .op2_o(pipe_id_ex_op2_o), .link_addr_o(pipe_id_ex_link_addr_o), 90 | .write_o(pipe_id_ex_write_o), .regw_addr_o(pipe_id_ex_regw_addr_o), 91 | .mem_offset_o(pipe_id_ex_mem_offset_o), 92 | .br_addr_o(pipe_id_ex_br_addr_o), .br_offset_o(pipe_id_ex_br_offset_o), 93 | .prediction_o(pipe_id_ex_prediction_o), .pc_o(pipe_id_ex_pc_o), 94 | .no_prediction_o(pipe_id_ex_no_prediction_o) 95 | ); 96 | 97 | wire pipe_ex_mem_write_i, pipe_ex_mem_write_o; 98 | wire [`RegAddrBus] pipe_ex_mem_regw_addr_i, pipe_ex_mem_regw_addr_o; 99 | wire [`RegBus] pipe_ex_mem_regw_data_i, pipe_ex_mem_regw_data_o; 100 | wire pipe_ex_mem_load_i, pipe_ex_mem_load_o; 101 | wire pipe_ex_mem_store_i, pipe_ex_mem_store_o; 102 | wire [`MemDataBus] pipe_ex_mem_mem_write_data_i, pipe_ex_mem_mem_write_data_o; 103 | wire [2:0] pipe_ex_mem_mem_length_i, pipe_ex_mem_mem_length_o; 104 | wire pipe_ex_mem_mem_signed_i, pipe_ex_mem_mem_signed_o; 105 | pipe_ex_mem pipe_ex_mem_( 106 | .clock(clk_in), .reset(reset), .stall(ctrl_stall_stall[4:3]), 107 | .write_i(pipe_ex_mem_write_i), 108 | .regw_addr_i(pipe_ex_mem_regw_addr_i), .regw_data_i(pipe_ex_mem_regw_data_i), 109 | .load_i(pipe_ex_mem_load_i), .store_i(pipe_ex_mem_store_i), 110 | .mem_write_data_i(pipe_ex_mem_mem_write_data_i), 111 | .mem_length_i(pipe_ex_mem_mem_length_i), .mem_signed_i(pipe_ex_mem_mem_signed_i), 112 | .write_o(pipe_ex_mem_write_o), 113 | .regw_addr_o(pipe_ex_mem_regw_addr_o), .regw_data_o(pipe_ex_mem_regw_data_o), 114 | .load_o(pipe_ex_mem_load_o), .store_o(pipe_ex_mem_store_o), 115 | .mem_write_data_o(pipe_ex_mem_mem_write_data_o), 116 | .mem_length_o(pipe_ex_mem_mem_length_o), .mem_signed_o(pipe_ex_mem_mem_signed_o) 117 | ); 118 | 119 | wire pipe_mem_wb_write_i, pipe_mem_wb_write_o; 120 | wire [`RegAddrBus] pipe_mem_wb_regw_addr_i, pipe_mem_wb_regw_addr_o; 121 | wire [`RegBus] pipe_mem_wb_regw_data_i, pipe_mem_wb_regw_data_o; 122 | pipe_mem_wb pipe_mem_wb_( 123 | .clock(clk_in), .reset(reset), .stall(ctrl_stall_stall[5:4]), 124 | .write_i(pipe_mem_wb_write_i), .write_o(pipe_mem_wb_write_o), 125 | .regw_addr_i(pipe_mem_wb_regw_addr_i), .regw_data_i(pipe_mem_wb_regw_data_i), 126 | .regw_addr_o(pipe_mem_wb_regw_addr_o), .regw_data_o(pipe_mem_wb_regw_data_o) 127 | ); 128 | 129 | buffer_branch buffer_branch_( 130 | .clock(clk_in), .reset(reset), 131 | .pc_i(pipe_if_id_pc_i), .pc_o(reg_pc_pc_i), .prediction(pipe_if_id_prediction_i), 132 | .update(ex_br_inst), .committed(ex_br), 133 | .current(pipe_id_ex_pc_o[`BTBAllBytes]), .target(ex_br_addr) 134 | ); 135 | 136 | wire stage_if_ram_read, stage_if_ram_ready; 137 | wire [`MemAddrBus] stage_if_ram_addr; 138 | wire [`InstBus] stage_if_ram_data; 139 | stage_if stage_if_( 140 | .reset(reset), .stall_if(ctrl_stall_stall_if), 141 | .pc_i(reg_pc_pc_o), .pc_o(pipe_if_id_pc_i), .inst_o(pipe_if_id_inst_i), 142 | .ram_read(stage_if_ram_read), .ram_ready(stage_if_ram_ready), 143 | .ram_addr(stage_if_ram_addr), .ram_data(stage_if_ram_data) 144 | ); 145 | 146 | wire cache_i_ram_read, cache_i_ram_ready, cache_i_ram_busy; 147 | wire [`MemAddrBus] cache_i_ram_addr; 148 | wire [`MemDataBus] cache_i_ram_data; 149 | cache_i cache_i_( 150 | .clock(clk_in), .reset(reset), .discard(br_error), 151 | .read(stage_if_ram_read), .addr(stage_if_ram_addr), 152 | .ready(stage_if_ram_ready), .data(stage_if_ram_data), 153 | .ram_busy(cache_i_ram_busy), .ram_ready(cache_i_ram_ready), .ram_data(cache_i_ram_data), 154 | .ram_read(cache_i_ram_read), .ram_addr(cache_i_ram_addr) 155 | ); 156 | 157 | stage_ex stage_ex_( 158 | .reset(reset), .stall_ex(ctrl_stall_stall_ex), 159 | .alusel(pipe_id_ex_alusel_o), .aluop(pipe_id_ex_aluop_o), 160 | .op1(pipe_id_ex_op1_o), .op2(pipe_id_ex_op2_o), .link_addr(pipe_id_ex_link_addr_o), 161 | .write_i(pipe_id_ex_write_o), .regw_addr_i(pipe_id_ex_regw_addr_o), 162 | .mem_offset(pipe_id_ex_mem_offset_o), 163 | .br_addr_i(pipe_id_ex_br_addr_o), .br_offset(pipe_id_ex_br_offset_o), 164 | .write_o(pipe_ex_mem_write_i), 165 | .regw_addr_o(pipe_ex_mem_regw_addr_i), .regw_data(pipe_ex_mem_regw_data_i), 166 | .load(pipe_ex_mem_load_i), .store(pipe_ex_mem_store_i), 167 | .mem_write_data(pipe_ex_mem_mem_write_data_i), 168 | .mem_length(pipe_ex_mem_mem_length_i), .mem_signed(pipe_ex_mem_mem_signed_i), 169 | .no_prediction(pipe_id_ex_no_prediction_o), 170 | .prediction(pipe_id_ex_prediction_o), .pc(pipe_id_ex_pc_o), 171 | .br_inst(ex_br_inst), .br_addr_o(ex_br_addr), .br(ex_br), 172 | .br_error(ex_br_error), .br_actual_addr(ex_br_actual_addr) 173 | ); 174 | 175 | wire stage_mem_ram_ready, stage_mem_ram_read, stage_mem_ram_write, stage_mem_ram_signed; 176 | wire [`MemAddrBus] stage_mem_ram_addr; 177 | wire [`MemDataBus] stage_mem_ram_data_i, stage_mem_ram_data_o; 178 | wire [2:0] stage_mem_ram_length; 179 | stage_mem stage_mem_( 180 | .reset(reset), .stall_mem(ctrl_stall_stall_mem), 181 | .load(pipe_ex_mem_load_o), .store(pipe_ex_mem_store_o), 182 | .addr(pipe_ex_mem_regw_data_o), .data(pipe_ex_mem_mem_write_data_o), 183 | .length(pipe_ex_mem_mem_length_o), .signed_(pipe_ex_mem_mem_signed_o), 184 | .write_i(pipe_ex_mem_write_o), 185 | .regw_addr_i(pipe_ex_mem_regw_addr_o), .regw_data_i(pipe_ex_mem_regw_data_o), 186 | .write_o(pipe_mem_wb_write_i), 187 | .regw_addr_o(pipe_mem_wb_regw_addr_i), .regw_data_o(pipe_mem_wb_regw_data_i), 188 | .ram_ready(stage_mem_ram_ready), .ram_addr(stage_mem_ram_addr), 189 | .ram_data_i(stage_mem_ram_data_i), .ram_data_o(stage_mem_ram_data_o), 190 | .ram_length(stage_mem_ram_length), .ram_signed(stage_mem_ram_signed), 191 | .ram_read(stage_mem_ram_read), .ram_write(stage_mem_ram_write) 192 | ); 193 | 194 | wire cache_d_ram_busy, cache_d_ram_ready, cache_d_ram_read, cache_d_ram_signed; 195 | wire [2:0] cache_d_ram_length; 196 | wire [`MemAddrBus] cache_d_ram_addr; 197 | wire [`MemDataBus] cache_d_ram_data; 198 | wire cache_d_buffer_busy, cache_d_buffer_write; 199 | wire [2:0] cache_d_buffer_length; 200 | wire [`MemAddrBus] cache_d_buffer_addr; 201 | wire [`MemDataBus] cache_d_buffer_data; 202 | cache_d cache_d_( 203 | .clock(clk_in), .reset(reset), 204 | .read(stage_mem_ram_read), .write(stage_mem_ram_write), .ready(stage_mem_ram_ready), 205 | .length(stage_mem_ram_length), .signed_(stage_mem_ram_signed), 206 | .addr(stage_mem_ram_addr), 207 | .data_i(stage_mem_ram_data_o), .data_o(stage_mem_ram_data_i), 208 | .ram_busy(cache_d_ram_busy), .ram_ready(cache_d_ram_ready), .ram_read(cache_d_ram_read), 209 | .ram_length(cache_d_ram_length), .ram_signed(cache_d_ram_signed), 210 | .ram_addr(cache_d_ram_addr), .ram_data(cache_d_ram_data), 211 | .buffer_busy(cache_d_buffer_busy), .buffer_write(cache_d_buffer_write), 212 | .buffer_length(cache_d_buffer_length), .buffer_addr(cache_d_buffer_addr), 213 | .buffer_data(cache_d_buffer_data) 214 | ); 215 | 216 | wire buffer_ram_busy, buffer_ram_write, buffer_ram_success; 217 | wire [`MemAddrBus] buffer_ram_addr; 218 | wire [`ByteBus] buffer_ram_data; 219 | buffer_write buffer_( 220 | .clock(clk_in), .reset(reset), 221 | .write(cache_d_buffer_write), .busy(cache_d_buffer_busy), 222 | .length(cache_d_buffer_length), .addr(cache_d_buffer_addr), .data(cache_d_buffer_data), 223 | .ram_busy(buffer_ram_busy), .ram_write(buffer_ram_write), .ram_seccess(buffer_ram_success), 224 | .ram_addr(buffer_ram_addr), .ram_data(buffer_ram_data) 225 | ); 226 | 227 | ctrl_mem ctrl_mem_( 228 | .clock(clk_in), .reset(reset), .if_discard(br_error), 229 | .if_read(cache_i_ram_read), .if_addr(cache_i_ram_addr), 230 | .if_busy(cache_i_ram_busy), .if_ready(cache_i_ram_ready), .if_data(cache_i_ram_data), 231 | .mem_read(cache_d_ram_read), .mem_r_addr(cache_d_ram_addr), 232 | .mem_r_length(cache_d_ram_length), .mem_r_signed(cache_d_ram_signed), 233 | .mem_r_busy(cache_d_ram_busy), .mem_r_ready(cache_d_ram_ready), 234 | .mem_r_data(cache_d_ram_data), 235 | .mem_write(buffer_ram_write), .mem_w_addr(buffer_ram_addr), 236 | .mem_w_data(buffer_ram_data), .mem_w_busy(buffer_ram_busy), 237 | .mem_w_success(buffer_ram_success), 238 | .ram_rw(mem_wr), .ram_addr(mem_a), 239 | .ram_w_data(mem_dout), .ram_r_data(mem_din) 240 | ); 241 | 242 | wire stage_id_read1, stage_id_read2; 243 | wire [`RegAddrBus] stage_id_reg1_addr, stage_id_reg2_addr; 244 | wire [`RegBus] stage_id_reg1_data, stage_id_reg2_data; 245 | stage_id stage_id_( 246 | .reset(reset), .stall_id(ctrl_stall_stall_id), 247 | .pc_i(pipe_if_id_pc_o), .inst(pipe_if_id_inst_o), 248 | .alusel(pipe_id_ex_alusel_i), .aluop(pipe_id_ex_aluop_i), 249 | .op1(pipe_id_ex_op1_i), .op2(pipe_id_ex_op2_i), .link_addr(pipe_id_ex_link_addr_i), 250 | .write(pipe_id_ex_write_i), .regw_addr(pipe_id_ex_regw_addr_i), 251 | .mem_offset(pipe_id_ex_mem_offset_i), 252 | .br_addr(pipe_id_ex_br_addr_i), .br_offset(pipe_id_ex_br_offset_i), 253 | .ex_load(stage_ex_.load), .ex_write(stage_ex_.write_i), 254 | .ex_regw_addr(stage_ex_.regw_addr_i), .ex_regw_data(stage_ex_.regw_data), 255 | .mem_write(stage_mem_.write_i), 256 | .mem_regw_addr(stage_mem_.regw_addr_i), .mem_regw_data(stage_mem_.regw_data_o), 257 | .read1(stage_id_read1), .reg1_addr(stage_id_reg1_addr), .reg1_data(stage_id_reg1_data), 258 | .read2(stage_id_read2), .reg2_addr(stage_id_reg2_addr), .reg2_data(stage_id_reg2_data), 259 | .prediction_i(pipe_if_id_prediction_o), .prediction_o(pipe_id_ex_prediction_i), 260 | .pc_o(pipe_id_ex_pc_i), .no_prediction(pipe_id_ex_no_prediction_i) 261 | ); 262 | 263 | reg_file reg_file_( 264 | .clock(clk_in), .reset(reset), 265 | .write(pipe_mem_wb_write_o), 266 | .regw_addr(pipe_mem_wb_regw_addr_o), .regw_data(pipe_mem_wb_regw_data_o), 267 | .read1(stage_id_read1), .reg1_addr(stage_id_reg1_addr), .reg1_data(stage_id_reg1_data), 268 | .read2(stage_id_read2), .reg2_addr(stage_id_reg2_addr), .reg2_data(stage_id_reg2_data) 269 | ); 270 | 271 | endmodule 272 | -------------------------------------------------------------------------------- /src/ctrl_mem.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module ctrl_mem( 4 | input wire clock, 5 | input wire reset, 6 | input wire if_discard, 7 | 8 | input wire if_read, 9 | input wire [`MemAddrBus] if_addr, 10 | output reg if_busy, 11 | output reg if_ready, 12 | output reg [`MemDataBus] if_data, 13 | 14 | input wire mem_read, 15 | input wire [`MemAddrBus] mem_r_addr, 16 | input wire [2:0] mem_r_length, 17 | input wire mem_r_signed, 18 | output reg mem_r_busy, 19 | output reg mem_r_ready, 20 | output reg [`MemDataBus] mem_r_data, 21 | 22 | input wire mem_write, 23 | input wire [`MemAddrBus] mem_w_addr, 24 | input wire [`ByteBus] mem_w_data, 25 | output reg mem_w_busy, 26 | output wire mem_w_success, 27 | 28 | output wire ram_rw, 29 | output reg [`MemAddrBus] ram_addr, 30 | output wire [`ByteBus] ram_w_data, 31 | input wire [`ByteBus] ram_r_data 32 | ); 33 | 34 | reg [2:0] cur; 35 | reg [`ByteBus] if_ret [3:0], mem_ret [2:0]; 36 | 37 | reg ahead, ahead_ready; 38 | reg [2:0] ahead_cur; 39 | reg [`MemAddrBus] ahead_addr; 40 | wire [`MemAddrBus] delay_ahead_addr = if_addr+4; 41 | 42 | wire mem_read_working = mem_read && !mem_r_ready; 43 | wire if_working = if_read && !if_ready; 44 | wire ahead_working = ahead && !ahead_ready; 45 | wire mem_write_working = mem_write; 46 | assign mem_w_success = !mem_read_working && !if_working && !ahead_working && mem_write_working; 47 | 48 | assign ram_rw = mem_w_success; 49 | assign ram_w_data = mem_w_data; 50 | 51 | always @(*) begin 52 | if (mem_read_working) begin 53 | ram_addr = (ahead && mem_r_length == cur) ? ahead_addr+ahead_cur:mem_r_addr+cur; 54 | end else if (if_working) begin 55 | ram_addr = ahead && ahead_addr == if_addr ? ahead_addr+ahead_cur:if_addr+cur; 56 | end else if (ahead_working) begin 57 | ram_addr = ahead_addr+ahead_cur; 58 | end else if (mem_write_working) begin 59 | ram_addr = mem_w_addr; 60 | end else begin 61 | ram_addr = 0; 62 | end 63 | end 64 | 65 | always @(posedge clock) begin 66 | if (reset) begin 67 | if_ready <= 0; mem_r_ready <= 0; 68 | if_busy <= 0; mem_r_busy <= 0; mem_w_busy <= 0; 69 | ahead <= 0; cur <= 0; ahead_cur <= 0; 70 | end else if (mem_read_working) begin 71 | if (cur == 0) begin 72 | if_ready <= 0; mem_r_ready <= 0; 73 | if_busy <= 1; mem_r_busy <= 0; mem_w_busy <= 1; 74 | cur <= 1; 75 | if (mem_r_addr[17]) ahead <= 0; 76 | else if (!ahead_ready) if_ret[ahead_cur-1] <= ram_r_data; 77 | end else if (cur < mem_r_length) begin 78 | mem_ret[cur-1] <= ram_r_data; 79 | cur <= cur+1; 80 | end else begin 81 | mem_r_ready <= 1; 82 | if_busy <= 0; mem_w_busy <= 0; 83 | cur <= 0; 84 | case (mem_r_length) 85 | 1: mem_r_data <= {{24{mem_r_signed && ram_r_data[7]}}, ram_r_data}; 86 | 2: mem_r_data <= {{16{mem_r_signed && ram_r_data[7]}}, ram_r_data, mem_ret[0]}; 87 | 4: mem_r_data <= {ram_r_data, mem_ret[2], mem_ret[1], mem_ret[0]}; 88 | endcase 89 | if (ahead && !ahead_ready) begin 90 | if (ahead_cur[2]) ahead_ready <= 1; 91 | else ahead_cur <= ahead_cur+1; 92 | end 93 | end 94 | end else if (if_working) begin 95 | if (if_discard) begin 96 | if_ready <= 0; mem_r_ready <= 0; 97 | if_busy <= 0; mem_r_busy <= 0; mem_w_busy <= 0; 98 | ahead <= 0; cur <= 0; 99 | end else if (cur == 0) begin 100 | if (!ahead || ahead_addr != if_addr) begin 101 | if_ready <= 0; mem_r_ready <= 0; 102 | if_busy <= 0; mem_r_busy <= 1; mem_w_busy <= 1; 103 | cur <= 1; 104 | end else if (ahead_ready) begin 105 | if_ready <= 1; mem_r_ready <= 0; 106 | if_busy <= 0; mem_r_busy <= 0; mem_w_busy <= 0; 107 | cur <= 0; 108 | if_data <= {if_ret[3], if_ret[2], if_ret[1], if_ret[0]}; 109 | ahead_addr <= delay_ahead_addr; ahead_cur <= 1; ahead_ready <= 0; 110 | end else if (ahead_cur[2]) begin 111 | if_ready <= 1; mem_r_ready <= 0; 112 | if_busy <= 0; mem_r_busy <= 0; mem_w_busy <= 0; 113 | cur <= 0; 114 | if_data <= {ram_r_data, if_ret[2], if_ret[1], if_ret[0]}; 115 | ahead_addr <= delay_ahead_addr; ahead_cur <= 1; ahead_ready <= 0; 116 | end else begin 117 | if_ready <= 0; mem_r_ready <= 0; 118 | if_busy <= 0; mem_r_busy <= 1; mem_w_busy <= 1; 119 | if_ret[ahead_cur-1] <= ram_r_data; 120 | cur <= ahead_cur+1; 121 | ahead <= 0; 122 | end 123 | end else if (!cur[2]) begin 124 | if_ret[cur-1] <= ram_r_data; 125 | cur <= cur+1; 126 | end else begin 127 | if_ready <= 1; 128 | mem_r_busy <= 0; mem_w_busy <= 0; 129 | cur <= 0; 130 | if_data <= {ram_r_data, if_ret[2], if_ret[1], if_ret[0]}; 131 | ahead <= 1; ahead_addr <= delay_ahead_addr; ahead_cur <= 1; ahead_ready <= 0; 132 | end 133 | end else if (ahead_working) begin 134 | if (if_discard) begin 135 | if_ready <= 0; mem_r_ready <= 0; 136 | ahead <= 0; cur <= 0; ahead_cur <= 0; 137 | end else begin 138 | if_ready <= 0; mem_r_ready <= 0; 139 | if_ret[ahead_cur-1] <= ram_r_data; 140 | if (ahead_cur[2]) ahead_ready <= 1; 141 | else ahead_cur <= ahead_cur+1; 142 | end 143 | end else begin 144 | if_ready <= 0; mem_r_ready <= 0; 145 | end 146 | end 147 | 148 | endmodule 149 | -------------------------------------------------------------------------------- /src/ctrl_stall.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module ctrl_stall( 4 | input wire reset, 5 | input wire stall_if, 6 | input wire stall_id, 7 | input wire stall_ex, 8 | input wire stall_mem, 9 | 10 | output reg [`StallBus] stall 11 | ); 12 | 13 | always @(*) begin 14 | if (reset) 15 | stall = 6'b000000; 16 | else if (stall_mem) 17 | stall = 6'b011111; 18 | else if (stall_ex) 19 | stall = 6'b001111; 20 | else if (stall_id) 21 | stall = 6'b000111; 22 | else if (stall_if) 23 | stall = 6'b000011; 24 | else 25 | stall = 6'b000000; 26 | end 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /src/define.v: -------------------------------------------------------------------------------- 1 | `ifndef DEFINE_V 2 | `define DEFINE_V 3 | 4 | `define OP_LUI 7'b0110111 5 | `define OP_AUIPC 7'b0010111 6 | `define OP_JAL 7'b1101111 7 | `define OP_JALR 7'b1100111 8 | `define OP_BRANCH 7'b1100011 9 | `define OP_LOAD 7'b0000011 10 | `define OP_STORE 7'b0100011 11 | `define OP_OP_IMM 7'b0010011 12 | `define OP_OP 7'b0110011 13 | `define OP_MISC_MEM 7'b0001111 14 | 15 | // BRANCH 16 | `define FUNCT3_BEQ 3'b000 17 | `define FUNCT3_BNE 3'b001 18 | `define FUNCT3_BLT 3'b100 19 | `define FUNCT3_BGE 3'b101 20 | `define FUNCT3_BLTU 3'b110 21 | `define FUNCT3_BGEU 3'b111 22 | // LOAD 23 | `define FUNCT3_LB 3'b000 24 | `define FUNCT3_LH 3'b001 25 | `define FUNCT3_LW 3'b010 26 | `define FUNCT3_LBU 3'b100 27 | `define FUNCT3_LHU 3'b101 28 | // STORE 29 | `define FUNCT3_SB 3'b000 30 | `define FUNCT3_SH 3'b001 31 | `define FUNCT3_SW 3'b010 32 | // OP_IMM 33 | `define FUNCT3_ADDI 3'b000 34 | `define FUNCT3_SLLI 3'b001 35 | `define FUNCT3_SLTI 3'b010 36 | `define FUNCT3_SLTIU 3'b011 37 | `define FUNCT3_XORI 3'b100 38 | `define FUNCT3_SRI 3'b101 39 | `define FUNCT3_ORI 3'b110 40 | `define FUNCT3_ANDI 3'b111 41 | // OP 42 | `define FUNCT3_ADD_SUB 3'b000 43 | `define FUNCT3_SLL 3'b001 44 | `define FUNCT3_SLT 3'b010 45 | `define FUNCT3_SLTU 3'b011 46 | `define FUNCT3_XOR 3'b100 47 | `define FUNCT3_SR 3'b101 48 | `define FUNCT3_OR 3'b110 49 | `define FUNCT3_AND 3'b111 50 | // MISC_MEM 51 | `define FUNCT3_FENCE 3'b000 52 | `define FUNCT3_FENCEI 3'b001 53 | 54 | // SRI 55 | `define FUNCT3_SRLI 7'b0000000 56 | `define FUNCT3_SHAI 7'b0100000 57 | // ADD_SUB 58 | `define FUNCT3_ADD 7'b0000000 59 | `define FUNCT3_SUB 7'b0100000 60 | // SR 61 | `define FUNCT3_SRL 7'b0000000 62 | `define FUNCT3_SHA 7'b0100000 63 | 64 | `define EXE_RES_NOP 3'b000 65 | `define EXE_RES_LOGIC 3'b001 66 | `define EXE_RES_SHIFT 3'b010 67 | `define EXE_RES_MOVE 3'b011 68 | `define EXE_RES_ARITH 3'b100 69 | `define EXE_RES_MUL 3'b101 70 | `define EXE_RES_JUMP_BRANCH 3'b110 71 | `define EXE_RES_LOAD_STORE 3'b111 72 | 73 | `define EXE_OP_NOP 0 74 | `define EXE_OP_AND 1 75 | `define EXE_OP_OR 2 76 | `define EXE_OP_XOR 3 77 | `define EXE_OP_SLL 4 78 | `define EXE_OP_SRL 5 79 | `define EXE_OP_SRA 6 80 | `define EXE_OP_ADD 7 81 | `define EXE_OP_SUB 8 82 | `define EXE_OP_SLT 9 83 | `define EXE_OP_SLTU 10 84 | `define EXE_OP_JAL 11 85 | `define EXE_OP_JALR 12 86 | `define EXE_OP_BEQ 13 87 | `define EXE_OP_BNE 14 88 | `define EXE_OP_BLT 15 89 | `define EXE_OP_BGE 16 90 | `define EXE_OP_BLTU 17 91 | `define EXE_OP_BGEU 18 92 | `define EXE_OP_LB 19 93 | `define EXE_OP_LH 20 94 | `define EXE_OP_LW 21 95 | `define EXE_OP_LBU 22 96 | `define EXE_OP_LHU 23 97 | `define EXE_OP_SB 24 98 | `define EXE_OP_SH 25 99 | `define EXE_OP_SW 26 100 | 101 | `define InstBus 31:0 102 | `define InstMemNum 131072 103 | `define InstMemNumLog2 17 104 | 105 | `define RegAddrBus 4:0 106 | `define RegBus 31:0 107 | `define RegNum 32 108 | `define RegNumLog2 5 109 | 110 | `define AluOpBus 4:0 111 | `define AluSelBus 2:0 112 | 113 | `define MemAddrBus 31:0 114 | `define MemAddrWidth 32 115 | `define MemDataBus 31:0 116 | `define MemDataWidth 32 117 | `define ByteBus 7:0 118 | `define DataMemNum 131072 119 | `define DataMemNumLog2 17 120 | `define ICacheBus 9:2 121 | `define ICacheNum 256 122 | `define ICacheNumLog2 8 123 | `define ICacheTagBytes 16:10 124 | `define ICacheTagBus 6:0 125 | `define DCacheBus 8:2 126 | `define DCacheNum 128 127 | `define DCacheNumLog2 7 128 | `define DCacheTagBytes 16:9 129 | `define DCacheTagBus 7:0 130 | `define DCacheAllBytes 31:2 131 | `define BTBBus 6:2 132 | `define BTBNum 32 133 | `define BTBNumLog2 5 134 | `define BTBTagBytes 16:7 135 | `define BTBTagBus 9:0 136 | `define BTBAllBytes 16:2 137 | 138 | `define StallBus 5:0 139 | 140 | `endif // DEFINE_V 141 | -------------------------------------------------------------------------------- /src/fifo.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************************** 2 | * 3 | * Copyright (c) 2012, Brian Bennett 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are permitted 7 | * provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 10 | * and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other materials provided 13 | * with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 22 | * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * Circular first in first out buffer implementation. 25 | ***************************************************************************************************/ 26 | 27 | module fifo 28 | #( 29 | parameter DATA_BITS = 8, 30 | parameter ADDR_BITS = 3 31 | ) 32 | ( 33 | input wire clk, // 50MHz system clock 34 | input wire reset, // Reset signal 35 | input wire rd_en, // Read enable, pop front of queue 36 | input wire wr_en, // Write enable, add wr_data to end of queue 37 | input wire [DATA_BITS-1:0] wr_data, // Data to be written on wr_en 38 | output wire [DATA_BITS-1:0] rd_data, // Current front of fifo data 39 | output wire full, // FIFO is full (writes invalid) 40 | output wire empty // FIFO is empty (reads invalid) 41 | ); 42 | 43 | reg [ADDR_BITS-1:0] q_rd_ptr; 44 | wire [ADDR_BITS-1:0] d_rd_ptr; 45 | reg [ADDR_BITS-1:0] q_wr_ptr; 46 | wire [ADDR_BITS-1:0] d_wr_ptr; 47 | reg q_empty; 48 | wire d_empty; 49 | reg q_full; 50 | wire d_full; 51 | 52 | reg [DATA_BITS-1:0] q_data_array [2**ADDR_BITS-1:0]; 53 | wire [DATA_BITS-1:0] d_data; 54 | 55 | wire rd_en_prot; 56 | wire wr_en_prot; 57 | 58 | // FF update logic. Synchronous reset. 59 | always @(posedge clk) 60 | begin 61 | if (reset) 62 | begin 63 | q_rd_ptr <= 0; 64 | q_wr_ptr <= 0; 65 | q_empty <= 1'b1; 66 | q_full <= 1'b0; 67 | end 68 | else 69 | begin 70 | q_rd_ptr <= d_rd_ptr; 71 | q_wr_ptr <= d_wr_ptr; 72 | q_empty <= d_empty; 73 | q_full <= d_full; 74 | q_data_array[q_wr_ptr] <= d_data; 75 | end 76 | end 77 | 78 | // Derive "protected" read/write signals. 79 | assign rd_en_prot = (rd_en && !q_empty); 80 | assign wr_en_prot = (wr_en && !q_full); 81 | 82 | // Handle writes. 83 | assign d_wr_ptr = (wr_en_prot) ? q_wr_ptr + 1'h1 : q_wr_ptr; 84 | assign d_data = (wr_en_prot) ? wr_data : q_data_array[q_wr_ptr]; 85 | 86 | // Handle reads. 87 | assign d_rd_ptr = (rd_en_prot) ? q_rd_ptr + 1'h1 : q_rd_ptr; 88 | 89 | wire [ADDR_BITS-1:0] addr_bits_wide_1; 90 | assign addr_bits_wide_1 = 1; 91 | 92 | // Detect empty state: 93 | // 1) We were empty before and there was no write. 94 | // 2) We had one entry and there was a read. 95 | assign d_empty = ((q_empty && !wr_en_prot) || 96 | (((q_wr_ptr - q_rd_ptr) == addr_bits_wide_1) && rd_en_prot)); 97 | 98 | // Detect full state: 99 | // 1) We were full before and there was no read. 100 | // 2) We had n-1 entries and there was a write. 101 | assign d_full = ((q_full && !rd_en_prot) || 102 | (((q_rd_ptr - q_wr_ptr) == addr_bits_wide_1) && wr_en_prot)); 103 | 104 | // Assign output signals to appropriate FFs. 105 | assign rd_data = q_data_array[q_rd_ptr]; 106 | assign full = q_full; 107 | assign empty = q_empty; 108 | 109 | endmodule 110 | 111 | -------------------------------------------------------------------------------- /src/pipe_ex_mem.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module pipe_ex_mem( 4 | input wire clock, 5 | input wire reset, 6 | 7 | input wire [4:3] stall, 8 | 9 | input wire write_i, 10 | input wire [`RegAddrBus] regw_addr_i, 11 | input wire [`RegBus] regw_data_i, 12 | input wire load_i, 13 | input wire store_i, 14 | input wire [`MemDataBus] mem_write_data_i, 15 | input wire [2:0] mem_length_i, 16 | input wire mem_signed_i, 17 | 18 | output reg write_o, 19 | output reg [`RegAddrBus] regw_addr_o, 20 | output reg [`RegBus] regw_data_o, 21 | output reg load_o, 22 | output reg store_o, 23 | output reg [`MemDataBus] mem_write_data_o, 24 | output reg [2:0] mem_length_o, 25 | output reg mem_signed_o 26 | ); 27 | 28 | always @(posedge clock) begin 29 | if (reset || (stall[3] && !stall[4])) begin 30 | write_o <= 0; 31 | regw_addr_o <= 0; 32 | regw_data_o <= 0; 33 | load_o <= 0; 34 | store_o <= 0; 35 | mem_write_data_o <= 0; 36 | mem_length_o <= 0; 37 | mem_signed_o <= 0; 38 | end else if (!stall[3] && !stall[4]) begin 39 | write_o <= write_i; 40 | regw_addr_o <= regw_addr_i; 41 | regw_data_o <= regw_data_i; 42 | load_o <= load_i; 43 | store_o <= store_i; 44 | mem_write_data_o <= mem_write_data_i; 45 | mem_length_o <= mem_length_i; 46 | mem_signed_o <= mem_signed_i; 47 | end 48 | end 49 | 50 | endmodule 51 | -------------------------------------------------------------------------------- /src/pipe_id_ex.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module pipe_id_ex( 4 | input wire clock, 5 | input wire reset, 6 | input wire discard, 7 | 8 | input wire [3:2] stall, 9 | 10 | input wire [`AluSelBus] alusel_i, 11 | input wire [`AluOpBus] aluop_i, 12 | input wire [`RegBus] op1_i, 13 | input wire [`RegBus] op2_i, 14 | input wire [`RegBus] link_addr_i, 15 | input wire write_i, 16 | input wire [`RegAddrBus] regw_addr_i, 17 | input wire [`RegBus] mem_offset_i, 18 | input wire [`MemAddrBus] br_addr_i, 19 | input wire [`MemAddrBus] br_offset_i, 20 | input wire prediction_i, 21 | input wire [`MemAddrBus] pc_i, 22 | input wire no_prediction_i, 23 | 24 | output reg [`AluSelBus] alusel_o, 25 | output reg [`AluOpBus] aluop_o, 26 | output reg [`RegBus] op1_o, 27 | output reg [`RegBus] op2_o, 28 | output reg [`RegBus] link_addr_o, 29 | output reg write_o, 30 | output reg [`RegAddrBus] regw_addr_o, 31 | output reg [`RegBus] mem_offset_o, 32 | output reg [`MemAddrBus] br_addr_o, 33 | output reg [`MemAddrBus] br_offset_o, 34 | output reg prediction_o, 35 | output reg [`MemAddrBus] pc_o, 36 | output reg no_prediction_o 37 | ); 38 | 39 | always @(posedge clock) begin 40 | if (reset || discard || (stall[2] && !stall[3])) begin 41 | alusel_o <= 0; 42 | aluop_o <= 0; 43 | op1_o <= 0; 44 | op2_o <= 0; 45 | link_addr_o <= 0; 46 | write_o <= 0; 47 | regw_addr_o <= 0; 48 | mem_offset_o <= 0; 49 | br_addr_o <= 0; 50 | br_offset_o <= 0; 51 | prediction_o <= 0; 52 | pc_o <= 0; 53 | no_prediction_o <= 0; 54 | end else if (!stall[2] && !stall[3]) begin 55 | alusel_o <= alusel_i; 56 | aluop_o <= aluop_i; 57 | op1_o <= op1_i; 58 | op2_o <= op2_i; 59 | link_addr_o <= link_addr_i; 60 | write_o <= write_i; 61 | regw_addr_o <= regw_addr_i; 62 | mem_offset_o <= mem_offset_i; 63 | br_addr_o <= br_addr_i; 64 | br_offset_o <= br_offset_i; 65 | prediction_o <= prediction_i; 66 | pc_o <= pc_i; 67 | no_prediction_o <= no_prediction_i; 68 | end 69 | end 70 | 71 | endmodule 72 | -------------------------------------------------------------------------------- /src/pipe_if_id.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module pipe_if_id( 4 | input wire clock, 5 | input wire reset, 6 | input wire discard, 7 | 8 | input wire [2:1] stall, 9 | 10 | input wire [`MemAddrBus] pc_i, 11 | input wire [`InstBus] inst_i, 12 | input wire prediction_i, 13 | 14 | output reg [`MemAddrBus] pc_o, 15 | output reg [`InstBus] inst_o, 16 | output reg prediction_o 17 | ); 18 | 19 | always @(posedge clock) begin 20 | if (reset || discard || (stall[1] && !stall[2])) begin 21 | pc_o <= 0; 22 | inst_o <= 0; 23 | prediction_o <= 0; 24 | end else if (!stall[1] && !stall[2]) begin 25 | pc_o <= pc_i; 26 | inst_o <= inst_i; 27 | prediction_o <= prediction_i; 28 | end 29 | end 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /src/pipe_mem_wb.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module pipe_mem_wb( 4 | input wire clock, 5 | input wire reset, 6 | 7 | input wire [5:4] stall, 8 | 9 | input wire write_i, 10 | input wire [`RegAddrBus] regw_addr_i, 11 | input wire [`RegBus] regw_data_i, 12 | 13 | output reg write_o, 14 | output reg [`RegAddrBus] regw_addr_o, 15 | output reg [`RegBus] regw_data_o 16 | ); 17 | 18 | always @(posedge clock) begin 19 | if (reset || (stall[4] && !stall[5])) begin 20 | write_o <= 0; 21 | regw_addr_o <= 0; 22 | regw_data_o <= 0; 23 | end else if (!stall[4] && !stall[5]) begin 24 | write_o <= write_i; 25 | regw_addr_o <= regw_addr_i; 26 | regw_data_o <= regw_data_i; 27 | end 28 | end 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /src/ram.v: -------------------------------------------------------------------------------- 1 | // implements 128KB of on-board RAM 2 | 3 | module ram 4 | #( 5 | parameter ADDR_WIDTH = 17 6 | ) 7 | ( 8 | input wire clk_in, // system clock 9 | input wire en_in, // chip enable 10 | input wire r_nw_in, // read/write select (read: 1, write: 0) 11 | input wire [ADDR_WIDTH-1:0] a_in, // memory address 12 | input wire [ 7:0] d_in, // data input 13 | output wire [ 7:0] d_out // data output 14 | ); 15 | 16 | wire ram_bram_we; 17 | wire [7:0] ram_bram_dout; 18 | 19 | single_port_ram_sync #(.ADDR_WIDTH(ADDR_WIDTH), 20 | .DATA_WIDTH(8)) ram_bram( 21 | .clk(clk_in), 22 | .we(ram_bram_we), 23 | .addr_a(a_in), 24 | .din_a(d_in), 25 | .dout_a(ram_bram_dout) 26 | ); 27 | 28 | assign ram_bram_we = (en_in) ? ~r_nw_in : 1'b0; 29 | assign d_out = (en_in) ? ram_bram_dout : 8'h00; 30 | 31 | endmodule -------------------------------------------------------------------------------- /src/reg_file.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module reg_file( 4 | input wire clock, 5 | input wire reset, 6 | 7 | input wire write, 8 | input wire [`RegAddrBus] regw_addr, 9 | input wire [`RegBus] regw_data, 10 | 11 | input wire read1, 12 | input wire [`RegAddrBus] reg1_addr, 13 | output reg [`RegBus] reg1_data, 14 | 15 | input wire read2, 16 | input wire [`RegAddrBus] reg2_addr, 17 | output reg [`RegBus] reg2_data 18 | ); 19 | 20 | reg [`RegBus] regs [`RegNum-1:0]; 21 | reg [31:0] i; 22 | 23 | initial begin 24 | // TODO for difficulties when making test data 25 | for (i = 0; i < 32; i = i+1) regs[i] <= 0; 26 | end 27 | 28 | always @(posedge clock) begin 29 | if (reset == 0 && write == 1 && regw_addr != 0) regs[regw_addr] <= regw_data; 30 | end 31 | 32 | always @(*) begin 33 | if (reset == 1 || read1 == 0 || reg1_addr == 0) 34 | reg1_data = 0; 35 | else if (write && regw_addr == reg1_addr) 36 | reg1_data = regw_data; 37 | else 38 | reg1_data = regs[reg1_addr]; 39 | end 40 | 41 | always @(*) begin 42 | if (reset == 1 || read2 == 0 || reg2_addr == 0) 43 | reg2_data = 0; 44 | else if (write && regw_addr == reg2_addr) 45 | reg2_data = regw_data; 46 | else 47 | reg2_data = regs[reg2_addr]; 48 | end 49 | 50 | endmodule 51 | -------------------------------------------------------------------------------- /src/reg_pc.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module reg_pc( 4 | input wire clock, 5 | input wire reset, 6 | 7 | input wire stall0, 8 | 9 | input wire [`MemAddrBus] pc_i, 10 | input wire br, 11 | input wire [`MemAddrBus] br_addr, 12 | output reg [`MemAddrBus] pc_o 13 | ); 14 | 15 | always @(posedge clock) begin 16 | if (reset) begin 17 | pc_o <= 0; 18 | end else if (br) begin 19 | pc_o <= br_addr; 20 | end else if (!stall0) begin 21 | pc_o <= pc_i; 22 | end 23 | end 24 | 25 | endmodule 26 | -------------------------------------------------------------------------------- /src/riscv_top.v: -------------------------------------------------------------------------------- 1 | // riscv top module file 2 | // modification allowed for debugging purposes 3 | 4 | module riscv_top 5 | #( 6 | parameter SIM = 0 // whether in simulation 7 | ) 8 | ( 9 | input wire EXCLK, 10 | input wire btnC, 11 | output wire Tx, 12 | input wire Rx, 13 | output wire led 14 | ); 15 | 16 | localparam SYS_CLK_FREQ = 230000000; 17 | localparam UART_BAUD_RATE = 115200; 18 | localparam RAM_ADDR_WIDTH = 17; // 128KiB ram, should not be modified 19 | 20 | reg rst; 21 | reg rst_delay; 22 | 23 | wire clk; 24 | 25 | `ifdef iverilog 26 | assign clk = EXCLK; 27 | `else 28 | 29 | wire locked; 30 | 31 | clk_wiz_0 NEW_CLOCK( 32 | .reset(btnC), .clk_in1(EXCLK), .clk_out1(clk), .locked(locked) 33 | ); 34 | 35 | `endif 36 | 37 | // assign EXCLK (or your own clock module) to clk 38 | // assign clk = EXCLK; 39 | 40 | always @(posedge clk or posedge btnC) 41 | begin 42 | if (btnC) 43 | begin 44 | rst <= 1'b1; 45 | rst_delay <= 1'b1; 46 | end 47 | else 48 | begin 49 | rst_delay <= 1'b0; 50 | rst <= rst_delay; 51 | end 52 | end 53 | 54 | // 55 | // System Memory Buses 56 | // 57 | wire [ 7:0] cpumc_din; 58 | wire [31:0] cpumc_a; 59 | wire cpumc_wr; 60 | 61 | // 62 | // RAM: internal ram 63 | // 64 | wire ram_en; 65 | wire [RAM_ADDR_WIDTH-1:0] ram_a; 66 | wire [ 7:0] ram_dout; 67 | 68 | ram #(.ADDR_WIDTH(RAM_ADDR_WIDTH))ram0( 69 | .clk_in(clk), 70 | .en_in(ram_en), 71 | .r_nw_in(~cpumc_wr), 72 | .a_in(ram_a), 73 | .d_in(cpumc_din), 74 | .d_out(ram_dout) 75 | ); 76 | 77 | assign ram_en = (cpumc_a[RAM_ADDR_WIDTH:RAM_ADDR_WIDTH-1] == 2'b11) ? 1'b0 : 1'b1; 78 | assign ram_a = cpumc_a[RAM_ADDR_WIDTH-1:0]; 79 | 80 | // 81 | // CPU: CPU that implements RISC-V 32b integer base user-level real-mode ISA 82 | // 83 | wire [31:0] cpu_ram_a; 84 | wire cpu_ram_wr; 85 | wire [ 7:0] cpu_ram_din; 86 | wire [ 7:0] cpu_ram_dout; 87 | wire cpu_rdy; 88 | 89 | wire [31:0] cpu_dbgreg_dout; 90 | 91 | // fakecpu cpu0( 92 | cpu cpu0( 93 | .clk_in(clk), 94 | .rst_in(rst), 95 | .rdy_in(cpu_rdy), 96 | 97 | .mem_din(cpu_ram_din), 98 | .mem_dout(cpu_ram_dout), 99 | .mem_a(cpu_ram_a), 100 | .mem_wr(cpu_ram_wr), 101 | 102 | .dbgreg_dout(cpu_dbgreg_dout) // demo 103 | ); 104 | 105 | // 106 | // HCI: host communication interface block. Use controller to interact. 107 | // 108 | wire hci_active_out; 109 | wire [ 7:0] hci_ram_din; 110 | wire [ 7:0] hci_ram_dout; 111 | wire [RAM_ADDR_WIDTH-1:0] hci_ram_a; 112 | wire hci_ram_wr; 113 | 114 | wire hci_io_en; 115 | wire [ 2:0] hci_io_sel; 116 | wire [ 7:0] hci_io_din; 117 | wire [ 7:0] hci_io_dout; 118 | wire hci_io_wr; 119 | 120 | hci #(.SYS_CLK_FREQ(SYS_CLK_FREQ), 121 | .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH), 122 | .BAUD_RATE(UART_BAUD_RATE)) hci0 123 | ( 124 | .clk(clk), 125 | .rst(rst), 126 | .tx(Tx), 127 | .rx(Rx), 128 | .active(hci_active_out), 129 | .ram_din(hci_ram_din), 130 | .ram_dout(hci_ram_dout), 131 | .ram_a(hci_ram_a), 132 | .ram_wr(hci_ram_wr), 133 | .io_sel(hci_io_sel), 134 | .io_en(hci_io_en), 135 | .io_din(hci_io_din), 136 | .io_dout(hci_io_dout), 137 | .io_wr(hci_io_wr), 138 | 139 | .cpu_dbgreg_din(cpu_dbgreg_dout) // demo 140 | ); 141 | 142 | assign hci_io_sel = cpumc_a[2:0]; 143 | assign hci_io_en = (cpumc_a[RAM_ADDR_WIDTH:RAM_ADDR_WIDTH-1] == 2'b11) ? 1'b1 : 1'b0; 144 | assign hci_io_wr = cpumc_wr; 145 | assign hci_io_din = cpumc_din; 146 | 147 | // hci is always disabled in simulation 148 | wire hci_active; 149 | assign hci_active = hci_active_out & ~SIM; 150 | 151 | // indicates debug break 152 | assign led = hci_active; 153 | 154 | // pause cpu on hci active 155 | assign cpu_rdy = (hci_active) ? 1'b0 : 1'b1; 156 | 157 | // Mux cpumc signals from cpu or hci blk, depending on debug break state (hci_active). 158 | assign cpumc_a = (hci_active) ? hci_ram_a : cpu_ram_a; 159 | assign cpumc_wr = (hci_active) ? hci_ram_wr : cpu_ram_wr; 160 | assign cpumc_din = (hci_active) ? hci_ram_dout : cpu_ram_dout; 161 | 162 | assign cpu_ram_din = (hci_io_en) ? hci_io_dout : ram_dout; 163 | assign hci_ram_din = ram_dout; 164 | 165 | endmodule 166 | -------------------------------------------------------------------------------- /src/stage_ex.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module stage_ex( 4 | input wire reset, 5 | 6 | output wire stall_ex, 7 | 8 | input wire [`AluSelBus] alusel, 9 | input wire [`AluOpBus] aluop, 10 | input wire [`RegBus] op1, 11 | input wire [`RegBus] op2, 12 | input wire [`RegBus] link_addr, 13 | input wire write_i, 14 | input wire [`RegAddrBus] regw_addr_i, 15 | input wire [`RegBus] mem_offset, 16 | input wire [`MemAddrBus] br_addr_i, 17 | input wire [`MemAddrBus] br_offset, 18 | 19 | output reg write_o, 20 | output reg [`RegAddrBus] regw_addr_o, 21 | output reg [`RegBus] regw_data, 22 | 23 | output reg load, 24 | output reg store, 25 | output reg [`RegBus] mem_write_data, 26 | output reg [2:0] mem_length, 27 | output reg mem_signed, 28 | 29 | input wire no_prediction, 30 | input wire prediction, 31 | input wire [`MemAddrBus] pc, 32 | output reg br_inst, 33 | output wire [`MemAddrBus] br_addr_o, 34 | output reg br, 35 | output wire br_error, 36 | output wire [`MemAddrBus] br_actual_addr 37 | ); 38 | 39 | assign br_error = (br_inst && br != prediction) || (no_prediction && br); 40 | assign br_actual_addr = br ? br_addr_o:pc+4; 41 | 42 | assign stall_ex = 0; 43 | 44 | reg [`RegBus] logic_ret; 45 | reg [`RegBus] arith_ret; 46 | reg [`RegBus] shift_ret; 47 | reg [`RegBus] mem_ret; 48 | wire [`RegBus] jump_ret; 49 | 50 | always @(*) begin 51 | logic_ret = 0; 52 | if (!reset && alusel == 3'b001) begin 53 | case (aluop) 54 | 0: logic_ret = op1 | op2; 55 | 1: logic_ret = op1 & op2; 56 | 2: logic_ret = op1 ^ op2; 57 | endcase 58 | end 59 | end 60 | 61 | always @(*) begin 62 | shift_ret = 0; 63 | if (!reset && alusel == 3'b010) begin 64 | case (aluop) 65 | 0: shift_ret = op1 << op2[4:0]; 66 | 1: shift_ret = op1 >> op2[4:0]; 67 | 2: shift_ret = ({32{op1[31]}} << (32-op2[4:0])) | (op1 >> op2[4:0]); 68 | endcase 69 | end 70 | end 71 | 72 | always @(*) begin 73 | arith_ret = 0; 74 | if (!reset && alusel == 3'b100) begin 75 | case (aluop) 76 | 0: arith_ret = op1+op2; 77 | 1: arith_ret = op1-op2; 78 | 2: arith_ret = $signed(op1) < $signed(op2); 79 | 3: arith_ret = op1 < op2; 80 | endcase 81 | end 82 | end 83 | 84 | assign br_addr_o = br_addr_i+br_offset; 85 | assign jump_ret = link_addr+4; 86 | 87 | always @(*) begin 88 | br = 0; br_inst = 0; 89 | if (!reset) begin 90 | if (alusel == 3'b101) begin 91 | case (aluop) 92 | 0: br = op1 == op2; 93 | 1: br = op1 != op2; 94 | 2: br = $signed(op1) < $signed(op2); 95 | 3: br = $signed(op1) >= $signed(op2); 96 | 4: br = op1 < op2; 97 | 5: br = op1 >= op2; 98 | endcase 99 | br_inst = 1; 100 | end else if (alusel == 3'b110) begin 101 | br = 1; br_inst = !no_prediction; 102 | end 103 | end 104 | end 105 | 106 | always @(*) begin 107 | load = 0; 108 | store = 0; 109 | mem_ret = 0; 110 | mem_signed = 0; 111 | mem_length = 0; 112 | mem_write_data = 0; 113 | if (!reset && alusel == 3'b111) begin 114 | case (aluop) 115 | 0: begin load = 1; mem_length = 1; mem_signed = 1; end // LB 116 | 1: begin load = 1; mem_length = 2; mem_signed = 1; end // LH 117 | 2: begin load = 1; mem_length = 4; mem_signed = 1; end // LW 118 | 3: begin load = 1; mem_length = 1; mem_signed = 0; end // LBU 119 | 4: begin load = 1; mem_length = 2; mem_signed = 0; end // LHU 120 | 5: begin store = 1; mem_length = 1; mem_write_data = op2; end // SB 121 | 6: begin store = 1; mem_length = 2; mem_write_data = op2; end // SH 122 | 7: begin store = 1; mem_length = 4; mem_write_data = op2; end // SW 123 | endcase 124 | mem_ret = op1+mem_offset; 125 | end 126 | end 127 | 128 | always @(*) begin 129 | regw_data = 0; 130 | if (reset) begin 131 | write_o = 0; 132 | regw_addr_o = 0; 133 | end else begin 134 | write_o = write_i; 135 | regw_addr_o = regw_addr_i; 136 | case (alusel) 137 | 3'b001: regw_data = logic_ret; // LOGIC 138 | 3'b010: regw_data = shift_ret; // SHIFT 139 | 3'b100: regw_data = arith_ret; // ARITH 140 | 3'b110: regw_data = jump_ret; // JUMP 141 | 3'b111: regw_data = mem_ret; // MEM 142 | endcase 143 | end 144 | end 145 | 146 | endmodule 147 | -------------------------------------------------------------------------------- /src/stage_id.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module stage_id( 4 | input wire reset, 5 | 6 | output wire stall_id, 7 | 8 | input wire [`MemAddrBus] pc_i, 9 | input wire [`InstBus] inst, 10 | 11 | output reg read1, 12 | output reg [`RegAddrBus] reg1_addr, 13 | input wire [`RegBus] reg1_data, 14 | output reg read2, 15 | output reg [`RegAddrBus] reg2_addr, 16 | input wire [`RegBus] reg2_data, 17 | 18 | output reg [`AluSelBus] alusel, 19 | output reg [`AluOpBus] aluop, 20 | output reg [`RegBus] op1, 21 | output reg [`RegBus] op2, 22 | output reg [`RegBus] link_addr, 23 | output reg write, 24 | output reg [`RegAddrBus] regw_addr, 25 | output reg [`RegBus] mem_offset, 26 | 27 | output reg [`MemAddrBus] br_addr, 28 | output reg [`MemAddrBus] br_offset, 29 | 30 | input wire ex_load, 31 | input wire ex_write, 32 | input wire [`RegAddrBus] ex_regw_addr, 33 | input wire [`RegBus] ex_regw_data, 34 | 35 | input wire mem_write, 36 | input wire [`RegAddrBus] mem_regw_addr, 37 | input wire [`RegBus] mem_regw_data, 38 | 39 | input wire prediction_i, 40 | output wire prediction_o, 41 | output wire [`MemAddrBus] pc_o, 42 | output reg no_prediction 43 | ); 44 | 45 | assign prediction_o = prediction_i; 46 | assign pc_o = pc_i; 47 | 48 | wire [6:0] opcode = inst[6:0]; 49 | wire [2:0] funct3 = inst[14:12]; 50 | wire [6:0] funct7 = inst[31:25]; 51 | wire [31:0] I_imm = {{20{inst[31]}}, inst[31:20]}; 52 | wire [31:0] S_imm = {{20{inst[31]}}, inst[31:25], inst[11:7]}; 53 | wire [31:0] B_imm = {{20{inst[31]}}, inst[7], inst[30:25], inst[11:8], 1'b0}; 54 | wire [31:0] U_imm = {inst[31:12], 12'b0}; 55 | wire [31:0] J_imm = {{12{inst[31]}}, inst[19:12], inst[20], inst[30:21], 1'b0}; 56 | 57 | wire [`RegAddrBus] rd = inst[11:7]; 58 | wire [`RegAddrBus] rs = inst[19:15]; 59 | wire [`RegAddrBus] rt = inst[24:20]; 60 | 61 | reg [`RegBus] imm1, imm2; 62 | 63 | always @(*) begin 64 | alusel = 3'b000; aluop = 0; 65 | read1 = 0; reg1_addr = 0; imm1 = 0; 66 | read2 = 0; reg2_addr = 0; imm2 = 0; 67 | write = 0; regw_addr = 0; 68 | br_addr = 0; br_offset = 0; link_addr = 0; 69 | mem_offset = 0; no_prediction = 0; 70 | if (!reset) begin 71 | case (opcode) 72 | 7'b0110111: begin 73 | alusel = 3'b100; aluop = 0; 74 | imm1 = U_imm; 75 | imm2 = 0; 76 | write = 1; regw_addr = rd; 77 | end // LUI 78 | 7'b0010111: begin 79 | alusel = 3'b100; aluop = 0; 80 | imm1 = U_imm; 81 | imm2 = pc_i; 82 | write = 1; regw_addr = rd; 83 | end // AUIPC 84 | 7'b1101111: begin 85 | alusel = 3'b110; 86 | write = 1; regw_addr = rd; 87 | br_addr = pc_i; br_offset = J_imm; link_addr = pc_i; 88 | end // JAL 89 | 7'b1100111: begin 90 | alusel = 3'b110; 91 | read1 = 1; reg1_addr = rs; 92 | write = 1; regw_addr = rd; 93 | br_addr = op1; br_offset = I_imm; link_addr = pc_i; no_prediction = 1; 94 | end // JALR 95 | 7'b1100011: begin 96 | alusel = 3'b101; 97 | read1 = 1; reg1_addr = rs; 98 | read2 = 1; reg2_addr = rt; 99 | br_addr = pc_i; br_offset = B_imm; 100 | case (funct3) 101 | 3'b000: aluop = 0; // BEQ 102 | 3'b001: aluop = 1; // BNE 103 | 3'b100: aluop = 2; // BLT 104 | 3'b101: aluop = 3; // BGE 105 | 3'b110: aluop = 4; // BLTU 106 | 3'b111: aluop = 5; // BGEU 107 | endcase 108 | end // BRANCH 109 | 7'b0000011: begin 110 | alusel = 3'b111; 111 | read1 = 1; reg1_addr = rs; 112 | write = 1; regw_addr = rd; 113 | mem_offset = I_imm; 114 | case (funct3) 115 | 3'b000: aluop = 0; // LB 116 | 3'b001: aluop = 1; // LH 117 | 3'b010: aluop = 2; // LW 118 | 3'b100: aluop = 3; // LBU 119 | 3'b101: aluop = 4; // LHU 120 | endcase 121 | end // LOAD 122 | 7'b0100011: begin 123 | alusel = 3'b111; 124 | read1 = 1; reg1_addr = rs; 125 | read2 = 1; reg2_addr = rt; 126 | mem_offset = S_imm; 127 | case (funct3) 128 | 3'b000: aluop = 5; // SB 129 | 3'b001: aluop = 6; // SH 130 | 3'b010: aluop = 7; // SW 131 | endcase 132 | end // STORE 133 | 7'b0010011: begin 134 | read1 = 1; reg1_addr = rs; 135 | imm2 = I_imm; 136 | write = 1; regw_addr = rd; 137 | case (funct3) 138 | 3'b000: begin alusel = 3'b100; aluop = 0; end // ADDI 139 | 3'b010: begin alusel = 3'b100; aluop = 2; end // SLTI 140 | 3'b011: begin alusel = 3'b100; aluop = 3; end // SLTIU 141 | 3'b100: begin alusel = 3'b001; aluop = 2; end // XORI 142 | 3'b110: begin alusel = 3'b001; aluop = 0; end // ORI 143 | 3'b111: begin alusel = 3'b001; aluop = 1; end // ANDI 144 | 3'b001: begin alusel = 3'b010; aluop = 0; end // SLLI 145 | 3'b101: begin 146 | case (funct7) 147 | 7'b0000000: begin alusel = 3'b010; aluop = 1; end // SRLI 148 | 7'b0100000: begin alusel = 3'b010; aluop = 2; end // SRAI 149 | endcase 150 | end // SRLI & SRAI 151 | endcase 152 | end // OP_IMM 153 | 7'b0110011: begin 154 | read1 = 1; reg1_addr = rs; 155 | read2 = 1; reg2_addr = rt; 156 | write = 1; regw_addr = rd; 157 | case (funct3) 158 | 3'b000: begin 159 | case (funct7) 160 | 7'b0000000: begin alusel = 3'b100; aluop = 0; end // ADD 161 | 7'b0100000: begin alusel = 3'b100; aluop = 1; end // SUB 162 | endcase 163 | end // ADD & SUB 164 | 3'b001: begin alusel = 3'b010; aluop = 0; end // SLL 165 | 3'b010: begin alusel = 3'b100; aluop = 2; end // SLT 166 | 3'b011: begin alusel = 3'b100; aluop = 3; end // SLTU 167 | 3'b100: begin alusel = 3'b001; aluop = 2; end // XOR 168 | 3'b101: begin 169 | case (funct7) 170 | 7'b0000000: begin alusel = 3'b010; aluop = 1; end // SRL 171 | 7'b0100000: begin alusel = 3'b010; aluop = 2; end // SRA 172 | endcase 173 | end // SRL & SRA 174 | 3'b110: begin alusel = 3'b001; aluop = 0; end // OR 175 | 3'b111: begin alusel = 3'b001; aluop = 1; end // AND 176 | endcase 177 | end // OP_OP 178 | endcase 179 | end 180 | end 181 | 182 | reg stall_id1, stall_id2; 183 | assign stall_id = stall_id1 || stall_id2; 184 | 185 | always @(*) begin 186 | stall_id1 = 0; 187 | if (reset) begin 188 | op1 = 0; 189 | end else if (read1 == 0) begin 190 | op1 = imm1; 191 | end else if (reg1_addr == 0) begin 192 | op1 = 0; 193 | end else if (ex_load && ex_regw_addr == reg1_addr) begin 194 | op1 = 0; stall_id1 = 1; 195 | end else if (ex_write && ex_regw_addr == reg1_addr) begin 196 | op1 = ex_regw_data; 197 | end else if (mem_write && mem_regw_addr == reg1_addr) begin 198 | op1 = mem_regw_data; 199 | end else begin 200 | op1 = reg1_data; 201 | end 202 | end 203 | 204 | always @(*) begin 205 | stall_id2 = 0; 206 | if (reset) begin 207 | op2 = 0; 208 | end else if (read2 == 0) begin 209 | op2 = imm2; 210 | end else if (reg2_addr == 0) begin 211 | op2 = 0; 212 | end else if (ex_load && ex_regw_addr == reg2_addr) begin 213 | op2 = 0; stall_id2 = 1; 214 | end else if (ex_write && ex_regw_addr == reg2_addr) begin 215 | op2 = ex_regw_data; 216 | end else if (mem_write && mem_regw_addr == reg2_addr) begin 217 | op2 = mem_regw_data; 218 | end else begin 219 | op2 = reg2_data; 220 | end 221 | end 222 | 223 | endmodule 224 | -------------------------------------------------------------------------------- /src/stage_if.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module stage_if( 4 | input wire reset, 5 | 6 | output wire stall_if, 7 | 8 | input wire [`MemAddrBus] pc_i, 9 | 10 | output reg ram_read, 11 | output reg [`MemAddrBus] ram_addr, 12 | input wire ram_ready, 13 | input wire [`InstBus] ram_data, 14 | 15 | output reg [`MemAddrBus] pc_o, 16 | output reg [`InstBus] inst_o 17 | ); 18 | 19 | reg [`MemAddrBus] pc; 20 | 21 | assign stall_if = !ram_ready; 22 | 23 | always @(*) begin 24 | if (reset) begin 25 | pc_o = 0; ram_read = 0; ram_addr = 0; 26 | end else begin 27 | pc_o = pc_i; ram_read = 1; ram_addr = pc_i; 28 | end 29 | end 30 | 31 | always @(*) begin 32 | if (!reset && ram_ready) begin 33 | inst_o = ram_data; 34 | end else begin 35 | inst_o = 0; 36 | end 37 | end 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /src/stage_mem.v: -------------------------------------------------------------------------------- 1 | `include "define.v" 2 | 3 | module stage_mem( 4 | input wire reset, 5 | 6 | output wire stall_mem, 7 | 8 | input wire load, 9 | input wire store, 10 | input wire [`MemAddrBus] addr, 11 | input wire [`RegBus] data, 12 | input wire [2:0] length, 13 | input wire signed_, 14 | 15 | input wire ram_ready, 16 | output reg [`MemAddrBus] ram_addr, 17 | input wire [`MemDataBus] ram_data_i, 18 | output reg [`MemDataBus] ram_data_o, 19 | output reg [2:0] ram_length, 20 | output reg ram_signed, 21 | 22 | output reg ram_read, 23 | output reg ram_write, 24 | 25 | input wire write_i, 26 | input wire [`RegAddrBus] regw_addr_i, 27 | input wire [`RegBus] regw_data_i, 28 | 29 | output reg write_o, 30 | output reg [`RegAddrBus] regw_addr_o, 31 | output reg [`RegBus] regw_data_o 32 | ); 33 | 34 | assign stall_mem = (load || store) && !ram_ready; 35 | 36 | always @(*) begin 37 | write_o = write_i; 38 | regw_addr_o = regw_addr_i; 39 | ram_read = 0; 40 | ram_write = 0; 41 | ram_addr = 0; 42 | ram_length = 0; 43 | ram_signed = 0; 44 | ram_data_o = 0; 45 | if (reset) begin 46 | write_o = 0; 47 | regw_addr_o = 0; 48 | end else if (load) begin 49 | ram_read = 1; 50 | ram_addr = addr; 51 | ram_length = length; 52 | ram_signed = signed_; 53 | end else if (store) begin 54 | ram_write = 1; 55 | ram_addr = addr; 56 | ram_length = length; 57 | ram_data_o = data; 58 | end 59 | end 60 | 61 | always @(*) begin 62 | if (reset) begin 63 | regw_data_o = 0; 64 | end else if (!load) begin 65 | regw_data_o = regw_data_i; 66 | end else begin 67 | regw_data_o = ram_data_i; 68 | end 69 | end 70 | 71 | endmodule 72 | -------------------------------------------------------------------------------- /src/testbench.v: -------------------------------------------------------------------------------- 1 | // testbench top module file 2 | // for simulation only 3 | 4 | `timescale 1ns/1ps 5 | module testbench; 6 | 7 | reg clk; 8 | reg rst; 9 | 10 | riscv_top #(.SIM(1)) top( 11 | .EXCLK(clk), 12 | .btnC(rst), 13 | .Tx(), 14 | .Rx(), 15 | .led() 16 | ); 17 | 18 | initial begin 19 | clk=0; 20 | rst=1; 21 | repeat(50) #1 clk=!clk; 22 | rst=0; 23 | forever #1 clk=!clk; 24 | 25 | $finish; 26 | end 27 | 28 | endmodule 29 | -------------------------------------------------------------------------------- /src/uart.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************************** 2 | * 3 | * Copyright (c) 2012, Brian Bennett 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, are permitted 7 | * provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 10 | * and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other materials provided 13 | * with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 22 | * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * UART controller. Universal Asynchronous Receiver/Transmitter control module for an RS-232 25 | * (serial) port. 26 | ***************************************************************************************************/ 27 | 28 | module uart 29 | #( 30 | parameter SYS_CLK_FREQ = 50000000, 31 | parameter BAUD_RATE = 19200, 32 | parameter DATA_BITS = 8, 33 | parameter STOP_BITS = 1, 34 | parameter PARITY_MODE = 0 // 0 = none, 1 = odd, 2 = even 35 | ) 36 | ( 37 | input wire clk, // System clk 38 | input wire reset, // Reset signal 39 | input wire rx, // RS-232 rx pin 40 | input wire [DATA_BITS-1:0] tx_data, // Data to be transmitted when wr_en is 1 41 | input wire rd_en, // Pops current read FIFO front off the queue 42 | input wire wr_en, // Write tx_data over serial connection 43 | output wire tx, // RS-232 tx pin 44 | output wire [DATA_BITS-1:0] rx_data, // Data currently at front of read FIFO 45 | output wire rx_empty, // 1 if there is no more read data available 46 | output wire tx_full, // 1 if the transmit FIFO cannot accept more requests 47 | output wire parity_err // 1 if a parity error has been detected 48 | ); 49 | 50 | localparam BAUD_CLK_OVERSAMPLE_RATE = 16; 51 | 52 | wire baud_clk_tick; 53 | 54 | wire [DATA_BITS-1:0] rx_fifo_wr_data; 55 | wire rx_done_tick; 56 | wire rx_parity_err; 57 | 58 | wire [DATA_BITS-1:0] tx_fifo_rd_data; 59 | wire tx_done_tick; 60 | wire tx_fifo_empty; 61 | 62 | // Store parity error in a flip flop as persistent state. 63 | reg q_rx_parity_err; 64 | wire d_rx_parity_err; 65 | 66 | always @(posedge clk, posedge reset) 67 | begin 68 | if (reset) 69 | q_rx_parity_err <= 1'b0; 70 | else 71 | q_rx_parity_err <= d_rx_parity_err; 72 | end 73 | 74 | assign parity_err = q_rx_parity_err; 75 | assign d_rx_parity_err = q_rx_parity_err || rx_parity_err; 76 | 77 | // BAUD clock module 78 | uart_baud_clk #(.SYS_CLK_FREQ(SYS_CLK_FREQ), 79 | .BAUD(BAUD_RATE), 80 | .BAUD_CLK_OVERSAMPLE_RATE(BAUD_CLK_OVERSAMPLE_RATE)) uart_baud_clk_blk 81 | ( 82 | .clk(clk), 83 | .reset(reset), 84 | .baud_clk_tick(baud_clk_tick) 85 | ); 86 | 87 | // RX (receiver) module 88 | uart_rx #(.DATA_BITS(DATA_BITS), 89 | .STOP_BITS(STOP_BITS), 90 | .PARITY_MODE(PARITY_MODE), 91 | .BAUD_CLK_OVERSAMPLE_RATE(BAUD_CLK_OVERSAMPLE_RATE)) uart_rx_blk 92 | ( 93 | .clk(clk), 94 | .reset(reset), 95 | .baud_clk_tick(baud_clk_tick), 96 | .rx(rx), 97 | .rx_data(rx_fifo_wr_data), 98 | .rx_done_tick(rx_done_tick), 99 | .parity_err(rx_parity_err) 100 | ); 101 | 102 | // TX (transmitter) module 103 | uart_tx #(.DATA_BITS(DATA_BITS), 104 | .STOP_BITS(STOP_BITS), 105 | .PARITY_MODE(PARITY_MODE), 106 | .BAUD_CLK_OVERSAMPLE_RATE(BAUD_CLK_OVERSAMPLE_RATE)) uart_tx_blk 107 | ( 108 | .clk(clk), 109 | .reset(reset), 110 | .baud_clk_tick(baud_clk_tick), 111 | .tx_start(~tx_fifo_empty), 112 | .tx_data(tx_fifo_rd_data), 113 | .tx_done_tick(tx_done_tick), 114 | .tx(tx) 115 | ); 116 | 117 | // RX FIFO 118 | fifo #(.DATA_BITS(DATA_BITS), 119 | .ADDR_BITS(3)) uart_rx_fifo 120 | ( 121 | .clk(clk), 122 | .reset(reset), 123 | .rd_en(rd_en), 124 | .wr_en(rx_done_tick), 125 | .wr_data(rx_fifo_wr_data), 126 | .rd_data(rx_data), 127 | .empty(rx_empty), 128 | .full() 129 | ); 130 | 131 | // TX FIFO (increased size) 132 | fifo #(.DATA_BITS(DATA_BITS), 133 | .ADDR_BITS(10)) uart_tx_fifo 134 | ( 135 | .clk(clk), 136 | .reset(reset), 137 | .rd_en(tx_done_tick), 138 | .wr_en(wr_en), 139 | .wr_data(tx_data), 140 | .rd_data(tx_fifo_rd_data), 141 | .empty(tx_fifo_empty), 142 | .full(tx_full) 143 | ); 144 | 145 | endmodule 146 | 147 | -------------------------------------------------------------------------------- /src/uart_baud_clk.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************************** 2 | ** fpga_nes/hw/src/cmn/uart/uart_baud_clk.v 3 | * 4 | * Copyright (c) 2012, Brian Bennett 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, are permitted 8 | * provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 11 | * and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 13 | * conditions and the following disclaimer in the documentation and/or other materials provided 14 | * with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 23 | * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * Generates a tick signal at OVERSAMPLE_RATE times the baud rate. Should be fed to the uart_rx 26 | * and uart_tx blocks. 27 | ***************************************************************************************************/ 28 | 29 | module uart_baud_clk 30 | #( 31 | parameter SYS_CLK_FREQ = 50000000, 32 | parameter BAUD = 19200, 33 | parameter BAUD_CLK_OVERSAMPLE_RATE = 16 34 | ) 35 | ( 36 | input wire clk, 37 | input wire reset, 38 | output wire baud_clk_tick 39 | ); 40 | 41 | localparam [15:0] CLKS_PER_OVERSAMPLE_TICK = (SYS_CLK_FREQ / BAUD) / BAUD_CLK_OVERSAMPLE_RATE; 42 | 43 | // Registers 44 | reg [15:0] q_cnt; 45 | wire [15:0] d_cnt; 46 | 47 | always @(posedge clk, posedge reset) 48 | begin 49 | if (reset) 50 | q_cnt <= 0; 51 | else 52 | q_cnt <= d_cnt; 53 | end 54 | 55 | assign d_cnt = (q_cnt == (CLKS_PER_OVERSAMPLE_TICK - 1)) ? 16'h0000 : (q_cnt + 16'h0001); 56 | assign baud_clk_tick = (q_cnt == (CLKS_PER_OVERSAMPLE_TICK - 1)) ? 1'b1 : 1'b0; 57 | 58 | endmodule 59 | 60 | -------------------------------------------------------------------------------- /src/uart_rx.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************************** 2 | ** fpga_nes/hw/src/cmn/uart/uart_rx.v 3 | * 4 | * Copyright (c) 2012, Brian Bennett 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, are permitted 8 | * provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 11 | * and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 13 | * conditions and the following disclaimer in the documentation and/or other materials provided 14 | * with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 23 | * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * UART receiver. 26 | ***************************************************************************************************/ 27 | 28 | module uart_rx 29 | #( 30 | parameter DATA_BITS = 8, 31 | parameter STOP_BITS = 1, 32 | parameter PARITY_MODE = 1, // 0 = NONE, 1 = ODD, 2 = EVEN 33 | parameter BAUD_CLK_OVERSAMPLE_RATE = 16 34 | ) 35 | ( 36 | input wire clk, // System clock 37 | input wire reset, // Reset signal 38 | input wire baud_clk_tick, // 1 tick per OVERSAMPLE_RATE baud clks 39 | input wire rx, // RX transmission wire 40 | output wire [DATA_BITS-1:0] rx_data, // Output data 41 | output wire rx_done_tick, // Output rdy signal 42 | output wire parity_err // Asserted for one clk on parity error 43 | ); 44 | 45 | localparam [5:0] STOP_OVERSAMPLE_TICKS = STOP_BITS * BAUD_CLK_OVERSAMPLE_RATE; 46 | 47 | // Symbolic state representations. 48 | localparam [4:0] S_IDLE = 5'h01, 49 | S_START = 5'h02, 50 | S_DATA = 5'h04, 51 | S_PARITY = 5'h08, 52 | S_STOP = 5'h10; 53 | 54 | // Registers 55 | reg [4:0] q_state, d_state; 56 | reg [3:0] q_oversample_tick_cnt, d_oversample_tick_cnt; 57 | reg [DATA_BITS-1:0] q_data, d_data; 58 | reg [2:0] q_data_bit_idx, d_data_bit_idx; 59 | reg q_done_tick, d_done_tick; 60 | reg q_parity_err, d_parity_err; 61 | reg q_rx; 62 | 63 | always @(posedge clk, posedge reset) 64 | begin 65 | if (reset) 66 | begin 67 | q_state <= S_IDLE; 68 | q_oversample_tick_cnt <= 0; 69 | q_data <= 0; 70 | q_data_bit_idx <= 0; 71 | q_done_tick <= 1'b0; 72 | q_parity_err <= 1'b0; 73 | q_rx <= 1'b1; 74 | end 75 | else 76 | begin 77 | q_state <= d_state; 78 | q_oversample_tick_cnt <= d_oversample_tick_cnt; 79 | q_data <= d_data; 80 | q_data_bit_idx <= d_data_bit_idx; 81 | q_done_tick <= d_done_tick; 82 | q_parity_err <= d_parity_err; 83 | q_rx <= rx; 84 | end 85 | end 86 | 87 | always @* 88 | begin 89 | // Default most state to remain unchanged. 90 | d_state = q_state; 91 | d_data = q_data; 92 | d_data_bit_idx = q_data_bit_idx; 93 | 94 | // Increment the tick counter if the baud_clk counter ticked. 95 | d_oversample_tick_cnt = (baud_clk_tick) ? q_oversample_tick_cnt + 4'h1 : q_oversample_tick_cnt; 96 | 97 | // Default the done signal and parity err to 0. 98 | d_done_tick = 1'b0; 99 | d_parity_err = 1'b0; 100 | 101 | case (q_state) 102 | S_IDLE: 103 | begin 104 | // Detect incoming data when rx goes low (start bit). 105 | if (~q_rx) 106 | begin 107 | d_state = S_START; 108 | d_oversample_tick_cnt = 0; 109 | end 110 | end 111 | 112 | S_START: 113 | begin 114 | // Wait for BAUD_CLK_OVERSAMPLE_RATE / 2 ticks to get "centered" in the start bit signal. 115 | if (baud_clk_tick && (q_oversample_tick_cnt == ((BAUD_CLK_OVERSAMPLE_RATE - 1) / 2))) 116 | begin 117 | d_state = S_DATA; 118 | d_oversample_tick_cnt = 0; 119 | d_data_bit_idx = 0; 120 | end 121 | end 122 | 123 | S_DATA: 124 | begin 125 | // Every BAUD_CLK_OVERSAMPLE_RATE clocks, sample rx and shift its value into the data reg. 126 | if (baud_clk_tick && (q_oversample_tick_cnt == (BAUD_CLK_OVERSAMPLE_RATE - 1))) 127 | begin 128 | d_data = { q_rx, q_data[DATA_BITS-1:1] }; 129 | d_oversample_tick_cnt = 0; 130 | 131 | if (q_data_bit_idx == (DATA_BITS - 1)) 132 | begin 133 | if (PARITY_MODE == 0) 134 | d_state = S_STOP; 135 | else 136 | d_state = S_PARITY; 137 | end 138 | else 139 | d_data_bit_idx = q_data_bit_idx + 3'h1; 140 | end 141 | end 142 | 143 | S_PARITY: 144 | begin 145 | if (baud_clk_tick && (q_oversample_tick_cnt == (BAUD_CLK_OVERSAMPLE_RATE - 1))) 146 | begin 147 | if (PARITY_MODE == 1) 148 | d_parity_err = (q_rx != ~^q_data); 149 | else 150 | d_parity_err = (q_rx != ^q_data); 151 | 152 | d_state = S_STOP; 153 | d_oversample_tick_cnt = 0; 154 | end 155 | end 156 | 157 | S_STOP: 158 | begin 159 | // Wait for stop bit before returning to idle. Signal done_tick. 160 | if (baud_clk_tick && (q_oversample_tick_cnt == STOP_OVERSAMPLE_TICKS - 1)) 161 | begin 162 | d_state = S_IDLE; 163 | d_done_tick = 1'b1; 164 | end 165 | end 166 | endcase 167 | end 168 | 169 | assign rx_data = q_data; 170 | assign rx_done_tick = q_done_tick; 171 | assign parity_err = q_parity_err; 172 | 173 | endmodule 174 | 175 | -------------------------------------------------------------------------------- /src/uart_tx.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************************************** 2 | ** fpga_nes/hw/src/cmn/uart/uart_tx.v 3 | * 4 | * Copyright (c) 2012, Brian Bennett 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without modification, are permitted 8 | * provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 11 | * and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 13 | * conditions and the following disclaimer in the documentation and/or other materials provided 14 | * with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 23 | * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * UART transmitter. 26 | ***************************************************************************************************/ 27 | 28 | module uart_tx 29 | #( 30 | parameter DATA_BITS = 8, 31 | parameter STOP_BITS = 1, 32 | parameter PARITY_MODE = 1, // 0 = NONE, 1 = ODD, 2 = EVEN 33 | parameter BAUD_CLK_OVERSAMPLE_RATE = 16 34 | ) 35 | ( 36 | input wire clk, // System clock 37 | input wire reset, // Reset signal 38 | input wire baud_clk_tick, // 1 tick per OVERSAMPLE_RATE baud clks 39 | input wire tx_start, // Signal requesting trasmission start 40 | input wire [DATA_BITS-1:0] tx_data, // Data to be transmitted 41 | output wire tx_done_tick, // Transfer done signal 42 | output wire tx // TX transmission wire 43 | ); 44 | 45 | localparam [5:0] STOP_OVERSAMPLE_TICKS = STOP_BITS * BAUD_CLK_OVERSAMPLE_RATE; 46 | 47 | // Symbolic state representations. 48 | localparam [4:0] S_IDLE = 5'h01, 49 | S_START = 5'h02, 50 | S_DATA = 5'h04, 51 | S_PARITY = 5'h08, 52 | S_STOP = 5'h10; 53 | 54 | // Registers 55 | reg [4:0] q_state, d_state; 56 | reg [3:0] q_baud_clk_tick_cnt, d_baud_clk_tick_cnt; 57 | reg [DATA_BITS-1:0] q_data, d_data; 58 | reg [2:0] q_data_bit_idx, d_data_bit_idx; 59 | reg q_parity_bit, d_parity_bit; 60 | reg q_tx, d_tx; 61 | reg q_tx_done_tick, d_tx_done_tick; 62 | 63 | always @(posedge clk, posedge reset) 64 | begin 65 | if (reset) 66 | begin 67 | q_state <= S_IDLE; 68 | q_baud_clk_tick_cnt <= 0; 69 | q_data <= 0; 70 | q_data_bit_idx <= 0; 71 | q_tx <= 1'b1; 72 | q_tx_done_tick <= 1'b0; 73 | q_parity_bit <= 1'b0; 74 | end 75 | else 76 | begin 77 | q_state <= d_state; 78 | q_baud_clk_tick_cnt <= d_baud_clk_tick_cnt; 79 | q_data <= d_data; 80 | q_data_bit_idx <= d_data_bit_idx; 81 | q_tx <= d_tx; 82 | q_tx_done_tick <= d_tx_done_tick; 83 | q_parity_bit <= d_parity_bit; 84 | end 85 | end 86 | 87 | always @* 88 | begin 89 | // Default most state to remain unchanged. 90 | d_state = q_state; 91 | d_data = q_data; 92 | d_data_bit_idx = q_data_bit_idx; 93 | d_parity_bit = q_parity_bit; 94 | 95 | // Increment the tick counter if the baud clk counter ticked. 96 | d_baud_clk_tick_cnt = (baud_clk_tick) ? (q_baud_clk_tick_cnt + 4'h1) : q_baud_clk_tick_cnt; 97 | 98 | d_tx_done_tick = 1'b0; 99 | d_tx = 1'b1; 100 | 101 | case (q_state) 102 | S_IDLE: 103 | begin 104 | // Detect tx_start signal from client, latch data, and begin transmission. Don't latch 105 | // during done_tick. 106 | if (tx_start && ~q_tx_done_tick) 107 | begin 108 | d_state = S_START; 109 | d_baud_clk_tick_cnt = 0; 110 | d_data = tx_data; 111 | 112 | if (PARITY_MODE == 1) 113 | d_parity_bit = ~^tx_data; 114 | else if (PARITY_MODE == 2) 115 | d_parity_bit = ~tx_data; 116 | end 117 | end 118 | 119 | S_START: 120 | begin 121 | // Send low signal to indicate start bit. When done, move to data transmission. 122 | d_tx = 1'b0; 123 | if (baud_clk_tick && (q_baud_clk_tick_cnt == (BAUD_CLK_OVERSAMPLE_RATE - 1))) 124 | begin 125 | d_state = S_DATA; 126 | d_baud_clk_tick_cnt = 0; 127 | d_data_bit_idx = 0; 128 | end 129 | end 130 | 131 | S_DATA: 132 | begin 133 | // Transmit current low data bit. After OVERSAMPLE_RATE ticks, shift the data reg 134 | // and move on to the next bit. After DATA_BITS bits, move to stop bit state. 135 | d_tx = q_data[0]; 136 | if (baud_clk_tick && (q_baud_clk_tick_cnt == (BAUD_CLK_OVERSAMPLE_RATE - 1))) 137 | begin 138 | d_data = q_data >> 1; 139 | d_data_bit_idx = q_data_bit_idx + 3'h1; 140 | d_baud_clk_tick_cnt = 0; 141 | 142 | if (q_data_bit_idx == (DATA_BITS - 1)) 143 | begin 144 | if (PARITY_MODE == 0) 145 | d_state = S_STOP; 146 | else 147 | d_state = S_PARITY; 148 | end 149 | end 150 | end 151 | 152 | S_PARITY: 153 | begin 154 | // Send parity bit. 155 | d_tx = q_parity_bit; 156 | if (baud_clk_tick && (q_baud_clk_tick_cnt == (BAUD_CLK_OVERSAMPLE_RATE - 1))) 157 | begin 158 | d_state = S_STOP; 159 | d_baud_clk_tick_cnt = 0; 160 | end 161 | end 162 | 163 | S_STOP: 164 | begin 165 | // Issue stop bit. 166 | if (baud_clk_tick && (q_baud_clk_tick_cnt == (STOP_OVERSAMPLE_TICKS - 1))) 167 | begin 168 | d_state = S_IDLE; 169 | d_tx_done_tick = 1'b1; 170 | end 171 | end 172 | endcase 173 | end 174 | 175 | assign tx = q_tx; 176 | assign tx_done_tick = q_tx_done_tick; 177 | 178 | endmodule 179 | 180 | -------------------------------------------------------------------------------- /test_tool/ctrl/build.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | dir=`dirname $0` 3 | g++ $dir/controller.cpp -std=c++14 -I /tmp/usr/local/include/ -L /tmp/usr/local/lib/ -lserial -lpthread -o $dir/ctrl 4 | -------------------------------------------------------------------------------- /test_tool/ctrl/controller.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int run_mode; 9 | 10 | #define error(msg...) printf(msg) 11 | #define info(msg...) do{if(run_mode) printf(msg);}while(0) 12 | 13 | typedef std::uint8_t byte; 14 | typedef std::uint16_t word; 15 | typedef std::uint32_t dword; 16 | 17 | serial::Serial serPort; 18 | 19 | void uart_send(const byte *data, int send_count, byte* recv, int return_count) { 20 | serPort.write(data,send_count); 21 | if (!return_count) return; 22 | try { 23 | serPort.read(recv,return_count); 24 | } catch (std::exception &e) { 25 | error("recv error: %s\n",e.what()); 26 | } 27 | } 28 | void uart_send(const std::vector data, byte* recv, int return_count) { 29 | uart_send(data.data(),data.size(),recv,return_count); 30 | } 31 | void uart_send(const std::string &data) { serPort.write(data); } 32 | void uart_send(const byte *data, int size) { serPort.write(data,size); } 33 | void uart_send(const std::vector &data) { serPort.write(data); } 34 | void uart_read(byte *data, int size) { serPort.read(data, size); } 35 | 36 | #include "listener.h" 37 | 38 | int init_port(char* port) { 39 | serPort.setPort(port); 40 | serPort.setBaudrate(baud_rate); 41 | serPort.setBytesize(byte_size); 42 | serPort.setParity(parity); 43 | serPort.setStopbits(stopbits); 44 | serPort.setTimeout( 45 | inter_byte_timeout, 46 | read_timeout_constant, 47 | read_timeout_multiplier, 48 | write_timeout_constant, 49 | write_timeout_multiplier 50 | ); 51 | try { 52 | serPort.open(); 53 | } catch (std::exception &e) { 54 | error("failed to open port: %s\n",e.what()); 55 | return 1; 56 | } 57 | info("initialized UART port on: %s\n",port); 58 | return 0; 59 | } 60 | 61 | byte ram_data[0x40000]; 62 | byte in_data[0x400]; 63 | 64 | int load_ram(char* rom_path) { 65 | std::ifstream fin(rom_path); 66 | if (!fin.is_open()) return 0; 67 | fin.seekg(0, std::ios_base::end); 68 | int ram_size = fin.tellg(); 69 | info("RAM size: %x\n", ram_size); 70 | fin.seekg(0, std::ios_base::beg); 71 | fin.read(reinterpret_cast(ram_data), ram_size); 72 | for (int i=0;i<0x40; ++i) { 73 | info("%02x ", (byte)ram_data[i+0x1000]); 74 | if (!((i+1)%16)) info("\n"); 75 | } 76 | fin.close(); 77 | return ram_size; 78 | } 79 | 80 | int load_input(char* in_path) { 81 | if (!in_path) return 0; 82 | std::ifstream fin(in_path); 83 | if (!fin.is_open()) return 0; 84 | fin.seekg(0, std::ios_base::end); 85 | int in_size = fin.tellg(); 86 | info("INPUT size: %x\n", in_size); 87 | fin.seekg(0, std::ios_base::beg); 88 | fin.read(reinterpret_cast(in_data), in_size); 89 | for (int i=0;i<0x10; ++i) { 90 | info("%02x ", (byte)in_data[i]); 91 | if (!((i+1)%16)) info("\n"); 92 | } 93 | fin.close(); 94 | return in_size; 95 | } 96 | 97 | clock_t start_tm; 98 | clock_t end_tm; 99 | 100 | void run() { 101 | // demo 102 | 103 | // debug packet format: see hci.v or README.md 104 | // send[0] is always OPCODE 105 | // to send debug packets, use uart_send(send,send_count) 106 | // to receive data after send, use uart_send(send,send_count,recv,recv_count) 107 | char c; 108 | int run = 0; 109 | while (1){ 110 | info("Enter r to run, q to quit, p to get cpu PC(demo)\n"); 111 | c=getchar(); 112 | if (c=='q') { 113 | break; 114 | } 115 | else if (c=='p') { 116 | // demo for debugging cpu 117 | // add support in hci.v to allow more debug operations 118 | byte send[6]={0}; 119 | byte recv[64]={0}; 120 | send[0]=0x01; 121 | uart_send(send,1,recv,4); 122 | int pc = *reinterpret_cast(recv); 123 | info("pc:%08x\n",pc); 124 | send[0] = 0x09; 125 | int get_size = 16; 126 | *reinterpret_cast(send+1)=pc; 127 | *reinterpret_cast(send+4)=get_size; 128 | uart_send(send,6,recv,get_size); 129 | for (int i=0;i<16;++i) { 130 | info("%02x ",recv[i]); 131 | } 132 | info("\n"); 133 | } 134 | else if (c=='r') { 135 | // run or pause cpu 136 | byte send[2]; 137 | send[0]=(run?0x03:0x04); 138 | run = !run; 139 | info("CPU start\n"); 140 | uart_send(send,1); 141 | start_tm = clock(); 142 | // receive output bytes from fpga 143 | while (1) { 144 | byte data; 145 | // to debug cpu at the same time, implement separate thread 146 | while (!serPort.available()); 147 | uart_read(&data,1); 148 | if (on_recv(data)) break; 149 | } 150 | end_tm = clock(); 151 | info("\nCPU returned with running time: %f\n",(double)(end_tm - start_tm) / CLOCKS_PER_SEC); 152 | 153 | // manually pressing reset button is recommended 154 | 155 | // or pause and reset cpu through uart (TODO) 156 | // send[0]=(run?0x03:0x04); 157 | // run = !run; 158 | // uart_send(send,1); 159 | 160 | return; 161 | } 162 | } 163 | } 164 | 165 | void run_auto() { 166 | byte send[2]; 167 | send[0]=(0x04); 168 | uart_send(send,1); 169 | start_tm = clock(); 170 | while (1) { 171 | byte data; 172 | while (!serPort.available()); 173 | uart_read(&data,1); 174 | if (data==0) break; 175 | putchar(data); 176 | } 177 | end_tm = clock(); 178 | } 179 | 180 | int main(int argc, char** argv) { 181 | if (argc<4) { 182 | error("usage: path-to-ram [path-to-input] com-port -I(interactive)/-T(testing)\n"); 183 | return 1; 184 | } 185 | char* ram_path = argv[1]; 186 | int no_input = argc<5; 187 | char* input_path = no_input ? NULL : argv[2]; 188 | char* comport = argv[argc-2]; 189 | char param = argv[argc-1][1]; 190 | if (param=='I') { 191 | run_mode = 1; 192 | } else if (param=='T') { 193 | run_mode = 0; 194 | } 195 | int ram_size = 0, in_size = 0; 196 | if (!(ram_size=load_ram(ram_path))) { 197 | error("failed to read ram file\n"); 198 | return 1; 199 | } 200 | if (!no_input && !(in_size=load_input(input_path))){ 201 | info("input file not found, skipping\n"); 202 | } 203 | if (init_port(comport)) return 1; 204 | if (on_init()) return 1; 205 | upload_ram(ram_data, ram_size); 206 | upload_input(in_data, in_size); 207 | // verify_ram(ram_data, ram_size); 208 | if (run_mode) run(); 209 | else run_auto(); 210 | serPort.close(); 211 | } 212 | -------------------------------------------------------------------------------- /test_tool/ctrl/listener.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // UART port configuration, adjust according to implementation 9 | int baud_rate = 115200; 10 | serial::bytesize_t byte_size = serial::eightbits; 11 | serial::parity_t parity = serial::parity_odd; 12 | serial::stopbits_t stopbits = serial::stopbits_one; 13 | int inter_byte_timeout = 50; 14 | int read_timeout_constant = 50; 15 | int read_timeout_multiplier = 10; 16 | int write_timeout_constant = 50; 17 | int write_timeout_multiplier = 10; 18 | 19 | //methods 20 | int on_init() { 21 | using namespace std::chrono_literals; 22 | byte junk[10]; 23 | uart_read(junk,8); 24 | std::this_thread::sleep_for(std::chrono::seconds(1)); 25 | byte init[10]; 26 | byte recv[10]={0}; 27 | init[0] = 0x00; 28 | int len = 4; 29 | *reinterpret_cast(init+1) = len; 30 | char test[10] = "UART"; 31 | for (int i=0;i(recv); 42 | if (strcmp(str,test)) { 43 | error("UART assertion failed\n"); 44 | return 1; 45 | } 46 | return 0; 47 | } 48 | 49 | void upload_ram(byte* ram_data, int ram_size) { 50 | if (!ram_size) return; 51 | const int short blk_size = 0x400; 52 | const int pld_size = 1+3+2+blk_size; 53 | byte payload[pld_size]; 54 | int blk_cnt = (ram_size / blk_size); 55 | if (blk_cnt*blk_size(payload+1) = addr; 63 | *reinterpret_cast(payload+4) = blk_size; 64 | for (int j=0;j(payload+1) = pre_size; 85 | uart_send(payload,1+2+pre_size); 86 | int rem_size = in_size; 87 | for (int i=0; i(payload+1) = dat_size; 93 | for (int j=0;j(payload+1) = addr; 117 | *reinterpret_cast(payload+4) = blk_size; 118 | uart_send(payload,6,recv_data,blk_size); 119 | for (int j=0; j test/test.dump 11 | -------------------------------------------------------------------------------- /test_tool/fpga_run.sh: -------------------------------------------------------------------------------- 1 | zsh fpga_build.sh $1 2 | if [ -f ./testcase/$1.in ]; then cp ./testcase/$1.in ./test/test.in; fi 3 | if [ -f ./testcase/$1.ans ]; then cp ./testcase/$1.ans ./test/test.ans; fi 4 | zsh ctrl/build.sh 5 | echo Answer: 6 | cat test/test.ans 7 | echo 8 | zsh ctrl/run.sh test/test.bin test/test.in /dev/$fpga_port -I 9 | #./ctrl/run.sh ./test/test.bin ./test/test.in /dev/tty$$port -T > ./test/test.out 10 | #if [ -f ./test/test.ans ]; then diff ./test/test.ans ./test/test.out; fi 11 | -------------------------------------------------------------------------------- /test_tool/sim_build.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | rm -rf test 3 | mkdir test 4 | riscv32-unknown-elf-as -o sys/rom.o -march=rv32i sys/rom.s 5 | cp testcase/$1.sim.c test/test.c 6 | riscv32-unknown-elf-gcc -o test/test.o -I sys -c test/test.c $sim_optimize -march=rv32i -mabi=ilp32 -Wall 7 | riscv32-unknown-elf-ld -T sys/memory.ld sys/rom.o test/test.o -L /opt/riscv/riscv32-unknown-elf/lib -L /opt/riscv/lib/gcc/riscv32-unknown-elf/8.3.0 -lc -lgcc -lm -lnosys -o test/test.om 8 | riscv32-unknown-elf-objcopy -O verilog test/test.om test/test.data 9 | riscv32-unknown-elf-objcopy -O binary test/test.om test/test.bin 10 | riscv32-unknown-elf-objdump -D test/test.om > test/test.dump 11 | -------------------------------------------------------------------------------- /test_tool/sim_run.sh: -------------------------------------------------------------------------------- 1 | zsh sim_build.sh $1 2 | if [ -f testcase/$1.in ]; then cp testcase/$1.in test/test.in; fi 3 | if [ -f testcase/$1.ans ]; then cp testcase/$1.ans test/test.ans; fi 4 | -------------------------------------------------------------------------------- /test_tool/sys/io.h: -------------------------------------------------------------------------------- 1 | #ifndef CPU_JUDGE_TEST_IO_H 2 | #define CPU_JUDGE_TEST_IO_H 3 | 4 | // #define SIM // whether in simulation 5 | 6 | #define BYTE_PORT_IN 0x30000 // port for reading bytes from input 7 | #define BYTE_PORT_OUT 0x30000 // port for writing bytes to output 8 | 9 | #define CPUCLK_PORT_IN 0x30004 // port that reads clocks passed since cpu starts 10 | 11 | #define CPU_CLK_FREQ 70000000 // clock frequency of the cpu on FPGA 12 | 13 | static inline unsigned char inb() 14 | { 15 | return *((volatile unsigned char *)BYTE_PORT_IN); 16 | } 17 | 18 | static inline void outb(const unsigned char data) 19 | { 20 | *((volatile unsigned char *)BYTE_PORT_OUT) = data; 21 | } 22 | 23 | static inline unsigned long inl() 24 | { 25 | unsigned long ret = 0; 26 | unsigned char ch; 27 | int sign=0; 28 | while ((ch=inb())) if(ch!='\n'&&ch!=' '&&ch!='\t') break; 29 | do { 30 | if(ch=='-'&&!sign) sign=1; 31 | else if(ch<'0'||ch>'9') break; 32 | ret = ret * 10 + ch - '0'; 33 | }while ((ch=inb())); 34 | return sign?-ret:ret; 35 | } 36 | 37 | static inline void getstr(char* data) 38 | { 39 | char c; 40 | int i=0; 41 | while((c=inb())!='\n') data[i++]=c; 42 | data[i]='\0'; 43 | } 44 | 45 | static inline unsigned int ord(char data) 46 | { 47 | return (unsigned int)data; 48 | } 49 | 50 | static inline void outl(const int data) 51 | { 52 | unsigned char str[12]; 53 | int tmp = data; 54 | int i=0, s=0; 55 | if (tmp<0){ 56 | s=1; 57 | tmp=-tmp; 58 | } 59 | do { 60 | str[i++] = tmp % 10 + '0'; 61 | } 62 | while ((tmp/=10)>0); 63 | if(s) str[i++]='-'; 64 | while (i--) { 65 | outb(str[i]); 66 | } 67 | } 68 | 69 | static inline void print(const char *str) 70 | { 71 | for (; *str; str++) 72 | outb(*str); 73 | } 74 | 75 | static inline void println(const char *str) 76 | { 77 | print(str); 78 | outb('\n'); 79 | } 80 | 81 | static inline void outlln(const unsigned int data) 82 | { 83 | outl(data); 84 | outb('\n'); 85 | } 86 | 87 | static inline unsigned int clock() 88 | { 89 | // return *((volatile unsigned int*)CPUCLK_PORT_IN); 90 | unsigned t1 = (unsigned)(*((volatile unsigned char *)(CPUCLK_PORT_IN))); 91 | unsigned t2 = (unsigned)(*((volatile unsigned char *)(CPUCLK_PORT_IN+1))); 92 | unsigned t3 = (unsigned)(*((volatile unsigned char *)(CPUCLK_PORT_IN+2))); 93 | unsigned t4 = (unsigned)(*((volatile unsigned char *)(CPUCLK_PORT_IN+3))); 94 | return (t4<<24) | (t3<<16) | (t2<<8) | (t1); 95 | } 96 | 97 | #ifdef SIM 98 | #define sleep(x) 99 | #else 100 | static inline void sleep(const unsigned int milli_sec) 101 | { 102 | unsigned int s = 0, d = milli_sec * (CPU_CLK_FREQ / 1000); 103 | s = clock(); 104 | while (clock() - s < d); 105 | } 106 | #endif 107 | 108 | #endif -------------------------------------------------------------------------------- /test_tool/sys/memory.ld: -------------------------------------------------------------------------------- 1 | SECTIONS 2 | { 3 | . = 0x00000000; 4 | .rom : 5 | { 6 | *(.rom) 7 | } 8 | 9 | . = 0x00001000; 10 | .text : 11 | { 12 | *(.text) 13 | } 14 | 15 | .rodata ALIGN(4) : 16 | { 17 | *(.rodata) 18 | } 19 | 20 | .data ALIGN(4) : 21 | { 22 | *(.data) 23 | } 24 | 25 | __bss_start = .; 26 | 27 | .bss ALIGN(4) : 28 | { 29 | *(.bss) 30 | } 31 | 32 | __bss_end = .; 33 | __heap_start = (__bss_end + 0xfff) & 0xfffff000; 34 | } 35 | -------------------------------------------------------------------------------- /test_tool/sys/rom.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wu-qing-157/RISCV-CPU/7a2897619837c8b03b7536d391d38ac7fa6e43ce/test_tool/sys/rom.o -------------------------------------------------------------------------------- /test_tool/sys/rom.s: -------------------------------------------------------------------------------- 1 | .section .rom,"ax" 2 | .globl main 3 | 4 | li sp, 0x00020000 5 | jal main 6 | li a0, 0xff 7 | .L0: 8 | lui a3, 0x30 9 | sb a0, 4(a3) 10 | j .L0 11 | -------------------------------------------------------------------------------- /test_tool/testcase/array_test1.ans: -------------------------------------------------------------------------------- 1 | 0000 2 | 1234 -------------------------------------------------------------------------------- /test_tool/testcase/array_test1.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | //input: 1 2 3 4 3 | 4 | int a[4]; 5 | int main() 6 | { 7 | int b[4]; 8 | int i; 9 | for (i = 0; i < 4; i++) 10 | { 11 | a[i] = 0; 12 | b[i] = inl(); 13 | } 14 | for (i = 0; i < 4; i++) 15 | { 16 | outl(a[i]); 17 | } 18 | println(""); 19 | int *p; 20 | p=b; 21 | for (i = 0; i < 4; i++) 22 | { 23 | outl(p[i]); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test_tool/testcase/array_test1.in: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | -------------------------------------------------------------------------------- /test_tool/testcase/array_test1.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | //input: 1 2 3 4 3 | 4 | int a[4]; 5 | int main() 6 | { 7 | int b[4]; 8 | int i; 9 | for (i = 0; i < 4; i++) 10 | { 11 | a[i] = 0; 12 | b[i] = inl(); 13 | } 14 | for (i = 0; i < 4; i++) 15 | { 16 | outl(a[i]); 17 | } 18 | println(""); 19 | int *p; 20 | p=b; 21 | for (i = 0; i < 4; i++) 22 | { 23 | outl(p[i]); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test_tool/testcase/array_test2.ans: -------------------------------------------------------------------------------- 1 | 4 2 | 1234 3 | 0000 -------------------------------------------------------------------------------- /test_tool/testcase/array_test2.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | // input: 1 2 3 4 3 | int a[4]; 4 | int *pa = a; 5 | int main() 6 | { 7 | int *pb[4]; 8 | int i; 9 | pb[0] = pa; 10 | pb[1] = pa; 11 | pb[2] = pa; 12 | pb[3] = pa; 13 | outlln(4); 14 | for (i = 0; i < 4; i++) 15 | pb[0][i] = inl(); 16 | for (i = 0; i < 4; i++) 17 | outl(pb[1][i]); 18 | println(""); 19 | for (i = 0; i < 4; i++) 20 | pb[2][i] = 0; 21 | for (i = 0; i < 4; i++) 22 | outl(pb[3][i]); 23 | } 24 | -------------------------------------------------------------------------------- /test_tool/testcase/array_test2.in: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | -------------------------------------------------------------------------------- /test_tool/testcase/basicopt1.ans: -------------------------------------------------------------------------------- 1 | 99850 2 | -------------------------------------------------------------------------------- /test_tool/testcase/basicopt1.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int main() 3 | { 4 | int a[100][100]; 5 | int i; 6 | int j; 7 | int sum = 0; 8 | 9 | for (i = 0;i < 100;i++) 10 | for (j = 0;j < 100;j++) 11 | a[i][j] = 0; 12 | int quotient; 13 | int remainder; 14 | for (i = 0;i < 100;i++) 15 | if (i > 20 && i < 80) { 16 | for (j = 0;j < 100;j++) 17 | if (j > 5 || i < 90) { 18 | quotient = j * 4 / 100; 19 | remainder = j * 4 % 100; 20 | a[i + quotient][remainder] = j + (100 - 1 + 1 - 1 + 1) / 2; 21 | } 22 | } 23 | 24 | for (i = 0;i < 100;i++) 25 | for (j = 0;j < 100;j++) 26 | sum = sum + a[i][j]; 27 | outlln(sum); 28 | } 29 | -------------------------------------------------------------------------------- /test_tool/testcase/basicopt1.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int main() 3 | { 4 | int a[100][100]; 5 | int i; 6 | int j; 7 | int sum = 0; 8 | 9 | for (i = 0;i < 100;i++) 10 | for (j = 0;j < 100;j++) 11 | a[i][j] = 0; 12 | int quotient; 13 | int remainder; 14 | for (i = 0;i < 100;i++) 15 | if (i > 20 && i < 80) { 16 | for (j = 0;j < 100;j++) 17 | if (j > 5 || i < 90) { 18 | quotient = j * 4 / 100; 19 | remainder = j * 4 % 100; 20 | a[i + quotient][remainder] = j + (100 - 1 + 1 - 1 + 1) / 2; 21 | } 22 | } 23 | 24 | for (i = 0;i < 100;i++) 25 | for (j = 0;j < 100;j++) 26 | sum = sum + a[i][j]; 27 | outlln(sum); 28 | } 29 | -------------------------------------------------------------------------------- /test_tool/testcase/bulgarian.ans: -------------------------------------------------------------------------------- 1 | Let's start! 2 | 5 3 | 5 5 1 6 193 4 | step 1: 5 | 4 4 5 192 5 6 | step 2: 7 | 3 3 4 191 4 5 8 | step 3: 9 | 2 2 3 190 3 4 6 10 | step 4: 11 | 1 1 2 189 2 3 5 7 12 | step 5: 13 | 1 188 1 2 4 6 8 14 | step 6: 15 | 187 1 3 5 7 7 16 | step 7: 17 | 186 2 4 6 6 6 18 | step 8: 19 | 185 1 3 5 5 5 6 20 | step 9: 21 | 184 2 4 4 4 5 7 22 | step 10: 23 | 183 1 3 3 3 4 6 7 24 | step 11: 25 | 182 2 2 2 3 5 6 8 26 | step 12: 27 | 181 1 1 1 2 4 5 7 8 28 | step 13: 29 | 180 1 3 4 6 7 9 30 | step 14: 31 | 179 2 3 5 6 8 7 32 | step 15: 33 | 178 1 2 4 5 7 6 7 34 | step 16: 35 | 177 1 3 4 6 5 6 8 36 | step 17: 37 | 176 2 3 5 4 5 7 8 38 | step 18: 39 | 175 1 2 4 3 4 6 7 8 40 | step 19: 41 | 174 1 3 2 3 5 6 7 9 42 | step 20: 43 | 173 2 1 2 4 5 6 8 9 44 | step 21: 45 | 172 1 1 3 4 5 7 8 9 46 | step 22: 47 | 171 2 3 4 6 7 8 9 48 | step 23: 49 | 170 1 2 3 5 6 7 8 8 50 | step 24: 51 | 169 1 2 4 5 6 7 7 9 52 | step 25: 53 | 168 1 3 4 5 6 6 8 9 54 | step 26: 55 | 167 2 3 4 5 5 7 8 9 56 | step 27: 57 | 166 1 2 3 4 4 6 7 8 9 58 | step 28: 59 | 165 1 2 3 3 5 6 7 8 10 60 | step 29: 61 | 164 1 2 2 4 5 6 7 9 10 62 | step 30: 63 | 163 1 1 3 4 5 6 8 9 10 64 | step 31: 65 | 162 2 3 4 5 7 8 9 10 66 | step 32: 67 | 161 1 2 3 4 6 7 8 9 9 68 | step 33: 69 | 160 1 2 3 5 6 7 8 8 10 70 | step 34: 71 | 159 1 2 4 5 6 7 7 9 10 72 | step 35: 73 | 158 1 3 4 5 6 6 8 9 10 74 | step 36: 75 | 157 2 3 4 5 5 7 8 9 10 76 | step 37: 77 | 156 1 2 3 4 4 6 7 8 9 10 78 | step 38: 79 | 155 1 2 3 3 5 6 7 8 9 11 80 | step 39: 81 | 154 1 2 2 4 5 6 7 8 10 11 82 | step 40: 83 | 153 1 1 3 4 5 6 7 9 10 11 84 | step 41: 85 | 152 2 3 4 5 6 8 9 10 11 86 | step 42: 87 | 151 1 2 3 4 5 7 8 9 10 10 88 | step 43: 89 | 150 1 2 3 4 6 7 8 9 9 11 90 | step 44: 91 | 149 1 2 3 5 6 7 8 8 10 11 92 | step 45: 93 | 148 1 2 4 5 6 7 7 9 10 11 94 | step 46: 95 | 147 1 3 4 5 6 6 8 9 10 11 96 | step 47: 97 | 146 2 3 4 5 5 7 8 9 10 11 98 | step 48: 99 | 145 1 2 3 4 4 6 7 8 9 10 11 100 | step 49: 101 | 144 1 2 3 3 5 6 7 8 9 10 12 102 | step 50: 103 | 143 1 2 2 4 5 6 7 8 9 11 12 104 | step 51: 105 | 142 1 1 3 4 5 6 7 8 10 11 12 106 | step 52: 107 | 141 2 3 4 5 6 7 9 10 11 12 108 | step 53: 109 | 140 1 2 3 4 5 6 8 9 10 11 11 110 | step 54: 111 | 139 1 2 3 4 5 7 8 9 10 10 12 112 | step 55: 113 | 138 1 2 3 4 6 7 8 9 9 11 12 114 | step 56: 115 | 137 1 2 3 5 6 7 8 8 10 11 12 116 | step 57: 117 | 136 1 2 4 5 6 7 7 9 10 11 12 118 | step 58: 119 | 135 1 3 4 5 6 6 8 9 10 11 12 120 | step 59: 121 | 134 2 3 4 5 5 7 8 9 10 11 12 122 | step 60: 123 | 133 1 2 3 4 4 6 7 8 9 10 11 12 124 | step 61: 125 | 132 1 2 3 3 5 6 7 8 9 10 11 13 126 | step 62: 127 | 131 1 2 2 4 5 6 7 8 9 10 12 13 128 | step 63: 129 | 130 1 1 3 4 5 6 7 8 9 11 12 13 130 | step 64: 131 | 129 2 3 4 5 6 7 8 10 11 12 13 132 | step 65: 133 | 128 1 2 3 4 5 6 7 9 10 11 12 12 134 | step 66: 135 | 127 1 2 3 4 5 6 8 9 10 11 11 13 136 | step 67: 137 | 126 1 2 3 4 5 7 8 9 10 10 12 13 138 | step 68: 139 | 125 1 2 3 4 6 7 8 9 9 11 12 13 140 | step 69: 141 | 124 1 2 3 5 6 7 8 8 10 11 12 13 142 | step 70: 143 | 123 1 2 4 5 6 7 7 9 10 11 12 13 144 | step 71: 145 | 122 1 3 4 5 6 6 8 9 10 11 12 13 146 | step 72: 147 | 121 2 3 4 5 5 7 8 9 10 11 12 13 148 | step 73: 149 | 120 1 2 3 4 4 6 7 8 9 10 11 12 13 150 | step 74: 151 | 119 1 2 3 3 5 6 7 8 9 10 11 12 14 152 | step 75: 153 | 118 1 2 2 4 5 6 7 8 9 10 11 13 14 154 | step 76: 155 | 117 1 1 3 4 5 6 7 8 9 10 12 13 14 156 | step 77: 157 | 116 2 3 4 5 6 7 8 9 11 12 13 14 158 | step 78: 159 | 115 1 2 3 4 5 6 7 8 10 11 12 13 13 160 | step 79: 161 | 114 1 2 3 4 5 6 7 9 10 11 12 12 14 162 | step 80: 163 | 113 1 2 3 4 5 6 8 9 10 11 11 13 14 164 | step 81: 165 | 112 1 2 3 4 5 7 8 9 10 10 12 13 14 166 | step 82: 167 | 111 1 2 3 4 6 7 8 9 9 11 12 13 14 168 | step 83: 169 | 110 1 2 3 5 6 7 8 8 10 11 12 13 14 170 | step 84: 171 | 109 1 2 4 5 6 7 7 9 10 11 12 13 14 172 | step 85: 173 | 108 1 3 4 5 6 6 8 9 10 11 12 13 14 174 | step 86: 175 | 107 2 3 4 5 5 7 8 9 10 11 12 13 14 176 | step 87: 177 | 106 1 2 3 4 4 6 7 8 9 10 11 12 13 14 178 | step 88: 179 | 105 1 2 3 3 5 6 7 8 9 10 11 12 13 15 180 | step 89: 181 | 104 1 2 2 4 5 6 7 8 9 10 11 12 14 15 182 | step 90: 183 | 103 1 1 3 4 5 6 7 8 9 10 11 13 14 15 184 | step 91: 185 | 102 2 3 4 5 6 7 8 9 10 12 13 14 15 186 | step 92: 187 | 101 1 2 3 4 5 6 7 8 9 11 12 13 14 14 188 | step 93: 189 | 100 1 2 3 4 5 6 7 8 10 11 12 13 13 15 190 | step 94: 191 | 99 1 2 3 4 5 6 7 9 10 11 12 12 14 15 192 | step 95: 193 | 98 1 2 3 4 5 6 8 9 10 11 11 13 14 15 194 | step 96: 195 | 97 1 2 3 4 5 7 8 9 10 10 12 13 14 15 196 | step 97: 197 | 96 1 2 3 4 6 7 8 9 9 11 12 13 14 15 198 | step 98: 199 | 95 1 2 3 5 6 7 8 8 10 11 12 13 14 15 200 | step 99: 201 | 94 1 2 4 5 6 7 7 9 10 11 12 13 14 15 202 | step 100: 203 | 93 1 3 4 5 6 6 8 9 10 11 12 13 14 15 204 | step 101: 205 | 92 2 3 4 5 5 7 8 9 10 11 12 13 14 15 206 | step 102: 207 | 91 1 2 3 4 4 6 7 8 9 10 11 12 13 14 15 208 | step 103: 209 | 90 1 2 3 3 5 6 7 8 9 10 11 12 13 14 16 210 | step 104: 211 | 89 1 2 2 4 5 6 7 8 9 10 11 12 13 15 16 212 | step 105: 213 | 88 1 1 3 4 5 6 7 8 9 10 11 12 14 15 16 214 | step 106: 215 | 87 2 3 4 5 6 7 8 9 10 11 13 14 15 16 216 | step 107: 217 | 86 1 2 3 4 5 6 7 8 9 10 12 13 14 15 15 218 | step 108: 219 | 85 1 2 3 4 5 6 7 8 9 11 12 13 14 14 16 220 | step 109: 221 | 84 1 2 3 4 5 6 7 8 10 11 12 13 13 15 16 222 | step 110: 223 | 83 1 2 3 4 5 6 7 9 10 11 12 12 14 15 16 224 | step 111: 225 | 82 1 2 3 4 5 6 8 9 10 11 11 13 14 15 16 226 | step 112: 227 | 81 1 2 3 4 5 7 8 9 10 10 12 13 14 15 16 228 | step 113: 229 | 80 1 2 3 4 6 7 8 9 9 11 12 13 14 15 16 230 | step 114: 231 | 79 1 2 3 5 6 7 8 8 10 11 12 13 14 15 16 232 | step 115: 233 | 78 1 2 4 5 6 7 7 9 10 11 12 13 14 15 16 234 | step 116: 235 | 77 1 3 4 5 6 6 8 9 10 11 12 13 14 15 16 236 | step 117: 237 | 76 2 3 4 5 5 7 8 9 10 11 12 13 14 15 16 238 | step 118: 239 | 75 1 2 3 4 4 6 7 8 9 10 11 12 13 14 15 16 240 | step 119: 241 | 74 1 2 3 3 5 6 7 8 9 10 11 12 13 14 15 17 242 | step 120: 243 | 73 1 2 2 4 5 6 7 8 9 10 11 12 13 14 16 17 244 | step 121: 245 | 72 1 1 3 4 5 6 7 8 9 10 11 12 13 15 16 17 246 | step 122: 247 | 71 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 248 | step 123: 249 | 70 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 16 250 | step 124: 251 | 69 1 2 3 4 5 6 7 8 9 10 12 13 14 15 15 17 252 | step 125: 253 | 68 1 2 3 4 5 6 7 8 9 11 12 13 14 14 16 17 254 | step 126: 255 | 67 1 2 3 4 5 6 7 8 10 11 12 13 13 15 16 17 256 | step 127: 257 | 66 1 2 3 4 5 6 7 9 10 11 12 12 14 15 16 17 258 | step 128: 259 | 65 1 2 3 4 5 6 8 9 10 11 11 13 14 15 16 17 260 | step 129: 261 | 64 1 2 3 4 5 7 8 9 10 10 12 13 14 15 16 17 262 | step 130: 263 | 63 1 2 3 4 6 7 8 9 9 11 12 13 14 15 16 17 264 | step 131: 265 | 62 1 2 3 5 6 7 8 8 10 11 12 13 14 15 16 17 266 | step 132: 267 | 61 1 2 4 5 6 7 7 9 10 11 12 13 14 15 16 17 268 | step 133: 269 | 60 1 3 4 5 6 6 8 9 10 11 12 13 14 15 16 17 270 | step 134: 271 | 59 2 3 4 5 5 7 8 9 10 11 12 13 14 15 16 17 272 | step 135: 273 | 58 1 2 3 4 4 6 7 8 9 10 11 12 13 14 15 16 17 274 | step 136: 275 | 57 1 2 3 3 5 6 7 8 9 10 11 12 13 14 15 16 18 276 | step 137: 277 | 56 1 2 2 4 5 6 7 8 9 10 11 12 13 14 15 17 18 278 | step 138: 279 | 55 1 1 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 280 | step 139: 281 | 54 2 3 4 5 6 7 8 9 10 11 12 13 15 16 17 18 282 | step 140: 283 | 53 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 17 284 | step 141: 285 | 52 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 16 18 286 | step 142: 287 | 51 1 2 3 4 5 6 7 8 9 10 12 13 14 15 15 17 18 288 | step 143: 289 | 50 1 2 3 4 5 6 7 8 9 11 12 13 14 14 16 17 18 290 | step 144: 291 | 49 1 2 3 4 5 6 7 8 10 11 12 13 13 15 16 17 18 292 | step 145: 293 | 48 1 2 3 4 5 6 7 9 10 11 12 12 14 15 16 17 18 294 | step 146: 295 | 47 1 2 3 4 5 6 8 9 10 11 11 13 14 15 16 17 18 296 | step 147: 297 | 46 1 2 3 4 5 7 8 9 10 10 12 13 14 15 16 17 18 298 | step 148: 299 | 45 1 2 3 4 6 7 8 9 9 11 12 13 14 15 16 17 18 300 | step 149: 301 | 44 1 2 3 5 6 7 8 8 10 11 12 13 14 15 16 17 18 302 | step 150: 303 | 43 1 2 4 5 6 7 7 9 10 11 12 13 14 15 16 17 18 304 | step 151: 305 | 42 1 3 4 5 6 6 8 9 10 11 12 13 14 15 16 17 18 306 | step 152: 307 | 41 2 3 4 5 5 7 8 9 10 11 12 13 14 15 16 17 18 308 | step 153: 309 | 40 1 2 3 4 4 6 7 8 9 10 11 12 13 14 15 16 17 18 310 | step 154: 311 | 39 1 2 3 3 5 6 7 8 9 10 11 12 13 14 15 16 17 19 312 | step 155: 313 | 38 1 2 2 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 314 | step 156: 315 | 37 1 1 3 4 5 6 7 8 9 10 11 12 13 14 15 17 18 19 316 | step 157: 317 | 36 2 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 318 | step 158: 319 | 35 1 2 3 4 5 6 7 8 9 10 11 12 13 15 16 17 18 18 320 | step 159: 321 | 34 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 17 19 322 | step 160: 323 | 33 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 16 18 19 324 | step 161: 325 | 32 1 2 3 4 5 6 7 8 9 10 12 13 14 15 15 17 18 19 326 | step 162: 327 | 31 1 2 3 4 5 6 7 8 9 11 12 13 14 14 16 17 18 19 328 | step 163: 329 | 30 1 2 3 4 5 6 7 8 10 11 12 13 13 15 16 17 18 19 330 | step 164: 331 | 29 1 2 3 4 5 6 7 9 10 11 12 12 14 15 16 17 18 19 332 | step 165: 333 | 28 1 2 3 4 5 6 8 9 10 11 11 13 14 15 16 17 18 19 334 | step 166: 335 | 27 1 2 3 4 5 7 8 9 10 10 12 13 14 15 16 17 18 19 336 | step 167: 337 | 26 1 2 3 4 6 7 8 9 9 11 12 13 14 15 16 17 18 19 338 | step 168: 339 | 25 1 2 3 5 6 7 8 8 10 11 12 13 14 15 16 17 18 19 340 | step 169: 341 | 24 1 2 4 5 6 7 7 9 10 11 12 13 14 15 16 17 18 19 342 | step 170: 343 | 23 1 3 4 5 6 6 8 9 10 11 12 13 14 15 16 17 18 19 344 | step 171: 345 | 22 2 3 4 5 5 7 8 9 10 11 12 13 14 15 16 17 18 19 346 | step 172: 347 | 21 1 2 3 4 4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 348 | step 173: 349 | 20 1 2 3 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 350 | step 174: 351 | 19 1 2 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 20 352 | step 175: 353 | 18 1 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 354 | step 176: 355 | 17 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 18 19 20 356 | step 177: 357 | 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 19 358 | step 178: 359 | 15 1 2 3 4 5 6 7 8 9 10 11 12 13 15 16 17 18 18 20 360 | step 179: 361 | 14 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 17 19 20 362 | step 180: 363 | 13 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 16 18 19 20 364 | step 181: 365 | 12 1 2 3 4 5 6 7 8 9 10 12 13 14 15 15 17 18 19 20 366 | step 182: 367 | 11 1 2 3 4 5 6 7 8 9 11 12 13 14 14 16 17 18 19 20 368 | step 183: 369 | 10 1 2 3 4 5 6 7 8 10 11 12 13 13 15 16 17 18 19 20 370 | step 184: 371 | 9 1 2 3 4 5 6 7 9 10 11 12 12 14 15 16 17 18 19 20 372 | step 185: 373 | 8 1 2 3 4 5 6 8 9 10 11 11 13 14 15 16 17 18 19 20 374 | step 186: 375 | 7 1 2 3 4 5 7 8 9 10 10 12 13 14 15 16 17 18 19 20 376 | step 187: 377 | 6 1 2 3 4 6 7 8 9 9 11 12 13 14 15 16 17 18 19 20 378 | step 188: 379 | 5 1 2 3 5 6 7 8 8 10 11 12 13 14 15 16 17 18 19 20 380 | step 189: 381 | 4 1 2 4 5 6 7 7 9 10 11 12 13 14 15 16 17 18 19 20 382 | step 190: 383 | 3 1 3 4 5 6 6 8 9 10 11 12 13 14 15 16 17 18 19 20 384 | step 191: 385 | 2 2 3 4 5 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 386 | step 192: 387 | 1 1 2 3 4 4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 388 | step 193: 389 | 1 2 3 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 21 390 | step 194: 391 | 1 2 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 20 392 | step 195: 393 | 1 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 19 20 394 | step 196: 395 | 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 18 19 20 396 | step 197: 397 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 17 18 19 19 398 | step 198: 399 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 16 17 18 18 20 400 | step 199: 401 | 1 2 3 4 5 6 7 8 9 10 11 12 13 15 15 16 17 17 19 20 402 | step 200: 403 | 1 2 3 4 5 6 7 8 9 10 11 12 14 14 15 16 16 18 19 20 404 | step 201: 405 | 1 2 3 4 5 6 7 8 9 10 11 13 13 14 15 15 17 18 19 20 406 | step 202: 407 | 1 2 3 4 5 6 7 8 9 10 12 12 13 14 14 16 17 18 19 20 408 | step 203: 409 | 1 2 3 4 5 6 7 8 9 11 11 12 13 13 15 16 17 18 19 20 410 | step 204: 411 | 1 2 3 4 5 6 7 8 10 10 11 12 12 14 15 16 17 18 19 20 412 | step 205: 413 | 1 2 3 4 5 6 7 9 9 10 11 11 13 14 15 16 17 18 19 20 414 | step 206: 415 | 1 2 3 4 5 6 8 8 9 10 10 12 13 14 15 16 17 18 19 20 416 | step 207: 417 | 1 2 3 4 5 7 7 8 9 9 11 12 13 14 15 16 17 18 19 20 418 | step 208: 419 | 1 2 3 4 6 6 7 8 8 10 11 12 13 14 15 16 17 18 19 20 420 | step 209: 421 | 1 2 3 5 5 6 7 7 9 10 11 12 13 14 15 16 17 18 19 20 422 | step 210: 423 | 1 2 4 4 5 6 6 8 9 10 11 12 13 14 15 16 17 18 19 20 424 | step 211: 425 | 1 3 3 4 5 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 426 | step 212: 427 | 2 2 3 4 4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 428 | step 213: 429 | 1 1 2 3 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 430 | step 214: 431 | 1 2 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 21 432 | step 215: 433 | 1 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 20 434 | step 216: 435 | 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 19 20 436 | step 217: 437 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 18 19 19 438 | step 218: 439 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 17 18 18 20 440 | step 219: 441 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 16 17 17 19 20 442 | step 220: 443 | 1 2 3 4 5 6 7 8 9 10 11 12 13 15 15 16 16 18 19 20 444 | step 221: 445 | 1 2 3 4 5 6 7 8 9 10 11 12 14 14 15 15 17 18 19 20 446 | step 222: 447 | 1 2 3 4 5 6 7 8 9 10 11 13 13 14 14 16 17 18 19 20 448 | step 223: 449 | 1 2 3 4 5 6 7 8 9 10 12 12 13 13 15 16 17 18 19 20 450 | step 224: 451 | 1 2 3 4 5 6 7 8 9 11 11 12 12 14 15 16 17 18 19 20 452 | step 225: 453 | 1 2 3 4 5 6 7 8 10 10 11 11 13 14 15 16 17 18 19 20 454 | step 226: 455 | 1 2 3 4 5 6 7 9 9 10 10 12 13 14 15 16 17 18 19 20 456 | step 227: 457 | 1 2 3 4 5 6 8 8 9 9 11 12 13 14 15 16 17 18 19 20 458 | step 228: 459 | 1 2 3 4 5 7 7 8 8 10 11 12 13 14 15 16 17 18 19 20 460 | step 229: 461 | 1 2 3 4 6 6 7 7 9 10 11 12 13 14 15 16 17 18 19 20 462 | step 230: 463 | 1 2 3 5 5 6 6 8 9 10 11 12 13 14 15 16 17 18 19 20 464 | step 231: 465 | 1 2 4 4 5 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 466 | step 232: 467 | 1 3 3 4 4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 468 | step 233: 469 | 2 2 3 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 470 | step 234: 471 | 1 1 2 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 472 | step 235: 473 | 1 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 21 474 | step 236: 475 | 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 20 476 | step 237: 477 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 19 19 478 | step 238: 479 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 18 18 20 480 | step 239: 481 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 17 17 19 20 482 | step 240: 483 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 16 16 18 19 20 484 | step 241: 485 | 1 2 3 4 5 6 7 8 9 10 11 12 13 15 15 15 17 18 19 20 486 | step 242: 487 | 1 2 3 4 5 6 7 8 9 10 11 12 14 14 14 16 17 18 19 20 488 | step 243: 489 | 1 2 3 4 5 6 7 8 9 10 11 13 13 13 15 16 17 18 19 20 490 | step 244: 491 | 1 2 3 4 5 6 7 8 9 10 12 12 12 14 15 16 17 18 19 20 492 | step 245: 493 | 1 2 3 4 5 6 7 8 9 11 11 11 13 14 15 16 17 18 19 20 494 | step 246: 495 | 1 2 3 4 5 6 7 8 10 10 10 12 13 14 15 16 17 18 19 20 496 | step 247: 497 | 1 2 3 4 5 6 7 9 9 9 11 12 13 14 15 16 17 18 19 20 498 | step 248: 499 | 1 2 3 4 5 6 8 8 8 10 11 12 13 14 15 16 17 18 19 20 500 | step 249: 501 | 1 2 3 4 5 7 7 7 9 10 11 12 13 14 15 16 17 18 19 20 502 | step 250: 503 | 1 2 3 4 6 6 6 8 9 10 11 12 13 14 15 16 17 18 19 20 504 | step 251: 505 | 1 2 3 5 5 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 506 | step 252: 507 | 1 2 4 4 4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 508 | step 253: 509 | 1 3 3 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 510 | step 254: 511 | 2 2 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 512 | step 255: 513 | 1 1 1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 514 | step 256: 515 | 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 21 516 | step 257: 517 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 19 518 | Total: 257 step(s) 519 | -------------------------------------------------------------------------------- /test_tool/testcase/bulgarian.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | // Target: Simulate a Bulgarian-solitaire game. 3 | // Possible opitimization: Dead code elimination, common expression, inline function, loop unrolling, etc. 4 | // REMARKS: A funny game. If you like, you can try to prove that when n=1+2+..+i(i>0), the game will always stop 5 | // and converge to the only solution: {1,2,...i}. :) 6 | 7 | int n; 8 | int h; 9 | int now; 10 | int a[100]; 11 | int A = 48271; 12 | int M = 2147483647; 13 | int Q; 14 | int R; 15 | int seed=1; 16 | int random() { 17 | int tempseed = A * (seed % Q) - R * (seed / Q); 18 | if (tempseed >= 0) 19 | seed = tempseed; 20 | else 21 | seed = tempseed + M; 22 | return seed; 23 | } 24 | void initialize(int val) { 25 | seed = val; 26 | } 27 | void swap(int x,int y) { 28 | int temp = a[x]; 29 | a[x] = a[y]; 30 | a[y] = temp; 31 | } 32 | int pd(int x) { 33 | for (;h <= x; ++h) 34 | if (x == h * (h + 1) / 2) 35 | return 1; 36 | return 0; 37 | } 38 | void show() { 39 | int i; 40 | for (i = 0; i < now; ++i){ 41 | outl(a[i]); 42 | sleep(1); 43 | print(" "); 44 | } 45 | println(""); 46 | } 47 | int win() 48 | { 49 | int i; 50 | int j; 51 | int b[100]; 52 | int temp; 53 | if (now != h) 54 | return 0; 55 | for (j = 0; j < now; ++j) 56 | b[j] = a[j]; 57 | for (i = 0;i < now - 1; ++i) 58 | for (j = i + 1;j < now; ++j) 59 | if (b[i] > b[j]) { 60 | temp = b[i]; 61 | b[i] = b[j]; 62 | b[j] = temp; 63 | } 64 | for (i = 0; i < now; ++i) 65 | if (b[i] != i + 1) 66 | return 0; 67 | return 1; 68 | } 69 | void merge() 70 | { 71 | int i; 72 | for (i = 0;i < now; ++i) 73 | if (a[i] == 0) { 74 | int j; 75 | for (j = i+1; j < now; ++j) 76 | if (a[j] != 0) { 77 | swap(i,j); 78 | break; 79 | } 80 | } 81 | for (i=0;i n) 116 | a[i] = random() % 10 + 1; 117 | temp = temp + a[i]; 118 | } 119 | a[now - 1] = n - temp; 120 | show(); 121 | merge(); 122 | while (!win()) { 123 | print("step "); 124 | outl(++count); 125 | println(":"); 126 | move(); 127 | merge(); 128 | show(); 129 | sleep(10); // to prevent UART buffer from overflowing 130 | } 131 | print("Total: "); 132 | outl(count); 133 | println(" step(s)"); 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /test_tool/testcase/bulgarian.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | // Target: Simulate a Bulgarian-solitaire game. 3 | // Possible opitimization: Dead code elimination, common expression, inline function, loop unrolling, etc. 4 | // REMARKS: A funny game. If you like, you can try to prove that when n=1+2+..+i(i>0), the game will always stop 5 | // and converge to the only solution: {1,2,...i}. :) 6 | 7 | int n; 8 | int h; 9 | int now; 10 | int a[100]; 11 | int A = 48271; 12 | int M = 2147483647; 13 | int Q; 14 | int R; 15 | int seed=1; 16 | int random() { 17 | int tempseed = A * (seed % Q) - R * (seed / Q); 18 | if (tempseed >= 0) 19 | seed = tempseed; 20 | else 21 | seed = tempseed + M; 22 | return seed; 23 | } 24 | void initialize(int val) { 25 | seed = val; 26 | } 27 | void swap(int x,int y) { 28 | int temp = a[x]; 29 | a[x] = a[y]; 30 | a[y] = temp; 31 | } 32 | int pd(int x) { 33 | for (;h <= x; ++h) 34 | if (x == h * (h + 1) / 2) 35 | return 1; 36 | return 0; 37 | } 38 | void show() { 39 | int i; 40 | for (i = 0; i < now; ++i){ 41 | outl(a[i]); 42 | print(" "); 43 | } 44 | println(""); 45 | } 46 | int win() 47 | { 48 | int i; 49 | int j; 50 | int b[100]; 51 | int temp; 52 | if (now != h) 53 | return 0; 54 | for (j = 0; j < now; ++j) 55 | b[j] = a[j]; 56 | for (i = 0;i < now - 1; ++i) 57 | for (j = i + 1;j < now; ++j) 58 | if (b[i] > b[j]) { 59 | temp = b[i]; 60 | b[i] = b[j]; 61 | b[j] = temp; 62 | } 63 | for (i = 0; i < now; ++i) 64 | if (b[i] != i + 1) 65 | return 0; 66 | return 1; 67 | } 68 | void merge() 69 | { 70 | int i; 71 | for (i = 0;i < now; ++i) 72 | if (a[i] == 0) { 73 | int j; 74 | for (j = i+1; j < now; ++j) 75 | if (a[j] != 0) { 76 | swap(i,j); 77 | break; 78 | } 79 | } 80 | for (i=0;i n) 115 | a[i] = random() % 10 + 1; 116 | temp = temp + a[i]; 117 | } 118 | a[now - 1] = n - temp; 119 | show(); 120 | merge(); 121 | while (!win()) { 122 | print("step "); 123 | outl(++count); 124 | println(":"); 125 | move(); 126 | merge(); 127 | show(); 128 | //sleep(10); // to prevent UART buffer from overflowing 129 | } 130 | print("Total: "); 131 | outl(count); 132 | println(" step(s)"); 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /test_tool/testcase/expr.ans: -------------------------------------------------------------------------------- 1 | -66060719 -323398799 -743275679 2 | -------------------------------------------------------------------------------- /test_tool/testcase/expr.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | //This file use massive recursive expression to test: Common Expression substitution. 3 | //For my optimized version: All: 1397 Load: 86 Store: 55 Jumped: 23 4 | //For my unoptimized version: All: 24519 Load: 12183 Store: 55 Jumped: 23 5 | //A better result is welcomed. ------ From JinTianxing. 6 | 7 | int A = 1; 8 | int B = 1; 9 | int C = 1; 10 | 11 | int main(){ 12 | while (C < (1 << 29) && C > -(1 << 29)){ 13 | A = ((((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))))) - (((((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B)))) + (((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))))))); 14 | B = ((((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))))) - (((((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B)))) + (((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))))))); 15 | C = ((((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))))) - (((((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B)))) + (((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))))))); 16 | } 17 | outl(A); 18 | print(" "); 19 | outl(B); 20 | print(" "); 21 | outlln(C); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test_tool/testcase/expr.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | //This file use massive recursive expression to test: Common Expression substitution. 3 | //For my optimized version: All: 1397 Load: 86 Store: 55 Jumped: 23 4 | //For my unoptimized version: All: 24519 Load: 12183 Store: 55 Jumped: 23 5 | //A better result is welcomed. ------ From JinTianxing. 6 | 7 | int A = 1; 8 | int B = 1; 9 | int C = 1; 10 | 11 | int main(){ 12 | while (C < (1 << 29) && C > -(1 << 29)){ 13 | A = ((((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))))) - (((((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B)))) + (((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))))))); 14 | B = ((((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))))) - (((((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B)))) + (((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))))))); 15 | C = ((((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))))) - (((((((A + B) + (C - A + B)) - ((A + B) + (C - A + B))) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B)))) + (((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))) + ((((C - A + B) - (A + B)) + (C - A + B)) - (((A + B) + (C - A + B)) - (A + B))))) + ((((((C - A + B) - (A + B)) + ((C - A + B) - (A + B))) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B)))) - (((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))) - ((((A + B) + (C - A + B)) - (A + B)) + (((C - A + B) - (A + B)) + (C - A + B))))))); 16 | } 17 | outl(A); 18 | print(" "); 19 | outl(B); 20 | print(" "); 21 | outlln(C); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test_tool/testcase/gcd.ans: -------------------------------------------------------------------------------- 1 | 1 2 | 1029 3 | 171 4 | -------------------------------------------------------------------------------- /test_tool/testcase/gcd.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int gcd(int x, int y) { 3 | if (x%y == 0) return y; 4 | else return gcd(y, x%y); 5 | } 6 | 7 | int main() { 8 | outlln(gcd(10,1)); 9 | outlln(gcd(34986,3087)); 10 | outlln(gcd(2907,1539)); 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test_tool/testcase/gcd.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int gcd(int x, int y) { 3 | if (x%y == 0) return y; 4 | else return gcd(y, x%y); 5 | } 6 | 7 | int main() { 8 | outlln(gcd(10,1)); 9 | outlln(gcd(34986,3087)); 10 | outlln(gcd(2907,1539)); 11 | 12 | return 0; 13 | } -------------------------------------------------------------------------------- /test_tool/testcase/hanoi.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int cd(int d, char* a, char* b, char* c, int sum) { 3 | sleep(5); // to prevent UART buffer from overflowing 4 | if (d == 1) { 5 | print("move "); 6 | print(a); 7 | print(" --> "); 8 | println(c); 9 | sum++; 10 | } else { 11 | sum = cd(d - 1, a, c, b, sum); 12 | print("move "); 13 | print(a); 14 | print(" --> "); 15 | println(c); 16 | sum = cd(d - 1, b, a, c, sum); 17 | sum++; 18 | } 19 | return sum; 20 | } 21 | 22 | int main() { 23 | char a[5] = "A"; 24 | char b[5] = "B"; 25 | char c[5] = "C"; 26 | int d = inl(); 27 | int sum = cd(d, a, b, c, 0); 28 | outlln(sum); 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /test_tool/testcase/hanoi.in: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /test_tool/testcase/love.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | float f(float x, float y, float z) { 4 | float a = x * x + 9.0f / 4.0f * y * y + z * z - 1; 5 | return a * a * a - x * x * z * z * z - 9.0f / 80.0f * y * y * z * z * z; 6 | } 7 | 8 | float h(float x, float z) { 9 | for (float y = 1.0f; y >= 0.0f; y -= 0.001f) 10 | if (f(x, y, z) <= 0.0f) 11 | return y; 12 | return 0.0f; 13 | } 14 | 15 | float mysqrt(float x) { 16 | if (x == 0) return 0; 17 | int i; 18 | double v = x / 2; 19 | for (i = 0; i < 50; ++i) 20 | v = (v + x / v)/2; 21 | 22 | return v; 23 | } 24 | 25 | int main() { 26 | for (float z = 1.5f; z > -1.5f; z -= 0.05f) { 27 | for (float x = -1.5f; x < 1.5f; x += 0.025f) { 28 | float v = f(x, 0.0f, z); 29 | if (v <= 0.0f) { 30 | float y0 = h(x, z); 31 | float ny = 0.01f; 32 | float nx = h(x + ny, z) - y0; 33 | float nz = h(x, z + ny) - y0; 34 | float nd = 1.0f / mysqrt(nx * nx + ny * ny + nz * nz); 35 | float d = (nx + ny - nz) * nd * 0.5f + 0.5f; 36 | int index = (int)(d * 5.0f); 37 | outb(".:-=+*#%@"[index]); 38 | } 39 | else 40 | outb('_'); 41 | //sleep(1); 42 | } 43 | outb('\n'); 44 | } 45 | } 46 | //_______________________________ 47 | //_______________________________ 48 | -------------------------------------------------------------------------------- /test_tool/testcase/love.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | float f(float x, float y, float z) { 4 | float a = x * x + 9.0f / 4.0f * y * y + z * z - 1; 5 | return a * a * a - x * x * z * z * z - 9.0f / 80.0f * y * y * z * z * z; 6 | } 7 | 8 | float h(float x, float z) { 9 | for (float y = 1.0f; y >= 0.0f; y -= 0.001f) 10 | if (f(x, y, z) <= 0.0f) 11 | return y; 12 | return 0.0f; 13 | } 14 | 15 | float mysqrt(float x) { 16 | if (x == 0) return 0; 17 | int i; 18 | double v = x / 2; 19 | for (i = 0; i < 50; ++i) 20 | v = (v + x / v)/2; 21 | 22 | return v; 23 | } 24 | 25 | int main() { 26 | for (float z = 1.5f; z > -1.5f; z -= 0.05f) { 27 | for (float x = -1.5f; x < 1.5f; x += 0.025f) { 28 | float v = f(x, 0.0f, z); 29 | if (v <= 0.0f) { 30 | float y0 = h(x, z); 31 | float ny = 0.01f; 32 | float nx = h(x + ny, z) - y0; 33 | float nz = h(x, z + ny) - y0; 34 | float nd = 1.0f / mysqrt(nx * nx + ny * ny + nz * nz); 35 | float d = (nx + ny - nz) * nd * 0.5f + 0.5f; 36 | int index = (int)(d * 5.0f); 37 | outb(".:-=+*#%@"[index]); 38 | } 39 | else 40 | outb('_'); 41 | //sleep(1); 42 | } 43 | outb('\n'); 44 | } 45 | } 46 | //_______________________________ 47 | //_______________________________ 48 | -------------------------------------------------------------------------------- /test_tool/testcase/lvalue2.ans: -------------------------------------------------------------------------------- 1 | 2 2 | -------------------------------------------------------------------------------- /test_tool/testcase/lvalue2.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int a[4]; 3 | int main() 4 | { 5 | int b[4]; 6 | b[2]=2; 7 | int *p; 8 | p=b; 9 | outlln(p[2]); 10 | } 11 | -------------------------------------------------------------------------------- /test_tool/testcase/lvalue2.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int a[4]; 3 | int main() 4 | { 5 | int b[4]; 6 | b[2]=2; 7 | int *p; 8 | p=b; 9 | outlln(p[2]); 10 | } 11 | -------------------------------------------------------------------------------- /test_tool/testcase/magic.ans: -------------------------------------------------------------------------------- 1 | 2 7 6 2 | 9 5 1 3 | 4 3 8 4 | 5 | 2 9 4 6 | 7 5 3 7 | 6 1 8 8 | 9 | 4 3 8 10 | 9 5 1 11 | 2 7 6 12 | 13 | 4 9 2 14 | 3 5 7 15 | 8 1 6 16 | 17 | 6 1 8 18 | 7 5 3 19 | 2 9 4 20 | 21 | 6 7 2 22 | 1 5 9 23 | 8 3 4 24 | 25 | 8 1 6 26 | 3 5 7 27 | 4 9 2 28 | 29 | 8 3 4 30 | 1 5 9 31 | 6 7 2 32 | 33 | 8 34 | -------------------------------------------------------------------------------- /test_tool/testcase/magic.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int make[3][3]; 3 | int color[10]; 4 | int count[1]; 5 | int i; 6 | int j; 7 | 8 | void origin(int N) 9 | { 10 | for (i = 0; i < N; i ++ ) { 11 | for (j = 0; j < N; j ++ ) 12 | make[i][j] = 0; 13 | } 14 | } 15 | 16 | void search(int x, int y, int z) 17 | { 18 | int s; 19 | int i; 20 | int j; 21 | if ((y > 0 || y < 0) || x == 0 || make[x-1][0] + make[x-1][1] + make[x-1][2] == 15) 22 | { 23 | if (x == 2 && y == 2) { 24 | make[2][2] = 45 - z; 25 | s = make[0][0] + make[0][1] + make[0][2]; 26 | if (make[1][0] + make[1][1] + make[1][2] == s && 27 | make[2][0] + make[2][1] + make[2][2] == s && 28 | make[0][0] + make[1][0] + make[2][0] == s && 29 | make[0][1] + make[1][1] + make[2][1] == s && 30 | make[0][2] + make[1][2] + make[2][2] == s && 31 | make[0][0] + make[1][1] + make[2][2] == s && 32 | make[2][0] + make[1][1] + make[0][2] == s) 33 | { 34 | count[0] = count[0] + 1; 35 | for (i = 0;i <= 2;i ++) 36 | { 37 | for (j = 0;j <= 2;j ++) 38 | { 39 | outl(make[i][j]); 40 | print(" "); 41 | } 42 | print("\n"); 43 | } 44 | print("\n"); 45 | } 46 | } 47 | else { 48 | if (y == 2) { 49 | make[x][y] = 15 - make[x][0] - make[x][1]; 50 | if (make[x][y] > 0 && make[x][y] < 10 && color[make[x][y]] == 0) { 51 | color[make[x][y]] = 1; 52 | if (y == 2) 53 | search(x + 1, 0, z+make[x][y]); 54 | else 55 | search(x, y+1, z+make[x][y]); 56 | color[make[x][y]] = 0; 57 | } 58 | } 59 | else { 60 | for (i = 1;i <= 9;i ++) { 61 | if (color[i] == 0) { 62 | color[i] = 1; 63 | make[x][y] = i; 64 | if (y == 2) 65 | search(x + 1, 0, z+i); 66 | else 67 | search(x, y+1, z+i); 68 | make[x][y] = 0; 69 | color[i] = 0; 70 | } 71 | } 72 | } 73 | } 74 | } 75 | } 76 | int main() 77 | { 78 | origin(3); 79 | search(0, 0, 0); 80 | outlln(count[0]); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /test_tool/testcase/magic.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int make[3][3]; 3 | int color[10]; 4 | int count[1]; 5 | int i; 6 | int j; 7 | 8 | void origin(int N) 9 | { 10 | for (i = 0; i < N; i ++ ) { 11 | for (j = 0; j < N; j ++ ) 12 | make[i][j] = 0; 13 | } 14 | } 15 | 16 | void search(int x, int y, int z) 17 | { 18 | int s; 19 | int i; 20 | int j; 21 | if ((y > 0 || y < 0) || x == 0 || make[x-1][0] + make[x-1][1] + make[x-1][2] == 15) 22 | { 23 | if (x == 2 && y == 2) { 24 | make[2][2] = 45 - z; 25 | s = make[0][0] + make[0][1] + make[0][2]; 26 | if (make[1][0] + make[1][1] + make[1][2] == s && 27 | make[2][0] + make[2][1] + make[2][2] == s && 28 | make[0][0] + make[1][0] + make[2][0] == s && 29 | make[0][1] + make[1][1] + make[2][1] == s && 30 | make[0][2] + make[1][2] + make[2][2] == s && 31 | make[0][0] + make[1][1] + make[2][2] == s && 32 | make[2][0] + make[1][1] + make[0][2] == s) 33 | { 34 | count[0] = count[0] + 1; 35 | for (i = 0;i <= 2;i ++) 36 | { 37 | for (j = 0;j <= 2;j ++) 38 | { 39 | outl(make[i][j]); 40 | print(" "); 41 | } 42 | print("\n"); 43 | } 44 | print("\n"); 45 | } 46 | } 47 | else { 48 | if (y == 2) { 49 | make[x][y] = 15 - make[x][0] - make[x][1]; 50 | if (make[x][y] > 0 && make[x][y] < 10 && color[make[x][y]] == 0) { 51 | color[make[x][y]] = 1; 52 | if (y == 2) 53 | search(x + 1, 0, z+make[x][y]); 54 | else 55 | search(x, y+1, z+make[x][y]); 56 | color[make[x][y]] = 0; 57 | } 58 | } 59 | else { 60 | for (i = 1;i <= 9;i ++) { 61 | if (color[i] == 0) { 62 | color[i] = 1; 63 | make[x][y] = i; 64 | if (y == 2) 65 | search(x + 1, 0, z+i); 66 | else 67 | search(x, y+1, z+i); 68 | make[x][y] = 0; 69 | color[i] = 0; 70 | } 71 | } 72 | } 73 | } 74 | } 75 | } 76 | int main() 77 | { 78 | origin(3); 79 | search(0, 0, 0); 80 | outlln(count[0]); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /test_tool/testcase/manyarguments.ans: -------------------------------------------------------------------------------- 1 | 120 2 | -------------------------------------------------------------------------------- /test_tool/testcase/manyarguments.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int a(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15) 3 | { 4 | return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15; 5 | } 6 | 7 | int main() 8 | { 9 | outlln(a(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test_tool/testcase/manyarguments.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int a(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15) 3 | { 4 | return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + a13 + a14 + a15; 5 | } 6 | 7 | int main() 8 | { 9 | outlln(a(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test_tool/testcase/multiarray.ans: -------------------------------------------------------------------------------- 1 | 888 2 | 0 3 | 1 4 | 2 5 | 3 6 | 4 7 | 5 8 | 6 9 | 7 10 | 8 11 | 9 12 | 10 13 | 11 14 | 12 15 | 13 16 | 14 17 | 15 18 | 16 19 | 17 20 | 18 21 | 19 22 | 20 23 | 21 24 | 22 25 | 23 26 | 24 27 | 25 28 | 26 29 | 27 30 | 28 31 | 29 32 | 30 33 | 31 34 | 32 35 | 33 36 | 34 37 | 35 38 | 36 39 | 37 40 | 38 41 | 39 42 | 0 43 | -10 44 | -1 45 | -------------------------------------------------------------------------------- /test_tool/testcase/multiarray.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int a[4][11]; 3 | int i; 4 | int j; 5 | 6 | struct rec { 7 | int num; 8 | int c; 9 | }b[5]; 10 | 11 | void printNum(int num) { 12 | outlln(num); 13 | } 14 | int main() { 15 | 16 | 17 | for (i = 0; i < 4; i ++) { 18 | for (j = 0; j < 10; j ++) 19 | a[i][j] = 888; 20 | } 21 | for (i = 0; i < 5; i ++) { 22 | b[i].num = -1; 23 | } 24 | 25 | printNum(a[3][9]); 26 | for (i = 0; i <= 3; i ++) 27 | for (j = 0; j <= 9; j ++) 28 | a[i][j] = i * 10 + j; 29 | 30 | for (i = 0; i <= 3; i ++) 31 | for (j = 0; j <= 9; j ++) 32 | printNum(a[i][j]); 33 | a[2][10]=0; 34 | printNum(a[2][10]); 35 | b[0].num = -2; 36 | b[a[2][10]].num = -10; 37 | printNum(b[0].num); 38 | printNum(b[1].num); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /test_tool/testcase/multiarray.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int a[4][11]; 3 | int i; 4 | int j; 5 | 6 | struct rec { 7 | int num; 8 | int c; 9 | }b[5]; 10 | 11 | void printNum(int num) { 12 | outlln(num); 13 | } 14 | int main() { 15 | 16 | 17 | for (i = 0; i < 4; i ++) { 18 | for (j = 0; j < 10; j ++) 19 | a[i][j] = 888; 20 | } 21 | for (i = 0; i < 5; i ++) { 22 | b[i].num = -1; 23 | } 24 | 25 | printNum(a[3][9]); 26 | for (i = 0; i <= 3; i ++) 27 | for (j = 0; j <= 9; j ++) 28 | a[i][j] = i * 10 + j; 29 | 30 | for (i = 0; i <= 3; i ++) 31 | for (j = 0; j <= 9; j ++) 32 | printNum(a[i][j]); 33 | a[2][10]=0; 34 | printNum(a[2][10]); 35 | b[0].num = -2; 36 | b[a[2][10]].num = -10; 37 | printNum(b[0].num); 38 | printNum(b[1].num); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /test_tool/testcase/pi.ans: -------------------------------------------------------------------------------- 1 | 3141592653589793238462643383279528841971693993751058209749445923078164062862089986280348253421170679821480865132823664709384469555822317253594081284811174502841270193852115559644622948954930381964428810975665933446128475648233786783165271201991456485669234634861045432664821339360726024914127372458706606315588174881520920962829254917153643678925903611330530548820466521384146951941511609433057273657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566438602139494639522473719070217986943702770539217176293176752384674818467669451320005681271452635608277857713427577896091736371787214684409012249534301465495853710579227968925892354201995611212902196864344181598136297747713099605187072113499999983729780499510597317328160963185 2 | -------------------------------------------------------------------------------- /test_tool/testcase/pi.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int f[2801]; 3 | int main() { 4 | int a = 10000; 5 | int b = 0; 6 | int c = 2800; 7 | int d = 0; 8 | int e = 0; 9 | int g = 0; 10 | 11 | for (;b-c!=0;) 12 | f[b++] = a/5; 13 | for (;; e = d%a){ 14 | d = 0; 15 | g = c*2; 16 | if (g==0) break; 17 | 18 | for (b=c;;d=d*b){ 19 | d=d+f[b]*a; 20 | f[b] = d%--g; 21 | d=d/g--; 22 | if (--b==0) break; 23 | } 24 | 25 | c = c-14; 26 | outl(e+d/a); 27 | } 28 | 29 | print("\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /test_tool/testcase/pi.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int f[2801]; 3 | int main() { 4 | int a = 1000; 5 | int b = 0; 6 | int c = 280; 7 | int d = 0; 8 | int e = 0; 9 | int g = 0; 10 | 11 | for (;b-c!=0;) 12 | f[b++] = a/5; 13 | for (;; e = d%a){ 14 | d = 0; 15 | g = c*2; 16 | if (g==0) break; 17 | 18 | for (b=c;;d=d*b){ 19 | d=d+f[b]*a; 20 | f[b] = d%--g; 21 | d=d/g--; 22 | if (--b==0) break; 23 | } 24 | 25 | c = c-14; 26 | outl(e+d/a); 27 | } 28 | 29 | print("\n"); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /test_tool/testcase/print_hello.ans: -------------------------------------------------------------------------------- 1 | 32768 2 | -------------------------------------------------------------------------------- /test_tool/testcase/print_hello.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | int f(int x, int y) { 4 | //outl(x); print(" "); 5 | //outl(y); print("\n"); 6 | if (y == 1) return x; 7 | if (y == 0) return 1; 8 | return f(x, y / 2) * f(x, (y + 1) / 2); 9 | } 10 | 11 | int main() { 12 | outl(f(2, 15)); 13 | } -------------------------------------------------------------------------------- /test_tool/testcase/print_hello.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | int f(int x, int y) { 4 | //outl(x); print(" "); 5 | //outl(y); print("\n"); 6 | if (y == 1) return x; 7 | if (y == 0) return 1; 8 | return f(x, y / 2) * f(x, (y + 1) / 2); 9 | } 10 | 11 | int main() { 12 | outl(f(2, 15)); 13 | } -------------------------------------------------------------------------------- /test_tool/testcase/qsort.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | // Target: qsort 3 | // Possible optimization: Dead code elimination, common expression, strength reduction 4 | // REMARKS: nothing. 5 | // 6 | // 7 | 8 | //int a[10100]; 9 | int a[10100]; 10 | int n = 10000; 11 | 12 | int qsrt(int l, int r) { 13 | int i = l; 14 | int j = r; 15 | int x = a[(l + r) / 2]; 16 | while (i <= j) { 17 | while (a[i] < x) i++; 18 | while (a[j] > x) j--; 19 | if (i <= j) { 20 | int temp = a[i]; 21 | a[i] = a[j]; 22 | a[j] = temp; 23 | i++; 24 | j--; 25 | } 26 | } 27 | if (l < j) qsrt(l, j); 28 | if (i < r) qsrt(i, r); 29 | return 0; 30 | } 31 | 32 | int main() { 33 | int i; 34 | for (i = 1; i <= n; i++) 35 | a[i] = n + 1 - i; 36 | qsrt(1, n); 37 | for (i = 1; i <= n; i++) { 38 | outl(a[i]); 39 | print(" "); 40 | sleep(2); // to prevent UART buffer from overflowing 41 | } 42 | print("\n"); 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /test_tool/testcase/qsort.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | // Target: qsort 3 | // Possible optimization: Dead code elimination, common expression, strength reduction 4 | // REMARKS: nothing. 5 | // 6 | // 7 | 8 | //int a[10100]; 9 | int a[1010]; 10 | int n = 1000; 11 | 12 | int qsrt(int l, int r) { 13 | int i = l; 14 | int j = r; 15 | int x = a[(l + r) / 2]; 16 | while (i <= j) { 17 | while (a[i] < x) i++; 18 | while (a[j] > x) j--; 19 | if (i <= j) { 20 | int temp = a[i]; 21 | a[i] = a[j]; 22 | a[j] = temp; 23 | i++; 24 | j--; 25 | } 26 | } 27 | if (l < j) qsrt(l, j); 28 | if (i < r) qsrt(i, r); 29 | return 0; 30 | } 31 | 32 | int main() { 33 | int i; 34 | for (i = 1; i <= n; i++) 35 | a[i] = n + 1 - i; 36 | qsrt(1, n); 37 | for (i = 1; i <= n; i++) { 38 | outl(a[i]); 39 | print(" "); 40 | //sleep(1); // to prevent UART buffer from overflowing 41 | } 42 | print("\n"); 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /test_tool/testcase/queens.ans: -------------------------------------------------------------------------------- 1 | O . . . . . . . 2 | . . . . O . . . 3 | . . . . . . . O 4 | . . . . . O . . 5 | . . O . . . . . 6 | . . . . . . O . 7 | . O . . . . . . 8 | . . . O . . . . 9 | 10 | O . . . . . . . 11 | . . . . . O . . 12 | . . . . . . . O 13 | . . O . . . . . 14 | . . . . . . O . 15 | . . . O . . . . 16 | . O . . . . . . 17 | . . . . O . . . 18 | 19 | O . . . . . . . 20 | . . . . . . O . 21 | . . . O . . . . 22 | . . . . . O . . 23 | . . . . . . . O 24 | . O . . . . . . 25 | . . . . O . . . 26 | . . O . . . . . 27 | 28 | O . . . . . . . 29 | . . . . . . O . 30 | . . . . O . . . 31 | . . . . . . . O 32 | . O . . . . . . 33 | . . . O . . . . 34 | . . . . . O . . 35 | . . O . . . . . 36 | 37 | . O . . . . . . 38 | . . . O . . . . 39 | . . . . . O . . 40 | . . . . . . . O 41 | . . O . . . . . 42 | O . . . . . . . 43 | . . . . . . O . 44 | . . . . O . . . 45 | 46 | . O . . . . . . 47 | . . . . O . . . 48 | . . . . . . O . 49 | O . . . . . . . 50 | . . O . . . . . 51 | . . . . . . . O 52 | . . . . . O . . 53 | . . . O . . . . 54 | 55 | . O . . . . . . 56 | . . . . O . . . 57 | . . . . . . O . 58 | . . . O . . . . 59 | O . . . . . . . 60 | . . . . . . . O 61 | . . . . . O . . 62 | . . O . . . . . 63 | 64 | . O . . . . . . 65 | . . . . . O . . 66 | O . . . . . . . 67 | . . . . . . O . 68 | . . . O . . . . 69 | . . . . . . . O 70 | . . O . . . . . 71 | . . . . O . . . 72 | 73 | . O . . . . . . 74 | . . . . . O . . 75 | . . . . . . . O 76 | . . O . . . . . 77 | O . . . . . . . 78 | . . . O . . . . 79 | . . . . . . O . 80 | . . . . O . . . 81 | 82 | . O . . . . . . 83 | . . . . . . O . 84 | . . O . . . . . 85 | . . . . . O . . 86 | . . . . . . . O 87 | . . . . O . . . 88 | O . . . . . . . 89 | . . . O . . . . 90 | 91 | . O . . . . . . 92 | . . . . . . O . 93 | . . . . O . . . 94 | . . . . . . . O 95 | O . . . . . . . 96 | . . . O . . . . 97 | . . . . . O . . 98 | . . O . . . . . 99 | 100 | . O . . . . . . 101 | . . . . . . . O 102 | . . . . . O . . 103 | O . . . . . . . 104 | . . O . . . . . 105 | . . . . O . . . 106 | . . . . . . O . 107 | . . . O . . . . 108 | 109 | . . O . . . . . 110 | O . . . . . . . 111 | . . . . . . O . 112 | . . . . O . . . 113 | . . . . . . . O 114 | . O . . . . . . 115 | . . . O . . . . 116 | . . . . . O . . 117 | 118 | . . O . . . . . 119 | . . . . O . . . 120 | . O . . . . . . 121 | . . . . . . . O 122 | O . . . . . . . 123 | . . . . . . O . 124 | . . . O . . . . 125 | . . . . . O . . 126 | 127 | . . O . . . . . 128 | . . . . O . . . 129 | . O . . . . . . 130 | . . . . . . . O 131 | . . . . . O . . 132 | . . . O . . . . 133 | . . . . . . O . 134 | O . . . . . . . 135 | 136 | . . O . . . . . 137 | . . . . O . . . 138 | . . . . . . O . 139 | O . . . . . . . 140 | . . . O . . . . 141 | . O . . . . . . 142 | . . . . . . . O 143 | . . . . . O . . 144 | 145 | . . O . . . . . 146 | . . . . O . . . 147 | . . . . . . . O 148 | . . . O . . . . 149 | O . . . . . . . 150 | . . . . . . O . 151 | . O . . . . . . 152 | . . . . . O . . 153 | 154 | . . O . . . . . 155 | . . . . . O . . 156 | . O . . . . . . 157 | . . . . O . . . 158 | . . . . . . . O 159 | O . . . . . . . 160 | . . . . . . O . 161 | . . . O . . . . 162 | 163 | . . O . . . . . 164 | . . . . . O . . 165 | . O . . . . . . 166 | . . . . . . O . 167 | O . . . . . . . 168 | . . . O . . . . 169 | . . . . . . . O 170 | . . . . O . . . 171 | 172 | . . O . . . . . 173 | . . . . . O . . 174 | . O . . . . . . 175 | . . . . . . O . 176 | . . . . O . . . 177 | O . . . . . . . 178 | . . . . . . . O 179 | . . . O . . . . 180 | 181 | . . O . . . . . 182 | . . . . . O . . 183 | . . . O . . . . 184 | O . . . . . . . 185 | . . . . . . . O 186 | . . . . O . . . 187 | . . . . . . O . 188 | . O . . . . . . 189 | 190 | . . O . . . . . 191 | . . . . . O . . 192 | . . . O . . . . 193 | . O . . . . . . 194 | . . . . . . . O 195 | . . . . O . . . 196 | . . . . . . O . 197 | O . . . . . . . 198 | 199 | . . O . . . . . 200 | . . . . . O . . 201 | . . . . . . . O 202 | O . . . . . . . 203 | . . . O . . . . 204 | . . . . . . O . 205 | . . . . O . . . 206 | . O . . . . . . 207 | 208 | . . O . . . . . 209 | . . . . . O . . 210 | . . . . . . . O 211 | O . . . . . . . 212 | . . . . O . . . 213 | . . . . . . O . 214 | . O . . . . . . 215 | . . . O . . . . 216 | 217 | . . O . . . . . 218 | . . . . . O . . 219 | . . . . . . . O 220 | . O . . . . . . 221 | . . . O . . . . 222 | O . . . . . . . 223 | . . . . . . O . 224 | . . . . O . . . 225 | 226 | . . O . . . . . 227 | . . . . . . O . 228 | . O . . . . . . 229 | . . . . . . . O 230 | . . . . O . . . 231 | O . . . . . . . 232 | . . . O . . . . 233 | . . . . . O . . 234 | 235 | . . O . . . . . 236 | . . . . . . O . 237 | . O . . . . . . 238 | . . . . . . . O 239 | . . . . . O . . 240 | . . . O . . . . 241 | O . . . . . . . 242 | . . . . O . . . 243 | 244 | . . O . . . . . 245 | . . . . . . . O 246 | . . . O . . . . 247 | . . . . . . O . 248 | O . . . . . . . 249 | . . . . . O . . 250 | . O . . . . . . 251 | . . . . O . . . 252 | 253 | . . . O . . . . 254 | O . . . . . . . 255 | . . . . O . . . 256 | . . . . . . . O 257 | . O . . . . . . 258 | . . . . . . O . 259 | . . O . . . . . 260 | . . . . . O . . 261 | 262 | . . . O . . . . 263 | O . . . . . . . 264 | . . . . O . . . 265 | . . . . . . . O 266 | . . . . . O . . 267 | . . O . . . . . 268 | . . . . . . O . 269 | . O . . . . . . 270 | 271 | . . . O . . . . 272 | . O . . . . . . 273 | . . . . O . . . 274 | . . . . . . . O 275 | . . . . . O . . 276 | O . . . . . . . 277 | . . O . . . . . 278 | . . . . . . O . 279 | 280 | . . . O . . . . 281 | . O . . . . . . 282 | . . . . . . O . 283 | . . O . . . . . 284 | . . . . . O . . 285 | . . . . . . . O 286 | O . . . . . . . 287 | . . . . O . . . 288 | 289 | . . . O . . . . 290 | . O . . . . . . 291 | . . . . . . O . 292 | . . O . . . . . 293 | . . . . . O . . 294 | . . . . . . . O 295 | . . . . O . . . 296 | O . . . . . . . 297 | 298 | . . . O . . . . 299 | . O . . . . . . 300 | . . . . . . O . 301 | . . . . O . . . 302 | O . . . . . . . 303 | . . . . . . . O 304 | . . . . . O . . 305 | . . O . . . . . 306 | 307 | . . . O . . . . 308 | . O . . . . . . 309 | . . . . . . . O 310 | . . . . O . . . 311 | . . . . . . O . 312 | O . . . . . . . 313 | . . O . . . . . 314 | . . . . . O . . 315 | 316 | . . . O . . . . 317 | . O . . . . . . 318 | . . . . . . . O 319 | . . . . . O . . 320 | O . . . . . . . 321 | . . O . . . . . 322 | . . . . O . . . 323 | . . . . . . O . 324 | 325 | . . . O . . . . 326 | . . . . . O . . 327 | O . . . . . . . 328 | . . . . O . . . 329 | . O . . . . . . 330 | . . . . . . . O 331 | . . O . . . . . 332 | . . . . . . O . 333 | 334 | . . . O . . . . 335 | . . . . . O . . 336 | . . . . . . . O 337 | . O . . . . . . 338 | . . . . . . O . 339 | O . . . . . . . 340 | . . O . . . . . 341 | . . . . O . . . 342 | 343 | . . . O . . . . 344 | . . . . . O . . 345 | . . . . . . . O 346 | . . O . . . . . 347 | O . . . . . . . 348 | . . . . . . O . 349 | . . . . O . . . 350 | . O . . . . . . 351 | 352 | . . . O . . . . 353 | . . . . . . O . 354 | O . . . . . . . 355 | . . . . . . . O 356 | . . . . O . . . 357 | . O . . . . . . 358 | . . . . . O . . 359 | . . O . . . . . 360 | 361 | . . . O . . . . 362 | . . . . . . O . 363 | . . O . . . . . 364 | . . . . . . . O 365 | . O . . . . . . 366 | . . . . O . . . 367 | O . . . . . . . 368 | . . . . . O . . 369 | 370 | . . . O . . . . 371 | . . . . . . O . 372 | . . . . O . . . 373 | . O . . . . . . 374 | . . . . . O . . 375 | O . . . . . . . 376 | . . O . . . . . 377 | . . . . . . . O 378 | 379 | . . . O . . . . 380 | . . . . . . O . 381 | . . . . O . . . 382 | . . O . . . . . 383 | O . . . . . . . 384 | . . . . . O . . 385 | . . . . . . . O 386 | . O . . . . . . 387 | 388 | . . . O . . . . 389 | . . . . . . . O 390 | O . . . . . . . 391 | . . O . . . . . 392 | . . . . . O . . 393 | . O . . . . . . 394 | . . . . . . O . 395 | . . . . O . . . 396 | 397 | . . . O . . . . 398 | . . . . . . . O 399 | O . . . . . . . 400 | . . . . O . . . 401 | . . . . . . O . 402 | . O . . . . . . 403 | . . . . . O . . 404 | . . O . . . . . 405 | 406 | . . . O . . . . 407 | . . . . . . . O 408 | . . . . O . . . 409 | . . O . . . . . 410 | O . . . . . . . 411 | . . . . . . O . 412 | . O . . . . . . 413 | . . . . . O . . 414 | 415 | . . . . O . . . 416 | O . . . . . . . 417 | . . . O . . . . 418 | . . . . . O . . 419 | . . . . . . . O 420 | . O . . . . . . 421 | . . . . . . O . 422 | . . O . . . . . 423 | 424 | . . . . O . . . 425 | O . . . . . . . 426 | . . . . . . . O 427 | . . . O . . . . 428 | . O . . . . . . 429 | . . . . . . O . 430 | . . O . . . . . 431 | . . . . . O . . 432 | 433 | . . . . O . . . 434 | O . . . . . . . 435 | . . . . . . . O 436 | . . . . . O . . 437 | . . O . . . . . 438 | . . . . . . O . 439 | . O . . . . . . 440 | . . . O . . . . 441 | 442 | . . . . O . . . 443 | . O . . . . . . 444 | . . . O . . . . 445 | . . . . . O . . 446 | . . . . . . . O 447 | . . O . . . . . 448 | O . . . . . . . 449 | . . . . . . O . 450 | 451 | . . . . O . . . 452 | . O . . . . . . 453 | . . . O . . . . 454 | . . . . . . O . 455 | . . O . . . . . 456 | . . . . . . . O 457 | . . . . . O . . 458 | O . . . . . . . 459 | 460 | . . . . O . . . 461 | . O . . . . . . 462 | . . . . . O . . 463 | O . . . . . . . 464 | . . . . . . O . 465 | . . . O . . . . 466 | . . . . . . . O 467 | . . O . . . . . 468 | 469 | . . . . O . . . 470 | . O . . . . . . 471 | . . . . . . . O 472 | O . . . . . . . 473 | . . . O . . . . 474 | . . . . . . O . 475 | . . O . . . . . 476 | . . . . . O . . 477 | 478 | . . . . O . . . 479 | . . O . . . . . 480 | O . . . . . . . 481 | . . . . . O . . 482 | . . . . . . . O 483 | . O . . . . . . 484 | . . . O . . . . 485 | . . . . . . O . 486 | 487 | . . . . O . . . 488 | . . O . . . . . 489 | O . . . . . . . 490 | . . . . . . O . 491 | . O . . . . . . 492 | . . . . . . . O 493 | . . . . . O . . 494 | . . . O . . . . 495 | 496 | . . . . O . . . 497 | . . O . . . . . 498 | . . . . . . . O 499 | . . . O . . . . 500 | . . . . . . O . 501 | O . . . . . . . 502 | . . . . . O . . 503 | . O . . . . . . 504 | 505 | . . . . O . . . 506 | . . . . . . O . 507 | O . . . . . . . 508 | . . O . . . . . 509 | . . . . . . . O 510 | . . . . . O . . 511 | . . . O . . . . 512 | . O . . . . . . 513 | 514 | . . . . O . . . 515 | . . . . . . O . 516 | O . . . . . . . 517 | . . . O . . . . 518 | . O . . . . . . 519 | . . . . . . . O 520 | . . . . . O . . 521 | . . O . . . . . 522 | 523 | . . . . O . . . 524 | . . . . . . O . 525 | . O . . . . . . 526 | . . . O . . . . 527 | . . . . . . . O 528 | O . . . . . . . 529 | . . O . . . . . 530 | . . . . . O . . 531 | 532 | . . . . O . . . 533 | . . . . . . O . 534 | . O . . . . . . 535 | . . . . . O . . 536 | . . O . . . . . 537 | O . . . . . . . 538 | . . . O . . . . 539 | . . . . . . . O 540 | 541 | . . . . O . . . 542 | . . . . . . O . 543 | . O . . . . . . 544 | . . . . . O . . 545 | . . O . . . . . 546 | O . . . . . . . 547 | . . . . . . . O 548 | . . . O . . . . 549 | 550 | . . . . O . . . 551 | . . . . . . O . 552 | . . . O . . . . 553 | O . . . . . . . 554 | . . O . . . . . 555 | . . . . . . . O 556 | . . . . . O . . 557 | . O . . . . . . 558 | 559 | . . . . O . . . 560 | . . . . . . . O 561 | . . . O . . . . 562 | O . . . . . . . 563 | . . O . . . . . 564 | . . . . . O . . 565 | . O . . . . . . 566 | . . . . . . O . 567 | 568 | . . . . O . . . 569 | . . . . . . . O 570 | . . . O . . . . 571 | O . . . . . . . 572 | . . . . . . O . 573 | . O . . . . . . 574 | . . . . . O . . 575 | . . O . . . . . 576 | 577 | . . . . . O . . 578 | O . . . . . . . 579 | . . . . O . . . 580 | . O . . . . . . 581 | . . . . . . . O 582 | . . O . . . . . 583 | . . . . . . O . 584 | . . . O . . . . 585 | 586 | . . . . . O . . 587 | . O . . . . . . 588 | . . . . . . O . 589 | O . . . . . . . 590 | . . O . . . . . 591 | . . . . O . . . 592 | . . . . . . . O 593 | . . . O . . . . 594 | 595 | . . . . . O . . 596 | . O . . . . . . 597 | . . . . . . O . 598 | O . . . . . . . 599 | . . . O . . . . 600 | . . . . . . . O 601 | . . . . O . . . 602 | . . O . . . . . 603 | 604 | . . . . . O . . 605 | . . O . . . . . 606 | O . . . . . . . 607 | . . . . . . O . 608 | . . . . O . . . 609 | . . . . . . . O 610 | . O . . . . . . 611 | . . . O . . . . 612 | 613 | . . . . . O . . 614 | . . O . . . . . 615 | O . . . . . . . 616 | . . . . . . . O 617 | . . . O . . . . 618 | . O . . . . . . 619 | . . . . . . O . 620 | . . . . O . . . 621 | 622 | . . . . . O . . 623 | . . O . . . . . 624 | O . . . . . . . 625 | . . . . . . . O 626 | . . . . O . . . 627 | . O . . . . . . 628 | . . . O . . . . 629 | . . . . . . O . 630 | 631 | . . . . . O . . 632 | . . O . . . . . 633 | . . . . O . . . 634 | . . . . . . O . 635 | O . . . . . . . 636 | . . . O . . . . 637 | . O . . . . . . 638 | . . . . . . . O 639 | 640 | . . . . . O . . 641 | . . O . . . . . 642 | . . . . O . . . 643 | . . . . . . . O 644 | O . . . . . . . 645 | . . . O . . . . 646 | . O . . . . . . 647 | . . . . . . O . 648 | 649 | . . . . . O . . 650 | . . O . . . . . 651 | . . . . . . O . 652 | . O . . . . . . 653 | . . . O . . . . 654 | . . . . . . . O 655 | O . . . . . . . 656 | . . . . O . . . 657 | 658 | . . . . . O . . 659 | . . O . . . . . 660 | . . . . . . O . 661 | . O . . . . . . 662 | . . . . . . . O 663 | . . . . O . . . 664 | O . . . . . . . 665 | . . . O . . . . 666 | 667 | . . . . . O . . 668 | . . O . . . . . 669 | . . . . . . O . 670 | . . . O . . . . 671 | O . . . . . . . 672 | . . . . . . . O 673 | . O . . . . . . 674 | . . . . O . . . 675 | 676 | . . . . . O . . 677 | . . . O . . . . 678 | O . . . . . . . 679 | . . . . O . . . 680 | . . . . . . . O 681 | . O . . . . . . 682 | . . . . . . O . 683 | . . O . . . . . 684 | 685 | . . . . . O . . 686 | . . . O . . . . 687 | . O . . . . . . 688 | . . . . . . . O 689 | . . . . O . . . 690 | . . . . . . O . 691 | O . . . . . . . 692 | . . O . . . . . 693 | 694 | . . . . . O . . 695 | . . . O . . . . 696 | . . . . . . O . 697 | O . . . . . . . 698 | . . O . . . . . 699 | . . . . O . . . 700 | . O . . . . . . 701 | . . . . . . . O 702 | 703 | . . . . . O . . 704 | . . . O . . . . 705 | . . . . . . O . 706 | O . . . . . . . 707 | . . . . . . . O 708 | . O . . . . . . 709 | . . . . O . . . 710 | . . O . . . . . 711 | 712 | . . . . . O . . 713 | . . . . . . . O 714 | . O . . . . . . 715 | . . . O . . . . 716 | O . . . . . . . 717 | . . . . . . O . 718 | . . . . O . . . 719 | . . O . . . . . 720 | 721 | . . . . . . O . 722 | O . . . . . . . 723 | . . O . . . . . 724 | . . . . . . . O 725 | . . . . . O . . 726 | . . . O . . . . 727 | . O . . . . . . 728 | . . . . O . . . 729 | 730 | . . . . . . O . 731 | . O . . . . . . 732 | . . . O . . . . 733 | O . . . . . . . 734 | . . . . . . . O 735 | . . . . O . . . 736 | . . O . . . . . 737 | . . . . . O . . 738 | 739 | . . . . . . O . 740 | . O . . . . . . 741 | . . . . . O . . 742 | . . O . . . . . 743 | O . . . . . . . 744 | . . . O . . . . 745 | . . . . . . . O 746 | . . . . O . . . 747 | 748 | . . . . . . O . 749 | . . O . . . . . 750 | O . . . . . . . 751 | . . . . . O . . 752 | . . . . . . . O 753 | . . . . O . . . 754 | . O . . . . . . 755 | . . . O . . . . 756 | 757 | . . . . . . O . 758 | . . O . . . . . 759 | . . . . . . . O 760 | . O . . . . . . 761 | . . . . O . . . 762 | O . . . . . . . 763 | . . . . . O . . 764 | . . . O . . . . 765 | 766 | . . . . . . O . 767 | . . . O . . . . 768 | . O . . . . . . 769 | . . . . O . . . 770 | . . . . . . . O 771 | O . . . . . . . 772 | . . O . . . . . 773 | . . . . . O . . 774 | 775 | . . . . . . O . 776 | . . . O . . . . 777 | . O . . . . . . 778 | . . . . . . . O 779 | . . . . . O . . 780 | O . . . . . . . 781 | . . O . . . . . 782 | . . . . O . . . 783 | 784 | . . . . . . O . 785 | . . . . O . . . 786 | . . O . . . . . 787 | O . . . . . . . 788 | . . . . . O . . 789 | . . . . . . . O 790 | . O . . . . . . 791 | . . . O . . . . 792 | 793 | . . . . . . . O 794 | . O . . . . . . 795 | . . . O . . . . 796 | O . . . . . . . 797 | . . . . . . O . 798 | . . . . O . . . 799 | . . O . . . . . 800 | . . . . . O . . 801 | 802 | . . . . . . . O 803 | . O . . . . . . 804 | . . . . O . . . 805 | . . O . . . . . 806 | O . . . . . . . 807 | . . . . . . O . 808 | . . . O . . . . 809 | . . . . . O . . 810 | 811 | . . . . . . . O 812 | . . O . . . . . 813 | O . . . . . . . 814 | . . . . . O . . 815 | . O . . . . . . 816 | . . . . O . . . 817 | . . . . . . O . 818 | . . . O . . . . 819 | 820 | . . . . . . . O 821 | . . . O . . . . 822 | O . . . . . . . 823 | . . O . . . . . 824 | . . . . . O . . 825 | . O . . . . . . 826 | . . . . . . O . 827 | . . . . O . . . 828 | 829 | -------------------------------------------------------------------------------- /test_tool/testcase/queens.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int N = 8; 3 | int row[8]; 4 | int col[8]; 5 | int d[2][16]; 6 | 7 | void printBoard() { 8 | int i; 9 | int j; 10 | for (i = 0; i < N; i++) { 11 | for (j = 0; j < N; j++) { 12 | if (col[i] == j) 13 | print(" O"); 14 | else 15 | print(" ."); 16 | } 17 | println(""); 18 | } 19 | println(""); 20 | sleep(50); // to prevent UART buffer from overflowing 21 | } 22 | 23 | void search(int c) { 24 | if (c == N) { 25 | printBoard(); 26 | } 27 | else { 28 | int r; 29 | for (r = 0; r < N; r++) { 30 | if (row[r] == 0 && d[0][r+c] == 0 && d[1][r+N-1-c] == 0) { 31 | row[r] = d[0][r+c] = d[1][r+N-1-c] = 1; 32 | col[c] = r; 33 | search(c+1); 34 | row[r] = d[0][r+c] = d[1][r+N-1-c] = 0; 35 | } 36 | } 37 | } 38 | } 39 | 40 | int main() { 41 | search(0); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /test_tool/testcase/queens.sim.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int N = 8; 3 | int row[8]; 4 | int col[8]; 5 | int d[2][16]; 6 | 7 | void printBoard() { 8 | int i; 9 | int j; 10 | for (i = 0; i < N; i++) { 11 | for (j = 0; j < N; j++) { 12 | if (col[i] == j) 13 | print(" O"); 14 | else 15 | print(" ."); 16 | } 17 | println(""); 18 | } 19 | println(""); 20 | //sleep(50); // to prevent UART buffer from overflowing 21 | } 22 | 23 | void search(int c) { 24 | if (c == N) { 25 | printBoard(); 26 | } 27 | else { 28 | int r; 29 | for (r = 0; r < N; r++) { 30 | if (row[r] == 0 && d[0][r+c] == 0 && d[1][r+N-1-c] == 0) { 31 | row[r] = d[0][r+c] = d[1][r+N-1-c] = 1; 32 | col[c] = r; 33 | search(c+1); 34 | row[r] = d[0][r+c] = d[1][r+N-1-c] = 0; 35 | } 36 | } 37 | } 38 | } 39 | 40 | int main() { 41 | search(0); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /test_tool/testcase/statement_test.ans: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 2 4 | 4 5 | 2 6 | 6 7 | 4 8 | 6 9 | 4 10 | -------------------------------------------------------------------------------- /test_tool/testcase/statement_test.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | //考察点:section 8 语句,包括if,while,for,break,continue,return等 3 | //算法:线性筛法求欧拉函数 4 | //样例输入:10 5 | //样例输出: 6 | //1 7 | //2 8 | //2 9 | //4 10 | //2 11 | //6 12 | //4 13 | //6 14 | //4 15 | 16 | int N; 17 | int M = 0; 18 | int check[20]; 19 | 20 | int main() { 21 | N = inl(); 22 | int i = 0; 23 | while ( i <= N ) check[i++] = 1; 24 | int phi[15]; 25 | int P[15]; 26 | phi[1] = 1; 27 | for (i = 2; ; ++i ) { 28 | if ( i > N ) break; 29 | if ( check[i] ) { 30 | P[++M] = i; 31 | phi[i] = i - 1; 32 | } 33 | int k = i; 34 | int i; 35 | for (i = 1; i <= M && (k * P[i] <= N); i++) { 36 | int tmp = k * P[i]; 37 | if ( tmp > N ) continue; 38 | check[tmp] = 0; 39 | if ( k % P[i] == 0) { 40 | phi[tmp] = phi[k] * P[i]; 41 | break; 42 | } 43 | else { 44 | phi[k * P[i]] = phi[k] * (P[i] - 1); 45 | } 46 | } 47 | outlln(phi[k]); 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /test_tool/testcase/statement_test.in: -------------------------------------------------------------------------------- 1 | 10 -------------------------------------------------------------------------------- /test_tool/testcase/superloop.ans: -------------------------------------------------------------------------------- 1 | 720 2 | -------------------------------------------------------------------------------- /test_tool/testcase/superloop.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | //Target: use loops to calculate calculator of 6! 3 | //@author yixi 4 | 5 | int N; 6 | int h = 99; 7 | int i = 100; 8 | int j = 101; 9 | int k = 102; 10 | int total = 0; 11 | 12 | int main() { 13 | int a; 14 | int b; 15 | int c; 16 | int d; 17 | int e; 18 | int f; 19 | N=inl(); 20 | for ( a=1; a<=N; a++ ) 21 | for ( b=1; b<=N; b++ ) 22 | for ( c=1; c<=N; c++ ) 23 | for ( d=1; d<=N; d++ ) 24 | for ( e=1; e<=N; e++ ) 25 | for ( f=1; f<=N; f++ ) 26 | if (a!=b && a!=c && a!=d && a!=e && a!=f && a!=h && a!=i && a!=j && a!=k 27 | && b!=c && b!=d && b!=e && b!=f && b!=h && b!=i && b!=j && b!=k 28 | && c!=d && c!=e && c!=f && c!=h && c!=i && c!=j && c!=k 29 | && d!=e && d!=f && d!=h && d!=i && d!=j && d!=k 30 | && e!=f && e!=h && e!=i && e!=j && e!=k 31 | && f!=h && f!=i && f!=j && f!=k && i!=j && h!=k) 32 | { 33 | total++; 34 | } 35 | 36 | outlln(total); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /test_tool/testcase/superloop.in: -------------------------------------------------------------------------------- 1 | 6 2 | -------------------------------------------------------------------------------- /test_tool/testcase/tak.ans: -------------------------------------------------------------------------------- 1 | 13 2 | -------------------------------------------------------------------------------- /test_tool/testcase/tak.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int tak(int x, int y, int z) { 3 | if ( y < x ) return 1 + tak( tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y) ); 4 | else return z; 5 | } 6 | 7 | int main(){ 8 | int a; 9 | int b; 10 | int c; 11 | a=inl(); 12 | b=inl(); 13 | c=inl(); 14 | outlln(tak(a,b,c)); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test_tool/testcase/tak.in: -------------------------------------------------------------------------------- 1 | 18 2 | 12 3 | 6 4 | -------------------------------------------------------------------------------- /test_tool/testcase/testsleep.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | int main() 3 | { 4 | int a = clock(); 5 | sleep(10000); // sleep for 10s 6 | int b = clock(); 7 | outlln(b-a); 8 | outlln((b-a)/CPU_CLK_FREQ); // should be 10 9 | return 0; // check actual running time 10 | } --------------------------------------------------------------------------------