SD Controller modifications - nealcrook/multicomp6809 GitHub Wiki

With Grant's sd_controller.vhd code as the starting-point, I have made a mumber of changes to the code. Grant has given me permission to repost his code. My version in github has been created as a sequence of separate commits, starting with Grant's original, so that each individual change can be inspected. Some changes are functional (affect the behaviour) and some are non-functional (affect the commenting/indentation/whitespace).

  1. Add a detailed header explaining the programming model (I've now updated that to cover both SDSC and SDHC).

  2. Some additional comments.

  3. Merged the two processes that used n_wr into a single process.

  4. Added names to all the processes (aids debug in simulation).

  5. Corrected a bug where init_busy was 0 for one half sdSCLK time immediately after reset (unlikely to cause a problem in practice).

  6. Merged in changes from RHKoolap which add support for SDHC cards.

  7. Changed the clocking. Previously the design used a "derived clock" - the clock input was a divided-down clock from the 50MHz input. The design is now intended to use the 50MHz clock directly and is clock-gated to run at a lower rate to generate an appropriate sdSCLK. The clock-gating is controlled by a divider whose value is set through a generic. Using a gated clock rather than a divided clock has the apparent disadvantage that the logic needs to timing close at 50MHz (even though it will never actually run that fast). However, since the logic will timing-close at that speed with no effort, it is not a real disadvantage. The compensating advantage is that derived clocks are always a nuisance and can make timing closure (particularly meeting hold) difficult. To use the new clocking, change the port map like this:

    sd1 : entity work.sd_controller

    generic map(

      `CLKEDGE_DIVIDER => 25      -- clk=50MHz / 25 gives edges at 2MHz and therefore`
                                 `-- an sdSCLK of 1MHz.`
    

    ) port map(

          `sdCS => sdCS,`
          `sdMOSI => sdMOSI,`
          `sdMISO => sdMISO,`
          `sdSCLK => sdSCLK,`
          `n_wr => n_WR_sd,`
          `n_rd => n_RD_sd,`
          `n_reset => n_reset,`
          `dataIn => cpuDataOut,`
          `dataOut => sdCardDataOut,`
          `regAddr => cpuAddress(2 downto 0),`
          `driveLED => driveLED,`
          `clk => clk`
    

    );