diff --git a/libraries/technology/ddr/tech_ddr_pkg.vhd b/libraries/technology/ddr/tech_ddr_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..33b251f5cdb9e291ce4e54697ccd98eb920f33f2 --- /dev/null +++ b/libraries/technology/ddr/tech_ddr_pkg.vhd @@ -0,0 +1,128 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + +PACKAGE tech_ddr_pkg IS + + -- DDR3 + TYPE t_c_tech_ddr_phy IS RECORD + a_w : NATURAL; -- = 16; + a_row_w : NATURAL; -- = 16; -- = a_w, row address width, via a_w lines + a_col_w : NATURAL; -- = 10; -- <= a_w, col address width, via a_w lines + ba_w : NATURAL; -- = 3; + dq_w : NATURAL; -- = 64; + dqs_w : NATURAL; -- = 8; -- = dq_w / nof_dq_per_dqs; + dm_w : NATURAL; -- = 8; + cs_w : NATURAL; -- = 2; + clk_w : NATURAL; -- = 2; + END RECORD; + + CONSTANT c_tech_ddr_phy : t_c_tech_ddr_phy := (16, 16, 10, 3, 64, 8, 8, 2, 2); + CONSTANT c_tech_ddr_phy_4g : t_c_tech_ddr_phy := (15, 15, 10, 3, 64, 8, 8, 2, 2); + + TYPE t_tech_ddr_phy_in IS RECORD + evt : STD_LOGIC; + oct_rup : STD_LOGIC; + oct_rdn : STD_LOGIC; + END RECORD; + + TYPE t_tech_ddr_phy_io IS RECORD + dq : STD_LOGIC_VECTOR(c_tech_ddr_phy.dq_w-1 DOWNTO 0); -- data bus + dqs : STD_LOGIC_VECTOR(c_tech_ddr_phy.dqs_w-1 DOWNTO 0); -- data strobe bus + dqs_n : STD_LOGIC_VECTOR(c_tech_ddr_phy.dqs_w-1 DOWNTO 0); + clk : STD_LOGIC_VECTOR(c_tech_ddr_phy.clk_w-1 DOWNTO 0); -- clock, positive edge clock + clk_n : STD_LOGIC_VECTOR(c_tech_ddr_phy.clk_w-1 DOWNTO 0); -- clock, negative edge clock + scl : STD_LOGIC; -- I2C + sda : STD_LOGIC; + END RECORD; + + TYPE t_tech_ddr_phy_ou IS RECORD + a : STD_LOGIC_VECTOR(c_tech_ddr_phy.a_w-1 DOWNTO 0); -- row and column address + ba : STD_LOGIC_VECTOR(c_tech_ddr_phy.ba_w-1 DOWNTO 0); -- bank address + dm : STD_LOGIC_VECTOR(c_tech_ddr_phy.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 + odt : STD_LOGIC_VECTOR(c_tech_ddr_phy.cs_w-1 DOWNTO 0); -- on-die termination control signal + cke : STD_LOGIC_VECTOR(c_tech_ddr_phy.cs_w-1 DOWNTO 0); -- clock enable + cs_n : STD_LOGIC_VECTOR(c_tech_ddr_phy.cs_w-1 DOWNTO 0); -- chip select + END RECORD; + + CONSTANT c_tech_ddr_phy_in_rst : t_tech_ddr_phy_in := ('0', 'X', 'X', 'X'); + CONSTANT c_tech_ddr_phy_io_rst : t_tech_ddr_phy_io := ((OTHERS=>'0'), (OTHERS=>'0'), (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')); + + 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; + TYPE t_tech_ddr_phy_ou_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_phy_ou; + + TYPE t_tech_ddr_addr IS RECORD + chip : STD_LOGIC_VECTOR(ceil_log2(c_tech_ddr_phy.cs_w) -1 DOWNTO 0); -- Use ceil_log2() because the controller interprets the chip address as logical address (NOT individual chip select lines) + bank : STD_LOGIC_VECTOR( c_tech_ddr_phy.ba_w -1 DOWNTO 0); + row : STD_LOGIC_VECTOR( c_tech_ddr_phy.a_row_w-1 DOWNTO 0); + column : STD_LOGIC_VECTOR( c_tech_ddr_phy.a_col_w-1 DOWNTO 0); + END RECORD; + + TYPE t_tech_ddr_addr_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_addr; + + TYPE t_c_tech_ddr_ctlr IS RECORD -- DDR3 + rsl : NATURAL; -- = 4 = 2 (use both PHY clock edges) * 2 (PHY transfer at double rate), resolution + rsl_w : NATURAL; -- = 2 = ceil_log2(rsl) + address_w : NATURAL; -- = 32 = (2**32)*c_tech_ddr_phy.dq_w/c_byte_w bytes + data_w : NATURAL; -- = 256 = rsl * c_tech_ddr_phy.dq_w + maxburstsize : NATURAL; -- = 64 + maxburstsize_w : NATURAL; -- = 8 = ceil_log2(maxburstsize+1) + END RECORD; + + CONSTANT c_tech_ddr_ctlr : t_c_tech_ddr_ctlr := (4, 2, 256, 64, 9); + + CONSTANT c_tech_ddr_ctrl_nof_latent_reads : NATURAL := 100; -- Due to having a command cue, even after de-asserting read requests, the PHY keeps processing the cued read requests. + -- This makes sure 100 words are still available in the read FIFO after it de-asserted its siso.ready signal towards the ddr3 read side. + + CONSTANT c_tech_ddr_addr_lo : t_tech_ddr_addr := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0')); + CONSTANT c_tech_ddr_addr_hi_4gb : t_tech_ddr_addr := ((OTHERS=>'1'), (OTHERS=>'1'), (OTHERS=>'1'), TO_UVEC(2**c_tech_ddr_phy_4g.a_col_w - c_tech_ddr_ctlr.rsl, c_tech_ddr_phy_4g.a_col_w)); + CONSTANT c_tech_ddr_addr_hi_sim : t_tech_ddr_addr := ((OTHERS=>'0'), (OTHERS=>'0'), TO_UVEC(3, c_tech_ddr_phy.a_row_w), TO_UVEC(2**c_tech_ddr_phy_4g.a_col_w - c_tech_ddr_ctlr.rsl, c_tech_ddr_phy_4g.a_col_w)); + + TYPE t_tech_ddr_miso IS RECORD + rddata : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.data_w-1 DOWNTO 0); + rd : STD_LOGIC; + waitrequest_n : STD_LOGIC; + END RECORD; + + TYPE t_tech_ddr_mosi IS RECORD + address : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.address_w-1 DOWNTO 0); + wrdata : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.data_w-1 DOWNTO 0); + wr : STD_LOGIC; + rd : STD_LOGIC; + burstbegin : STD_LOGIC; + burstsize : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.maxburstsize_w-1 DOWNTO 0); + END RECORD; + +END tech_ddr_pkg; + +PACKAGE BODY tech_ddr_pkg IS +END tech_ddr_pkg; +