Forum Discussion
Altera_Forum
Honored Contributor
9 years agoWriting a LPDDR controller without IP
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)1 Reply
- Altera_Forum
Honored Contributor
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;
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.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;