dcc reacted to [email protected] in Read from MicroSD in HDL, Write on PC
This is really the backwards way to get something like this going. You should be proving your design in simulation before jumping into a design on hardware.
Let me offer you an alternative.
Here is a Verilog driver for talking to an SD card using SPI. If you have already chosen to use the AXI bus, you can find an AXI-lite to WB bridge here that will allow you to talk to this core. Even if you already have a driver you like, this documentation for this one describes how to set up the SD card to where you can talk to it, and provides examples of how to read and write sectors. Even better, there's a piece of C++ code which can be used as a simulator with Verilator. (Not sure if this would work with MicroBlaze or not.) You can then use Linux tools, such as mkfatfs and such, to create a file with a FAT format that you can use as a "simulated" SD card. When the simulation isn't running, you can mount the card on your system and check out/modify the files, and so know that things will work (based upon your experience with simulation) once you finally switch to hardware. Indeed, if you are willing to accept the risks, you could even interact with your SD card from the simulation environment itself. If you want an example of a set up that would control the SD card interface from a ZipCPU, you can check out the ZBasic repository which has such a simulation integrated into it. Indeed, there's even an sdtest.c program that can be used for that purpose. As for reading and comprehending the FAT filesystem, there's a FATFS repository that is supposedly good for use with embedded software. I haven't tried it, so I can't comment upon it that much. Alternatively, if you can control how the file system is laid out, you should be able to place a file of (nearly) arbitrary length a couple of sectors into the FS, and force the file to be use contiguous sectors. If you do that, then you've dealt with the most complicated parts about reading from the SD card. Just my two cents, and some thoughts and ideas along the way.
dcc reacted to JColvin in Read from MicroSD in HDL, Write on PC
I'm not certain how you are verifying that the HDL is writing to and then reading back from the SD card in a normal formatting style, but in general FAT32 is a widely used format for SD cards that has existing material for it.
I am uncertain why you are using a special tool to write to the SD card though; from what I can tell the tool is Windows compatible, so why not just use the Notepad program which comes with Windows and save a .txt file with the data you are interested in reading to the SD card or just using Windows Explorer (the file manager) to move the file of interest onto the SD card? If you do have a header in your file, you will need to take account for that, though I do not know what you mean by "random file" in this case.
dcc reacted to [email protected] in How to read and write to sd card in Artix 7 Nexys4 board? If i want to access image and work on it and store it back on sd card. Please help me in terms of coding advice i'm new for this.
For being new, you've picked a pretty challenging project!
Reading an image from an SD card requires several layers of processing. The first part is the physical layer. The specification outlines one of two means of communicating with a cards physical layer: using the SDIO protocol (a four-wire, bidirectional data/command channel), and using the SPI protocol. I have personally built a Verilog core that communicates over the SPI protocol, and you are welcome to use my core, while other's have done their work with SDIO and ... I haven't tried their cores so I cannot speak to it.
Across this physical layer, and to get things up and running, a protocol handshake must take place between the card and the controller. This handshake is outlined in the physical specification above, and also in the instructions for the controller I just mentioned. For a given card, the handshake isn't all that difficult. Indeed, for a given class of cards it's probably not that bad. To process every possible SD card, finding appropriate examples to test with can be a challenge--just to prove that you can handle all the corner cases.
Once you can handle communications at this level, you will then be able to read and write sectors from the SD card.
The next level, beyond sectors, involves reading and understanding the partition table. This table will tell you where the file systems are on the SD card, and more specifically, what file systems are on the SD card. In general, most SD cards have only one file system on them so partition processing is pretty simple. That file system is a FAT filesystem--whether FAT16, FAT32, etc. I'm not certain. (I haven't gotten this far yet.)
After the partition layer, you will need to process the file system. Assuming that your SD card has a FAT filesystem on it, there will be two types of files on the system: file containing directory entries, and other. These files may be found in any order on the SD card, as specified by the file allocation table. That table contains one entry per cluster on the file system, telling you that after you read the given cluster, where to find the next one. (Clusters are similar to sectors, but may be implemented as groups of sectors.) If the filesystem is in proper order, the last cluster will identify itself as the last cluster.
So, the steps to processing this filesystem involve:
Identifying which version of the FAT system you are working with Finding, from that information, the first cluster of the root directory Reading through the directory for the file you want. (Keep in mind, other clutsers to this directory may be out of order--you'll need to look up their locations in the table.) If your file is in a subdirectory, you'll have to find the subdirectory entry. Once you have the file (subdirectory) you want, you'll find a location on the disk where that file begins. (IIRC, it's the cluster number of the first sector of the file) You'll also find the length of the file (or subdirectory) you are interested in. If what you found was a subdirectory, and if it's the subdirectory your file is in (assuming it is in a subdirectory and not the main directory), you'll then need to repeat this process, reading the subdirectory "file" and looking for your file's entry. (Or perhaps looking for another subdirectory entry.) From the final entry, you will now know where to find the first cluster of your file, and the full length of the file in bytes. (It may be longer or shorter than the number of clusters allocated for it in the allocation table.) The file allocation table will tell you where to find subsequent clusters. If all you wish to do is to change the image in place, then you now know where to find all the pieces. At this point, you can change the file as it exists on the SD card at will. Creating new files on the SD card requires creating a directory entry that file, find empty clusters to hold the file, placing the number of the first cluster into the directory, adjusting the directory length, etc.
It doesn't take long and this becomes an in-depth software task.
I have seen some approaches where individuals have created their own partitions containing their own file system with their own format just to avoid all of this hassle, and to be successful doing this within a microcontroller. While doable, such solutions tend to be application specific.
Hope this helps,
dcc reacted to [email protected] in ARTY board, read from DDR3 and write to PMOD
If you actually want to set/read memory, you'll need to learn how to interact with a bus. I like to use a B4 pipelined wishbone bus. I find it very simple and easy to use. For example, you can find a very simple block RAM device here that interacts with a wishbone bus. (It would be even simpler if I wasn't keeping my high speed and low speed code in the same file ...)
Xilinx has committed themselves to the AXI bus--a bus that requires the management of five separate data paths just to get right. If you want access to DDR3 SDRAM, you'll need to use Xilinx's memory interface generator (MIG) to build an interface for you. (I tried without MIG, made lots of progress, but ... after two months of full time work on it hadn't finished the task. It's a shame. The memory access delay would've been about half of what Xilinx's delay is.) Xilinx's MIG generates a DDR3 interface to a memory using an AXI controller. You can see how I interact with that AXI controller in my own Arty design here. Within that file, take a look at the mig_axis component and then roll your eyes with me at the quantity of wires and communications paths you need to handle just to read or write from memory. Yuck.
That's why, in the same file, you'll find a wishbone to axi bridge, one I call wbm2axisp, or wishbone master to AXI slave pipelined. As a result, I can interact with that core using wishbone signals, such as i_wb_cyc to indicate that I am accessing the bus (needs to be high throughout the transaction), i_wb_stb to request a memory interaction (only needs to be high for one clock while o_wb_stall is low per request), i_wb_addr (specifying the address of my request, must be valid any time i_wb_stb is high), i_wb_we (specifies if I am reading or writing), i_wb_data (data to write, must be valid anytime i_wb_stb and i_wb_we are high), o_wb_ack (true any time a memory access completes), o_wb_stall (true if the memory isn't ready to accept a transaction), and o_wb_data (the data result of any read transaction). The number of wishbone signals are truly ... much less than that giant AXI bus. (10 signals, of which 4 have multiple bits associated with them.) Looking at the AXI bus, to interact with it you will need 35 signals, of which 23 have multiple bits. Take your pick. (By the way, going from an 8-bit data width to the 128 bit data width used by the DDR3 SDRAM is not nearly as hard as it sounds, if that's something you would be struggling with.)
If you are trying to read/write from memory to support both an ADC and a DAC, you'll need a couple of things. One of them is a FIFO. You can see an example of a FIFO supporting a UART here. DDR3 memory speed can be unpredictable, and it can drop out suddenly for a refresh cycle while you are trying to interact with it. Worse, that MIG interface takes upwards of 24 clocks to complete a transaction. (If you pipeline your requests, only the first will take 24 clocks, the rest can take one clock. See the wishbone B4 spec for a discussion of this.) However, with a FIFO you can weather some of these problems without dropping samples, and even get on and off the memory bus faster. Second, you'll need an arbiter--something that decides of the two transactions you'd like to make, which of them actually gets access to the bus. You can find my own wishbone arbiter here.
If you are wondering just how to get a wishbone transaction working, I have examples ranging from simple to complex. For example, here is a simple prefetch example that just reads a single value from memory (i.e., the next instruction for a CPU). Here's another, similar example, which reads two values from memory at a time. (When working with that SDRAM, the first can take 24 cycles per read, the second can do two reads in 25 clock cycles.) And, while we are at it, here's an example which reads 2^N values at once--but since it's got a cache within it, it ... tends to be more complicated. Another example would be the code I've used for building my own DMA. Take your pick. How deep would you like to dive into this? I could go on and on for a while with more examples ...
Is this the sort of thing you are looking for? Let me know, and I can offer more, explain any of the above, or ... you tell me.