
Introduction:
=============

This design implemented by Verilog language is targeted to LFEC20E-5F672C for running
DDR memory test at 200MHz on LatticeEC Advanced Evaluation Board.

There is a 200-pin SO-DIMM DDR memory socket on the evaluation board where 
DDR memory module can be installed.

As of the draft of this document, three DDR memory modules from different 
vendors were tested and all worked successfully with the design.

These DDR modules are

  Micron's MT8VDDT3264HDG-40B 
  http://www.micron.com/products/modules/ddrsdram/part.aspx?part=MT8VDDT3264HDG-40B 

  Corsair's VS512SDS400 
  http://www.corsairmicro.com/corsair/valueselect.html

  Pqi's MD4212UOE 
  http://www.pqimemory.com/power_memory.asp

  Infineon's HYS64D32020GDL-5-B
  http://www.infineon.com/cgi/ecrm.dll/ecrm/scripts/prod_ov.jsp?oid=32338&cat_oid=-9476

For accessing the SO-DIMM DDR memory module, Lattice IP core "Lattice DDR SDRAM 
Controller - Pipelined for LatticeECP/EC (DDRCT-GEN-E2-N1)" is used.

Therefore, only a small portion of the memory module is tested.
There are 3 bitstream files included in this ZIP file for supporting 133MHz DDR266,
166MHz DDR333, and 200MHz DDR400.  Please make sure the 33.33MHz oscillator is
installed to provide clock through ball F6.  These 3 bitstream files are:

ddr_verilog_pnr_200MHz_DDR400.bit
ddr_verilog_pnr_166MHz_DDR333.bit
ddr_verilog_pnr_133MHz_DDR266.bit

Board Setup
===========

1. Set the Vccio pins of all banks to 2.5V by putting all 8 jumpers of JP2-JP5 to JP4.
2. Push SW4 down.
3. Set all 3 pins(CFG2, CFG1, CFG0) of SW5 ON. (Push all SW5 pins down.)
4. SW1 pin 1 is the "rst_n" reset signal.  It needs to be pull up to lease reset state.
5. On Rev-C board there is a 3-pin header between SW4 and SW5.  If you are running 
   200MHz DDR400, please select 2.6V by moving jumper to the upper 2 pins.  For 133MHz 
   DDR266 and 166MHz DDR333, please select 2.5V.
6. The 33.33MHz Oscillator needs to be installed Pin 2, 8(GND), 9(CLK), 15(3.3V) of the
   DIP-16 socket.  This will provide clock signal to the FPGA through ball F6.
7. Make sure you are using the 5V wall-mount power supply that can provide enough current
   to the board.

Limitation:
===========

The 200-pin SO-DIMM DDR module contains 64-bit wide data bus, however, in order 
to reserve I/Os for demonstrating other features on the evaluation board only 
16 data bits are connected to LFEC20E FPGA.

This design is using the evaluation version of the Lattice IP core, the 
configuration is limited to 12-bit row address, 9-bit column address, and 1 chip 
select(rank).

Memory Testing Algorithm:
=========================

The test is completed by writing test_data into address space (from 0 to 7FFFFC) 
of the user interface and then read the data back for checking.

The test starts from writing 0x01 to byte_1 (D15-D8) and 0xfe to byte_0 (D7-D0) 
of address 0x00000, then the test data will be rotated within the byte and the 
address will be increased by 4 for the next write cycle.

When the write reaches address 0x7ffff, reading and verification will be started 
from address 0x00000, and then address 0x00004, ...

After the read reaches address 0x7ffff, one test is considered as completed and 
the test_data will be changed for the next test.

In order to prevent writing the same pattern to the same address location for 
every test, the test_data is rotated and then inverted at address 0x00000 before 
a new test starts.

The following are the testing sequences:

                           byte_1  byte_0
                           D15-D8  D7-D0
Test 1 started----------------------------
Write to address 0x00000:  0x01    0xfe
Write to address 0x00004:  0x02    0xfd
Write to address 0x00008:  0x04    0xfb
Write to address 0x0000c:  0x08    0xf7
Write to address 0x00010:  0x10    0xef
Write to address 0x00014:  0x20    0xdf
Write to address 0x00018:  0x40    0xbf
Write to address 0x0001c:  0x80    0x7f
Write to address 0x00020:  0x01    0xfe
Write to address 0x00024:  0x02    0xfd
Write to address 0x00028:  0x04    0xfb
Write to address 0x0002c:  0x08    0xf7
 :
 :
Write to address 0x7ffff:  0x80    0x7f
Read from address 0x00000
Read from address 0x00004
 :
 :
Read from address 0x7ffff
Test 2 started----------------------------
Write to address 0x00000:  0xfd    0x02
Write to address 0x00004:  0xfb    0x04
Write to address 0x00008:  0xf7    0x08
Write to address 0x0000c:  0xef    0x10
Write to address 0x00010:  0xdf    0x20
Write to address 0x00014:  0xbf    0x40
Write to address 0x00018:  0x7f    0x80
Write to address 0x0001c:  0xfe    0x01
Write to address 0x00020:  0xfd    0x02
Write to address 0x00024:  0xfb    0x04
Write to address 0x00028:  0xf7    0x08
Write to address 0x0002c:  0xef    0x10
 :
 :
Write to address 0x7ffff:  0xfe    0x01
Read from address 0x00000
Read from address 0x00004
 :
 :
Read from address 0x7ffff
Test 3 started----------------------------
Write to address 0x00000:  0x04    0xfb
Write to address 0x00004:  0x08    0xf7
Write to address 0x00008:  0x10    0xef
Write to address 0x0000c:  0x20    0xdf
Write to address 0x00010:  0x40    0xbf
Write to address 0x00014:  0x80    0x7f
Write to address 0x00018:  0x01    0xfe
Write to address 0x0001c:  0x02    0xfd
Write to address 0x00020:  0x04    0xfb
Write to address 0x00024:  0x08    0xf7
Write to address 0x00028:  0x10    0xef
Write to address 0x0002c:  0x20    0xdf
 :
 :
Write to address 0x7ffff:  0x02    0xfd
Read from address 0x00000
Read from address 0x00004
 :
 :
Read from address 0x7ffff
Test 3 started----------------------------
Write to address 0x00000:  0xf7    0x08
 :
 :
 
Test results:
=============

There are two counters implemented for showing the number of successful tests 
and failed tests.

While reading data back for verification, if any data in any address location 
is incorrect, the failure counter will be increased by one.

Only if all the data in all address locations are correct, the success counter 
will be increased.

   number_of_tests_passed: displayed on LEDs D8, D7, D6, D5
   number_of_tests_failed: displayed on LEDs D4, D3, D2, D1

Waveform Measuring:
===================

For measuring write cycle timing, set trigger at falling edge of AC5 (signal cmd[0]).

For measuring read cycle timing, set trigger at rising edge of AC5 (signal cmd[0]).

The following 3 TIF files are DDR waveforms captured using Tektronics digital scope.
The upper waveform is the DQS signal and the lower wavform is one of the DQ signals.

   DDR_side_Write_Timing.TIF
   DDR_side_Read_Timing.TIF
   DDR_side_Write_To_Read_Timing.TIF

The following 3 BMP files are user interface waveforms captured using Agilent logic
analyzer.

   User_side_Write_To_Read_Timing.bmp
   User_side_Read_To_Write_Timing.bmp
   User_side_Multiple_Tests.bmp

Steps for Programming BIT files into SPI Serial Flash
=====================================================

1. Launch ispVM
2. Click [File]>[New]
3. Click [Edit]>[Add Device]
4. Click [Select] and select [FPGA Loader] for "Device Family" and then click [OK]
5. Highlight [Configuration Data Setup] and click the "lower" [Browse] to select
   either "ddr_verilog_pnr_200MHz_DDR400.bit", "ddr_verilog_pnr_166MHz_DDR333.bit", or
   "ddr_verilog_pnr_133MHz_DDR266.bit"
6. Highlight [Flash Device] and click [Select...] to select [SPI Serial Flash], 
   [SPI-M25P80], [8-pin SOIC], then click [OK]
7. Click [OK] again to close "FPGA Loader" window
8. Make sure SW4 switch is at the UP position and download cable is connected to 
   either JP6 or JP8
9. Click [GO] to program mcs to SPI flash.
10. Push SW4 back to DOWN position.
