kerob_labs
Newbie
Hi all,
I'm using board with CycloneV (5CEFA5F23) with two SDRAM (W9825G-6) to form a 32bit memory bus.
According to the datasheet, it seems I'm interfacing the SDRAM correctly, but it's not working. It seems it's not doing the refresh.
So I'm here in the hope someone will tell me what I'm doing wrong.
Background:
I wrote VHDL to access the SDRAM. It can be seem (hopefully) in https://github.com/keroblabs/fpga_dev/tree/master
The project consists in USART RX/TX (basic USART stuff), USART DMA (receives commands from the USART and convert them to address, RD/WR, etc), the SDRAM interface (control DQMs, and generate the refresh) and the SDRAM module (got from someone else). The toplevel project is called SOC_Toplevel (creative).
The board has a 50MHz clock input, this goes through a PLL to generate 126MHz. This choice of clock is tied to an upcoming VGA module. All modules are driven by this clock. The refresh rate and the baudrate is set in soc_toplevel.vhd. The baudrate is set to 38400bps so the "baudrate" variable value is calculate as (126 * 1000 / 38400). The "mem_refresh_rate" value comes from (126 * 7us). The file was committed with a refresh rate of 2.9 us (I will explain soon). There is a "simulation" pin that cut the SDRAM initialisation short.
The modules can be compiled individually:
memory_development/sdram_module to compile only the SDRAM module
memory_development/sdram_interface to compile the memory interface with SDRAM module
usart_block to compile the USART TX/RX
usart_schedule (sorry for the confusing name) to compile the USART DMA test module.
soc_toplevel put everything together.
Everything was created using Quartus Prime 20.1.1 Lite Edition. Everything checked in to github should work from the individual project to the soc_toplevel.
I order to understand why the refresh was not working, the USART DMA module was modified and looks very patchy.
It will perform a test every 2 seconds (approximately). First will do a write of a test value to the SDRAM, followed by a read and send the read value to the USART. After 2 seconds, it will only read the same SDRAM address. After another 2 seconds, It will increment the test value and the cycle restarts by a new write + read + send value.
In short, the test module does: "write + read + send via serial", wait 2 seconds "read + send via serial", wait 2 seconds, "Increment test value, write + read + send via serial"
As the refresh is not working, we see the following in the USART, each byte coming every 2 seconds: 00 FF 01 FF 03 FF 04 FF.
At reset, the address in which the write + read is performed is $000000. This address can be changed via the USART.
Additionally to the write + read test, the USART will receive commands to read and write to the SDRAM. The command starts with the first byte with MSB bit set to 1, following by 3 bytes with MSB set to zero so only 7 bits encode the address. The first byte is encoded from MSB: "1 0 WE A25 A24 A23 A22 A21". WE=1 for read and 0 for write (this follows the SDRAM encoding). The following bytes uses only 7 bits to encode the remaining address bits (with MSB set to zero). The command can be restarted by send the first byte with MSB bit set to 1. For a write command, the 5th byte will be the data, and for reading, the read byte will be returned after the 4th bytes of address. This address will then be used to the write + read test.
What I tried:
I double checked the FPGA pinout to the SDRAM, I tried to switch between clock-rise and clock-fall, but the datasheet specifically says all signals are retained on clock-rise.
I tried to add a precharge before the refresh, I initially tried 7us refresh rate, reduced to 2.9us, I also tried two clocks between RAS and CAS.
The only thing I didn't try is to reduce the clock, to, say, 100MHz, but I don't it will make any difference.
I would like to think that something is wrong with the VHDL code, rather than faulty components.
Sorry for a long background. I'm trying to anticipate most of questions.
Hope someone can help.
Thanks!
I'm using board with CycloneV (5CEFA5F23) with two SDRAM (W9825G-6) to form a 32bit memory bus.
According to the datasheet, it seems I'm interfacing the SDRAM correctly, but it's not working. It seems it's not doing the refresh.
So I'm here in the hope someone will tell me what I'm doing wrong.
Background:
I wrote VHDL to access the SDRAM. It can be seem (hopefully) in https://github.com/keroblabs/fpga_dev/tree/master
The project consists in USART RX/TX (basic USART stuff), USART DMA (receives commands from the USART and convert them to address, RD/WR, etc), the SDRAM interface (control DQMs, and generate the refresh) and the SDRAM module (got from someone else). The toplevel project is called SOC_Toplevel (creative).
The board has a 50MHz clock input, this goes through a PLL to generate 126MHz. This choice of clock is tied to an upcoming VGA module. All modules are driven by this clock. The refresh rate and the baudrate is set in soc_toplevel.vhd. The baudrate is set to 38400bps so the "baudrate" variable value is calculate as (126 * 1000 / 38400). The "mem_refresh_rate" value comes from (126 * 7us). The file was committed with a refresh rate of 2.9 us (I will explain soon). There is a "simulation" pin that cut the SDRAM initialisation short.
The modules can be compiled individually:
memory_development/sdram_module to compile only the SDRAM module
memory_development/sdram_interface to compile the memory interface with SDRAM module
usart_block to compile the USART TX/RX
usart_schedule (sorry for the confusing name) to compile the USART DMA test module.
soc_toplevel put everything together.
Everything was created using Quartus Prime 20.1.1 Lite Edition. Everything checked in to github should work from the individual project to the soc_toplevel.
I order to understand why the refresh was not working, the USART DMA module was modified and looks very patchy.
It will perform a test every 2 seconds (approximately). First will do a write of a test value to the SDRAM, followed by a read and send the read value to the USART. After 2 seconds, it will only read the same SDRAM address. After another 2 seconds, It will increment the test value and the cycle restarts by a new write + read + send value.
In short, the test module does: "write + read + send via serial", wait 2 seconds "read + send via serial", wait 2 seconds, "Increment test value, write + read + send via serial"
As the refresh is not working, we see the following in the USART, each byte coming every 2 seconds: 00 FF 01 FF 03 FF 04 FF.
At reset, the address in which the write + read is performed is $000000. This address can be changed via the USART.
Additionally to the write + read test, the USART will receive commands to read and write to the SDRAM. The command starts with the first byte with MSB bit set to 1, following by 3 bytes with MSB set to zero so only 7 bits encode the address. The first byte is encoded from MSB: "1 0 WE A25 A24 A23 A22 A21". WE=1 for read and 0 for write (this follows the SDRAM encoding). The following bytes uses only 7 bits to encode the remaining address bits (with MSB set to zero). The command can be restarted by send the first byte with MSB bit set to 1. For a write command, the 5th byte will be the data, and for reading, the read byte will be returned after the 4th bytes of address. This address will then be used to the write + read test.
What I tried:
I double checked the FPGA pinout to the SDRAM, I tried to switch between clock-rise and clock-fall, but the datasheet specifically says all signals are retained on clock-rise.
I tried to add a precharge before the refresh, I initially tried 7us refresh rate, reduced to 2.9us, I also tried two clocks between RAS and CAS.
The only thing I didn't try is to reduce the clock, to, say, 100MHz, but I don't it will make any difference.
I would like to think that something is wrong with the VHDL code, rather than faulty components.
Sorry for a long background. I'm trying to anticipate most of questions.
Hope someone can help.
Thanks!