(no commit message)
[libreriscv.git] / HDL_workflow / microwatt.mdwn
1 # Tutorial for setting up Microwatt chroot and running simulations
2
3 Useful Links (External):
4
5 * <https://codeconstruct.com.au/docs/microwatt-orangecrab/>
6 * <https://shenki.github.io/boot-linux-on-microwatt/>
7 * <https://github.com/gregdavill/OrangeCrab-test-sw>
8 * [Verilator docs, commands](https://verilator.org/guide/latest/exe_verilator.html)
9 * [Verilator runtime command documentation](https://verilator.org/guide/latest/exe_sim.html)
10 * Tutorials for how to work with verilator:
11 [part1](https://www.itsembedded.com/dhd/verilator_1/),
12 [part2](https://www.itsembedded.com/dhd/verilator_2/)
13
14 Useful links (Libre-SOC):
15
16 * Libre-SOC page covering our workflow: [[HDL_workflow]]
17 * Devscripts Libre-SOC page: [[devscripts]]
18 * Original Microwatt Libre-SOC page: [[microwatt]]
19 * [Libre-SOC Microwatt repo branch](https://git.libre-soc.org/?p=microwatt.git;a=tree;hb=refs/heads/verilator_trace)
20 * [Libre-SOC devscripts repo](https://git.libre-soc.org/?p=dev-env-setup.git;a=tree)
21
22 Other Tutorials (Libre-SOC):
23
24 * First steps for working with PowerISA instructions Libre-SOC page:
25 [[/docs/firststeps]]
26
27 ## Video Tutorial
28
29 [43min tutorial](https://youtu.be/02LCl3ang8g) was made and uploaded to
30 Youtube, covering some of the material you'll find on this page.
31
32 ## Development environment scripts
33
34 If you haven't already, clone Libre-SOC's development environment setup scripts.
35 These are bash scripts, and greatly simplify the time it takes to create a:
36
37 - Stable environment
38 - With all software and libraries at specific versions
39 (which are known to work).
40
41 These attributes are absolutely critical, and no support will be
42 provided, unless you use these scripts to setup a development environment. This
43 helps us fix any bugs in the scripts, and make sure everyone runs on the same
44 page.
45
46 $ git clone https://git.libre-soc.org/git/dev-env-setup.git
47
48 Do *look through* the
49 [code](https://git.libre-soc.org/?p=dev-env-setup.git;a=tree) before running
50 any of those scripts. They may be confusing, however after reading a few you'll
51 start to become more familiar with them.
52
53 It is expected for you to use Debian, we mostly use 11 (Bullseye) for the host
54 OS, while all the chroots run Debian 10 (Buster).
55
56 ## Setting up chroot
57
58 Scripts we will be using for the setup are:
59
60 * `mk-deb-chroot`, `cp-scripts-to-chroot` for chroot setup
61 * `install-hdl-apt-reqs`, `verilator-install`, `hdl-tools-yosys` for working
62 with Microwatt
63
64 (*Current limitation for `mk-deb-chroot`, is that you must be the first user on
65 the host machine, having user ID 1000.*)
66
67 Commands to run in terminal to setup a new chroot environment for microwatt
68 simulations.
69
70 $ cd dev-env-setup
71 $ sudo bash
72 # ./mk-deb-chroot microwatt
73 # ./cp-scripts-to-chroot microwatt
74 # exit
75 $ schroot -c microwatt
76 (microwatt):$ cd dev-env-setup
77 (microwatt):$ sudo bash
78 (microwatt):# ./install-hdl-apt-reqs
79 (microwatt):# ./verilator-install
80 (microwatt):# ./hdl-tools-yosys
81 (microwatt):# exit
82 (microwatt):$ cd ~/src/
83 (microwatt):$ git clone https://git.libre-soc.org/git/microwatt.git
84 (microwatt):$ cd microwatt
85 (microwatt):$ git checkout verilator_trace
86
87 Make sure verilator binaries in $PATH:
88
89 (microwatt):$ export PATH=/usr/local/verilator/bin:$PATH
90 (microwatt):$ export GHDLSYNTH=ghdl
91
92 (GHDLSYNTH needs to be redefined because the Makefile has default `ghdl.so`,
93 but somewhere else '.so' gets appended. You may see the following error if you
94 don't redefine:
95 `ERROR: Can't load module
96 ./ghdl.so':/usr/local/bin/../share/yosys/plugins/**ghdl.so.so**`)
97 [IRC](https://libre-soc.org/irclog/%23libre-soc.2023-01-25.log.html#t2023-01-25T11:10:47)
98
99 ## Compiling the verilator sim for Microwatt
100
101 * [Libre-SOC Microwatt repo branch, Makefile](https://git.libre-soc.org/?p=microwatt.git;a=blob;f=Makefile;hb=refs/heads/verilator_trace)
102
103 Verilator creates a fairly fast simulation by converting the HDL design to C++,
104 and then compiling a binary which the user runs.
105
106 To compile the verilator simulation, first set verilator as the target for the
107 makefile:
108
109 (microwatt):$ export FPGA_TARGET=verilator
110
111 Before compiling, you can change the `THREADS` variable in the makefile, which
112 will allow the compiled verilator simulation binary to use more than 1 thread
113 (*make sure to check how many CPU threads you have before changing this!*)
114
115 To compile the verilator simulation binary, call make with the
116 `microwatt-verilator` rule.
117
118 (microwatt):$ make microwatt-verilator
119
120 ## Compiling hello world code
121
122 We need some code to actually run on the core, so start with the 'hello world'.
123 Instructions assume you're still in the microwatt directory.
124
125 (microwatt):$ cd hello_world
126 (microwatt):$ make
127
128 A `hello_world.bin` should be generated (the final binary to be loaded), as
129 well as an
130 [.elf file](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format), and
131 .hex (representing the binary data as hex text strings).
132
133 To view the symbol table (useful to see where various sections of the binary
134 begin):
135
136 (microwatt):$ powerpc64le-linux-gnu-objdump -h hello_world.elf
137 (microwatt):$ powerpc64le-linux-gnu-objdump -x hello_world.elf
138
139 `-h` shows just the section headers, `-x` shows all headers.
140
141 And to view the disassembly (great for learning about the PowerISA instructions,
142 and for associating the binary hex with actual instructions), you can view the
143 automatically generated `hello_world.as` file.
144
145 Command to generate the disassembly:
146
147 (microwatt):$ powerpc64le-linux-gnu-objdump -D hello_world.elf
148
149 For more information about `objdump` (common utility, not just for PowerISA),
150 see the manual pages.
151
152 (microwatt):$ man powerpc64le-linux-gnu-objdump
153
154 The binary is ready to go, now it can be loaded into the simulation.
155
156 ## Simulation
157
158 ### Command line args
159
160 To find out the `microwatt-verilator` arguments, you can check with `-h` arg:
161
162 (microwatt):$ ./microwatt-verilator -h
163
164 Some of the arguments are explained in further sections.
165
166 ### Running
167
168 Run the `microwatt-verilator` binary, with `hello_world/hello_world.bin` as an
169 argument:
170
171 (microwatt):$ time ./microwatt-verilator hello_world/hello_world.bin
172
173 `time` is a utility you can use to measure how long it takes to run the sim.
174
175 A pretty ASCII art of a lightbulb should be printed, and then the user can type
176 any characters, which will be echoed back. To end the simulation press Ctrl+C.
177
178 If no characters are appearing after about 20 seconds, stop the simulation,
179 as there might be other issues.
180
181 Single-threaded verilator sim binary, on a 2nd gen intel i5 (sandybridge)
182 takes 53 seconds to print the ASCII lightbulb.
183
184 On another dev's machine, ASUS KGPE D16, this takes just over a minute.
185
186 (*You'll find that uart printout is one of the longer parts of the simulation
187 in general.*)
188
189 ## Analysing results after simulation
190
191 The following files will be generated during the sim:
192
193 - `bram.dump` - Shows the PC address and instruction being executed. If the sim
194 hangs without any printing, view this file, as the processor may have hit an
195 exception etc. Grows in size as the sim runs.
196
197 - `bram.snapshot.[NUMBER]`, `verilator.save.[NUMBER]` - Snapshot files of the
198 contents of bram and verilator model respectively. Can be used to resume the
199 simulation. The number on the end corresponds to the tick time (i.e.
200 `bram.snapshot.1999990`/`verilator.save.1999990`). First the verilator model is
201 loaded, and then the bram contents are loaded. See lines `#65-108` and
202 `#189-195` of the
203 [microwatt-verilator.cpp file](https://git.libre-soc.org/?p=microwatt.git;a=blob;f=verilator/microwatt-verilator.cpp;h=a226393f6ba74d5e3e1ffdb729d731d2311d53ad;hb=refs/heads/verilator_trace).
204 Pass the tick number on the end of the filename with the '-s' flag:
205
206 (microwatt):$ ./microwatt-verilator hello_world/hello_world.bin -s 1999990
207
208 You'll get a message like this:
209
210 loading hello_world/hello_world.bin at 0x0 size 0x1888
211 loading bram.snapshot.1999990 at 0x0 size 0x10000000
212 restored at 1999990
213
214 These snapshots are generated at intervals of every 2,000,000 ticks.
215
216 - `microwatt-verilator.vcd` - GTKWave waveform file, allowing you to look at
217 processor signals and transitions during simulation.
218 Pass `-d` flag to `microwatt-verilator` binary:
219
220 (microwatt):$ ./microwatt-verilator hello_world/hello_world.bin -d
221
222 **NOTE**: Trace dumping will generate a large VCD file (about 6GB for the hello
223 world example)!
224
225 If you want GTKWave to load it faster, convert to fst first:
226
227 (microwatt):$ vcd2fst --vcdname=microwatt-verilator.vcd --fstname=microwatt-verilator.fst
228 (microwatt):$ gtkwave microwatt-verilator.fst
229
230 Fst files are orders-of-magnitude smaller (about 20MB vs 6GB), but are specific
231 to the GTKWave tool.
232
233 ## Micropython
234
235 The Microwatt repo comes with a pre-compiled
236 [micropython binary](https://git.libre-soc.org/?p=microwatt.git;a=tree;f=micropython;h=18fa078c8145bdaa75667a0ab04eb0b261245665;hb=refs/heads/verilator_trace)
237 (version 1.12), which you can try out after confirming 'hello world' works.
238 Bear in mind, not all features of python will be available. Such as
239 floating-point numbers.
240
241 For micropython to work, you'll need to increase the RAM size in the makefile.
242 Go to the microwatt-verilator makefile, and comment out the following lines:
243
244 MEMORY_SIZE=8192
245 RAM_INIT_FILE=hello_world/hello_world.hex
246
247 And uncomment the following:
248
249 MEMORY_SIZE=393216
250 RAM_INIT_FILE=micropython/firmware.hex
251
252 This will increase the RAM size from 8KiB to 384KiB. The `RAM_INIT_FILE` in
253 these examples isn't doing anything, however good practice to follow.
254
255 Clean up generated files, and recompile:
256
257 (microwatt):$ make clean
258 (microwatt):$ make microwatt-verilator
259
260 Once the binary has been built, run the same way as before, but point to the
261 micropython firmware binary:
262
263 (microwatt):$ microwatt-verilator micropython/firmware.bin
264
265 On the same system as above, with 1 thread, it took 49 seconds to get to the
266 micropython shell.
267
268 ## Verilator runtime commands
269 A few examples:
270
271 # Show the version of verilator being used
272 (microwatt):$ ./microwatt-verilator +verilator+version
273
274 ## Building `microwatt-verilator` using the Libre-SOC core
275
276 In the Makefile, you need to set `EXTERNAL_CORE` to true, and copy the
277 generated core from soc repo to microwatt. *(If you use a separate chroot to
278 generate Libre-SOC cores, then you'll need to copy from that chroot to
279 microwatt chroot from host.*
280
281 cd /path/to/soc
282 make microwatt_external_core
283 cp external_core_top.v /path/to/microwatt
284
285 Then compile verilator sim binary as before:
286
287 cd ~/src/microwatt/
288 export FPGA_TARGET=verilator
289 export GHDLSYNTH=ghdl
290 make microwatt-verilator
291
292 ## Running Linux kernel
293
294 To run Linux on Microwatt, you'll need two binaries:
295
296 - The `sdram_init.bin`, which is easy to compile (no additional software
297 required).
298
299 - The `dtbImage.microwatt` device tree Linux kernel. This can be compiled (see
300 below), or a copy can be downloaded from: <https://ftp.libre-soc.org/dtbImage.microwatt>.
301
302 Like with the micropython example, you'll need to increase the RAM size in the
303 makefile, and recompile the microwatt-verilator binary.
304
305 Uncomment the following:
306
307 MEMORY_SIZE=536870912
308
309 Which will change the RAM size to 512KiB.
310
311 As there is no `dtbImage.microwatt.hex`, you can leave `RAM_INIT_FILE` unchanged.
312
313 ### Building the kernel - TODO:
314
315 *(Please don't build the kernel yourself, until you've tested with the existing kernel linked
316 above!)*
317
318 On a POWER9 there is no need to install gcc-powerpc64le-linux-gnu,
319 you can omit CROSS_COMPILE and ARCH in this case
320
321 apt install gcc-powerpc64le-linux-gnu
322 apt install flex bison lz4
323 git clone -b microwatt-5.7 https://git.kernel.org/pub/scm/linux/kernel/git/joel/microwatt.git
324 cd microwatt
325 wget https://ftp.libre-soc.org/microwatt-linux-5.7.patch
326 patch -p1 < microwatt-linux-5.7.patch
327 wget https://ftp.libre-soc.org/rootfs.cpio
328 CROSS_COMPILE="ccache powerpc64le-linux-gnu-" ARCH=powerpc make -j8 O=microwatt microwatt_defconfig
329 CROSS_COMPILE="ccache powerpc64le-linux-gnu-" ARCH=powerpc make -j8 O=microwatt
330
331 This will produce a file
332 microwatt/arch/powerpc/boot/dtbImage.microwatt
333
334 ### Building `sdram_init.bin`
335 This needs gcc-powerpc64le-linux-gnu (already included in the setup step) if
336 cross compilation is used. It is assumed you're already in `~/src/microwatt/`
337 directory.
338
339 (microwatt):$ cd litedram/gen-src/sdram_init/
340 (microwatt):$ make
341
342 The resulting binary will be in the `obj/` directory.
343
344 ### Running the simulation
345
346 Make sure to return back to `src/microwatt/`.
347
348 (microwatt):$ cd ~/src/microwatt/
349 (microwatt):$ cp microwatt/arch/powerpc/boot/dtbImage.microwatt
350 (microwatt):$ ./microwatt-verilator sdram_init.bin dtbImage.microwatt
351
352 This will take some time...
353
354 ### Sysconn information
355
356 TODO WIP integrate from <https://libre-soc.org/irclog/%23libre-soc.2022-01-26.log.html>
357
358 Sysconn is a module which includes information about the SoC, and the info is
359 printed at the start of the simulation.
360
361 ### Time benchmarks
362
363 `microwatt-verilator` was compiled with 3 threads for faster simulation.
364
365 - Time to finish printing Sysconn info: about 1min
366 - Time to allocate bytes to kernel: ?
367 - Time to login prompt: about 1 hour
368 - Time to user shell: ?
369
370 ### TODO: buildroot
371
372 * https://github.com/shenki/buildroot/commits/microwatt
373 * https://codeconstruct.com.au/docs/microwatt-orangecrab/
374
375 ## FPGA Development - TODO: Need checking
376 ### Building the bitstring for OrangeCrab
377
378 cd microwatt
379 export FPGA_TARGET=ORANGE-CRAB
380 export GHDLSYNTH=ghdl
381 make microwatt.bit
382
383 ### flashing the bitstring to the OrangeCrab
384
385 make prog # this will run OpenOCD
386
387 ### Notes for ulx3s
388
389 notes for how to compile for ulx3s
390
391 git clone https://github.com/kost/fujprog
392 (follow build procedure shown in fujprog README)
393 git clone https://git.libre-soc.org/git/microwatt.git
394 git checkout -b verilator_trace
395 export FPGA_TARGET=ulx3s
396 make microwatt.svf
397 fujprog microwatt.svf
398
399
400 ### Notes for nextpnr-xilinx
401
402 superceded: see page [[nextpnr-xilinx]] and devscript
403 <https://git.libre-soc.org/?p=dev-env-setup.git;a=blob;f=nextpnr-xilinx-install;hb=HEAD>
404
405 for compiling nextpnr-xilinx and making it useable for nmigen
406 to compile for the digilent arty-a7-100t, requires a little
407 futzing around, using the symbiflow version of prjxray-db
408 instead of the one recommended as a submodule
409
410 git clone https://github.com/gatecat/nextpnr-xilinx
411 cd nextpnr-xilinx
412 git checkout cd8b15db6ff5c1a7f10a9e
413 git submodule init
414 git submodule update
415 cd xilinx/external
416 mv prjxray-db prjxray-db-no
417 git clone https://github.com/SymbiFlow/prjxray-db
418 cd prjxray-db
419 git checkout 0a0addedd73e7
420 cp ./artix7/xc7a100t/*.json \
421 ./artix7/xc7a100tcsg324-1
422 cd ../../..
423 cmake -DARCH=xilinx .
424 make
425 make install
426 python3 xilinx/python/bbaexport.py --device xc7a100tcsg324-1 --bba xilinx/xc7a100t.bba
427 ./bbasm --l xilinx/xc7a100t.bba xilinx/xc7a100t.bin
428 mkdir -p /usr/share/nextpnr/xilinx-chipdb
429 cp xilinx/*.bin /usr/share/nextpnr/xilinx-chipdb
430 cp -aux xilinx/external/prjxray-db /usr/share/nextpnr
431
432 # Additional Useful Info for UART <-> USB Serial Interface Through OrangeCrab's Built-in USB Interface
433
434 This uses OrangeCrab's built-in USB interface, rather than needing a
435 separate USB-serial adapter. see the following for further details:
436
437 * <https://github.com/antonblanchard/microwatt/pull/347#issuecomment-1058800570>
438 * <https://github.com/antonblanchard/microwatt/pull/347#issuecomment-1058834790>
439
440 # running orangecrab-examples before flashing microwatt
441
442 See <https://github.com/orangecrab-fpga/orangecrab-hardware/blob/main/contrib/10-orangecrab.rules>
443
444 If the OrangeCrab is running in DFU mode, lsusb will show:
445
446 1209:5af0 Generic OrangeCrab r0.2 DFU Bootloader v3.1-6-g62e92e2
447
448 OrangeCrab has two DFU devices:
449
450 Found DFU: [1209:5af0] ver=0101, devnum=22, cfg=1, intf=0, path="1-4.2", alt=1, name="0x00100000 RISC-V Firmware", serial="UNKNOWN"
451 Found DFU: [1209:5af0] ver=0101, devnum=22, cfg=1, intf=0, path="1-4.2", alt=0, name="0x00080000 Bitstream", serial="UNKNOWN"
452
453 Then clone and patch orangecrab-examples:
454
455 git clone https://github.com/orangecrab-fpga/orangecrab-examples
456 patch -p1 < orangecrab-examples.diff
457
458 To build and flash the example:
459
460 pushd orangecrab-examples/nmigen
461 python3 blink.py
462 popd
463 sudo dfu-util -D orangecrab-examples/nmigen/build/top.bit -a 0