{"id":352,"date":"2013-04-06T19:56:10","date_gmt":"2013-04-06T19:56:10","guid":{"rendered":"http:\/\/retroramblings.net\/?p=352"},"modified":"2013-04-06T23:29:34","modified_gmt":"2013-04-06T23:29:34","slug":"pace-adventures-part-4","status":"publish","type":"post","link":"https:\/\/retroramblings.net\/?p=352","title":{"rendered":"PACE Adventures &#8211; Part 4"},"content":{"rendered":"<h1><strong>A worked example&#8230;<\/strong><\/h1>\n<p>Since I&#8217;ve been asked just how difficult it is to port a PACE arcade machine to the Chameleon, I figured a worked example would be useful! So what I&#8217;m going to do is document the process of getting Galaxian up an running. I&#8217;m going to assume you&#8217;re using Linux here. It&#8217;s all equally possible on Windows, but you&#8217;ll need to deal with things like getting an SVN client up and running, and I&#8217;m afraid I can&#8217;t help with that.<\/p>\n<p>The first thing you need is a copy of the current PACE repository (Revision 1402 at the time of writing), so from a terminal, type:<br \/>\n<code>svn checkout https:\/\/svn.pacedev.net\/repos\/pace<\/code><br \/>\n<!--more--><br \/>\nIf all goes well you&#8217;ll have a new directory called &#8220;pace&#8221; with about 360 megabytes of stuff within. The two directories we&#8217;re interested in are sw\/src and sw\/synth. The first contains the VHDL implementation of the various arcade machine chips PACE needs to emulate, and also toplevels for each target board, and any other board-specific supporting logic that might be required.<br \/>\nThe second contains certain device-specific implementations of things like dual-port RAMs emulated in FPGA BlockRAM, and also contains the actual project files for each combination of emulated platform and target board.<\/p>\n<p>We can find all the existing ports of Galaxian in sw\/synth\/platform\/galaxian\/galaxian\/<br \/>\nAt the time of writing there are targets for cb, de1, de2, nb1, p2, p3m, rc10 and s5a_r2c0. The easiest way to port to a new target is to pick a similar device that already has a port, and adapt its port. The most important thing is that we pick a port that targets an Altera device, since the Cyclone III in the Chameleon is an Altera device, so for no very good reason other than it targetting a Cyclone II device, we&#8217;ll pick the p2 port.  (With the benefit of hindsight, it&#8217;s a good idea to try building the project before you start, just to see whether it&#8217;s been maintained as the core of the project has evolved.)<\/p>\n<p>Use Quartus to open up the p2\/galaxian.qpf file, and once it&#8217;s open, go to &#8220;Project -&gt; Copy Project&#8221;.<br \/>\nIn the Destination directory box, change &#8220;p2_copy&#8221; to &#8220;chameleon64&#8221; and hit OK.<br \/>\n<a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/copyproject.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-361\" alt=\"copyproject\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/copyproject.png\" width=\"607\" height=\"264\" srcset=\"https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/copyproject.png 607w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/copyproject-300x130.png 300w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/copyproject-500x217.png 500w\" sizes=\"auto, (max-width: 607px) 100vw, 607px\" \/><\/a><br \/>\nNow we need to go through the list of project files, removing anything specific to the P2 board, such as &#8230;&#8230;\/p2\/target_pkg.vhd. We can also remove anything that mentioned &#8220;maple&#8221; or &#8220;gamecube&#8221;, since those are for interfacing console controllers, and we have no way of connecting those to the Chameleon.<\/p>\n<p>Now here we hit a snag: if you click on any of the files that have relative paths, you&#8217;ll find that they won&#8217;t open, and you&#8217;ll get a &#8220;file not found&#8221; error. I presume what&#8217;s happened here is that the project&#8217;s been moved into a subdirectory at some point, so the relative paths now all have the wrong number of &#8220;..\/&#8221; in them. To fix this we could either painstakingly remove and re-add each file, or we can ignore the dire warnings at the head of the .qsf file and edit it manually. I&#8217;m going to do the latter.<br \/>\nShut down Quartus (because editing the file while it&#8217;s open really would be asking for trouble), then open up galaxian.qsf in a text editor, and go a global search-and-replace, changing &#8220;..\/..\/..\/&#8221; to &#8220;..\/..\/..\/..\/&#8221; &#8211; i.e. changing three sets of dots to four. Open re-opening the project in Quartus you should now find that the files open up correctly.<\/p>\n<p>Now we need to add target-specific files to the project. Go to &#8220;Project -&gt; Add\/Remove files in Project&#8221;, click the &#8220;..&#8221; button beside the filename box and navigate to pace\/sw\/src\/target\/chameleon64\/ &#8211; and multi-select all the .VHD files in there. Add them to the project. We&#8217;re now about half way through the porting process!<\/p>\n<p>Next we need to change the FPGA we&#8217;re targetting, since the P2 board used a Cyclone II and we&#8217;re using a Cyclone III. Go to &#8220;Assignments -&gt; Device&#8221; and change &#8220;Family&#8221; to &#8220;Cyclone III&#8221;. (Yes, we want to remove assignments.)<br \/>\nSet the Pin Count to 144, to narrow down the available range, and select EP3C25E144C8. (Yes, again we want to remove assignments. Migration devices? Yeah, whatever &#8211; we don&#8217;t actually care&#8230;).<br \/>\nNow hit &#8220;Device and Pin options&#8221;, on the Voltage page set the default IO voltage to &#8220;3.3&#8221;, and on the Dual Purpose Pins page set everything to &#8220;Use as regular IO&#8221;.<br \/>\n<a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/DevicePin.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-362\" alt=\"Device&amp;Pin\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/DevicePin.png\" width=\"913\" height=\"749\" srcset=\"https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/DevicePin.png 913w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/DevicePin-300x246.png 300w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/DevicePin-365x300.png 365w\" sizes=\"auto, (max-width: 913px) 100vw, 913px\" \/><\/a><br \/>\nOne other thing we need to do: on the &#8220;Programming Files&#8221; page, enable &#8220;Raw Binary File (.rbf)&#8221;, since that&#8217;s the format Chaco prefers for flashing cores into the Chameleon.<br \/>\nNow Click OK until you&#8217;re back to the main Quartus Window.<\/p>\n<p>Now we need to tell Quartus which pin does what. To avoid having to enter assignments manually we&#8217;ll use a .csv file which you can download <a href=\"http:\/\/retroramblings.net\/downloads\/ChameleonPins.csv\">here<\/a>.<br \/>\nGo to &#8220;Assignments -&gt; Import Assignments&#8221;, select the .csv file, and click OK.<\/p>\n<p>We&#8217;re nearly there, now &#8211; we just need to take care of clocks. PACE doesn&#8217;t actually care all that much what the main clock frequency is, provided you set some constants correctly. The Chameleon, on the other hand, needs a clock of roughly 100MHz in order to read joystick events from the C64 or Docking Station, so we use a 100Mhz clock. We also need a secondary clock for video. The appropriate frequency depends on the video mode we&#8217;re using, but for 800&#215;600@60Hz, it should be 40Mhz.<br \/>\nWe need to create a PLL to generate these clocks from the Chameleon&#8217;s base 8MHz clock. To do this, go to &#8220;Tools -&gt; Megawizard Plug-in Manager&#8221;, and select &#8220;Create a new custom megafunction variation&#8221;.<br \/>\nThe filename should already be filled in with the correct path (i.e. the project&#8217;s own path), so just add to the end, &#8220;pllclk_ez&#8221; (without the quotes!), from the list of available megafunctions, unfold &#8220;IO&#8221; and select ALTPLL, then click next.<br \/>\nChange &#8220;inclk frequency&#8221; to 8 Mhz, then keep clicking next until you get to the page for configuring clock C0.<br \/>\nSimply select &#8220;Enter output clock frequency&#8221; and set the clock to 100Mhz, then click Next.<br \/>\nFor clock C1, check the &#8220;Use this clock&#8221; box, and set the frequency to 40Mhz. Now click &#8220;Finish&#8221;.<br \/>\n<a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/PLLConfig.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-360\" alt=\"PLLConfig\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/PLLConfig.png\" width=\"908\" height=\"754\" srcset=\"https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/PLLConfig.png 908w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/PLLConfig-300x249.png 300w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/PLLConfig-361x300.png 361w\" sizes=\"auto, (max-width: 908px) 100vw, 908px\" \/><\/a><\/p>\n<p>Nearly there. Now all we have to do is change the clock multipliers, which are found in project_pkg.vhd (about the only file that doesn&#8217;t begin with loads of &#8220;..\/&#8221;).<\/p>\n<p>We need to make sure that PACE_HAS_PLL is set to &#8220;true&#8221;, and that PACE_VIDEO_CONTROLLER_TYPE is set to PACE_VIDEO_VGA_800x600_60Hz; In both case this is already set the way we want it, so we only have to adjust PACE_CLK0_DIVIDE_BY, etc.<br \/>\nEverything&#8217;s referenced to the incoming 8MHz clock, so since we&#8217;ve used the PLL make CLK0 100Mhz, we need to inform the PACE framework. We&#8217;ve multiplied the clock by 100, and divided by 8, so cancelling down we can simplify that to multiplying by 25 and dividing by 2. So we set PACE_CLK0_MULTIPLY_BY to 25, and PACE_CLK0_DIVIDE_BY to 2.<br \/>\nSimilarly, for CLK1, the video clock, we&#8217;ve multiplied by 40 and divided by 8, which cancels down simply to multiplying by 5, so we set PACE_CLK1_MULTIPLY_BY to 5, and PACE_CLK1_DIVIDE_BY to 1.<\/p>\n<p>Finally we check that GALAXIAN_USE_INTERNAL_WRAM is set to true. This tells the project to emulate SRAM using the FPGA&#8217;s internal BlockRAM. The Chameleon doesn&#8217;t have any real SRAM.<\/p>\n<p>In theory that&#8217;s it, so we do a test compile&#8230; and&#8230; oops &#8211; we hit an error:<br \/>\n<code>Error (10482): VHDL error at project_pkg.vhd(56): object \"ADV724_STD_PAL\" is used but not declared<\/code><br \/>\nOK &#8211; double-click on the error, and we find a constant that&#8217;s not applicable to our target platform, and since it&#8217;s in the project-specific project_pkg file we can just comment it out by putting &#8220;&#8211;&#8221; (two dashes) before it.<\/p>\n<p>Try again, and this time we hit:<br \/>\n<code>Error (10481): VHDL Use Clause error at target_top.vhd(425): design library \"work\" does not contain primary unit \"sigma_delta_dac\"<\/code><br \/>\nOK &#8211; well that&#8217;s easy to fix &#8211; just add the file src\/component\/sound\/sigma_delta_dac.vhd to the project, and try again&#8230;<\/p>\n<p>Oops &#8211; another error!<br \/>\n<code>Error (10334): VHDL error at bitmapctl.vhd(14): entity \"bitmapCtl\" is used but not declared<br \/>\nHmmm - I guess the bitmap controller is missing from the project? OK adding src\/pace\/video<\/code>\/bitmapctl_e.vhd should do it.<\/p>\n<p>And&#8230;. nope! Man, bit-rot must have set in with this one!<br \/>\n<code>Error (10334): VHDL error at tilemapctl.vhd(18): entity \"tilemapCtl\" is used but not declared<br \/>\nError (10481): VHDL Use Clause error at tilemapctl.vhd(9): design library \"work\" does not contain primary unit \"platform_variant_pkg\"<\/code><br \/>\nOK so we&#8217;ll add tilemapctl_e.vhd from the same place as the last fix, and also src\/platform\/galaxian\/galaxian\/platform_variant_pkg.vhd, and see what happens now&#8230;<\/p>\n<p>OK yet another error:<br \/>\n<code>Error (10887): VHDL error at video_mixer.vhd(33): elsif or else statement inside a generate statement is not supported in VHDL_1993, and is only supported for VHDL 2008<\/code><br \/>\nOK that&#8217;s easy to solve, just tell the compiler to accept VHDL 2008 constructs, by going to &#8220;Assignments -&gt; Settings&#8221;, going to the &#8220;VHDL input&#8221; page and selecting &#8220;VHDL 2008&#8221;.<\/p>\n<p>Fingers crossed&#8230;. Darn!<br \/>\n<code>Error (10482): VHDL error at Graphics.VHD(88): object \"PACE_VIDEO_H_SYNC_POLARITY\" is used but not declared<br \/>\nError (10482): VHDL error at Graphics.VHD(89): object \"PACE_VIDEO_V_SYNC_POLARITY\" is used but not declared<\/code><br \/>\nOK to fix that we just add the following two lines to project_pkg.vhd:<br \/>\n<code>constant PACE_VIDEO_H_SYNC_POLARITY : std_logic := '1';<br \/>\nconstant PACE_VIDEO_V_SYNC_POLARITY : std_logic := '1';<\/code><\/p>\n<p>So are we there yet? No!<br \/>\n<code>Error (10481): VHDL Use Clause error at Inputs.VHD(75): design library \"work\" does not contain primary unit \"inputmapper\"<\/code><br \/>\nOK &#8211; the inputmapper file got moved, it seems, so add src\/platform\/galaxian\/galaxian\/input_mapper.vhd to the project. While we&#8217;re at it we&#8217;ll add src\/platform\/galaxian\/altera_mem.vhd too.<\/p>\n<p>So we build the project again, and this time&#8230; success!&#8230;. sort of!<br \/>\n<!--more--><a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-370\" alt=\"Galax1\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax1.jpg\" width=\"630\" height=\"500\" srcset=\"https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax1.jpg 630w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax1-300x238.jpg 300w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax1-378x300.jpg 378w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p>OK so what went wrong here? Well we&#8217;ve set the screen resolution to 800&#215;600@60Hz, but the Galaxian screenmode is much smaller than that, so it gets centred within the field. We can expand the screen by changing scale factors in the project_pkg.vhd file:<br \/>\n<code>constant PACE_VIDEO_H_SCALE : integer := 2;<br \/>\nconstant PACE_VIDEO_V_SCALE : integer := 2;<\/code><br \/>\nBut it still won&#8217;t fill the screen, so the other thing we can do is change the screenmode to 640&#215;480@60Hz.<br \/>\n<code>constant PACE_VIDEO_CONTROLLER_TYPE : PACEVideoController_t := PACE_VIDEO_VGA_640x480_60Hz;<\/code><br \/>\nBut if we do that, we have to edit the PLL megafunction (using the MegaWizard Plugin Manager), and change C1 from 40Mhz to 25MHz &#8211; a more appropriate pixel clock for 640&#215;480 mode. For the sake of completeness we&#8217;ll change the CLK1 scale factors in project_pkg.vhd too.<br \/>\n<a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-371\" alt=\"Galax2\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax2.jpg\" width=\"611\" height=\"500\" srcset=\"https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax2.jpg 611w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax2-300x245.jpg 300w, https:\/\/retroramblings.net\/wp-content\/uploads\/2013\/04\/Galax2-366x300.jpg 366w\" sizes=\"auto, (max-width: 611px) 100vw, 611px\" \/><\/a><br \/>\nOK that&#8217;s more like it!<\/p>\n<p>Well I seem to have picked the most difficult one to date for this guide, but that&#8217;s perhaps no bad thing. Binaries and source will follow later<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A worked example&#8230; Since I&#8217;ve been asked just how difficult it is to port a PACE arcade machine to the Chameleon, I figured a worked example would be useful! So what I&#8217;m going to do is document the process of &hellip; <a href=\"https:\/\/retroramblings.net\/?p=352\">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":[6,4],"tags":[],"class_list":["post-352","post","type-post","status-publish","format-standard","hentry","category-arcade","category-fpga"],"_links":{"self":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/352","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=352"}],"version-history":[{"count":21,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/352\/revisions"}],"predecessor-version":[{"id":378,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/352\/revisions\/378"}],"wp:attachment":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}