Update README
[riscv-isa-sim.git] / README.md
1 Spike RISC-V ISA Simulator
2 ============================
3
4 About
5 -------------
6
7 Spike, the RISC-V ISA Simulator, implements a functional model of one or more
8 RISC-V processors.
9
10 Spike is named after the golden spike used to celebrate the completion of the
11 US transcontinental railway.
12
13 Build Steps
14 ---------------
15
16 We assume that the RISCV environment variable is set to the RISC-V tools
17 install path, and that the riscv-fesvr package is installed there.
18
19 $ apt-get install device-tree-compiler
20 $ mkdir build
21 $ cd build
22 $ ../configure --prefix=$RISCV --with-fesvr=$RISCV
23 $ make
24 $ [sudo] make install
25
26 Compiling and Running a Simple C Program
27 -------------------------------------------
28
29 Install spike (see Build Steps), riscv-gnu-toolchain, and riscv-pk.
30
31 Write a short C program and name it hello.c. Then, compile it into a RISC-V
32 ELF binary named hello:
33
34 $ riscv64-unknown-elf-gcc -o hello hello.c
35
36 Now you can simulate the program atop the proxy kernel:
37
38 $ spike pk hello
39
40 Simulating a New Instruction
41 ------------------------------------
42
43 Adding an instruction to the simulator requires two steps:
44
45 1. Describe the instruction's functional behavior in the file
46 riscv/insns/<new_instruction_name>.h. Examine other instructions
47 in that directory as a starting point.
48
49 2. Add the opcode and opcode mask to riscv/opcodes.h. Alternatively,
50 add it to the riscv-opcodes package, and it will do so for you:
51
52 $ cd ../riscv-opcodes
53 $ vi opcodes // add a line for the new instruction
54 $ make install
55
56 3. Rebuild the simulator.
57
58 Interactive Debug Mode
59 ---------------------------
60
61 To invoke interactive debug mode, launch spike with -d:
62
63 $ spike -d pk hello
64
65 To see the contents of an integer register (0 is for core 0):
66
67 : reg 0 a0
68
69 To see the contents of a floating point register:
70
71 : fregs 0 ft0
72
73 or:
74
75 : fregd 0 ft0
76
77 depending upon whether you wish to print the register as single- or double-precision.
78
79 To see the contents of a memory location (physical address in hex):
80
81 : mem 2020
82
83 To see the contents of memory with a virtual address (0 for core 0):
84
85 : mem 0 2020
86
87 You can advance by one instruction by pressing <enter>. You can also
88 execute until a desired equality is reached:
89
90 : until pc 0 2020 (stop when pc=2020)
91 : until mem 2020 50a9907311096993 (stop when mem[2020]=50a9907311096993)
92
93 Alternatively, you can execute as long as an equality is true:
94
95 : while mem 2020 50a9907311096993
96
97 You can continue execution indefinitely by:
98
99 : r
100
101 At any point during execution (even without -d), you can enter the
102 interactive debug mode with `<control>-<c>`.
103
104 To end the simulation from the debug prompt, press `<control>-<c>` or:
105
106 : q
107
108 Debugging With Gdb
109 ------------------
110
111 An alternative to interactive debug mode is to attach using gdb. Because spike
112 tries to be like real hardware, you also need OpenOCD to do that. OpenOCD
113 doesn't currently know about address translation, so it's not possible to
114 easily debug programs that are run under `pk`. We'll use the following test
115 program:
116 ```
117 $ cat rot13.c
118 char text[] = "Vafgehpgvba frgf jnag gb or serr!";
119
120 // Don't use the stack, because sp isn't set up.
121 volatile int wait = 1;
122
123 int main()
124 {
125 while (wait)
126 ;
127
128 // Doesn't actually go on the stack, because there are lots of GPRs.
129 int i = 0;
130 while (text[i]) {
131 char lower = text[i] | 32;
132 if (lower >= 'a' && lower <= 'm')
133 text[i] += 13;
134 else if (lower > 'm' && lower <= 'z')
135 text[i] -= 13;
136 i++;
137 }
138
139 while (!wait)
140 ;
141 }
142 $ cat spike.lds
143 OUTPUT_ARCH( "riscv" )
144
145 SECTIONS
146 {
147 . = 0x10010000;
148 .text : { *(.text) }
149 .data : { *(.data) }
150 }
151 $ riscv64-unknown-elf-gcc -g -Og -o rot13-64.o -c rot13.c
152 $ riscv64-unknown-elf-gcc -g -Og -T spike.lds -nostartfiles -o rot13-64 rot13-64.o
153 ```
154
155 To debug this program, first run spike telling it to listen for OpenOCD:
156 ```
157 $ spike --rbb-port=9824 -m0x10000000:0x20000 rot13-64
158 Listening for remote bitbang connection on port 9824.
159 ```
160
161 In a separate shell run OpenOCD with the appropriate configuration file:
162 ```
163 $ cat spike.cfg
164 interface remote_bitbang
165 remote_bitbang_host localhost
166 remote_bitbang_port 9824
167
168 set _CHIPNAME riscv
169 jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
170
171 set _TARGETNAME $_CHIPNAME.cpu
172 target create $_TARGETNAME riscv -chain-position $_TARGETNAME
173
174 gdb_report_data_abort enable
175
176 init
177 halt
178 $ openocd -f spike.cfg
179 Open On-Chip Debugger 0.10.0-dev-00002-gc3b344d (2017-06-08-12:14)
180 ...
181 riscv.cpu: target state: halted
182 ```
183
184 In yet another shell, start your gdb debug session:
185 ```
186 tnewsome@compy-vm:~/SiFive/spike-test$ riscv64-unknown-elf-gdb rot13-64
187 GNU gdb (GDB) 7.12.50.20170505-git
188 Copyright (C) 2016 Free Software Foundation, Inc.
189 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
190 This is free software: you are free to change and redistribute it.
191 There is NO WARRANTY, to the extent permitted by law. Type "show copying"
192 and "show warranty" for details.
193 This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv64-unknown-elf".
194 Type "show configuration" for configuration details.
195 For bug reporting instructions, please see:
196 <http://www.gnu.org/software/gdb/bugs/>.
197 Find the GDB manual and other documentation resources online at:
198 <http://www.gnu.org/software/gdb/documentation/>.
199 For help, type "help".
200 Type "apropos word" to search for commands related to "word"...
201 Reading symbols from rot13-64...done.
202 (gdb) target remote localhost:3333
203 Remote debugging using localhost:3333
204 0x000000001001000a in main () at rot13.c:8
205 8 while (wait)
206 (gdb) print wait
207 $1 = 1
208 (gdb) print wait=0
209 $2 = 0
210 (gdb) print text
211 $3 = "Vafgehpgvba frgf jnag gb or serr!"
212 (gdb) b 23
213 Breakpoint 1 at 0x10010064: file rot13.c, line 23.
214 (gdb) c
215 Continuing.
216
217 Breakpoint 1, main () at rot13.c:23
218 23 while (!wait)
219 (gdb) print wait
220 $4 = 0
221 (gdb) print text
222 ...
223 ```