{"id":785,"date":"2014-05-05T00:26:27","date_gmt":"2014-05-05T00:26:27","guid":{"rendered":"http:\/\/retroramblings.net\/?p=785"},"modified":"2014-05-06T21:29:14","modified_gmt":"2014-05-06T21:29:14","slug":"experimenting-with-tg68-15","status":"publish","type":"post","link":"http:\/\/retroramblings.net\/?p=785","title":{"rendered":"Experimenting with TG68"},"content":{"rendered":"<p><strong>Part 14: Improving the SDRAM controller<\/strong><\/p>\n<p>One limitation of the MiniSOC project so far has been that only a very basic 16-bit 640&#215;480@60Hz screenmode is supported.\u00a0 The reason for this is mainly RAM bandwidth, since the boards I&#8217;m targetting have single-data-rate SDRAM.<\/p>\n<p>The SDRAM controller I&#8217;m using is derived from the one Tobias Gubener created for the TG68-based versions of the Minimig core.\u00a0 The original controller used 4-word bursts when reading from SDRAM, wrote in single words, and operated on a fixed 16-clock cycle, which had the advantage of guaranteeing a deterministic response time for the Amiga emulation.<!--more--><\/p>\n<p><a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_minimig.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-786\" alt=\"sdram_minimig\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_minimig.png\" width=\"600\" height=\"507\" \/><\/a><\/p>\n<p>In the work I did improving the Minimig core, I extended this so that writes also operated in burst mode, and took advantage of bank interleaving to add a second access slot to the SDRAM controller &#8211; while maintaining the fixed 16-clock cycle.\u00a0 The sequence of events looks something like this:<\/p>\n<p><a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_4wordbursts_2slots.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-787\" alt=\"sdram_4wordbursts_2slots\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_4wordbursts_2slots.png\" width=\"1200\" height=\"511\" srcset=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_4wordbursts_2slots.png 1200w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_4wordbursts_2slots-300x127.png 300w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_4wordbursts_2slots-1024x436.png 1024w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_4wordbursts_2slots-500x212.png 500w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/p>\n<p>While this allowed a significant speedup for the Minimig core, and allowed for a VGA framebuffer for the TG68MiniSOC project, resolution is limited by memory bandwidth; the standard 640x480x16@60Hz screenmode in 16-bit colour more or less saturates the first access slot, leaving the other free for the CPU (when bank interleaving allows.)<\/p>\n<p>Recently, however, I&#8217;ve wanted to increase the screen resolution to 800&#215;600 or above at 16-bit.\u00a0 The most popular 800x600x16 screenmode runs at 72Hz, and uses a pixel clock of 50Mhz (rather than the 25MHz pixel clock for 640&#215;480@60Hz) which means I&#8217;ll need to double the RAM bandwidth in order to achieve this.<\/p>\n<p>So how to approach this?<\/p>\n<p>The first thing we can do is increase the burst length from 4 words to 8 words.\u00a0 Getting this working turned out to be more tedious work than I expected, because the controller itself is a bit of a tangle, and the increased burst length shook out a few bugs elsewhere in the project, but eventually I did get this working stably.\u00a0 It required a 24-cycle ring, though, rather than 16, which means the increase in bandwidth was only 50%, not 100%.<\/p>\n<p><a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-792\" alt=\"sdram_burst8\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8.png\" width=\"1200\" height=\"712\" srcset=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8.png 1200w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8-300x178.png 300w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8-1024x607.png 1024w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8-500x296.png 500w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/p>\n<p>Nevertheless, after a complete re-architecting of the DMA cache, this was sufficient to implement something close to the standard 800x600x16@56Hz screenmode.\u00a0 This would normally require a 36MHz pixel clock, and the closest I could easily achieve was 33Mhz, but nonetheless my monitor displayed a picture, and the impact on Dhrystone score wasn&#8217;t huge, so I was happy.<\/p>\n<p>I couldn&#8217;t help thinking that the quest for more bandwidth needn&#8217;t be in vain, however.\u00a0 If you&#8217;re just reading from SDRAM then using bank interleave tricks it&#8217;s possible to transfer data on every single clock, while my 24-cycle ring version of the controller has a theoretical maximum of 16 words per 24 cycle circuit.<\/p>\n<p>Overlapping accesses to different banks is complicated by the 3-cycle CAS latency of the SDRAM, or more precisely by the fact that the latency only applies to reads, not writes.\u00a0 Ideally we want reads and writes to occupy the same &#8220;space&#8221; in the routine, so they can overlap more tightly.\u00a0 In actual operation, it turns out that the write cache doesn&#8217;t make a massive difference to the ultimate CPU speed, because generally the CPU can only write 2 words to the cache before the write has been serviced.\u00a0 Those two words are usually just a long-word (32-bit) write, aggregated into a pair of word writes, so reducing the size of the write cache to two words has only minimal impact on speed.\u00a0 What this buys us is the ability to delay writes so that they happen a few cycles later, and allowing us to &#8220;collapse&#8221; the 24-cycle ring into a 16-cycle ring, the same size as the original controller, but with double the bandwidth.<\/p>\n<p>The final sequence of events looks like this:<\/p>\n<p><a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8_2write.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-797\" alt=\"sdram_burst8_2write\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8_2write.png\" width=\"1200\" height=\"530\" srcset=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8_2write.png 1200w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8_2write-300x132.png 300w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8_2write-1024x452.png 1024w, http:\/\/retroramblings.net\/wp-content\/uploads\/2014\/05\/sdram_burst8_2write-500x220.png 500w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/p>\n<p>Using this version of the SDRAM controller, the TG68MiniSOC project is now capable of displaying an 800&#215;600 16-bit framebuffer at 72Hz refresh rate.<\/p>\n<p>As always, full\u00a0 source can be found on my GitHub page &#8211; tagged accordingly: <a href=\"https:\/\/github.com\/robinsonb5\/TG68_MiniSOC\/releases\/tag\/20140505_Part14\">https:\/\/github.com\/robinsonb5\/TG68_MiniSOC\/releases\/tag\/20140505_Part14<\/a><\/p>\n<p>If you want to try it out, build one of the project files in SOC\/fpga\/ then build Apps\/Demo or Apps\/Screenmodes<\/p>\n<p>The S-record can either be updated over RS232, or copied to an SD card and booted from there.\u00a0 (rename it to &#8220;boot.sre&#8221;.)<\/p>\n<p>In the main Demo app, the screenmode can be selected with F4-F9.\u00a0 Note that while the screenmode changes, the demo currently makes no effort to redraw what&#8217;s on screen to fit the new size, so it&#8217;ll look scrambled.<\/p>\n<p>In the Screenmodes demo app, F1 &#8211; F5 selects screenmode, and the testcard will be redrawn to fit the new size.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Part 14: Improving the SDRAM controller One limitation of the MiniSOC project so far has been that only a very basic 16-bit 640&#215;480@60Hz screenmode is supported.\u00a0 The reason for this is mainly RAM bandwidth, since the boards I&#8217;m targetting have &hellip; <a href=\"http:\/\/retroramblings.net\/?p=785\">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,8],"tags":[],"class_list":["post-785","post","type-post","status-publish","format-standard","hentry","category-fpga","category-hardware"],"_links":{"self":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/785","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=785"}],"version-history":[{"count":10,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/785\/revisions"}],"predecessor-version":[{"id":800,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/785\/revisions\/800"}],"wp:attachment":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=785"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=785"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=785"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}