Hamster's SDRAM_Controller


leon912

Recommended Posts

Yes, i'm writing ascii. Doing other tests, I discovered that if i do consecutive writes, there is no problem but when i try to read consecutively, 1 of the 2 16-bit words is stick to the previous value of the i/o bus. To be clearer:

 

I write:

 

ABCD

EFGH

IJKL

MNOP

 

and when I read, I get

 

MNCD

ABGH

EFKL

IJOP

 

The only solution I found was to perform a read, discard the result, read again and keep that one as a good result. In that way it works but the bandwidth is halved. 

 

Do you know any usefull solution?

Link to comment
Share on other sites

Hi,

 

the only thing I can give you is the FSM I wrote to read/write from the memory through the memory controller.

 

At the output of the memory controller I have a register to sample the read value and this register is enabled by sdram_data_ready generated by the controller itself. Finally the output of the register (which is a 32 bit word) is divided in 4 bytes and sent to a mux4x1 that selects the byte to be sent via usb.

 

 

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity FSM_SDRAM_TO_UART is
port( rst : in std_logic;
clk   : in std_logic;
led : out std_logic;
-- SDRAM CONTROLLER signals
cmd_ready       : in STD_LOGIC;                     -- '1' when a new command will be acted on
        cmd_enable       : out STD_LOGIC;                     -- Set to '1' to issue new command (only acted on when cmd_ready = '1')
        cmd_wr           : out STD_LOGIC;                     -- Is this a write?
        cmd_address     : out STD_LOGIC_VECTOR(20 downto 0); -- address to read/write
        cmd_byte_enable : out STD_LOGIC_VECTOR(3 downto 0);  -- byte masks for the write command
        cmd_data_in     : out STD_LOGIC_VECTOR(31 downto 0); -- data for the write command
 
sdram_data_ready : in std_logic;
 
mux_ctrl : out std_logic_vector(1 downto 0);
 
-- UART CONTROLLER signals
uart_new_data : out std_logic;
uart_busy : in std_logic);                     -- signs that transmitter is busy
end entity FSM_SDRAM_TO_UART;
 
 
 
architecture BEHAVIOURAL of FSM_SDRAM_TO_UART is
 
type state_type is ( IDLE, WRITE0, INCR_ADDR0, WAIT0, 
WRITE1, INCR_ADDR1, WAIT1, 
WRITE2, INCR_ADDR2, WAIT2, 
WRITE3, INCR_ADDR3, WAIT3,
READ_TEST, WAIT_TEST, READ0, SAMPLE, SAMPLING, SEND_UART0, WAIT_UART0, SEND_UART1, WAIT_UART1, SEND_UART2, WAIT_UART2, SEND_UART3, INCR_ADDR, WAIT_READ, STOP);
  signal CURRENT_STATE, NEXT_STATE : state_type;
 
signal sdram_addr     : STD_LOGIC_VECTOR(20 downto 0);
signal addr_incr : std_logic;
signal addr_rst : std_logic;
 
begin
 
cmd_address <= sdram_addr;
 
 
FSM_REG : process (clk, rst)
     begin
       if rst = '1' then
              CURRENT_STATE <= IDLE;
       elsif (clk'event and clk = '1') then
              CURRENT_STATE <= NEXT_STATE;
       end if;
   end process FSM_REG;
 
 
process(clk, rst, addr_incr, addr_rst)
variable temp  :  integer  := 0;  
 
begin
 
if(rst = '1' OR addr_rst = '1') then
temp := 0;
elsif(clk'event AND clk = '1') then
if(addr_incr = '1') then
if(temp = 5) then
temp := 0;
else
temp := temp + 1;
end if;
end if;
end if;
 
sdram_addr <= std_logic_vector(to_unsigned(temp, sdram_addr'length));
end process;
 
 
 
FSM_OUT : process (CURRENT_STATE)
     begin
       case CURRENT_STATE is
          when IDLE =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '1';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WRITE0 =>
cmd_enable       <= '1';
cmd_wr           <= '1';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "1111";
cmd_data_in     <= x"41424344";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when INCR_ADDR0 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '1';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WAIT0 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WRITE1 =>
cmd_enable       <= '1';
cmd_wr           <= '1';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "1111";
cmd_data_in     <= x"45464748";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when INCR_ADDR1 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '1';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WAIT1 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WRITE2 =>
cmd_enable       <= '1';
cmd_wr           <= '1';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "1111";
cmd_data_in     <= x"494A4B4C";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when INCR_ADDR2 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '1';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WAIT2 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WRITE3 =>
cmd_enable       <= '1';
cmd_wr           <= '1';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "1111";
cmd_data_in     <= x"4D4E4F50";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when INCR_ADDR3 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '1';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WAIT3 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '1';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when READ_TEST =>
cmd_enable       <= '1';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WAIT_TEST =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when READ0 =>
cmd_enable       <= '1';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when SAMPLE =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when SAMPLING =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when SEND_UART0 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '1';
led <= '0';
mux_ctrl <= "00";
 
when WAIT_UART0 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "01";
 
when SEND_UART1 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '1';
led <= '0';
mux_ctrl <= "01";
 
when WAIT_UART1 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "10";
 
when SEND_UART2 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '1';
led <= '0';
mux_ctrl <= "10";
 
when WAIT_UART2 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "11";
 
when SEND_UART3 =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '1';
led <= '0';
mux_ctrl <= "11";
 
when INCR_ADDR =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '1';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when WAIT_READ =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '0';
mux_ctrl <= "00";
 
when STOP =>
cmd_enable       <= '0';
cmd_wr           <= '0';
addr_incr <= '0';
addr_rst        <= '0';
cmd_byte_enable <= "0000";
cmd_data_in     <= x"00000000";
uart_new_data <= '0';
led <= '1';
mux_ctrl <= "00";
 
end case;
end process;
 
 
 
 
FSM_NEXT_STATE : process(CURRENT_STATE, uart_busy, cmd_ready, sdram_data_ready, sdram_addr)
begin
case CURRENT_STATE is
when IDLE =>
if (cmd_ready = '1') then
NEXT_STATE <= WRITE0;
else
NEXT_STATE <= IDLE;
end if;
 
when WRITE0 =>
if (cmd_ready = '0') then
NEXT_STATE <= INCR_ADDR0;
else
NEXT_STATE <= WRITE0;
end if;
 
when INCR_ADDR0 =>
NEXT_STATE <= WAIT0;
 
 
when WAIT0 =>
if (cmd_ready = '1') then
NEXT_STATE <= WRITE1;
else
NEXT_STATE <= WAIT0;
end if;
 
when WRITE1 =>
if (cmd_ready = '0') then
NEXT_STATE <= INCR_ADDR1;
else
NEXT_STATE <= WRITE1;
end if;
 
when INCR_ADDR1 =>
NEXT_STATE <= WAIT1;
 
when WAIT1 =>
if (cmd_ready = '1') then
NEXT_STATE <= WRITE2;
else
NEXT_STATE <= WAIT1;
end if;
 
when WRITE2 =>
if (cmd_ready = '0') then
NEXT_STATE <= INCR_ADDR2;
else
NEXT_STATE <= WRITE2;
end if;
 
when INCR_ADDR2 =>
NEXT_STATE <= WAIT2;
 
when WAIT2 =>
if (cmd_ready = '1') then
NEXT_STATE <= WRITE3;
else
NEXT_STATE <= WAIT2;
end if;
 
when WRITE3 =>
if (cmd_ready = '0') then
NEXT_STATE <= INCR_ADDR3;
else
NEXT_STATE <= WRITE3;
end if;
 
when INCR_ADDR3 =>
NEXT_STATE <= WAIT3;
 
when WAIT3 =>
if (cmd_ready = '1') then
NEXT_STATE <= READ_TEST;
else
NEXT_STATE <= WAIT3;
end if;
 
when READ_TEST =>
if (cmd_ready = '0') then
NEXT_STATE <= WAIT_TEST;
else
NEXT_STATE <= READ_TEST;
end if;
 
when WAIT_TEST =>
if (cmd_ready = '1') then
NEXT_STATE <= READ0;
else
NEXT_STATE <= WAIT_TEST;
end if;
 
when READ0 =>
if (cmd_ready = '0') then
NEXT_STATE <= SAMPLE;
else
NEXT_STATE <= READ0;
end if;
 
when SAMPLE =>
if (sdram_data_ready = '1') then
NEXT_STATE <= SAMPLING;
else
NEXT_STATE <= SAMPLE;
end if;
 
when SAMPLING =>
NEXT_STATE <= SEND_UART0;
 
when SEND_UART0 =>
if (uart_busy = '1') then
NEXT_STATE <= WAIT_UART0;
else
NEXT_STATE <= SEND_UART0;
end if;
 
when WAIT_UART0 =>
if (uart_busy = '0') then
NEXT_STATE <= SEND_UART1;
else
NEXT_STATE <= WAIT_UART0;
end if;
 
when SEND_UART1 =>
if (uart_busy = '1') then
NEXT_STATE <= WAIT_UART1;
else
NEXT_STATE <= SEND_UART1;
end if;
 
when WAIT_UART1 =>
if (uart_busy = '0') then
NEXT_STATE <= SEND_UART2;
else
NEXT_STATE <= WAIT_UART1;
end if;
 
when SEND_UART2 =>
if (uart_busy = '1') then
NEXT_STATE <= WAIT_UART2;
else
NEXT_STATE <= SEND_UART2;
end if;
 
when WAIT_UART2 =>
if (uart_busy = '0') then
NEXT_STATE <= SEND_UART3;
else
NEXT_STATE <= WAIT_UART2;
end if;
 
when SEND_UART3 =>
if (uart_busy = '1') then
NEXT_STATE <= INCR_ADDR;
else
NEXT_STATE <= SEND_UART3;
end if;
 
when INCR_ADDR =>
NEXT_STATE <= WAIT_READ;
 
when WAIT_READ =>
if (to_integer(unsigned(sdram_addr)) = 4) then
NEXT_STATE <= STOP;
elsif (cmd_ready = '1' AND uart_busy = '0') then
NEXT_STATE <= READ_TEST;
else
NEXT_STATE <= WAIT_READ;
end if;
 
when STOP =>
NEXT_STATE <= STOP;
 
when others =>
NEXT_STATE <= IDLE;
 
end case;
end process;
 
end architecture;
Link to comment
Share on other sites

First analysis in simulation show first output (through serial port) of ''0x41 0x44 0x43 0x42", "ADCB". Does this match your output ?

 

The SDRAM controller also seems to be writing out data in invalid endianess - I see the initial write of "0x41424344", but reads from this address come out as "0x43444142". The two 16-bit seem to be misaligned. Is this something you changed ?

 

Other issues:

 

- You are writing *twice* to the same address. This is not problematic because controller will be busy on second write, still this is a bad thing to do.

- You are waiting for cmd_ready to be '1' before asserting  cmd_enable. You should assert cmd_enable as soon you have a command, and keep it asserted while controller does not accept it (ie, keep it asserted with correct cada until cmd_ready is '1').

- Same applies to reads, and you are reading twice from each address, which does not make sense.

 

If you can install GTKWAVE I can send you the simulation output.

 

I am not using your SDRAM simulation model though, I am using my own (which I cannot distribute)

 

Alvie

Link to comment
Share on other sites

Hi Alvie,

 

thanks for your reply.

 

1. I used the Hamster's SDRAM model to run simulation on modelsim but the model itself doesn't work. For this reason I tested my component directly on the papilio board and it happened that, after writing x"41424344", the output was x"43444142", so the 2 16-bit words were swapped; for this reason I changed the code of the controller swapping the values "data_out       <= captured_data_last & captured_data;".

 

2. I checked my code and I don't see how I write twice in the same address: I have a counter that after each write increases the address so the write is done only once in each different address.

 

3. I wait for the cmd_ready to be 1 only because it was suggested to me to do so.

 

4. Regarding the reads, I do read twice from the same address for the following reason: as I wrote in the past posts, when I write for example

 

ABCD

EFGH

IJKL

MNOP

 

and I try to read from the same memory location in the same order, I read:

 

MNCD

ABGH

EFKL

IJOP

 

so it seems like that the first 16-bit word keeps the old value; reading the first time, discarding the data and the reading again from the same location, was the best solution.

 

As I said, I tryied this code of the papilio board, not only in simulation with modelsim or GTKWAVE, and it works.

 

Maybe you got a different code for the model or the controller with respects to me. Have you tryied to implement everything on the board?

Link to comment
Share on other sites

No, I did not implement on board (I rarely do until I am pretty much sure it works).

 

I wonder if you can use my own version of that controller, which is the one used by ZPUino. The interface is similar, but it requires an extra clock - I am wondering if this relates to the issue you see in hamster's.

 

I'll show you the dual writes later today.

 

I may happen that your IO blocks are sub-optimal. Can you send me these files too so I can run a timing check ?

.ncd file

.ngd file

.pcf file

 

Alvie

Link to comment
Share on other sites

  • 4 weeks later...
  • 7 months later...

Sorry for bumping this topic, but is there any progress on this? I'm also trying to implement sdram reads and writes from the microblaze using it's i/o bus, but I am also experiencing problems with the upper 16 bits which are for some reason stuck on the value that was written before. It really sounds like some neasty timing problem in which the (16 bit) value previously written is still on the data bus of the sdram and then read as the next top 16 bits. Could it anyhow be related to the 100 MHz clock I'm using? I used the sdram before with a slightly higher rate of 108 MHz, which worked fine. I will try using 108 MHz and report back if it works.

Edit: Switching to 108 MHz doesn't seem to work either. I'm still having the same problem.

Edit2: Appearently replacing the line 

signal data_ready_delay : std_logic_vector( 3 downto 0);   

by 

 signal data_ready_delay : std_logic_vector( 4 downto 0); 

in the sdram controller did the trick. That last line was there already commented out, so I think @hamster has been experimenting with this too.

It looks to me as if the problem has been solved this way. The 2 parts of the 32 bit value are also not reversed anymore now.

Link to comment
Share on other sites

55 minutes ago, alvieboy said:

It may relate to different setup/hold values, and how FPGA routes stuff.

Can you check that all your DATA/ADDRESS lines for the SDRAM have IO registers ?

 

Alvie

Were you talking to me or the OP? I've done some tests with writing audio to the sdram and playing it through a delta-sigma dac, all memory mapped to the microblaze, and that seems to work very well, so everything is solved for me. Also, I have mapped everything to the microblaze by using it's io bus, which makes it possible to access the sdram as if it's a continuous memory region on the chip and the dac as memory mapped io.

This is the c code for storing audio send over uart to the sdram and playing it.

#include <xparameters.h>
#include <xiomodule.h>
#include "xil_cache.h"
#include <xenv.h>
#include <stdbool.h>

#define REG_DAC_DATA				(*((volatile u32*)0xF0000010))
#define REG_DAC_DATA2				(*((volatile u32*)0xF0000014))

#define SDRAM_START					0xD0000000

int nrSamplesInSDRAM = 0;
int curSample = 0;
u16* sndPtr = (u16*)SDRAM_START;

void timerTick(void* ref)
{
	if(nrSamplesInSDRAM > 0)
	{
		u16 val = *sndPtr++;
		REG_DAC_DATA = val;
		REG_DAC_DATA2 = val;
		curSample++;
		//curSample+=2;
		if(curSample >= nrSamplesInSDRAM)
		{
			curSample = 0;
			sndPtr = (u16*)SDRAM_START;
		}
	}
}

XIOModule System;

void uartRead(u16 numBytes, u8 *data) {
	u16 counter = 0;
	while(counter < numBytes) {
		u16 numRead;
		while((numRead = XIOModule_Recv(&System,data,numBytes-counter)) == 0);
		counter += numRead;
		data += numRead;
	}
}

int main()
{
	Xil_DCacheDisable();

	nrSamplesInSDRAM = 0;
	curSample = 0;
	sndPtr = (u16*)SDRAM_START;

	XIOModule_Initialize(&System, XPAR_IOMODULE_0_DEVICE_ID);
	microblaze_register_handler(XIOModule_DeviceInterruptHandler, XPAR_IOMODULE_0_DEVICE_ID);
	XIOModule_Start(&System);
	XIOModule_CfgInitialize(&System,NULL,1);
	XIOModule_SetBaudRate(&System, 750000);//115200);

	xil_printf("==== START ====\n\r");

	// Set the interval of the PIT. Default counter clock is system clock.
	XIOModule_SetResetValue(&System, 0, 108000000 / 32000);//2250);//3375);

	// Register interrupt handler
	XIOModule_Connect(&System, XIN_IOMODULE_PIT_1_INTERRUPT_INTR, timerTick, NULL);

	// Enable interrupts
	XIOModule_Enable(&System, XIN_IOMODULE_PIT_1_INTERRUPT_INTR);

	// Specify PIT is to automatically reload. Without this, ISR runs once
	XIOModule_Timer_SetOptions(&System, 0, XTC_AUTO_RELOAD_OPTION);

	XIOModule_Timer_Start(&System, 0);

	microblaze_enable_interrupts();

	while(1)
	{
		if(nrSamplesInSDRAM < 4 * 1024 * 1024)
		{
			uartRead(8 * 1024, &((u16*)SDRAM_START)[nrSamplesInSDRAM]);
			nrSamplesInSDRAM+=8 * 1024 / 2;
		}
	}
}

 

Link to comment
Share on other sites

On the mapping report (.mrp) you should see if your IO pins have dedicated IO registers.

 

+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| IOB Name                           | Type             | Direction | IO Standard          | Diff  | Drive    | Slew | Reg (s)      | Resistor | IOB      |
|                                    |                  |           |                      | Term  | Strength | Rate |              |          | Delay    |
+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| CLK                                | IOB              | INPUT     | LVTTL                |       |          |      |              |          |          |
| DRAM_ADDR<0>                       | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST | OFF          |          |          |
....
| DRAM_CLK                           | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST | ODDR         |          |          |
| DRAM_CS_N                          | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST |              |          |          |
| DRAM_DQ<0>                         | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| DRAM_DQ<1>                         | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
...
| DRAM_DQM<0>                        | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST | OFF          |          |          |
| DRAM_DQM<1>                        | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST | OFF          |          |          |
| DRAM_RAS_N                         | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST | OFF          |          |          |
| DRAM_WE_N                          | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST | OFF          |          |          |

 

As you can see here, the address lines have OFF in Reg(s) tab, meaning "Output Flip Flop". The Clock line is driven by a ODDR flip flop. The data lines have both OFF and IFF (Input Flip Flop). All other control lines have OFF.

This ensures minimal delay from clock to pad, and to chip, and its very important to timing.

You seem to have increased one of the timings, though. I wonder it is the same issue we are facing with newer SDRAM parts.

Alvie

Link to comment
Share on other sites

This is my mapping report:

+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| IOB Name                           | Type             | Direction | IO Standard          | Diff  | Drive    | Slew | Reg (s)      | Resistor | IOB      |
|                                    |                  |           |                      | Term  | Strength | Rate |              |          | Delay    |
+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| CLK                                | IOB              | INPUT     | LVTTL                |       |          |      |              |          |          |
| RX                                 | IOB              | INPUT     | LVTTL                |       |          |      |              |          |          |
| SDRAM_ADDR<0>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<1>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<2>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<3>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<4>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<5>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<6>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<7>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<8>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<9>                      | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<10>                     | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<11>                     | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_ADDR<12>                     | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW |              |          |          |
| SDRAM_BA<0>                        | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_BA<1>                        | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_CKE                          | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_CLK                          | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | ODDR         |          |          |
| SDRAM_CS                           | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW |              |          |          |
| SDRAM_DQ<0>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<1>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<2>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<3>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<4>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<5>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<6>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<7>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<8>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<9>                        | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<10>                       | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<11>                       | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<12>                       | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<13>                       | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<14>                       | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQ<15>                       | IOB              | BIDIR     | LVTTL                |       | 12       | FAST | IFF          |          |          |
|                                    |                  |           |                      |       |          |      | OFF          |          |          |
| SDRAM_DQM<0>                       | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_DQM<1>                       | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_nCAS                         | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_nRAS                         | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| SDRAM_nWE                          | IOB              | OUTPUT    | LVTTL                |       | 12       | SLOW | OFF          |          |          |
| TX                                 | IOB              | OUTPUT    | LVTTL                |       | 8        | FAST |              | PULLUP   |          |
| dac_out                            | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST |              |          |          |
| dac_out2                           | IOB              | OUTPUT    | LVTTL                |       | 12       | FAST |              |          |          |
+---------------------------------------------------------------------------------------------------------------------------------------------------------+

Could it be related to the SLEW rate too? For some pins it seems to be SLOW.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.