{"id":870,"date":"2014-07-14T23:25:21","date_gmt":"2014-07-14T23:25:21","guid":{"rendered":"http:\/\/retroramblings.net\/?p=870"},"modified":"2014-07-14T23:25:21","modified_gmt":"2014-07-14T23:25:21","slug":"running-a-zpu-program-under-simulation","status":"publish","type":"post","link":"https:\/\/retroramblings.net\/?p=870","title":{"rendered":"Running a ZPU program under simulation"},"content":{"rendered":"<p>When I was debugging the ZPUFlex CPU core, I found myself using the ever-useful SignalTap to trace what was going on inside the CPU.\u00a0 One technique I wanted to use was to follow the program flow, and compare it against a simulated run through the program, thus spotting CPU bugs where the two diverged.\u00a0 To do this I needed a ZPU simulator.<\/p>\n<p><!--more-->There are two already in existence that I know of:\u00a0 Firstly, the one in the offical ZPU git repo, written in Java and requiring GDB to work.\u00a0 There is, however, no pre-built GDB binary for the ZPU, so gettng this up and running will be a challenge.<\/p>\n<p>The second pre-existing simulator is the ZPUino one.\u00a0 This has some x86 assembly language in it, so can&#8217;t easily be built on a 64-bit Linux install, and is also tightly coupled to the ZPUino way of doing things.<\/p>\n<p>Therefore, since I&#8217;d never written a CPU simulator before, I set about writing my own, and it&#8217;s now complete enough that it can run some of the demo apps from the ZPUDemos repo.\u00a0 The simulator can be found here in source form:\u00a0 <a href=\"https:\/\/github.com\/robinsonb5\/ZPUSim\">https:\/\/github.com\/robinsonb5\/ZPUSim<\/a><\/p>\n<p>Let&#8217;s start in the time-honoured tradition with a Hello World example, and run the Apps\/HelloWorld example from the ZPUDemos repository.<\/p>\n<p>The ZPUFlex core has a number of options which significantly change its operation.\u00a0 The simulator also has a few options which need to be set to match the CPU core:<\/p>\n<p>The base address of the Stack RAM can be set in the core by way of VHDL generics, and it&#8217;s critical that this matches between the core and simulator.\u00a0 This is done with the -o or -offsetstack options.\u00a0 The ZPUDemos\/RS232Bootstrap and ZPUDemos\/SDBootstrap projects map the stack to 0x40000000, so stack addresses have bit 30 set, so we specify -o30.<\/p>\n<p>If your code runs from a combined ROM \/ StackRAM and you&#8217;ve remapped the stack, then use the -b option.\u00a0 This sets the initial program counter to the start of Stack RAM, rather than zero.<\/p>\n<p>So let&#8217;s simulate a few instructions from ZPUDemos\/Apps\/HelloWorld:\u00a0 (We use the -s parameter to set the number of steps to simulate)<\/p>\n<pre>\r\n> \/path\/to\/zpusim -s10 -o30 Hello.bin\r\n\r\nPC: 0\u00a0\u00a0\u00a0 Op:b\u00a0\u00a0\u00a0 SP: 40007ff8, 40007ff8\u00a0\u00a0\u00a0 nop\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 1\u00a0\u00a0\u00a0 Op:b\u00a0\u00a0\u00a0 SP: 40007ff8, 40007ff8\u00a0\u00a0\u00a0 nop\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 2\u00a0\u00a0\u00a0 Op:b\u00a0\u00a0\u00a0 SP: 40007ff8, 40007ff8\u00a0\u00a0\u00a0 nop\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 3\u00a0\u00a0\u00a0 Op:88\u00a0\u00a0\u00a0 SP: 40007ff8, 40007ff4\u00a0\u00a0\u00a0 im 8\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 8\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 4\u00a0\u00a0\u00a0 Op:e5\u00a0\u00a0\u00a0 SP: 40007ff4, 40007ff4\u00a0\u00a0\u00a0 im (cont) 465\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 465\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 5\u00a0\u00a0\u00a0 Op:4\u00a0\u00a0\u00a0 SP: 40007ff4, 40007ff8\u00a0\u00a0\u00a0 poppc\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 465\u00a0\u00a0\u00a0 Op:88\u00a0\u00a0\u00a0 SP: 40007ff8, 40007ff4\u00a0\u00a0\u00a0 im 8\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 8\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 466\u00a0\u00a0\u00a0 Op:da\u00a0\u00a0\u00a0 SP: 40007ff4, 40007ff4\u00a0\u00a0\u00a0 im (cont) 45a\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 467\u00a0\u00a0\u00a0 Op:b\u00a0\u00a0\u00a0 SP: 40007ff4, 40007ff4\u00a0\u00a0\u00a0 nop\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 468\u00a0\u00a0\u00a0 Op:8c\u00a0\u00a0\u00a0 SP: 40007ff4, 40007ff0\u00a0\u00a0\u00a0 im c\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 c\u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 469\u00a0\u00a0\u00a0 Op:ab\u00a0\u00a0\u00a0 SP: 40007ff0, 40007ff0\u00a0\u00a0\u00a0 im (cont) 62b\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 62b\u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 46a\u00a0\u00a0\u00a0 Op:4\u00a0\u00a0\u00a0 SP: 40007ff0, 40007ff4\u00a0\u00a0\u00a0 poppc\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 62b\u00a0\u00a0\u00a0 Op:fd\u00a0\u00a0\u00a0 SP: 40007ff4, 40007ff0\u00a0\u00a0\u00a0 im 7d\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 fffffffd\u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 62c\u00a0\u00a0\u00a0 Op:3d\u00a0\u00a0\u00a0 SP: 40007ff0, 40007ff0\u00a0\u00a0\u00a0 pushspadd \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 40007fe4\u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 ffffffff\u00a0\u00a0\u00a0 ffffffff\r\nPC: 62d\u00a0\u00a0\u00a0 Op:d\u00a0\u00a0\u00a0 SP: 40007ff0, 40007fe4\u00a0\u00a0\u00a0 popsp\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 40007fe4\u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\r\nPC: 62e\u00a0\u00a0\u00a0 Op:91\u00a0\u00a0\u00a0 SP: 40007fe4, 40007fe0\u00a0\u00a0\u00a0 im 11\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 11\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 40007fe4\u00a0\u00a0\u00a0 45a\r\nPC: 62f\u00a0\u00a0\u00a0 Op:d8\u00a0\u00a0\u00a0 SP: 40007fe0, 40007fe0\u00a0\u00a0\u00a0 im (cont) 8d8\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 8d8\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 40007fe4\u00a0\u00a0\u00a0 45a\r\nPC: 630\u00a0\u00a0\u00a0 Op:51\u00a0\u00a0\u00a0 SP: 40007fe0, 40007fe4\u00a0\u00a0\u00a0 storesp 1\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 8d8\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 40007fe4\u00a0\u00a0\u00a0 45a\u00a0\u00a0\u00a0 0\r\nPC: 631\u00a0\u00a0\u00a0 Op:fd\u00a0\u00a0\u00a0 SP: 40007fe4, 40007fe0\u00a0\u00a0\u00a0 im 7d\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 fffffffd\u00a0\u00a0\u00a0 8d8\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 40007fe4\u00a0\u00a0\u00a0 45a\r\nPC: 632\u00a0\u00a0\u00a0 Op:9f\u00a0\u00a0\u00a0 SP: 40007fe0, 40007fe0\u00a0\u00a0\u00a0 im (cont) fffffe9f\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 fffffe9f\u00a0\u00a0\u00a0 8d8\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 40007fe4\u00a0\u00a0\u00a0 45a\r\nPC: 633\u00a0\u00a0\u00a0 Op:3f\u00a0\u00a0\u00a0 SP: 40007fe0, 40007fdc\u00a0\u00a0\u00a0 emulate 1f\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 634\u00a0\u00a0\u00a0 fffffe9f\u00a0\u00a0\u00a0 8d8\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 0\u00a0\u00a0\u00a0 40007fe4\r\n<\/pre>\n<p>Each line shows the current program counter, the opcode, the stack pointer before and after the intsruction, the instruction itself, then the top six stack entries after the instruction has taken effect.<\/p>\n<p>If we remove the -s parameter, we tell the simulator to run indefinitely, which results in the following output:<\/p>\n<pre>\r\n...\r\nPC: 5c9\tOp:d\tSP: 40007f98, 40007f94\tpopsp\t\t40007f98\t40007f94\t5b0\t48\t0\t0\r\nPC: 5ca\tOp:73\tSP: 40007f94, 40007f90\tloadsp 3\t\t48\t40007f98\t40007f94\t5b0\t48\t0\r\nPC: 5cb\tOp:52\tSP: 40007f90, 40007f94\tstoresp 2\t\t40007f98\t48\t5b0\t48\t0\t0\r\nPC: 5cc\tOp:c0\tSP: 40007f94, 40007f90\tim 40\t\tffffffc0\t40007f98\t48\t5b0\t48\t0\r\n\r\nReading from UART\r\n<\/pre>\n<p>The puts() routine in the firmware reads from the UART to check that the TX is available; the simulator currently waits for user input every time the register is read, so we need to supply some data.  The easiest way to this is just to add &#8220;<\/dev\/zero\" to the command line, like so:\n\n\n<pre>\r\n&gt; \/path\/to\/zpusim -o30 Hello.bin &lt;\/dev\/zero\r\n<\/pre>\n<p>Now the simulator spews massive amounts of output to the terminal, which isn&#8217;t all that useful if we&#8217;re not trying to trace through a specific routine.  It&#8217;s possible to separate the program trace and the program&#8217;s output, however; characters written to the UART are sent to stdout, while everything else goes to stderr &#8211; so if we add &#8220;2>\/dev\/null&#8221; to the command line, the output is reduced to something more manageable:<\/p>\n<pre>\r\n&gt; \/path\/to\/zpusim -o30 Hello.bin &lt;\/dev\/zero 2&gt;\/dev\/null\r\nHello, world!\r\n0\r\n2\r\n5\r\n8\r\n10\r\n13\r\n16\r\n18\r\n21\r\n24\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>When I was debugging the ZPUFlex CPU core, I found myself using the ever-useful SignalTap to trace what was going on inside the CPU.\u00a0 One technique I wanted to use was to follow the program flow, and compare it against &hellip; <a href=\"https:\/\/retroramblings.net\/?p=870\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,9],"tags":[],"class_list":["post-870","post","type-post","status-publish","format-standard","hentry","category-fpga","category-geekery"],"_links":{"self":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=870"}],"version-history":[{"count":5,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/870\/revisions"}],"predecessor-version":[{"id":875,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/870\/revisions\/875"}],"wp:attachment":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}