From 0c910766a007f66461cfee5f6d1e4f32533a4e84 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Tue, 20 Jan 2015 15:05:14 +0000 Subject: [PATCH] Added ip_arria10 DDR4 IP for 4Gbyte, 1600 MTps. --- libraries/technology/ddr/tech_ddr.vhd | 9 ++ .../technology/ddr/tech_ddr_component_pkg.vhd | 42 +++++++ libraries/technology/ddr/tech_ddr_pkg.vhd | 103 +++++++++++------- 3 files changed, 114 insertions(+), 40 deletions(-) diff --git a/libraries/technology/ddr/tech_ddr.vhd b/libraries/technology/ddr/tech_ddr.vhd index 97276c6288..fd24dbb948 100644 --- a/libraries/technology/ddr/tech_ddr.vhd +++ b/libraries/technology/ddr/tech_ddr.vhd @@ -78,6 +78,15 @@ BEGIN phy_in, phy_io, i_phy_ou); END GENERATE; + gen_ip_arria10 : IF g_technology=c_tech_arria10 GENERATE + u0 : ENTITY work.tech_ddr_arria10 + GENERIC MAP (g_tech_ddr) + PORT MAP (ctlr_ref_clk, ctlr_ref_rst, + ctlr_gen_clk, ctlr_gen_rst, + ctlr_mosi, ctlr_miso, + phy_in, phy_io, i_phy_ou); + END GENERATE; + -- Include DDR memory model for simulation no_sim : IF g_sim=FALSE GENERATE phy_ou <= i_phy_ou; diff --git a/libraries/technology/ddr/tech_ddr_component_pkg.vhd b/libraries/technology/ddr/tech_ddr_component_pkg.vhd index 67e5a1d371..679210d1dd 100644 --- a/libraries/technology/ddr/tech_ddr_component_pkg.vhd +++ b/libraries/technology/ddr/tech_ddr_component_pkg.vhd @@ -134,6 +134,48 @@ PACKAGE tech_ddr_component_pkg IS ); END COMPONENT; + ------------------------------------------------------------------------------ + -- ip_arria10 + ------------------------------------------------------------------------------ + + -- Manually derived VHDL entity from VHDL file $RADIOHDL/libraries/technology/ip_arria10/ddr4_4g_1600/generated/sim/ip_arria10_ddr4_4g_1600.vhd + COMPONENT ip_arria10_ddr4_4g_1600 IS + PORT ( + amm_ready_0 : out std_logic; -- ctrl_amm_avalon_slave_0.waitrequest_n + amm_read_0 : in std_logic := '0'; -- .read + amm_write_0 : in std_logic := '0'; -- .write + amm_address_0 : in std_logic_vector(25 downto 0) := (others => '0'); -- .address + amm_readdata_0 : out std_logic_vector(575 downto 0); -- .readdata + amm_writedata_0 : in std_logic_vector(575 downto 0) := (others => '0'); -- .writedata + amm_burstcount_0 : in std_logic_vector(6 downto 0) := (others => '0'); -- .burstcount + amm_byteenable_0 : in std_logic_vector(71 downto 0) := (others => '0'); -- .byteenable + amm_readdatavalid_0 : out std_logic; -- .readdatavalid + emif_usr_clk : out std_logic; -- emif_usr_clk_clock_source.clk + emif_usr_reset_n : out std_logic; -- emif_usr_reset_reset_source.reset_n + global_reset_n : in std_logic := '0'; -- global_reset_reset_sink.reset_n + mem_ck : out std_logic_vector(0 downto 0); -- mem_conduit_end.mem_ck + mem_ck_n : out std_logic_vector(0 downto 0); -- .mem_ck_n + mem_a : out std_logic_vector(16 downto 0); -- .mem_a + mem_act_n : out std_logic_vector(0 downto 0); -- .mem_act_n + mem_ba : out std_logic_vector(1 downto 0); -- .mem_ba + mem_bg : out std_logic_vector(1 downto 0); -- .mem_bg + mem_cke : out std_logic_vector(0 downto 0); -- .mem_cke + mem_cs_n : out std_logic_vector(0 downto 0); -- .mem_cs_n + mem_odt : out std_logic_vector(0 downto 0); -- .mem_odt + mem_reset_n : out std_logic_vector(0 downto 0); -- .mem_reset_n + mem_par : out std_logic_vector(0 downto 0); -- .mem_par + mem_alert_n : in std_logic_vector(0 downto 0) := (others => '0'); -- .mem_alert_n + mem_dqs : inout std_logic_vector(8 downto 0) := (others => '0'); -- .mem_dqs + mem_dqs_n : inout std_logic_vector(8 downto 0) := (others => '0'); -- .mem_dqs_n + mem_dq : inout std_logic_vector(71 downto 0) := (others => '0'); -- .mem_dq + mem_dbi_n : inout std_logic_vector(8 downto 0) := (others => '0'); -- .mem_dbi_n + oct_rzqin : in std_logic := '0'; -- oct_conduit_end.oct_rzqin + pll_ref_clk : in std_logic := '0'; -- pll_ref_clk_clock_sink.clk + local_cal_success : out std_logic; -- status_conduit_end.local_cal_success + local_cal_fail : out std_logic -- .local_cal_fail + ); + END COMPONENT; + END tech_ddr_component_pkg; PACKAGE BODY tech_ddr_component_pkg IS diff --git a/libraries/technology/ddr/tech_ddr_pkg.vhd b/libraries/technology/ddr/tech_ddr_pkg.vhd index 2997f39bcb..19c2f7d5e9 100644 --- a/libraries/technology/ddr/tech_ddr_pkg.vhd +++ b/libraries/technology/ddr/tech_ddr_pkg.vhd @@ -20,9 +20,10 @@ -- ------------------------------------------------------------------------------- -LIBRARY IEEE, common_lib; +LIBRARY IEEE, common_lib, technology_lib; USE IEEE.STD_LOGIC_1164.ALL; USE common_lib.common_pkg.ALL; +USE technology_lib.technology_pkg.ALL; PACKAGE tech_ddr_pkg IS @@ -40,6 +41,8 @@ PACKAGE tech_ddr_pkg IS dq_w : NATURAL; -- = 64 dqs_w : NATURAL; -- = 8 = dq_w / nof_dq_per_dqs dm_w : NATURAL; -- = 8 + dbi_w : NATURAL; -- = 8 + bg_w : NATURAL; -- = 2 ck_w : NATURAL; -- = 2 cke_w : NATURAL; -- = 2 cs_w : NATURAL; -- = 2 = number of chip select lines @@ -50,61 +53,71 @@ PACKAGE tech_ddr_pkg IS -- Controller rsl : NATURAL; -- = 4 = 2 (use both PHY clock edges) * 2 (PHY transfer at double rate), resolution rsl_w : NATURAL; -- = 2 = ceil_log2(rsl) + command_queue_depth : NATURAL; -- = 8 maxburstsize : NATURAL; -- = 64 maxburstsize_w : NATURAL; -- = 7 = ceil_log2(maxburstsize+1) END RECORD; + FUNCTION func_tech_sel_ddr(g_technology : NATURAL; g_ddr3, g_ddr4 : t_c_tech_ddr) RETURN t_c_tech_ddr; -- Select DDR3 or DDR4 dependent on the technology + FUNCTION func_tech_ddr_dq_address_w( c_ddr : t_c_tech_ddr) RETURN NATURAL; -- return DDR address width for the DQ data at the PHY mts rate FUNCTION func_tech_ddr_ctlr_address_w(c_ddr : t_c_tech_ddr) RETURN NATURAL; -- return DDR address width for the controller data at the by rsl=4 reduced rate FUNCTION func_tech_ddr_ctlr_data_w( c_ddr : t_c_tech_ddr) RETURN NATURAL; -- return DDR data width for the controller data at the by rsl=4 reduced rate FUNCTION func_tech_ddr_module_size( c_ddr : t_c_tech_ddr) RETURN NATURAL; -- return DDR module size in GByte - CONSTANT c_tech_ddr_max : t_c_tech_ddr := ("none", 800, TRUE, 16, 16, 10, 3, 64, 8, 8, 2, 2, 2, 1, 2, 14, 4, 2, 64, 7); -- maximum ranges for record field definitions - CONSTANT c_tech_ddr_4g : t_c_tech_ddr := ("none", 800, TRUE, 15, 15, 10, 3, 64, 8, 8, 2, 2, 2, 1, 2, 14, 4, 2, 64, 7); - CONSTANT c_tech_ddr3_4g_800m_master : t_c_tech_ddr := ("DDR3", 800, TRUE, 15, 15, 10, 3, 64, 8, 8, 2, 2, 2, 1, 2, 14, 4, 2, 64, 7); - CONSTANT c_tech_ddr3_4g_800m_slave : t_c_tech_ddr := ("DDR3", 800, FALSE, 15, 15, 10, 3, 64, 8, 8, 2, 2, 2, 1, 2, 14, 4, 2, 64, 7); + -- a a + -- a row col ba dq dqs dm dbi bg ck cke cs cs_w odt rsl + CONSTANT c_tech_ddr_max : t_c_tech_ddr := ("none", 800, TRUE, 17, 17, 10, 3, 72, 9, 9, 9, 2, 2, 2, 2, 1, 2, 14, 8, 3, 8, 64, 7); -- maximum ranges for record field definitions + CONSTANT c_tech_ddr3_4g_800m_master : t_c_tech_ddr := ("DDR3", 800, TRUE, 15, 15, 10, 3, 64, 8, 8, 0, 0, 2, 2, 2, 1, 2, 14, 4, 2, 8, 64, 7); + CONSTANT c_tech_ddr3_4g_800m_slave : t_c_tech_ddr := ("DDR3", 800, FALSE, 15, 15, 10, 3, 64, 8, 8, 0, 0, 2, 2, 2, 1, 2, 14, 4, 2, 8, 64, 7); + CONSTANT c_tech_ddr4_4g_1600m : t_c_tech_ddr := ("DDR4", 1600, TRUE, 17, 15, 10, 2, 72, 9, 0, 9, 2, 1, 1, 1, 0, 1, 0, 8, 3, 8, 64, 7); -- PHY in, inout and out signal records - TYPE t_tech_ddr_phy_in IS RECORD - evt : STD_LOGIC; -- event signal is Not Connected to DDR3 PHY - oct_rup : STD_LOGIC; -- only master DDR3 PHY has On Chip Termination OCT inputs - oct_rdn : STD_LOGIC; -- only master DDR3 PHY has On Chip Termination OCT inputs - seriesterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- termination control to slave from master DDR3 PHY (internal signal in FPGA) - parallelterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- termination control to slave from master DDR3 PHY (internal signal in FPGA) + TYPE t_tech_ddr_phy_in IS RECORD -- DDR3 DDR4 Description + evt : STD_LOGIC; -- + + event signal is Not Connected to DDR3 PHY + alert_n : STD_LOGIC; -- - + DDR4 alert signal + oct_rzqin : STD_LOGIC; -- - + DDR4 PHY has On Chip Termination OCT inputs + oct_rup : STD_LOGIC; -- + - only master DDR3 PHY has On Chip Termination OCT inputs + oct_rdn : STD_LOGIC; -- + - only master DDR3 PHY has On Chip Termination OCT inputs + seriesterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- + - termination control to slave from master DDR3 PHY (internal signal in FPGA) + parallelterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- + - termination control to slave from master DDR3 PHY (internal signal in FPGA) END RECORD; - TYPE t_tech_ddr_phy_io IS RECORD - dq : STD_LOGIC_VECTOR(c_tech_ddr_max.dq_w-1 DOWNTO 0); -- data bus - dqs : STD_LOGIC_VECTOR(c_tech_ddr_max.dqs_w-1 DOWNTO 0); -- data strobe bus - dqs_n : STD_LOGIC_VECTOR(c_tech_ddr_max.dqs_w-1 DOWNTO 0); - scl : STD_LOGIC; -- I2C - sda : STD_LOGIC; + TYPE t_tech_ddr_phy_io IS RECORD -- DDR3 DDR4 Description + dq : STD_LOGIC_VECTOR(c_tech_ddr_max.dq_w-1 DOWNTO 0); -- + + data bus + dqs : STD_LOGIC_VECTOR(c_tech_ddr_max.dqs_w-1 DOWNTO 0); -- + + data strobe bus + dqs_n : STD_LOGIC_VECTOR(c_tech_ddr_max.dqs_w-1 DOWNTO 0); -- + - + dbi_n : STD_LOGIC_VECTOR(c_tech_ddr_max.dbi_w-1 DOWNTO 0); -- - + data bus inversion + scl : STD_LOGIC; -- + - I2C clock + sda : STD_LOGIC; -- + - I2C data END RECORD; - TYPE t_tech_ddr_phy_ou IS RECORD - a : STD_LOGIC_VECTOR(c_tech_ddr_max.a_w-1 DOWNTO 0); -- row and column address - ba : STD_LOGIC_VECTOR(c_tech_ddr_max.ba_w-1 DOWNTO 0); -- bank address - dm : STD_LOGIC_VECTOR(c_tech_ddr_max.dm_w-1 DOWNTO 0); -- data mask bus - cas_n : STD_LOGIC; -- column address strobe - ras_n : STD_LOGIC; -- row address strobe - we_n : STD_LOGIC; -- write enable signal - reset_n : STD_LOGIC; -- reset signal - ck : STD_LOGIC_VECTOR(c_tech_ddr_max.ck_w-1 DOWNTO 0); -- clock, positive edge clock - ck_n : STD_LOGIC_VECTOR(c_tech_ddr_max.ck_w-1 DOWNTO 0); -- clock, negative edge clock - cke : STD_LOGIC_VECTOR(c_tech_ddr_max.cke_w-1 DOWNTO 0); -- clock enable - cs_n : STD_LOGIC_VECTOR(c_tech_ddr_max.cs_w-1 DOWNTO 0); -- chip select - odt : STD_LOGIC_VECTOR(c_tech_ddr_max.odt_w-1 DOWNTO 0); -- on-die termination control signal - seriesterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- termination control from master to slave DDR3 PHY (internal signal in FPGA) - parallelterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- termination control from master to slave DDR3 PHY (internal signal in FPGA) + TYPE t_tech_ddr_phy_ou IS RECORD -- DDR3 DDR4 Description + a : STD_LOGIC_VECTOR(c_tech_ddr_max.a_w-1 DOWNTO 0); -- + + row and column address + ba : STD_LOGIC_VECTOR(c_tech_ddr_max.ba_w-1 DOWNTO 0); -- + + bank address + dm : STD_LOGIC_VECTOR(c_tech_ddr_max.dm_w-1 DOWNTO 0); -- + - data mask bus + bg : STD_LOGIC_VECTOR(c_tech_ddr_max.bg_w-1 DOWNTO 0); -- - + bank group + ras_n : STD_LOGIC; -- + a16 row address strobe + cas_n : STD_LOGIC; -- + a15 column address strobe + we_n : STD_LOGIC; -- + a14 write enable signal + act_n : STD_LOGIC; -- - + activate signal + par : STD_LOGIC; -- - + parity signal + reset_n : STD_LOGIC; -- + + reset signal + ck : STD_LOGIC_VECTOR(c_tech_ddr_max.ck_w-1 DOWNTO 0); -- + + clock, positive edge clock + ck_n : STD_LOGIC_VECTOR(c_tech_ddr_max.ck_w-1 DOWNTO 0); -- + + clock, negative edge clock + cke : STD_LOGIC_VECTOR(c_tech_ddr_max.cke_w-1 DOWNTO 0); -- + + clock enable + cs_n : STD_LOGIC_VECTOR(c_tech_ddr_max.cs_w-1 DOWNTO 0); -- + + chip select + odt : STD_LOGIC_VECTOR(c_tech_ddr_max.odt_w-1 DOWNTO 0); -- + + on-die termination control signal + seriesterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- + - termination control from master to slave DDR3 PHY (internal signal in FPGA) + parallelterminationcontrol : STD_LOGIC_VECTOR(c_tech_ddr_max.terminationcontrol_w-1 DOWNTO 0); -- + - termination control from master to slave DDR3 PHY (internal signal in FPGA) END RECORD; - CONSTANT c_tech_ddr_phy_in_x : t_tech_ddr_phy_in := ('X', 'X', 'X', (OTHERS=>'X'), (OTHERS=>'X')); - CONSTANT c_tech_ddr_phy_io_x : t_tech_ddr_phy_io := ((OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), 'X', 'X'); - CONSTANT c_tech_ddr_phy_ou_x : t_tech_ddr_phy_ou := ((OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), 'X', 'X', 'X', 'X', (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X')); - - CONSTANT c_tech_ddr_phy_in_rst : t_tech_ddr_phy_in := ('0', 'X', 'X', (OTHERS=>'X'), (OTHERS=>'X')); - CONSTANT c_tech_ddr_phy_io_rst : t_tech_ddr_phy_io := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), '0', '0'); - CONSTANT c_tech_ddr_phy_ou_rst : t_tech_ddr_phy_ou := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), '0', '0', '0', '0', (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0')); + CONSTANT c_tech_ddr_phy_in_x : t_tech_ddr_phy_in := ('X', 'X', 'X', 'X', 'X', (OTHERS=>'X'), (OTHERS=>'X')); + CONSTANT c_tech_ddr_phy_in_rst : t_tech_ddr_phy_in := ('0', '1', 'X', 'X', 'X', (OTHERS=>'X'), (OTHERS=>'X')); + CONSTANT c_tech_ddr_phy_io_x : t_tech_ddr_phy_io := ((OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), 'X', 'X'); + CONSTANT c_tech_ddr_phy_io_rst : t_tech_ddr_phy_io := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), '0', '0'); + CONSTANT c_tech_ddr_phy_ou_x : t_tech_ddr_phy_ou := ((OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), 'X', 'X', 'X', 'X', 'X', 'X', (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X'), (OTHERS=>'X')); + CONSTANT c_tech_ddr_phy_ou_rst : t_tech_ddr_phy_ou := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), '0', '0', '0', '0', '0', '0', (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0')); TYPE t_tech_ddr_phy_in_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_phy_in; TYPE t_tech_ddr_phy_io_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_phy_io; @@ -114,9 +127,19 @@ END tech_ddr_pkg; PACKAGE BODY tech_ddr_pkg IS + FUNCTION func_tech_sel_ddr(g_technology : NATURAL; g_ddr3, g_ddr4 : t_c_tech_ddr) RETURN t_c_tech_ddr IS + BEGIN + CASE g_technology IS + WHEN c_tech_stratixiv => RETURN g_ddr3; + WHEN c_tech_arria10 => RETURN g_ddr4; + WHEN OTHERS => RETURN g_ddr3; + END CASE; + END; + FUNCTION func_tech_ddr_dq_address_w(c_ddr : t_c_tech_ddr) RETURN NATURAL IS BEGIN - RETURN c_ddr.cs_w_w + c_ddr.ba_w + c_ddr.a_w + c_ddr.a_col_w; -- PHY address + IF c_ddr.name="DDR3" THEN RETURN c_ddr.cs_w_w + c_ddr.ba_w + c_ddr.a_row_w + c_ddr.a_col_w; END IF; -- PHY address + IF c_ddr.name="DDR4" THEN RETURN c_ddr.cs_w_w + c_ddr.ba_w + c_ddr.a_row_w + c_ddr.a_col_w + c_ddr.bg_w; END IF; -- PHY address END; FUNCTION func_tech_ddr_ctlr_address_w(c_ddr : t_c_tech_ddr) RETURN NATURAL IS -- GitLab