[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[microblaze-uclinux] SDRAM on a Microblaze : I need help



Hello,

I'm experciencing problem using external SDRAM on my custom Virtex II
board. I've used a lot of things from Robin Coxe design :
http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/archive/2005/03/msg00145.html
but I still have a last problem. I nearly have the same memory chip as
he does, I have a 48L32M8A2-75, which means that I have a 8-bit data bus
and he has a 16-bit one. Here is the link for the datasheet :

I have a test program which is simple and is attached to the email (it
is only a simple version, the final one will check on more data, but
here I send a simple one for lisibilty). And here is what I get on the
console :

> Memory Test Program
> Erasing SDRAM
> Erasing done
>  checking erase
> address : 0x80000000 value : 0x0
> address : 0x80000004 value : 0x0
> address : 0x80000008 value : 0x0
> address : 0x8000000C value : 0x0
> Writing to the SDRAM
> address : 0x80000000 value to be written : 0x12345678
> address : 0x80000004 value to be written : 0x12345678
> address : 0x80000008 value to be written : 0x12345678
> address : 0x8000000C value to be written : 0x12345678
> write operations finished
> Reading back from the SDRAM
> address : 0x80000000 read value : 0x345678
> address : 0x80000004 read value : 0x12345678
> address : 0x80000008 read value : 0x345678
> address : 0x8000000C read value : 0x12345678
> end of Memory Test program

As you can see, I have a problem reading or writing (cannot know it yet)
the MSbyte, and since Microblaze is big-endian, it must be the last one.
  So I think this is a timing problem (maybe am I wrong ? but before I
had the same behaviour at the same addresses on the two last bytes, and
correcting timings gave me that better - but still false - behaviour).
I also have to say that if I shift up the addresses I work with by 4
bytes (one Word) the addresses where I have problem are the same :
0x.......0 and 0x.......8 : this is strange !

I've attached my MHS file, but here is the SDRAM_controller part :

> BEGIN opb_sdram
>  PARAMETER INSTANCE = sdram_controller
>  PARAMETER HW_VER = 1.00.d
>  PARAMETER C_BASEADDR = 0x80000000
>  PARAMETER C_HIGHADDR = 0x81ffffff
>  PARAMETER C_SDRAM_TRAS = 44000
>  PARAMETER C_SDRAM_TRC = 66000
>  PARAMETER C_SDRAM_TRFC = 66000
>  PARAMETER C_SDRAM_DWIDTH = 8
>  PARAMETER C_OPB_CLK_PERIOD_PS = 15000
>  PARAMETER C_SDRAM_COL_AWIDTH = 10
>  PARAMETER C_INCLUDE_BURST_SUPPORT = 0
>  PARAMETER C_SDRAM_TWR = 22500
>  PARAMETER C_SDRAM_TMRD = 2
>  PARAMETER C_SDRAM_TCCD = 1
>  PARAMETER C_SDRAM_TRCD = 20000
>  PARAMETER C_SDRAM_TRRD = 15000
>  PARAMETER C_SDRAM_TRP = 20000
>  PARAMETER C_SDRAM_TREF = 64
>  PARAMETER C_SDRAM_CAS_LAT = 2
>  PARAMETER C_SDRAM_AWIDTH = 13
>  PARAMETER C_SDRAM_BANK_AWIDTH = 2
>  PARAMETER C_SDRAM_TREFI = 7812500
>  PARAMETER C_SDRAM_REFRESH_NUMROWS = 8192
>  BUS_INTERFACE SOPB = mb_opb
>  PORT OPB_Clk = sys_clk
>  PORT SDRAM_Clk_in = sys_clk
>  PORT SDRAM_Clk = SDRAM_Clk
>  PORT SDRAM_CKE = SDRAM_CKE
>  PORT SDRAM_CSn = SDRAM_CSn
>  PORT SDRAM_RASn = SDRAM_RASn
>  PORT SDRAM_CASn = SDRAM_CASn
>  PORT SDRAM_WEn = SDRAM_WEn
>  PORT SDRAM_DQM = SDRAM_DQM
>  PORT SDRAM_BankAddr = SDRAM_BankAddr
>  PORT SDRAM_Addr = SDRAM_Addr
>  PORT SDRAM_DQ = SDRAM_DQ
> END

Has someone an idea ?

Thx a lot

Valentin Longchamp
/**********************************************************************
*
*  bootloader.c
*
*  Simple menu-driven bootloader for microblaze/uclinux/mbvanilla
*
*  uClinux kernel command line parameter handling 
*     by Brett Boren <borenb@eng.uah.edu>
*
*************************************************************************
*  Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
*  Copyright (C) 2004 Brett Boren <borenb@eng.uah.edu>
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*****************************************************************************/


/* Get general hardware memory map */
#include "xparameters.h"
#include "xbasic_types.h"
#include "xstatus.h"
#include "xuartlite_l.h"
#include "xgpio.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include "flash.h"

#define TAB_SIZE 0x4

int main(void)
{
	int *SDRAM_pointer = (int *) (XPAR_SDRAM_CONTROLLER_BASEADDR);
	int i = 0;
	int write_value = 0x12345678;
	
	xil_printf("Memory Test Program\r\n");

	//we erase memory to be sure of its state
	xil_printf("Erasing SDRAM\r\n");
	for (i=0; i<TAB_SIZE;i++) {
		*SDRAM_pointer = 0;
		SDRAM_pointer++;
	}
	xil_printf("Erasing done\r\n checking erase\r\n");

	SDRAM_pointer = (int *) (XPAR_SDRAM_CONTROLLER_BASEADDR);

	for (i = 0; i<TAB_SIZE; i++) {
		int value = *SDRAM_pointer;
		xil_printf("address : 0x%x value : 0x%x \r\n", SDRAM_pointer , value);
		SDRAM_pointer++;
	}

	SDRAM_pointer = (int *) (XPAR_SDRAM_CONTROLLER_BASEADDR);
	// we write into the memory
	xil_printf("Writing to the SDRAM\r\n");
	for (i=0; i<TAB_SIZE;i++) {
		*SDRAM_pointer = write_value;
		xil_printf("address : 0x%x value to be written : 0x%x \r\n", SDRAM_pointer, write_value);
		SDRAM_pointer++;
	}
	xil_printf("write operations finished\r\n");

	SDRAM_pointer = (int *) (XPAR_SDRAM_CONTROLLER_BASEADDR);

	xil_printf("Reading back from the SDRAM\r\n");
	for (i=0; i<TAB_SIZE;i++) {
		int j = 0;
		for (j = 0; j<1; j++) {
			int value = *SDRAM_pointer;
			xil_printf("address : 0x%x read value : 0x%x \r\n", SDRAM_pointer , value);
		}
		SDRAM_pointer++;
	}

	xil_printf("end of Memory Test program\r\n");
}


# ##############################################################################
# Target Board:	 Memec Design Virtex-2 1000  Development Board
# with P160 Comm Module
# Family:	     virtex2
# Device:	     XCV21000
# Package:
# Speed Grade:	 -6
# Processor:     Microblaze
# Debug interface: On-Chip HW Debug Module
# On Chip Memory :   16 KB
# Total Off Chip Memory :  32 MB
# - SDRAM_8Mx32 =  32 MB
# ##############################################################################
# Parameters
 PARAMETER VERSION = 2.1.0


 PORT ext_clk = ext_clk, DIR = IN
 PORT ddr_clk_fb = ddr_clk_fb, DIR = IN
 PORT sys_rst = sys_rst, DIR = IN
 PORT console_uart_rx = console_uart_rx, DIR = IN
 PORT console_uart_tx = console_uart_tx, DIR = OUT
 PORT sram_cen = sram_cen, VEC = [0:1], DIR = OUT
 PORT sram_addr = sram_addr, VEC = [10:29], DIR = OUT
 PORT sram_ben = sram_ben, VEC = [0:3], DIR = OUT
 PORT sram_data = sram_data, VEC = [0:31], DIR = INOUT
 PORT sram_oen = sram_oen, DIR = OUT
 PORT sram_wen = sram_wen, DIR = OUT
 PORT sram_rst = sram_rpn, DIR = OUT
 PORT gpio = gpio, VEC = [0:23], DIR = INOUT
 PORT SDRAM_Clk = SDRAM_Clk, DIR = O
 PORT SDRAM_CKE = SDRAM_CKE, DIR = O
 PORT SDRAM_CSn = SDRAM_CSn, DIR = O
 PORT SDRAM_RASn = SDRAM_RASn, DIR = O
 PORT SDRAM_CASn = SDRAM_CASn, DIR = O
 PORT SDRAM_WEn = SDRAM_WEn, DIR = O
 PORT SDRAM_DQM = SDRAM_DQM, DIR = O
 PORT SDRAM_BankAddr = SDRAM_BankAddr, VEC = [0:1], DIR = O
 PORT SDRAM_Addr = SDRAM_Addr, VEC = [0:12], DIR = O
 PORT SDRAM_DQ = SDRAM_DQ, VEC = [0:7], DIR = IO


# Sub Components
BEGIN microblaze
 PARAMETER INSTANCE = microblaze_0
 PARAMETER HW_VER = 3.00.a
 PARAMETER C_USE_BARREL = 1
 PARAMETER C_USE_DIV = 1
 PARAMETER C_USE_MSR_INSTR = 1
 PARAMETER C_DEBUG_ENABLED = 1
 PARAMETER C_NUMBER_OF_PC_BRK = 2
 PARAMETER C_NUMBER_OF_RD_ADDR_BRK = 1
 PARAMETER C_NUMBER_OF_WR_ADDR_BRK = 1
 PARAMETER C_USE_ICACHE = 1
 PARAMETER C_ICACHE_BASEADDR = 0x80000000
 PARAMETER C_ICACHE_HIGHADDR = 0x81FFFFFF
 PARAMETER C_CACHE_BYTE_SIZE = 16384
 PARAMETER C_ADDR_TAG_BITS = 11
 PARAMETER C_USE_DCACHE = 1
 PARAMETER C_DCACHE_BASEADDR = 0x80000000
 PARAMETER C_DCACHE_HIGHADDR = 0x81FFFFFF
 PARAMETER C_DCACHE_BYTE_SIZE = 16384
 PARAMETER C_DCACHE_ADDR_TAG = 11
 PARAMETER C_FSL_LINKS = 1
 BUS_INTERFACE SFSL0 = download_link
 BUS_INTERFACE DLMB = dlmb
 BUS_INTERFACE ILMB = ilmb
 BUS_INTERFACE DOPB = mb_opb
 BUS_INTERFACE IOPB = mb_opb
 PORT CLK = sys_clk
 PORT INTERRUPT = interrupt
END

BEGIN opb_mdm
 PARAMETER INSTANCE = debug_module
 PARAMETER HW_VER = 2.00.a
 PARAMETER C_MB_DBG_PORTS = 1
 PARAMETER C_USE_UART = 0
 PARAMETER C_UART_WIDTH = 8
 PARAMETER C_BASEADDR = 0xFFFFC000
 PARAMETER C_HIGHADDR = 0xFFFFC0FF
 PARAMETER C_WRITE_FSL_PORTS = 1
 BUS_INTERFACE MFSL0 = download_link
 BUS_INTERFACE SOPB = mb_opb
 PORT OPB_Clk = sys_clk
END

BEGIN fsl_v20
 PARAMETER INSTANCE = download_link
 PARAMETER HW_VER = 2.00.a
 PARAMETER C_EXT_RESET_HIGH = 0
 PORT SYS_Rst = sys_rst
 PORT FSL_Clk = sys_clk
END

BEGIN opb_emc
 PARAMETER INSTANCE = sram_flash
 PARAMETER HW_VER = 1.10.b
 PARAMETER C_OPB_CLK_PERIOD_PS = 15000
 PARAMETER C_NUM_BANKS_MEM = 2
 PARAMETER C_MAX_MEM_WIDTH = 32
 PARAMETER C_MEM0_WIDTH = 32
 PARAMETER C_MEM1_WIDTH = 32
 PARAMETER C_INCLUDE_DATAWIDTH_MATCHING_0 = 0
 PARAMETER C_INCLUDE_DATAWIDTH_MATCHING_1 = 0
 PARAMETER C_READ_ADDR_TO_OUT_SLOW_PS_0 = 150000
 PARAMETER C_WRITE_ADDR_TO_OUT_SLOW_PS_0 = 55000
 PARAMETER C_WRITE_MIN_PULSE_WIDTH_PS_0 = 70000
 PARAMETER C_READ_ADDR_TO_OUT_FAST_PS_0 = 150000
 PARAMETER C_WRITE_ADDR_TO_OUT_FAST_PS_0 = 55000
 PARAMETER C_READ_RECOVERY_BEFORE_WRITE_PS_0 = 15000
 PARAMETER C_WRITE_RECOVERY_BEFORE_READ_PS_0 = 35000
 PARAMETER C_READ_ADDR_TO_OUT_SLOW_PS_1 = 150000
 PARAMETER C_WRITE_ADDR_TO_OUT_SLOW_PS_1 = 55000
 PARAMETER C_WRITE_MIN_PULSE_WIDTH_PS_1 = 70000
 PARAMETER C_READ_ADDR_TO_OUT_FAST_PS_1 = 150000
 PARAMETER C_WRITE_ADDR_TO_OUT_FAST_PS_1 = 55000
 PARAMETER C_READ_RECOVERY_BEFORE_WRITE_PS_1 = 15000
 PARAMETER C_WRITE_RECOVERY_BEFORE_READ_PS_1 = 35000
 PARAMETER C_BASEADDR = 0xFFFF0000
 PARAMETER C_HIGHADDR = 0xFFFF01FF
 PARAMETER C_MEM0_BASEADDR = 0xFFE00000
 PARAMETER C_MEM0_HIGHADDR = 0xFFEFFFFF
 PARAMETER C_MEM1_BASEADDR = 0xFF000000
 PARAMETER C_MEM1_HIGHADDR = 0xFF7FFFFF
 BUS_INTERFACE SOPB = mb_opb
 PORT OPB_Clk = sys_clk
 PORT Mem_CEN = sram_cen
 PORT Mem_A = sram_addr_full
 PORT Mem_BEN = sram_ben
 PORT Mem_DQ = sram_data
 PORT Mem_OEN = sram_oen_full
 PORT Mem_WEN = sram_wen
 PORT Mem_RPN = sram_rpn
END

BEGIN util_reduced_logic
 PARAMETER INSTANCE = oe_adj
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_SIZE = 2
 PARAMETER C_OPERATION = and
 PORT Op1 = sram_oen_full
 PORT Res = sram_oen
END

BEGIN util_bus_split
 PARAMETER INSTANCE = addr_adj
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_SIZE_IN = 32
 PARAMETER C_LEFT_POS = 10
 PARAMETER C_SPLIT = 30
 PORT Sig = sram_addr_full
 PORT Out1 = sram_addr
END

BEGIN opb_uartlite
 PARAMETER INSTANCE = console_uart
 PARAMETER HW_VER = 1.00.b
 PARAMETER C_BAUDRATE = 57600
 PARAMETER C_DATA_BITS = 8
 PARAMETER C_USE_PARITY = 0
 PARAMETER C_ODD_PARITY = 0
 PARAMETER C_CLK_FREQ = 66_666_667
 PARAMETER C_BASEADDR = 0xFFFF2000
 PARAMETER C_HIGHADDR = 0xFFFF20FF
 BUS_INTERFACE SOPB = mb_opb
 PORT Interrupt = console_uart_interrupt
 PORT OPB_Clk = sys_clk
 PORT RX = console_uart_rx
 PORT TX = console_uart_tx
END

BEGIN opb_intc
 PARAMETER INSTANCE = system_intc
 PARAMETER HW_VER = 1.00.c
 PARAMETER C_BASEADDR = 0xffff3000
 PARAMETER C_HIGHADDR = 0xffff30ff
 BUS_INTERFACE SOPB = mb_opb
 PORT Irq = interrupt
 PORT OPB_Clk = sys_clk
 PORT Intr = console_uart_interrupt & timer_interrupt
END

BEGIN opb_timer
 PARAMETER INSTANCE = system_timer
 PARAMETER HW_VER = 1.00.b
 PARAMETER C_BASEADDR = 0xffff1000
 PARAMETER C_HIGHADDR = 0xffff10ff
 BUS_INTERFACE SOPB = mb_opb
 PORT OPB_Clk = sys_clk
 PORT Interrupt = timer_interrupt
END

BEGIN opb_gpio
 PARAMETER INSTANCE = system_gpio
 PARAMETER HW_VER = 2.00.a
 PARAMETER C_BASEADDR = 0xffff5000
 PARAMETER C_HIGHADDR = 0xffff50ff
 PARAMETER C_GPIO_WIDTH = 24
 BUS_INTERFACE SOPB = mb_opb
 PORT GPIO_IO = gpio
 PORT OPB_Clk = sys_clk
END

BEGIN lmb_bram_if_cntlr
 PARAMETER INSTANCE = dlmb_cntlr
 PARAMETER HW_VER = 1.00.b
 PARAMETER C_BASEADDR = 0x00000000
 PARAMETER C_HIGHADDR = 0x00003FFF
 BUS_INTERFACE SLMB = dlmb
 BUS_INTERFACE BRAM_PORT = conn_0
END

BEGIN lmb_bram_if_cntlr
 PARAMETER INSTANCE = ilmb_cntlr
 PARAMETER HW_VER = 1.00.b
 PARAMETER C_BASEADDR = 0x00000000
 PARAMETER C_HIGHADDR = 0x00003FFF
 BUS_INTERFACE SLMB = ilmb
 BUS_INTERFACE BRAM_PORT = conn_1
END

BEGIN bram_block
 PARAMETER INSTANCE = bram
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_MEMSIZE = 16384
 BUS_INTERFACE PORTA = conn_0
 BUS_INTERFACE PORTB = conn_1
END

BEGIN opb_v20
 PARAMETER INSTANCE = mb_opb
 PARAMETER HW_VER = 1.10.b
 PARAMETER C_EXT_RESET_HIGH = 0
 PORT OPB_Clk = sys_clk
 PORT SYS_Rst = sys_rst
END

BEGIN lmb_v10
 PARAMETER INSTANCE = ilmb
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_EXT_RESET_HIGH = 0
 PORT LMB_Clk = sys_clk
 PORT SYS_Rst = sys_rst
END

BEGIN lmb_v10
 PARAMETER INSTANCE = dlmb
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_EXT_RESET_HIGH = 0
 PORT LMB_Clk = sys_clk
 PORT SYS_Rst = sys_rst
END

BEGIN dcm_module
 PARAMETER INSTANCE = system_dcm
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_CLK0_BUF = TRUE
 PARAMETER C_CLKFX_BUF = TRUE
 PARAMETER C_CLKIN_PERIOD = 40.000000
 PARAMETER C_CLKFX_DIVIDE = 3
 PARAMETER C_CLKFX_MULTIPLY = 8
 PARAMETER C_EXT_RESET_HIGH = 1
 PORT CLKIN = ext_clk
 PORT CLKFX = sys_clk
 PORT CLK0 = sys_clk_fb
 PORT CLKFB = sys_clk_fb
 PORT RST = net_gnd
 PORT LOCKED = system_dcm_LOCKED
END

BEGIN dcm_module
 PARAMETER INSTANCE = pshift_dcm
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_CLKIN_PERIOD = 15.000000
 PARAMETER C_EXT_RESET_HIGH = 0
 PARAMETER C_CLK0_BUF = TRUE
 PARAMETER C_CLK90_BUF = TRUE
 PORT RST = system_dcm_LOCKED
 PORT CLK0 = pshiftdcm_fb
 PORT CLKFB = pshiftdcm_fb
 PORT CLKIN = sys_clk
 PORT CLK90 = clk_90
 PORT LOCKED = pshift_dcm_LOCKED
END

BEGIN dcm_module
 PARAMETER INSTANCE = ddr_dcm
 PARAMETER HW_VER = 1.00.a
 PARAMETER C_CLKIN_PERIOD = 15.000000
 PARAMETER C_EXT_RESET_HIGH = 0
 PARAMETER C_CLK0_BUF = TRUE
 PARAMETER C_CLK90_BUF = TRUE
 PORT RST = pshift_dcm_LOCKED
 PORT CLK0 = ddrdcm_fb
 PORT CLKFB = ddrdcm_fb
 PORT CLKIN = ddr_clk_fb
 PORT Clk90 = ddr_clk_90
END

BEGIN opb_sdram
 PARAMETER INSTANCE = sdram_controller
 PARAMETER HW_VER = 1.00.d
 PARAMETER C_BASEADDR = 0x80000000
 PARAMETER C_HIGHADDR = 0x81ffffff
 PARAMETER C_SDRAM_TRAS = 44000
 PARAMETER C_SDRAM_TRC = 66000
 PARAMETER C_SDRAM_TRFC = 66000
 PARAMETER C_SDRAM_DWIDTH = 8
 PARAMETER C_OPB_CLK_PERIOD_PS = 15000
 PARAMETER C_SDRAM_COL_AWIDTH = 10
 PARAMETER C_INCLUDE_BURST_SUPPORT = 0
 PARAMETER C_SDRAM_TWR = 22500
 PARAMETER C_SDRAM_TMRD = 2
 PARAMETER C_SDRAM_TCCD = 1
 PARAMETER C_SDRAM_TRCD = 20000
 PARAMETER C_SDRAM_TRRD = 15000
 PARAMETER C_SDRAM_TRP = 20000
 PARAMETER C_SDRAM_TREF = 64
 PARAMETER C_SDRAM_CAS_LAT = 2
 PARAMETER C_SDRAM_AWIDTH = 13
 PARAMETER C_SDRAM_BANK_AWIDTH = 2
 PARAMETER C_SDRAM_TREFI = 7812500
 PARAMETER C_SDRAM_REFRESH_NUMROWS = 8192
 BUS_INTERFACE SOPB = mb_opb
 PORT OPB_Clk = sys_clk
 PORT SDRAM_Clk_in = sys_clk
 PORT SDRAM_Clk = SDRAM_Clk
 PORT SDRAM_CKE = SDRAM_CKE
 PORT SDRAM_CSn = SDRAM_CSn
 PORT SDRAM_RASn = SDRAM_RASn
 PORT SDRAM_CASn = SDRAM_CASn
 PORT SDRAM_WEn = SDRAM_WEn
 PORT SDRAM_DQM = SDRAM_DQM
 PORT SDRAM_BankAddr = SDRAM_BankAddr
 PORT SDRAM_Addr = SDRAM_Addr
 PORT SDRAM_DQ = SDRAM_DQ
END