FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
5283 Discussions

Writing a LPDDR controller without IP

Altera_Forum
Honored Contributor II
981 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
188 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.
Reply