DEVICE NAME := "DDR1 TQFP 100"
PINS
DATA := 84, 83, 81, 80, 78, 77, 75, 74, 21, 20, 18, 17, 13, 12, 10, 9,
72, 71, 69, 68, 64, 63, 61, 60, 7, 6, 4, 3, 1, 100, 98, 97;
ADDR := 37, 36, 45, 51, 50, 49, 48, 47, 34, 33, 32, 31;
BANK := 30, 29;
DQM := 57, 24, 56, 23;
DQS := 94;
CLK := 55;
nCLK := 54;
CKE := 53;
COMMAND := 28, 27, 26, 25;
END;
DISABLE DEVICE
COMMAND := 1;
END;
TEST COVERAGE
DATA := SHORTS OPEN HI LO;
ADDR := SHORTS OPEN HI LO;
BANK := SHORTS OPEN HI LO;
DQM := SHORTS OPEN HI LO;
DQS := OPEN HI LO;
CKE := OPEN HI LO;
CLK := OPEN HI LO;
nCLK := OPEN HI LO;
COMMAND := SHORTS OPEN HI LO;
END;
FILES
"memtestSDRAM.xje";
END;
END;
CONST INT COL_WIDTH WIDTH 32 := 8;
CONST INT ROW_WIDTH WIDTH 32 := 12;
CONST INT AP_BIT WIDTH 32 := 8;
CONST INT CAS_LATENCY WIDTH 3 := 3;
CONST INT DATA_BUS_WIDTH WIDTH 32 := WIDTHOF(DATA);
CONST INT DQM_BUS_WIDTH WIDTH 32 := WIDTHOF(DQM);
CONST INT DQS_BUS_WIDTH WIDTH 32 := WIDTHOF(DQS);
CONST INT BANK_BUS_WIDTH WIDTH 32 := WIDTHOF(BANK);
CONST INT CLK_BUS_WIDTH WIDTH 32 := WIDTHOF(CLK);
CONST INT ADDR_WIDTH WIDTH 32 := (ROW_WIDTH + COL_WIDTH + BANK_BUS_WIDTH);
CONST INT SIZE_MB WIDTH 32 := ((1 << (BANK_BUS_WIDTH + ROW_WIDTH + COL_WIDTH)) * (DATA_BUS_WIDTH) / 1048576)/8;
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_4;
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 4 := 0b1111;
CONST INT CMD_NOP WIDTH 4 := 0b0111;
CONST INT CMD_BTERM WIDTH 4 := 0b0110;
CONST INT CMD_READ WIDTH 4 := 0b0101;
CONST INT CMD_WRITE WIDTH 4 := 0b0100;
CONST INT CMD_ACTIVE WIDTH 4 := 0b0011;
CONST INT CMD_PRE WIDTH 4 := 0b0010;
CONST INT CMD_REF WIDTH 4 := 0b0001;
CONST INT CMD_MODE WIDTH 4 := 0b0000;
CONST INT DEBUG WIDTH 1 := FALSE;
CONST INT RESULT_PASS WIDTH 1 := FALSE;
CONST INT RESULT_FAIL WIDTH 1 := TRUE;
Test()(INT testFail)
PRINT("\nTesting memory chip ", DEVICE_REF, "...\n");
testFail := 0;
Initialise();
MemTest()(testFail);
IF (testFail = 1) THEN
PRINT("Memory chip ", DEVICE_REF, " FAILED...\n\n");
Deselect()();
RETURN;
END;
IF WRITEABLE(CKE) THEN
PRINT("Testing CKE...\n");
CKETest()(testFail);
IF testFail = 1 THEN
PRINT("Memory chip ", DEVICE_REF, " FAILED...\n\n");
Deselect()();
RETURN;
END;
END;
IF WRITEABLE(COMMAND) THEN
PRINT("Testing NCS...\n");
NCSTest()(testFail);
IF testFail = 1 THEN
PRINT("Memory chip ", DEVICE_REF, " FAILED...\n\n");
Deselect()();
RETURN;
END;
END;
PRINT("Memory chip ", DEVICE_REF, " PASSED...\n\n");
Deselect()();
END;
CKETest()(INT result)
INT data WIDTH DATA_BUS_WIDTH;
result := 0;
SET CKE := 0;
WriteCycle(0xAA, 0xBB, 0);
SET DATA := 0;
ReadCycle(0xAA)(data);
IF (DEBUG) THEN
PRINT("Wrote 0xBB with CKE set low, and read back 0x", HEX(data), "\n");
END;
IF (data = 0xBB) THEN
PRINT("ERROR: CKE stuck high\n");
result := 1;
END;
SET CKE := 1;
END;
NCSTest()(INT result)
INT data WIDTH DATA_BUS_WIDTH;
result := 0;
SET CLK := 0, nCLK := 1, COMMAND := 0b1011, ADDR := 0, BANK := 0, DATA := 0xAA;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := 0b1111;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := 0b1100, ADDR := 0, DQS := 0;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := 0b1111, DQM := 0;
SET CLK := 1, nCLK := 0, DQS := ~0[(DQS_BUS_WIDTH-1)..0];
SET CLK := 0, nCLK := 1, DQS := 0;
IF BURST_LENGTH > BURST_LENGTH_2 THEN
SET CLK := 1, nCLK := 0, DQS := ~0[(DQS_BUS_WIDTH-1)..0];
SET CLK := 0, nCLK := 1, DQS := 0, COMMAND := 0b1111;
END;
SET DQS := I, DATA := I;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1;
SET CLK := 1, nCLK := 0;
ReadCycle(0)(data);
IF (DEBUG) THEN
PRINT("Wrote 0xAA with NCS high, and read back 0x", HEX(data), "\n");
END;
IF (data = 0xAA) THEN
PRINT("ERROR : NCS stuck low\n");
result := 1;
END;
END;
PrintDQM(INT i)()
PRINT(PINNUM(DQM[i]));
END;
PrintDQS(INT i)()
PRINT(PINNUM(DQS[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 := 0, nCLK := 1, COMMAND := CMD_DESELECT;
SET CLK := 1, nCLK := 0;
END;
WriteNop()()
SET CLK := 0, nCLK := 1, COMMAND := CMD_NOP;
SET CLK := 1, nCLK := 0;
END;
PrechargeBank(INT bank WIDTH BANK_BUS_WIDTH)()
SET CLK := 0, nCLK := 1, COMMAND := CMD_PRE, ADDR[AP_BIT] := 0, BANK := bank;
SET CLK := 1, nCLK := 0;
END;
PrechargeAll()()
SET CLK := 0, nCLK := 1, COMMAND := CMD_PRE, ADDR[AP_BIT] := 1, BANK := 0;
SET CLK := 1, nCLK := 0;
END;
AutoRefresh()()
SET CLK := 0, nCLK := 1, COMMAND := CMD_REF;
SET CLK := 1, nCLK := 0;
END;
WriteMode(INT mode WIDTH ROW_WIDTH, INT bank)()
SET CLK := 0, nCLK := 1, COMMAND := CMD_MODE, ADDR := mode, BANK := bank;
SET CLK := 1, nCLK := 0;
IF (DEBUG) THEN PRINT("Mode (",bank,") set 0x", HEX(mode), "\n"); END;
END;
SetupModeRegister(INT resetDLL)()
INT mode;
mode := 0;
mode[2..0] := BURST_LENGTH;
mode[3] := BURST_TYPE;
mode[6..4] := CAS_LATENCY;
mode[8..7] := 0b00;
mode[12..9] := 0b0000;
IF resetDLL THEN
mode[8] := 1;
END;
WriteMode(mode, 0b00);
WriteNop()();
END;
SetupExtModeRegister(INT enableDLL)()
IF (!enableDLL) THEN
WriteMode(0b01, 0b01)();
WriteNop()();
ELSE
WriteMode(0, 0b01)();
END;
END;
Initialise()()
INT i;
INT mode WIDTH ROW_WIDTH;
INT resetDLL := TRUE;
INT enableDLL := FALSE;
SET CLK := 0, nCLK := 1, CKE := 1, DQM := ~0[DQM_BUS_WIDTH-1..0], COMMAND := CMD_NOP, ADDR := 0, DATA := 0, BANK := 0;
Deselect();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
PrechargeAll();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
SetupExtModeRegister(enableDLL)();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
SetupModeRegister(resetDLL)();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
resetDLL := FALSE;
SetupModeRegister(resetDLL)();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
PrechargeAll();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
AutoRefresh();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
AutoRefresh();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
enableDLL := FALSE;
SetupExtModeRegister(enableDLL)();
WriteNop();
WriteNop();
WriteNop();
WriteNop();
END;
WriteCycle(INT address WIDTH ADDR_WIDTH, INT data WIDTH DATA_BUS_WIDTH, INT dqm WIDTH DQM_BUS_WIDTH)()
INT data2 := 0x55;
INT data3 := 0xAA;
INT data4 := 0xBB;
WriteBurst(address, data, data2, data3, data4, dqm);
END;
WriteBurst(INT address WIDTH ADDR_WIDTH, INT data WIDTH DATA_BUS_WIDTH, INT data2 WIDTH DATA_BUS_WIDTH,
INT data3 WIDTH DATA_BUS_WIDTH, INT data4 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 : A=0x", HEX(address), " [Ba=0x", HEX(bank), " cl=0x", HEX(colA), " rw=0x", HEX(rowA), "] D=0x", HEX(data), " ",HEX(data2)," ",HEX(data3)," ",HEX(data4),"\n");
END;
SET CLK := 0, nCLK := 1, COMMAND := CMD_ACTIVE, ADDR := rowA, BANK := bank;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := CMD_NOP;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := CMD_WRITE, ADDR := colA, DQS := 0;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := CMD_NOP, DQM := dqm, DATA := data;
SET CLK := 1, nCLK := 0, DQS := ~0[DQS_BUS_WIDTH-1..0];
SET DATA := data2;
SET CLK := 0, nCLK := 1, DQS := 0;
IF BURST_LENGTH > BURST_LENGTH_2 THEN
SET DATA := data3;
SET CLK := 1, nCLK := 0, DQS := ~0[DQS_BUS_WIDTH-1..0];
SET DATA := data4;
SET CLK := 0, nCLK := 1, DQS := 0;
END;
SET DQS := I ,DATA := I;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1;
SET CLK := 1, nCLK := 0;
END;
ReadCycle(INT address WIDTH ADDR_WIDTH)(INT data WIDTH DATA_BUS_WIDTH)
INT data2, data3, data4;
ReadBurst(address)(data, data2, data3, data4);
END;
ReadBurst(INT address WIDTH ADDR_WIDTH)(INT data WIDTH DATA_BUS_WIDTH, INT data2 WIDTH DATA_BUS_WIDTH,
INT data3 WIDTH DATA_BUS_WIDTH, INT data4 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 DQSval := 1;
INT oldDQSval;
INT i;
INT clock WIDTH 1;
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 := 0, nCLK := 1, COMMAND := CMD_ACTIVE, ADDR := rowA, BANK := bank, DATA := I;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := CMD_NOP;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1, COMMAND := CMD_READ, ADDR := colA;
SET CLK := 1, nCLK := 0;
DO
oldDQSval := DQSval;
SET CLK := clock, nCLK := !clock, COMMAND := CMD_NOP;
SET DQSval := DQS, data := DATA; IF DEBUG THEN PRINT("DQS value is ",DQSval," data is 0x",HEX(data),"\n"); END;
clock := !clock;
i := i + 1;
UNTIL ((DQSval = ~0[(DQS_BUS_WIDTH-1)..0] && oldDQSval = 0) || i = 4*CAS_LATENCY)
END;
SET CLK := 0, nCLK := 1;
SET DQSval := DQS, data2 := DATA; IF DEBUG THEN PRINT("DQS value is ",DQSval," data is 0x",HEX(data2),"\n"); END;
IF BURST_LENGTH > BURST_LENGTH_2 THEN
SET CLK := 1, nCLK := 0;
SET DQSval := DQS, data3 := DATA; IF DEBUG THEN PRINT("DQS value is ",DQSval," data is 0x",HEX(data3),"\n"); END;
SET CLK := 0, nCLK := 1;
SET DQSval := DQS, data4 := DATA; IF DEBUG THEN PRINT("DQS value is ",DQSval," data is 0x",HEX(data4),"\n"); END;
END;
SET CLK := 1, nCLK := 0;
SET CLK := 0, nCLK := 1;
SET CLK := 1, nCLK := 0;
IF (DEBUG) THEN
PRINT("Read : A=0x", HEX(address), " [Ba=0x", HEX(bank), " cl=0x", HEX(colA), " rw=0x", HEX(rowA), "] D=0x", HEX(data), " ",HEX(data2)," ",HEX(data3)," ",HEX(data4),"\n");
END;
END;