FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
5931 Discussions

Writing a LPDDR controller without IP

Altera_Forum
Honored Contributor II
1,108 Views

Hello, guys. 

 

I have tried to write a controller for the LPDDR2 without IP to understand that what is the DDR and how to control it. 

 

The good news is the Micron provides a stub for simulations (it simulates the memory module), 

so I only have to write a controller. 

Bad news is not compilable that I wrote (errors in the fitting)... 

 

The error message is: 

169008 Can't turn on open-drain option for differential I/O pin <pin-name> 

 

I have googled what is the open-drain, but I think it does not need because they will use same power source; 

the pins DQS/DQS_n of the LPDDR2(MT42L128M32D1LF-25WT) allows 1.14~1.30 Volts, 

and an I/O standard of the pins DDR2LP_DQS_p/_n[0~3] is "Differential 1.2-V HSUL". 

Additionally, there are no words such as "drain" existing in the micron's catalog. 

 

So I have turned off the option "Auto Open-Drain Pins", but it still raises error. 

The message is: 

Error (169290): Can't place differential I/O positive pin <pin-name> at a differential I/O negative location <location>(PAD_<number>) 

 

The codes I wrote is below; 

 

utility.vhd: (partial) 

library ieee; use ieee.std_logic_1164.all; entity LPDDR2_controller is port ( -- Command/address inputs CA: out std_logic_vector(9 downto 0); -- Clock CK_p: out std_logic; CK_n: out std_logic; -- Clock enable CKE: out std_logic_vector(1 downto 0); -- Chip Select CS_n: out std_logic_vector(1 downto 0); -- Input data mask DM: out std_logic_vector(3 downto 0); -- Data input/output DQ: inout std_logic_vector(31 downto 0); -- Data strobe DQS_p: inout std_logic_vector(3 downto 0); DQS_n: inout std_logic_vector(3 downto 0); -- External impedance (240 ohm) ZQ: in std_logic ); end; architecture controller of LPDDR2_controller is begin CA <= "0000000111"; -- NOP CK_p <= '0'; CK_n <= '1'; CKE <= "00"; CS_n <= "00"; DM <= "0000"; DQ <= (others => '0'); DQS_p <= (others => '0'); DQS_n <= (others => '1'); end; 

 

main.vhd: (partial) 

library ieee; use ieee.numeric_std.all; use ieee.std_logic_1164.all; use work.all; entity main is port ( CLOCK_125_p: in std_logic; CPU_RESET_n: in std_logic; DDR2LP_CA: out std_logic_vector(9 downto 0); DDR2LP_DQ: inout std_logic_vector(31 downto 0); DDR2LP_DQS_p: inout std_logic_vector(3 downto 0); DDR2LP_DQS_n: inout std_logic_vector(3 downto 0); DDR2LP_DM: out std_logic_vector(3 downto 0); DDR2LP_CK_p: out std_logic; DDR2LP_CK_n: out std_logic; DDR2LP_CKE: out std_logic_vector(1 downto 0); DDR2LP_CS_n: out std_logic_vector(1 downto 0); DDR2LP_OCT_RZQ: in std_logic ); end; architecture main of main is component LPDDR2_controller port ( CA: out std_logic_vector(9 downto 0); CK_p: out std_logic; CK_n: out std_logic; CKE: out std_logic_vector(1 downto 0); CS_n: out std_logic_vector(1 downto 0); DM: out std_logic_vector(3 downto 0); DQ: inout std_logic_vector(31 downto 0); DQS_p: inout std_logic_vector(3 downto 0); DQS_n: inout std_logic_vector(3 downto 0); ZQ: in std_logic ); end component; begin mem: LPDDR2_controller port map( CA => DDR2LP_CA, CK_p => DDR2LP_CK_p, CK_n => DDR2LP_CK_n, CKE => DDR2LP_CKE, CS_n => DDR2LP_CS_n, DM => DDR2LP_DM, DQ => DDR2LP_DQ, DQS_p => DDR2LP_DQS_p, DQS_n => DDR2LP_DQS_n, ZQ => DDR2LP_OCT_RZQ ); -- and do something which does not touch to the memory... end; 

 

How to take the negative pins? 

or should I write to implement more features at the controller (e.g. reset the memory)?  

 

Thank you for reading! 

 

Environment Info: 

Windows 7 Ultimate Service Pack 1 

Quartus Prime Version 16.0.2 Build 222 07/20/2016 SJ Lite Edition 

Cyclone V GX Starter Kit (5CGXFC5C6F27C7)
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
315 Views

I am sorry for reading the previous. 

I have succeeded to avoid the errors myself. 

 

The way to use differential pins is to use ALTIOBUF_XXX Mega-Functions like below; 

library ieee, altera_mf; use ieee.std_logic_1164.all; use altera_mf.altera_mf_components.all; entity LPDDR2_controller is port ( -- Command/address inputs CA: out std_logic_vector(9 downto 0); -- Clock CK_p: out std_logic; CK_n: out std_logic; -- Clock enable CKE: out std_logic_vector(1 downto 0); -- Chip Select CS_n: out std_logic_vector(1 downto 0); -- Input data mask DM: out std_logic_vector(3 downto 0); -- Data input/output DQ: inout std_logic_vector(31 downto 0); -- Data strobe DQS_p: inout std_logic_vector(3 downto 0); DQS_n: inout std_logic_vector(3 downto 0); -- External impedance (240 ohm) ZQ: in std_logic ); end; architecture controller of LPDDR2_controller is signal dqs_out: std_logic_vector(3 downto 0); signal ck_out: std_logic_vector(0 to 0); signal ck_out_b: std_logic_vector(0 to 0); begin CA <= "0000000111"; -- NOP i0: altiobuf_out -- HERE generic map( number_of_channels => 1, use_differential_mode => "TRUE" ) port map( datain => "0", dataout => ck_out, dataout_b => ck_out_b ); CK_p <= ck_out(0); CK_n <= ck_out_b(0); CKE <= "00"; CS_n <= "00"; DM <= "0000"; DQ <= (others => '0'); i1: altiobuf_bidir -- AND HERE generic map( number_of_channels => 4, use_differential_mode => "TRUE" ) port map( datain => (others => '0'), dataio => DQS_p, dataio_b => DQS_n, dataout => dqs_out, oe => (others => '1') ); end; 

 

I will try to use this MFs. I will have to check that they work correctly... 

Thank you for reading. 

 

Post Script: 

Because the compiler raises a pretty critical warning to this code in my environment, I am going to search the next problem.
0 Kudos
Reply