OpenCores
no use no use 1/1 no use no use
SD controller PIO (not DMA) design documentation
by n6nfg on Oct 16, 2009
n6nfg
Posts: 5
Joined: Oct 7, 2009
Last seen: Feb 26, 2010
I am looking at the SD controller "simple" core (not using DMA) and I can't find any documentation on the register definitions and any sample initialization code sequences to use for SD init and read/write. All the documentation listed is for the DMA design. The RTL design files seem to be very independent of the DMA RTL design files, so it would be nice if there were design documentation on the smaller PIO design also.

Is there anyone that can provide information on how to actually use the PIO design from a programming standpoint? There doesn't seem to be a "command" register in the conventional sense, looks like maybe commands are simply sent to a "command fifo" address. I don't see any reference to any kind of busy status to poll to see when commands to the SD are complete.

Tac2, are you out there??

Thanks
Todd
RE: SD controller PIO (not DMA) design documentation
by tac2 on Oct 17, 2009
tac2
Posts: 27
Joined: Sep 23, 2008
Last seen: Feb 3, 2012
In the SW folder there are a main.c file for this project which i think gives you a good idea how it works.

You have 2 FIFO to write to and 2 to read from, one-set for CMD and DATA each.

#define TX_CMD_FIFO 0x00 --Command to be sent
#define RX_CMD_FIFO 0x04 --Response to command
#define TX_DATA_FIFO 0x08 --Data to send
#define RX_DATA_FIFO 0x0C -- Data received

To check FIFO flags there is a status register
#define STATUS 0x10
Where the bits [ ]
0 == 1 then TX_CMD_FIFO is Full
1 == 1 then RX_CMD_FIFO is Empty
2 == 1 then TX_DATA_FIFO is Full
3 == 1 then RX_DATA_FIFO is Empty



RE: SD controller PIO (not DMA) design documentation
by n6nfg on Oct 22, 2009
n6nfg
Posts: 5
Joined: Oct 7, 2009
Last seen: Feb 26, 2010
Thanks for the reply. I now understand the C driver and how it controls the FIFO SD design. I do have an additional question though. Was the FIFO design verified in RTL simulation or only in FPGA?

The reason I ask is that there is only an SD model to simulate against in the "DMA" bench directory, There is no "FIFO" bench directory. Is is OK to use the SD model from the DMA bench with the FIFO design? I have constructed an RTL test bench with the FIFO SD controller interfaced with the DMA SD model.

The reason I ask is that I am having trouble simulating both mmc_write_block and mmc_read_block using the SD model from the DMA directory. It would appear that the DMA SD model is configured to be a 1.x version design (doesn't return any response to the CMD8 in the mmc_init procedure). Is this correct?

When I do mmc_init followed by mmc_write_block, the SD controller accepts the 512 bytes of write data (I get a response to the CMD24 in the RX_CMD_FIFO) and see the data go out on the SD 4 bit data bus, but the SD model never sends a CRC response back to the SD controller (RX_DATA_FIFO stays empty, no activity on CMD or DATA lines from SD model).

When I do mmc_init followed by mmc_read_block I get a response to the CMD17 (in RX_CMD_FIFO) but no read data is transferred from the SD model to the SD controller (RX_DATA_FIFO stays empty).

Thanks
Todd
RE: SD controller PIO (not DMA) design documentation
by tac2 on Oct 22, 2009
tac2
Posts: 27
Joined: Sep 23, 2008
Last seen: Feb 3, 2012
No not a complete test bench, just tested the FIFO and WISHBONE part and used a dummy SD-model, because the back end SD-communication is more or less the same as in the DMA.

Yes its 1.0 model at the moment.

Sounds strange that no CRC appears after the sending of the Data, check what's happening internally in SD-model (check the states Datastate and State) to see if it get stuck somewhere or something.
If not probably some instantiation problem.

Can you upload you test bench or mail it to me?
RE: SD controller PIO (not DMA) design documentation
by n6nfg on Oct 23, 2009
n6nfg
Posts: 5
Joined: Oct 7, 2009
Last seen: Feb 26, 2010
Ok, I found out that the SD model wasn't being placed into the transfer state by CMD 7 in mmc_init. The reason for this is that the RCA obtained by the previous CMD 3 was not matching the RCA of the SD model, so the CMD 7 was not effective.

According to the SD Physical Layer Specification version 2.0, Command Index should be in positions 45:40, the RCA bits should occupy bit positions 39:24 and Card Status occupies bits 23:8 of the 48 bit argument field. Right shifting this by 8 bits to remove the CRC gives us a 40 bit response to read in the driver. It would appear that the SD FIFO Controller is returning the 40 bit R6 response in a "funny" order as read from the RX_CMD_FIFO. Let me try to explain below what I am seeing.

I see in the SD model that RCA occupies bits 127:112 and CardStatus occupies 111:96 of the response_CMD and inCmd occupies bits 133:128. This looks correct, in that the Command Index is above RCA which is above card status in bit position in the 136 bit response_CMD vector. Bits 135:112 are a good representation of the 40 bit R6 response. In my particular case, the 40 bit vector is `h0300200600, CMD Index 03, RCA 0020, CardStatus 0600.

The bytes fetched from the RX_CMD_FIFO when reading the response to CMD 7 come in the following order as read: 00, 20, 06, 00, 00. As you can see, this order is not the same as the original 40 bit vector sent by the SD model. Apparently once received and processed by the FIFO SD controller, the bytes are altered, before being presented to the FIFO for reading by the host. The CMD Index is gone (no byte = 03 in any of the 5 bytes), the RCA seems to be the first 2 bytes read while the Card Status seems to be the next 2 bytes. The fifth byte of 00 could be the position occupied by the CMD Index, but it is no longer 03 if so and should be adjacent to the RCA, not the Card Staus.

The C driver included in the SW directory does know how to interpret the RCA field positions as returned, but I am confused about the relative positions of the response as read from the FIFO, vs what was sent out by the SD Model. If my driver really needs to interpret status bits returned from the various commands, I don't know what positions to match up with the SD Physical Layer Specification and the bytes returned from the RX_CMD_FIFO. Can you provide any further insight into this?

For now, I have block writes working correctly, but block reads seem to have a nibble reversal (at byte written as 12 gets to the flash memory correctly, but upon reading it back with block read, it comes back as 21 from the RX_DATA_FIFO). This seems to happen with all bytes of the block. I haven't found the cause of this yet, but looks like there is an assembly problem from 2 nibbles to a byte in the receive direction.

Thanks
Todd
RE: SD controller PIO (not DMA) design documentation
by tac2 on Oct 23, 2009
tac2
Posts: 27
Joined: Sep 23, 2008
Last seen: Feb 3, 2012

The bytes fetched from the RX_CMD_FIFO when reading the response to CMD 7 come in the following order as read: 00, 20, 06, 00, 00. As you can see, this order is not the same as the original 40 bit vector sent by the SD model. Apparently once received and processed by the FIFO SD controller, the bytes are altered, before being presented to the FIFO for reading by the host. The CMD Index is gone (no byte = 03 in any of the 5 bytes), the RCA seems to be the first 2 bytes read while the Card Status seems to be the next 2 bytes. The fifth byte of 00 could be the position occupied by the CMD Index, but it is no longer 03 if so and should be adjacent to the RCA, not the Card Staus.



Yes its almost correct, the bits from the SD card is actual read from MSB to LSB.
Bit nr (SD-Spec) | Receive order
47:40 Not returned
39:32 [0] CMD-Reply
31:24 [1] CMD-Reply
23:16 [2] CMD-Reply
15:8 [3] CMD-Reply
7:0 [4] CRC-Status 0000 0000 = OK, 0000 0001 CRC error

If you want CMD-index to be return i can modifie it and send it


For now, I have block writes working correctly, but block reads seem to have a nibble reversal (at byte written as 12 gets to the flash memory correctly, but upon reading it back with block read, it comes back as 21 from the RX_DATA_FIFO). This seems to happen with all bytes of the block. I haven't found the cause of this yet, but looks like there is an assembly problem from 2 nibbles to a byte in the receive direction.
Thanks
Todd


Is this in the testbench? The nible order can be change in row 491 in the sd_data_phy.v .
RE: SD controller PIO (not DMA) design documentation
by n6nfg on Oct 24, 2009
n6nfg
Posts: 5
Joined: Oct 7, 2009
Last seen: Feb 26, 2010
Ok, I did have to reverse the nibble ordering in sd_data_phy.v (lines 364 and 365) to get the data to read back correctly. Don't know if this is a bug in the code, or some other issue in the initialization or test bench.

I am attaching the test bench I am using. It is loosely based in the DMA test bench. All of the "C" file has been translated to verilog, with three tasks mmc_init, mmc_write_block, and mmc_read_block working. The block number to read or write is currently hard coded to 0. There are 4 tests defined, 0 is initialize, 1 is write block, 2 is read block, and 3 is compare write/read memories. Maybe this test bench can be considered for inclusion into the FIFO bench directory since there isn't one currently.

I noticed in the sdModel file that the CRC 7 and CRC 16 module calls were undefined when the test bench is linked. I modified sdModel to instantiate the CRC 7 and 16 modules from the sd_cmd_phy and sd_data_phy RTL modules.

I also found that if you start a simulation and do mmc_init followed by mmc_read_block, that the read doesn't return good data. The RX_DATA_FIFO is not accessed correctly on the first read after mmc_init. The fifo gets underrun by 16 bytes at the end of the block, and the first several bytes read at the beginning of the block are bad (all zero). If you do a write block first after mmc_init, and then a read block, then the read is good.

I also noticed that making the sequence: mmc_init, mmc_write_block, mmc_read_block, compare data, mmc_write_block, mmc_read_block, compare data results in the second write block returning bad CRC, and the second read block returning wrong data (probably because the 2nd write didn't work properly). There would appear to be some problems still in more complicated accesses then one single write and read. I'll keep looking into things to try and explain the problems.
test_sd.v (21 kb)
RE: SD controller PIO (not DMA) design documentation
by tac2 on Oct 28, 2009
tac2
Posts: 27
Joined: Sep 23, 2008
Last seen: Feb 3, 2012
Ok, I did have to reverse the nibble ordering in sd_data_phy.v (lines 364 and 365) to get the data to read back correctly. Don't know if this is a bug in the code, or some other issue in the initialization or test bench.

I am attaching the test bench I am using. It is loosely based in the DMA test bench. All of the "C" file has been translated to verilog, with three tasks mmc_init, mmc_write_block, and mmc_read_block working. The block number to read or write is currently hard coded to 0. There are 4 tests defined, 0 is initialize, 1 is write block, 2 is read block, and 3 is compare write/read memories. Maybe this test bench can be considered for inclusion into the FIFO bench directory since there isn't one currently.

I noticed in the sdModel file that the CRC 7 and CRC 16 module calls were undefined when the test bench is linked. I modified sdModel to instantiate the CRC 7 and 16 modules from the sd_cmd_phy and sd_data_phy RTL modules.

I also found that if you start a simulation and do mmc_init followed by mmc_read_block, that the read doesn't return good data. The RX_DATA_FIFO is not accessed correctly on the first read after mmc_init. The fifo gets underrun by 16 bytes at the end of the block, and the first several bytes read at the beginning of the block are bad (all zero). If you do a write block first after mmc_init, and then a read block, then the read is good.

I also noticed that making the sequence: mmc_init, mmc_write_block, mmc_read_block, compare data, mmc_write_block, mmc_read_block, compare data results in the second write block returning bad CRC, and the second read block returning wrong data (probably because the 2nd write didn't work properly). There would appear to be some problems still in more complicated accesses then one single write and read. I'll keep looking into things to try and explain the problems.
test_sd.v (21 kb)


Sounds like some counters is not reseted correclty in the SD model, haven't tried many cycler in it before so, it much likely the problem,. I atatch a new sd_Model that should return right value if u do read after init. Also the FLASH-Memory write counter dident reset, this should fix the problem you encounted.
sd_model.v (19 kb)
RE: SD controller PIO (not DMA) design documentation
by n6nfg on Oct 29, 2009
n6nfg
Posts: 5
Joined: Oct 7, 2009
Last seen: Feb 26, 2010
I agree with both of your changes in sdModel.v. I found the same two issues.

I am attaching a new sd_data_phy.v file which has three changes to fix bugs I found when doing testing. You can "grep" for "TODD" to see the changes I made.

At lines 364 and 365, I reversed the nibble ordering of the read data from SD.

At line 377 I added "sd_we_o
At line 430 I added "busy_int
With these three changes (and the sdModel changes) I have reliable write and/or read of blocks in any order. I suggest these changes be put in the repository so the next user doesn't encounter the same bugs.

Thanks for all your help, everything is working good now.
sd_data_phy.v (10 kb)
RE: SD controller PIO (not DMA) design documentation
by mountainhua on Mar 1, 2010
mountainhua
Posts: 5
Joined: Mar 6, 2009
Last seen: Sep 16, 2011
Hi, tac2

I'm using SD controller PIO. I have finished the rtl simulation until now. But I involve in problem when FPGA verification.

1.In ./trunk/sw/sd_fifo/main.c, CMD55&ACMD41 is not executed when spv_2_0 is equal to 1(it means that v2.0 is compatible). It seems incorrect according to SEPC 2.0. Ok?

2.In my test code, CMD55&ACMD41 is cycled and bit[31] of the response of ACMD41 is the condition to exit the loop. Only when bit[31] is set to 1, CMD2 and proceeding CMD can be executed.
But this bit keeps 0 forever in verification even if voltage window of the response is OK. I'm confused.

Waiting for your reply.
RE: SD controller PIO (not DMA) design documentation
by udicemimi on Apr 23, 2010
udicemimi
Posts: 1
Joined: Jan 16, 2010
Last seen: Oct 7, 2011
Hi mountainhua,

I am getting the same result as busy bit keeps 0 forever. By any chances you find out the problem?

Thanks,
udice

Hi, tac2

I'm using SD controller PIO. I have finished the rtl simulation until now. But I involve in problem when FPGA verification.

1.In ./trunk/sw/sd_fifo/main.c, CMD55&ACMD41 is not executed when spv_2_0 is equal to 1(it means that v2.0 is compatible). It seems incorrect according to SEPC 2.0. Ok?

2.In my test code, CMD55&ACMD41 is cycled and bit[31] of the response of ACMD41 is the condition to exit the loop. Only when bit[31] is set to 1, CMD2 and proceeding CMD can be executed.
But this bit keeps 0 forever in verification even if voltage window of the response is OK. I'm confused.

Waiting for your reply.

RE: SD controller PIO (not DMA) questio about fifo
by gunde on Jul 5, 2010
gunde
Posts: 1
Joined: Jan 7, 2009
Last seen: Jan 11, 2012
Hi,
I would like to use this core with an FPGA from Lattice (xp2). Unfortunately I get an error
"Found NRAM ram_1[7:0] with multiple processes"
in the module "vfifo_dual_port_ram_dc_dw"

always @ (posedge clk_b)
...
q_b ...

The previous process (always @ (posedge clk_a)) also accesses the register RAM[].

Is it possible to modify the existing code to make it compatible to the Lattice tools, or would it be easier to exchange the fifos from this design with fifo ip-core from lattice?

Thanks

no use no use 1/1 no use no use
© copyright 1999-2012 OpenCores.org, equivalent to ORSoC AB, all rights reserved. OpenCores®, registered trademark.