-
Notifications
You must be signed in to change notification settings - Fork 17
SD Controller modifications
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).
-
Add a detailed header explaining the programming model (I've now updated that to cover both SDSC and SDHC).
-
Some additional comments.
-
Merged the two processes that used n_wr into a single process.
-
Added names to all the processes (aids debug in simulation).
-
Corrected a bug where init_busy was 0 for one half sdSCLK time immediately after reset (unlikely to cause a problem in practice).
-
Merged in changes from RHKoolap which add support for SDHC cards.
-
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`
);