* **Function**: FPGA acts as **SD-host**, specifying the file name to read the file content; or specifying the sector number to read the sector content.
* **Performance**: Use SD bus instead of SPI bus. Read faster.
* **Strong compatibility**: automatically adapt to **SDcard version**, automatically adapt to **FAT16/FAT32 file system**.
* pure Verilog implement, easy to simulate and transplant.
The pin definitions of these signals on SDcard and microSDcard are as follows (SDcard and microSDcard have no difference in function except for the shape and appearance).
The SDcard is just a large linear data storage space, divided into multiple sectors, each sector contains 512 bytes, the address range of sector 0 is 0x00000000\~0x000001FF, and the address range of sector 1 is 0x00000200\~0x000003FF, and so on…. The underlying read and write operations are performed in unit of sectors. In order to organize disk partitions and files in this linear storage space, people stipulate complex data structures: file system. The most commonly used file systems for SDcard are FAT16 and FAT32.
- Manipulate the SD bus according to the SD bus standard, specify the sector number and read the sector.
- On the basis of being able to read sectors, parse the file system, that is, given the file name, to find the location and length of the file. In fact, the file may not be stored contiguously (that is, split into multiple blocks in different sectors), my code will handle this case correctly.
-`FILE_NAME` specifies the name of the target file to read.
-`FILE_NAME_LEN` specifies the file name's length (in bytes). E.g., length of "example.txt" is 11.
-`CLK_DIV` is the clock frequency division factor, its value needs to be determined according to the `clk` frequency you provide (see code comments for details).
-`SIMULATE` is the simulation speed-up option. **Usually set to `0`**. It can be set to `1` only during simulation to speed up the SD card initialization progress and prevent the simulation from taking too much time.
-`clk` is the module driving clock.
-`rstn` is the reset signal, you need to set `rstn=0` before starting to work, and then set `rstn=1` to release it.
-`sdclk` , `sdcmd` , `sddat0` are SD bus signals, should connect to SDcard.
- Note that this module only uses `sddat0` and does not use `sddat1~sddat3`, because the SDcard will run in 1bit narrow data bus mode by default when powered on, and can be switched to 4bit wide data bus mode with the command, I did not switch it, always use only `sddat0`. And `sddat1~sddat3` can be left unconnected.
-`card_type` will output the detected SDcard type: 0 corresponds to unknown, 1 corresponds to SDv1, 2 corresponds to SDv2, 3 corresponds to SDHCv2.
-`file_system_type` will output the detected file system of SDcard: 1 corresponds to unknown, 2 corresponds to FAT16, 3 corresponds to FAT32.
-`file_found` will output whether the target file was found: 0 means not found, 1 means found.
- If the target file is found, the module will output all the bytes in the file. For each output byte, a high-level pulse will be generated on `outen`, and the byte will appear on `outbyte`.
> :warning: This repo only uses sddat0 (i.e. SD 1-bit bus mode) instead of sddat1\~3. When working, you need to continuously pull sddat1\~3 high (you can write `assign sddat[3:1] = 3'b111;` in the FPGA code, or use pull-up resistors on the PCB). This is to ensure that the SD card can enter SD bus mode normally, otherwise it will enter SPI bus mode.
- sd_fake.v is the code for FPGA to imitate an SDcard. It comes from another repo of mine: [FPGA-SDfake](https://github.com/WangXuan95/FPGA-SDfake) . In this simulation, it imitates an SDcard with FAT32 system with a file "example.txt" inside. And it will be readed by the design under test (sd_file_reader.v).
- tb_sd_file_reader.v is the top level of the simulation, it will call sd_file_reader.v to read the file in sd_fake.v .
- tb_sd_file_reader_run_iverilog.bat is a command script to run iverilog simulations.
Before simulate using iverilog, you need to install iverilog , see: [iverilog_usage](https://github.com/WangXuan95/WangXuan95/blob/main/iverilog_usage/iverilog_usage.md)
example-vivado-readfile.zip contains a vivado project, which runs on the [Nexys4 development board](http://www.digilent.com.cn/products/product-nexys-4-ddr-artix-7-fpga- trainer-board.html) (it has a microSDcard slot). It will search the file example.txt from the root directory of the SDcard and read its entire content, and then send it to PC via **UART**.
1. Prepare a **microSDcard** of **FAT16** or **FAT32**. If it is not **FAT16** or **FAT32**, you need to format it.
2. Create **example.txt** in the root directory (the file name is not limited in case), and write some content in the file.
3. Insert the SDcard into the card slot of Nexys4.
4. Plug the USB port of Nexys4 into PC, and open the corresponding serial port with software such as **Serial Assistant**, **Putty**, **HyperTerminal** or **minicom**.
5. Unzip example-vivado-readfile.zip . Then open the project in it with vivado, synthesize and program it.
6. Observe that the serial port prints the contents of the file.
7. Simutinously, you can see that the LEDs on the Nexys4 change, they indicate the type and status of the SDcard, see the code for the specific meaning.
8. Press the red CPU\_RESET button on Nexys4 to re-read and print out the file content again.
example-vivado-readsector.zip contains a vivado project, which runs on the [Nexys4 development board](http://www.digilent.com.cn/products/product-nexys-4-ddr-artix-7-fpga- trainer-board.html), it will read sector 0 from the SD card (it is often called the MBR sector in file systems) and send it to PC via **UART**.
1. Prepare a **microSDcard**. Plug it into the card slot of Nexys4.
2. Plug the USB port of Nexys4 into PC, use **Serial Assistant** to open the corresponding serial port, please select "HEX Receive Mode", print each byte in hexadecimal form, so that we can see those ASCII non-printable characters.
3. Unzip example-vivado-readsector.zip . Then use vivado to open the project in it, synthesize and program it.
4. Observe that the serial port prints the contents of sector 0.
5. At the same time, you can also see that the LEDs on the Nexys4 change, they indicate the type and status of the SDcard, see the code comments for the specific meaning.
6. Press the red CPU\_RESET button on Nexys4 to re-read and print out the sector content again.