{"id":1520,"date":"2021-02-25T21:55:43","date_gmt":"2021-02-25T21:55:43","guid":{"rendered":"http:\/\/retroramblings.net\/?p=1520"},"modified":"2021-03-02T21:33:21","modified_gmt":"2021-03-02T21:33:21","slug":"a-look-at-mists-toplevel","status":"publish","type":"post","link":"http:\/\/retroramblings.net\/?p=1520","title":{"rendered":"A look at MiST&#8217;s toplevel"},"content":{"rendered":"\n<p><strong>Porting a core, DeMiSTified &#8211; Part 2 &#8211; 2021-02-25<\/strong><\/p>\n\n\n\n<p>The goal is to provide an environment in which a MiST core can be included as a submodule, thus porting the core to a new target board without making large-scale changes.  To do this, we&#8217;re going to need a toplevel for each target board which maps the signals of MiST&#8217;s FPGA to board-specific resources.<\/p>\n\n\n\n<p>Let&#8217;s take a close look at a MiST core&#8217;s toplevel&#8230;<\/p>\n\n\n\n<!--more-->\n\n\n\n<pre class=\"wp-block-preformatted\">module NES_mist(  <br>   \/\/ clock input<br>   input [1:0]   CLOCK_27, \/\/ 27 MHz<br>   output LED<\/pre>\n\n\n\n<p>The very first entry could be a problem &#8211; we have a clock input that&#8217;s two bits wide so very likely a differential clock.  The target boards only have single-ended master clocks &#8211; but luckily I haven&#8217;t found a MiST core yet that uses more than just CLOCK_27[0].  Our target boards&#8217; master clocks aren&#8217;t 27MHz either &#8211; but that&#8217;s not actually a problem, as will become clear in a future installment.<\/p>\n\n\n\n<p>We have direct control over a single LED &#8211; we can map that to one of the target board&#8217;s LEDs easily enough.<\/p>\n\n\n\n<p>Next we have video output:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   output         VGA_HS, \/\/ VGA H_SYNC<br>   output         VGA_VS, \/\/ VGA V_SYNC<br>   output [ 5:0]  VGA_R, \/\/ VGA Red[5:0]<br>   output [ 5:0]  VGA_G, \/\/ VGA Green[5:0]<br>   output [ 5:0]  VGA_B, \/\/ VGA Blue[5:0]<\/pre>\n\n\n\n<p>The MiST has a simple resistor ladder DAC for video with six bits per gun (<a href=\"http:\/\/retroramblings.net\/?p=190\">it has this one<\/a>, in fact!)  The Turbo Chameleon 64 has only five bits per gun; for now we can simply discard the lower bit.  We could perform some dithering, but some cores already dither to 6 bits and double-dithering is likely to lead to poor results &#8211; so we&#8217;ll avoid that for now.  In the longer term, making the output bit depth of the guest core configurable is possible, but of course will require modifying the guest.<\/p>\n\n\n\n<p>Next up is SDRAM:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   inout [ 16-1:0]  SDRAM_DQ, \/\/ SDRAM Data bus 16 Bits                                                                                                        <br>   output [ 13-1:0] SDRAM_A, \/\/ SDRAM Address bus 13 Bits                                                                                                      <br>   output           SDRAM_DQML, \/\/ SDRAM Low-byte Data Mask                                                                                                    <br>   output           SDRAM_DQMH, \/\/ SDRAM High-byte Data Mask                                                                                                   <br>   output           SDRAM_nWE, \/\/ SDRAM Write Enable                                                                                                           <br>   output           SDRAM_nCAS, \/\/ SDRAM Column Address Strobe                                                                                                 <br>   output           SDRAM_nRAS, \/\/ SDRAM Row Address Strobe                                                                                                    <br>   output           SDRAM_nCS, \/\/ SDRAM Chip Select                                                                                                            <br>   output [ 2-1:0]  SDRAM_BA, \/\/ SDRAM Bank Address                                                                                                            <br>   output           SDRAM_CLK, \/\/ SDRAM Clock                                                                                                                  <br>   output           SDRAM_CKE, \/\/ SDRAM Clock Enable<\/pre>\n\n\n\n<p>The MiST&#8217;s SDRAM is 16 bits wide and provides 32 megabytes in a 13 row bits \/ 9 column bits layout &#8211; and luckily enough both iterations of the Turbo Chameleon 64 have chips with the same layout.  The DE10-lite has a 64 megabyte chip in a 13 \/ 10 layout but this will still be compatible unless a core&#8217;s SDRAM controller happens to do full-page bursts.  On the TC64 the chip select and clock enable pins are hardwired to save IOs, so we can simply leave those two signals unconnected.<\/p>\n\n\n\n<p>Next is audio:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>\/\/ audio<\/code><br><code>&nbsp;  output           AUDIO_L,<\/code><br><code>&nbsp;  output           AUDIO_R,<\/code><\/pre>\n\n\n\n<p>We have a single-bit output to each audio channel, typically fed from a sigma-delta converter or a PWM.   If our target board had an external audio codec on board we&#8217;d have to choose between making invasive changes to the guest core, or feeding the audio bitstream into a filter to recover a multi-bit signal suitable for the DAC.  Luckily, we don&#8217;t have to do either because the TC64 uses the same kind of single-bit audio outputs.<\/p>\n\n\n\n<p>Now we have the most important signals for this project &#8211; SPI:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ SPI<br>   inout          SPI_DO,<br>   input          SPI_DI,<br>   input          SPI_SCK,<br>   input          SPI_SS2,    \/\/ data_io<br>   input          SPI_SS3,    \/\/ OSD<br>   input          SPI_SS4,    \/\/ unused in this core<br>   input          CONF_DATA0, \/\/ SPI_SS for user_i<\/pre>\n\n\n\n<p>The broad design and function of these signals is inherited from the original Minimig project, on which a PIC microcontroller, the FPGA and the SD Card shared an SPI bus.  Multiple streams of SPI data are shared over this bus, with the SPI_SS[2-4] and CONF_DATA0 signals acting as subsystem selects.  At first glance this looks simple enough &#8211; we have data in, data out, clock and selects &#8211; but notice that SPI_DO is bidirectional.  That&#8217;s going to cause us some difficulty because only signals which map directly to toplevel pins can be bidirectional in an FPGA design.  If we&#8217;re going to replace the functionality of the MiST&#8217;s MCU within the FPGA we need to connect a new control module to these SPI signals &#8211; which makes them very much internal.<\/p>\n\n\n\n<p>The good news is that the bidirectional mode is only used in one specific circumstance &#8211; ROM loading can be sped up by allowing the controller to drive the SPI clock, but the SD card to drive the data line &#8211; we thus have a strange m\u00e9nage \u00e0 trois going on bettween the controller, FPGA and SD card &#8211; some cores don&#8217;t use it at all, including the NES core, which makes it a good starting point.  The bad news is that, for cores which *do* need it, we can&#8217;t leave the guest core completely unmodified &#8211; we will, unfortunately, have to replace this signal with separate inputs and outputs.  We&#8217;ll worry about that later, though.<\/p>\n\n\n\n<p>So let&#8217;s wrap up with:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ UART<br>   input           UART_RX,<br>   input           UART_TX<br> );<\/pre>\n\n\n\n<p>Pretty self-explanatory &#8211; and also irrelevant for the TC64, since it doesn&#8217;t have an RS232 serial port.  (It is possible, however, to pipe RS232 data over the IEC port, and I&#8217;ve done this for debugging, and also for connecting an ESP8266 WiFi module.)<\/p>\n\n\n\n<p>Next time I&#8217;ll look at the control module, and the services the guest core will need.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Porting a core, DeMiSTified &#8211; Part 2 &#8211; 2021-02-25 The goal is to provide an environment in which a MiST core can be included as a submodule, thus porting the core to a new target board without making large-scale changes. &hellip; <a href=\"http:\/\/retroramblings.net\/?p=1520\">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-1520","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\/1520","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=1520"}],"version-history":[{"count":2,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1520\/revisions"}],"predecessor-version":[{"id":1532,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1520\/revisions\/1532"}],"wp:attachment":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1520"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}