DEVICE NAME := "72-bit SDRAM DIMM-ECC"
PINS
CLK := 163, 79, 125, 42;
CKE := 63, 128;
DQM := 131, 130, 113, 112, 47, 46, 29, 28;
nCAS := 111;
nRAS := 115;
nWE := 27;
nCS := 129, 45, 114, 30;
COMMAND := 129, 45, 114, 30, 115, 111, 27;
COMMAND2:= 114, 30, 129, 45, 115, 111, 27;
ADDR := 126, 123, 38, 121, 37, 120, 36, 119, 35, 118, 34, 117, 33;
BANK := 39, 122;
SCL := 83;
SDA := 82;
SCB := 137, 136, 106, 105, 53, 52, 22, 21;
DATA := 161, 160, 159, 158, 156, 155, 154, 153, 151, 150,
149, 144, 142, 141, 140, 139, 104, 103, 101, 100,
99, 98, 97, 95, 94, 93, 92, 91, 89, 88,
87, 86, 77, 76, 75, 74, 72, 71, 70, 69,
67, 66, 65, 60, 58, 57, 56, 55, 20, 19,
17, 16, 15, 14, 13, 11, 10, 9, 8, 7,
5, 4, 3, 2,
137, 136, 106, 105, 53, 52, 22, 21;
SSA := 167, 166, 165;
END;
DISABLE DEVICE
nCS := 1;
END;
TEST COVERAGE
CLK := OPEN HI LO;
CKE := OPEN LO;
DQM := SHORTS OPEN HI LO;
ADDR := SHORTS OPEN HI LO;
BANK := SHORTS OPEN HI LO;
DATA := SHORTS OPEN HI LO;
COMMAND := SHORTS OPEN HI LO;
SCL := OPEN HI LO;
SDA := OPEN HI LO;
END;
FILES
"memtestSDRAM.xje";
"IIC.xje";
END;
END;
CONST INT COL_WIDTH WIDTH 32 := 9;
CONST INT ROW_WIDTH WIDTH 32 := 13;
CONST INT DATA_BUS_WIDTH WIDTH 32 := WIDTHOF(DATA);
CONST INT DQM_BUS_WIDTH WIDTH 32 := WIDTHOF(DQM);
CONST INT BANK_BUS_WIDTH WIDTH 32 := WIDTHOF(BANK);
CONST INT CLK_BUS_WIDTH WIDTH 32 := WIDTHOF(CLK);
CONST INT DQS_BUS_WIDTH WIDTH 32 := 0;
CONST INT ADDR_WIDTH WIDTH 32 := (ROW_WIDTH + COL_WIDTH + BANK_BUS_WIDTH);
CONST INT AP_BIT WIDTH 32 := 10;
CONST INT SIZE_MB WIDTH 32 := (1 << (BANK_BUS_WIDTH + ROW_WIDTH + COL_WIDTH)) * (DATA_BUS_WIDTH / 8) / 1048576;
CONST INT CAS_LATENCY WIDTH 3 := 0b010;
CONST INT BURST_LENGTH_1 WIDTH 3 := 0b000;
CONST INT BURST_LENGTH_2 WIDTH 3 := 0b001;
CONST INT BURST_LENGTH_4 WIDTH 3 := 0b010;
CONST INT BURST_LENGTH_8 WIDTH 3 := 0b011;
CONST INT BURST_LENGTH WIDTH 3 := BURST_LENGTH_1;
CONST INT BURST_TYPE_SEQ WIDTH 1 := 0b0;
CONST INT BURST_TYPE_INT WIDTH 1 := 0b1;
CONST INT BURST_TYPE WIDTH 1 := BURST_TYPE_SEQ;
CONST INT CMD_DESELECT WIDTH 7 := 0b1111111;
CONST INT CMD_NOP WIDTH 7 := 0b1010111;
CONST INT CMD_BTERM WIDTH 7 := 0b1010110;
CONST INT CMD_READ WIDTH 7 := 0b1010101;
CONST INT CMD_WRITE WIDTH 7 := 0b1010100;
CONST INT CMD_ACTIVE WIDTH 7 := 0b1010011;
CONST INT CMD_PRE WIDTH 7 := 0b1010010;
CONST INT CMD_REF WIDTH 7 := 0b1010001;
CONST INT CMD_MODE WIDTH 7 := 0b1010000;
CONST INT DEBUG WIDTH 1 := FALSE;
CONST INT RESULT_PASS WIDTH 1 := FALSE;
CONST INT RESULT_FAIL WIDTH 1 := TRUE;
CONST INT CKE_TIED_HIGH := FALSE;
CONST INT CLK_LO WIDTH CLK_BUS_WIDTH := 0;
CONST INT CLK_HI WIDTH CLK_BUS_WIDTH := ~0[CLK_BUS_WIDTH-1..0];
CONST INT IIC_ADDRESS := 0xA0;
CONST INT IIC_ADDRESS_BYTES := 1;
CONST INT IIC_WRITE_PAGE_SIZE := 16;
CONST INT IIC_READ_PAGE_SIZE := 16;
Test()(INT result)
PRINT("\nDDR memory test for chip, ",DEVICE_REF,"\n");
result := RESULT_PASS;
PRINT("Initialising DDR module...\n");
Initialise()();
PRINT("Testing I2C EEPROM...\n");
TestIIC()(result);
IF (result) THEN
PRINT("memory chip ", DEVICE_REF, " FAILED...\n\n");
Deselect()();
RETURN;
END;
PRINT("Calling MemTest...\n");
MemTest()(result);
IF (result) THEN
PRINT("Memory chip ", DEVICE_REF, " FAILED...\n\n");
Deselect()();
RETURN;
END;
PRINT("Testing nCS1/nCS3/CKE1...\n");
TestCS()(result);
IF (result) THEN
PRINT("Memory chip ", DEVICE_REF, " FAILED...\n\n");
Deselect()();
RETURN;
END;
PRINT("Memory chip ", DEVICE_REF, " PASSED...\n\n");
Deselect()();
END;
TestIIC()(INT result)
INT data WIDTH 8 := 0;
INT checksum WIDTH 8:= 0;
INT readFailure;
result := RESULT_PASS;
IIC_Read(0, 63)(data, readFailure);
IF readFailure THEN
PRINT("IIC read failure..\n");
result := RESULT_FAIL;
RETURN;
END;
GetSum(data,63)(checksum);
PRINT("Checksum (sum of first 63 addresses): 0x",HEX(checksum),"\n");
data := 0;
IIC_Read(63, 1)(data, readFailure);
PRINT("Checksum (value in 64th address): 0x",HEX(data),"\n");
IF (data != checksum) THEN
PRINT("\tSDRAM SPD data checksum error.\n");
result := RESULT_FAIL;
RETURN;
END;
PRINT("\tSPD ROM checksum is correct.\n");
IIC_Read(3, 1)(data, readFailure);
PRINT("\tSDRAM columns : ", data, "\n");
IIC_Read(4, 1)(data, readFailure);
PRINT("\tSDRAM rows : ", data, "\n");
PRINT("IIC EEPROM test passed.\n");
END;
GetSum(INT data, INT bytes)(INT result)
INT i;
result := 0;
FOR i := 0 FOR bytes
result := (result + data[(i*8)+7..i*8])[7..0];
END;
END;
TestCS()(INT result)
INT TestAddress := 0x55555555;
INT TestData := 0x55555555;
INT ReadData;
WriteCycleCS(TestAddress, TestData)();
SET DATA := 0;
ReadCycleCS(TestAddress)(ReadData);
IF ReadData != TestData THEN
result := RESULT_FAIL;
PRINT("Invalid data read: nCS1,nCS3 or CKE1 failure.\n");
ELSE
PRINT("nCS test passed.\n");
END;
END;
PrintDQM(INT i)()
PRINT(PINNUM(DQM[i]));
END;
PrintDQS(INT i)()
END;
PrintAddr(INT i)()
PRINT(PINNUM(ADDR[i]));
END;
PrintData(INT i)()
PRINT(PINNUM(DATA[i]));
END;
PrintBank(INT i)()
PRINT(PINNUM(BANK[i]));
END;
Deselect()()
SET CLK := CLK_LO, COMMAND := CMD_DESELECT;
SET CLK := CLK_HI;
END;
WriteNop()()
SET CLK := CLK_LO, COMMAND := CMD_NOP;
SET CLK := CLK_HI;
END;
PrechargeBank(INT bank WIDTH BANK_BUS_WIDTH)()
SET CLK := CLK_LO, COMMAND := CMD_PRE, ADDR[10] := 0, BANK := bank;
SET CLK := CLK_HI;
END;
PrechargeAll()()
SET CLK := CLK_LO, COMMAND := CMD_PRE, ADDR[10] := 1, BANK := 0;
SET CLK := CLK_HI;
END;
AutoRefresh()()
SET CLK := CLK_LO, COMMAND := CMD_REF;
SET CLK := CLK_HI;
END;
WriteMode(INT mode WIDTH ROW_WIDTH)()
SET CLK := CLK_LO, COMMAND := CMD_MODE, ADDR := mode, BANK := 0;
SET CLK := CLK_HI;
IF (DEBUG) THEN PRINT("Mode set 0x", HEX(mode), "\n"); END;
END;
Initialise()()
INT i;
INT mode WIDTH ROW_WIDTH;
IF WRITEABLE(CKE) THEN
SET CKE := ~0[(WIDTHOF(CKE)-1)..0];
END;
WriteNop();
PrechargeAll();
WriteNop();
WriteNop();
FOR i := 0 TO 15
AutoRefresh();
WriteNop();
AutoRefresh();
WriteNop();
END;
mode := 0;
mode[2..0] := BURST_LENGTH;
mode[3] := BURST_TYPE;
mode[6..4] := CAS_LATENCY;
mode[8..7] := 0b00;
mode[9] := 1;
WriteMode(mode);
END;
WriteCycle(INT address WIDTH ADDR_WIDTH, INT data WIDTH DATA_BUS_WIDTH, INT dqm WIDTH DQM_BUS_WIDTH)()
INT bank WIDTH BANK_BUS_WIDTH := address[(ADDR_WIDTH-1)..(ADDR_WIDTH-BANK_BUS_WIDTH)];
INT rowA WIDTH ROW_WIDTH := address[(COL_WIDTH+ROW_WIDTH-1)..(COL_WIDTH)];
INT colA WIDTH COL_WIDTH := address[(COL_WIDTH-1)..0];
IF (COL_WIDTH>AP_BIT) THEN
colA[(COL_WIDTH)..(AP_BIT+1)] := colA[(COL_WIDTH-1)..AP_BIT];
END;
colA[AP_BIT] := 1;
IF (DEBUG) THEN
PRINT("Write : address=0x", HEX(address), " [Bank=0x", HEX(bank), " col=0x", HEX(colA), " row=0x", HEX(rowA), "] data=0x", HEX(data), "\n");
END;
SET CLK := CLK_LO, COMMAND := CMD_ACTIVE, ADDR := rowA, BANK := bank, DATA := data;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND := CMD_NOP;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND := CMD_WRITE, DQM := dqm[DQM_BUS_WIDTH-1..0], ADDR := colA;
SET CLK := CLK_HI, DATA := I;
SET CLK := CLK_LO, COMMAND := CMD_NOP;
SET CLK := CLK_HI;
SET CLK := CLK_LO;
SET CLK := CLK_HI;
END;
ReadCycle(INT address WIDTH ADDR_WIDTH)(INT data WIDTH DATA_BUS_WIDTH)
INT bank WIDTH BANK_BUS_WIDTH := address[(ADDR_WIDTH-1)..(ADDR_WIDTH-BANK_BUS_WIDTH)];
INT rowA WIDTH ROW_WIDTH := address[(COL_WIDTH+ROW_WIDTH-1)..(COL_WIDTH)];
INT colA WIDTH COL_WIDTH := address[(COL_WIDTH-1)..0];
INT casloop;
IF (COL_WIDTH>AP_BIT) THEN
colA[(COL_WIDTH)..(AP_BIT+1)] := colA[(COL_WIDTH-1)..AP_BIT];
END;
colA[AP_BIT] := 1;
SET CLK := CLK_LO, COMMAND := CMD_ACTIVE, ADDR := rowA, BANK := bank, DATA := I, DQM := 0;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND := CMD_NOP ;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND := CMD_READ, ADDR := colA;
SET CLK := CLK_HI;
FOR casloop := 0 FOR CAS_LATENCY - 1
SET CLK := CLK_LO, COMMAND := CMD_NOP;
SET CLK := CLK_HI;
END;
SET CLK := CLK_LO;
SET CLK := CLK_HI, data := DATA;
SET CLK := CLK_LO, COMMAND := CMD_NOP;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND := CMD_NOP;
SET CLK := CLK_HI;
IF (DEBUG) THEN
PRINT("Read : address=0x", HEX(address), " [Bank=0x", HEX(bank), " col=0x", HEX(colA), " row=0x", HEX(rowA), "] data=0x", HEX(data), "\n");
END;
END;
WriteCycleCS(INT address WIDTH ADDR_WIDTH, INT data WIDTH DATA_BUS_WIDTH)()
INT bank WIDTH BANK_BUS_WIDTH := address[(ADDR_WIDTH-1)..(ADDR_WIDTH-BANK_BUS_WIDTH)];
INT rowA WIDTH ROW_WIDTH := address[(COL_WIDTH+ROW_WIDTH-1)..(COL_WIDTH)];
INT colA WIDTH COL_WIDTH := address[(COL_WIDTH-1)..0];
IF (COL_WIDTH>AP_BIT) THEN
colA[(COL_WIDTH)..(AP_BIT+1)] := colA[(COL_WIDTH-1)..AP_BIT];
END;
colA[AP_BIT] := 1;
IF (DEBUG) THEN
PRINT("Write : address=0x", HEX(address), " [Bank=0x", HEX(bank), " col=0x", HEX(colA), " row=0x", HEX(rowA), "] data=0x", HEX(data), "\n");
END;
SET CLK := CLK_LO, COMMAND2 := CMD_ACTIVE, ADDR := rowA, BANK := bank, DATA := data;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND2 := CMD_NOP;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND2 := CMD_WRITE, DQM := 0, ADDR := colA;
SET CLK := CLK_HI, DATA := I;
SET CLK := CLK_LO, COMMAND2 := CMD_NOP;
SET CLK := CLK_HI;
SET CLK := CLK_LO;
SET CLK := CLK_HI;
END;
ReadCycleCS(INT address WIDTH ADDR_WIDTH)(INT data WIDTH DATA_BUS_WIDTH)
INT bank WIDTH BANK_BUS_WIDTH := address[(ADDR_WIDTH-1)..(ADDR_WIDTH-BANK_BUS_WIDTH)];
INT rowA WIDTH ROW_WIDTH := address[(COL_WIDTH+ROW_WIDTH-1)..(COL_WIDTH)];
INT colA WIDTH COL_WIDTH := address[(COL_WIDTH-1)..0];
INT casloop;
IF (COL_WIDTH>AP_BIT) THEN
colA[(COL_WIDTH)..(AP_BIT+1)] := colA[(COL_WIDTH-1)..AP_BIT];
END;
colA[AP_BIT] := 1;
SET CLK := CLK_LO, COMMAND2 := CMD_ACTIVE, ADDR := rowA, BANK := bank, DATA := I, DQM := 0;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND2 := CMD_NOP ;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND2 := CMD_READ, ADDR := colA;
SET CLK := CLK_HI;
FOR casloop := 0 FOR CAS_LATENCY - 1
SET CLK := CLK_LO, COMMAND2 := CMD_NOP;
SET CLK := CLK_HI;
END;
SET CLK := CLK_LO;
SET CLK := CLK_HI, data := DATA;
SET CLK := CLK_LO, COMMAND2 := CMD_NOP;
SET CLK := CLK_HI;
SET CLK := CLK_LO, COMMAND2 := CMD_NOP;
SET CLK := CLK_HI;
IF (DEBUG) THEN
PRINT("Read : address=0x", HEX(address), " [Bank=0x", HEX(bank), " col=0x", HEX(colA), " row=0x", HEX(rowA), "] data=0x", HEX(data), "\n");
END;
END;