diff --git a/libraries/technology/ddr/tech_ddr_pkg.vhd b/libraries/technology/ddr/tech_ddr_pkg.vhd index 3e46c6687e0d914f5f3b305c8ee8cd588f08345d..efd9d4c4353865f75010acca76188434c24701e0 100644 --- a/libraries/technology/ddr/tech_ddr_pkg.vhd +++ b/libraries/technology/ddr/tech_ddr_pkg.vhd @@ -40,29 +40,30 @@ PACKAGE tech_ddr_pkg IS dq_w : NATURAL; -- = 64 dqs_w : NATURAL; -- = 8 = dq_w / nof_dq_per_dqs dm_w : NATURAL; -- = 8 + ck_w : NATURAL; -- = 2 + cke_w : NATURAL; -- = 2 cs_w : NATURAL; -- = 2 = number of chip select lines cs_w_w : NATURAL; -- = 1 = true_log2(cs_w), use when the number of chip select lines is converted to a logical address - clk_w : NATURAL; -- = 2 + odt_w : NATURAL; -- = 2 -- PHY internal FPGA IO terminationcontrol_w : NATURAL; -- = 14 internal bus in FPGA -- Controller 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; -- = 7 = ceil_log2(maxburstsize+1) END RECORD; - - CONSTANT c_tech_ddr_max : t_c_tech_ddr := ("none", 800, TRUE, 16, 16, 10, 3, 64, 8, 8, 2, 1, 2, 14, 4, 2, 32, 256, 64, 7); -- maximum ranges for record field definitions - CONSTANT c_tech_ddr_4g_800m : t_c_tech_ddr := ("none", 800, TRUE, 15, 15, 10, 3, 64, 8, 8, 2, 1, 2, 14, 4, 2, 32, 256, 64, 7); - CONSTANT c_tech_ddr3_4g_800m_master : t_c_tech_ddr := ("DDR3", 800, FALSE, 15, 15, 10, 3, 64, 8, 8, 2, 1, 2, 14, 4, 2, 32, 256, 64, 7); - CONSTANT c_tech_ddr3_4g_800m_slave : t_c_tech_ddr := ("DDR3", 800, FALSE, 15, 15, 10, 3, 64, 8, 8, 2, 1, 2, 14, 4, 2, 32, 256, 64, 7); - + 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_data_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_ctrl_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_ctrl_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_800m : 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); + -- 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 @@ -76,8 +77,6 @@ PACKAGE tech_ddr_pkg IS 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); - clk : STD_LOGIC_VECTOR(c_tech_ddr_max.clk_w-1 DOWNTO 0); -- clock, positive edge clock - clk_n : STD_LOGIC_VECTOR(c_tech_ddr_max.clk_w-1 DOWNTO 0); -- clock, negative edge clock scl : STD_LOGIC; -- I2C sda : STD_LOGIC; END RECORD; @@ -90,16 +89,18 @@ PACKAGE tech_ddr_pkg IS 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_max.cs_w-1 DOWNTO 0); -- on-die termination control signal - cke : STD_LOGIC_VECTOR(c_tech_ddr_max.cs_w-1 DOWNTO 0); -- clock enable + 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_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'), (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')); + 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')); 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; @@ -107,7 +108,7 @@ PACKAGE tech_ddr_pkg IS -- PHY address signal record TYPE t_tech_ddr_addr IS RECORD - chip : STD_LOGIC_VECTOR(c_tech_ddr_max.cs_w_w)-1 DOWNTO 0); + chip : STD_LOGIC_VECTOR(c_tech_ddr_max.cs_w_w -1 DOWNTO 0); bank : STD_LOGIC_VECTOR(c_tech_ddr_max.ba_w -1 DOWNTO 0); row : STD_LOGIC_VECTOR(c_tech_ddr_max.a_row_w-1 DOWNTO 0); column : STD_LOGIC_VECTOR(c_tech_ddr_max.a_col_w-1 DOWNTO 0); @@ -115,20 +116,32 @@ PACKAGE tech_ddr_pkg IS TYPE t_tech_ddr_addr_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_addr; - 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_800m : t_tech_ddr_addr := ((OTHERS=>'1'), (OTHERS=>'1'), (OTHERS=>'1'), TO_UVEC(2**c_tech_ddr_4g_800m.a_col_w - c_tech_ddr_4g_800m.rsl, c_tech_ddr_4g_800m.a_col_w)); - CONSTANT c_tech_ddr_addr_hi_sim : t_tech_ddr_addr := ((OTHERS=>'0'), (OTHERS=>'0'), TO_UVEC(3, c_tech_ddr_4g_800m.a_row_w), TO_UVEC(2**c_tech_ddr_4g_800m.a_col_w - c_tech_ddr_4g_800m.rsl, c_tech_ddr_4g_800m.a_col_w)); + 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_800m : t_tech_ddr_addr := ((OTHERS=>'1'), + (OTHERS=>'1'), + (OTHERS=>'1'), + TO_UVEC(2**c_tech_ddr_4g_800m.a_col_w-c_tech_ddr_4g_800m.rsl, c_tech_ddr_max.a_col_w)); + CONSTANT c_tech_ddr_addr_hi_sim : t_tech_ddr_addr := ((OTHERS=>'0'), + (OTHERS=>'0'), + TO_UVEC(3, c_tech_ddr_max.a_row_w), + TO_UVEC(2**c_tech_ddr_4g_800m.a_col_w-c_tech_ddr_4g_800m.rsl, c_tech_ddr_max.a_col_w)); -- PHY MM access signal record + CONSTANT c_tech_ddr_max_ctrl_address_w : NATURAL := 32; -- >= func_tech_ddr_ctrl_address_w(c_tech_ddr_max); + CONSTANT c_tech_ddr_max_ctrl_data_w : NATURAL := 576; -- >= func_tech_ddr_ctrl_data_w( c_tech_ddr_max); + TYPE t_tech_ddr_miso IS RECORD - rddata : STD_LOGIC_VECTOR(c_tech_ddr_max.data_w-1 DOWNTO 0); + rddata : STD_LOGIC_VECTOR(c_tech_ddr_max_ctrl_data_w-1 DOWNTO 0); rdval : STD_LOGIC; waitrequest_n : STD_LOGIC; END RECORD; TYPE t_tech_ddr_mosi IS RECORD - address : STD_LOGIC_VECTOR(c_tech_ddr_max.address_w-1 DOWNTO 0); - wrdata : STD_LOGIC_VECTOR(c_tech_ddr_max.data_w-1 DOWNTO 0); + address : STD_LOGIC_VECTOR(c_tech_ddr_max_ctrl_address_w-1 DOWNTO 0); + wrdata : STD_LOGIC_VECTOR(c_tech_ddr_max_ctrl_data_w-1 DOWNTO 0); wr : STD_LOGIC; rd : STD_LOGIC; burstbegin : STD_LOGIC; @@ -144,15 +157,22 @@ PACKAGE BODY tech_ddr_pkg IS RETURN c_ddr.cs_w_w + c_ddr.ba_w + c_ddr.a_w + c_ddr.a_col_w; END; - FUNCTION func_tech_ddr_data_address_w(c_ddr : t_c_tech_ddr) RETURN NATURAL IS + FUNCTION func_tech_ddr_ctrl_address_w(c_ddr : t_c_tech_ddr) RETURN NATURAL IS CONSTANT c_dq_address_w : NATURAL := func_tech_ddr_dq_address_w(c_ddr); BEGIN RETURN c_dq_address_w-c_ddr.rsl_w; END; + FUNCTION func_tech_ddr_ctrl_data_w(c_ddr : t_c_tech_ddr) RETURN NATURAL IS + CONSTANT c_dq_address_w : NATURAL := func_tech_ddr_dq_address_w(c_ddr); + BEGIN + RETURN c_ddr.dq_w*c_ddr.rsl; + END; + FUNCTION func_tech_ddr_module_size(c_ddr : t_c_tech_ddr) RETURN NATURAL IS CONSTANT c_dq_address_w : NATURAL := func_tech_ddr_dq_address_w(c_ddr); - CONSTANT c_dq_nof_bytes_w : NATURAL := 8; -- both dw_q = 64 and 72 are regarded as having 8 bytes (either with 8 or 9 bits per byte) + CONSTANT c_dq_nof_bytes : NATURAL := 8; -- both dw_q = 64 and 72 are regarded as having 8 bytes (either with 8 or 9 bits per byte) + CONSTANT c_dq_nof_bytes_w : NATURAL := ceil_log2(c_dq_nof_bytes); CONSTANT c_module_nof_bytes_w : NATURAL := c_dq_address_w + c_dq_nof_bytes_w; CONSTANT c_1GB_w : NATURAL := 30; BEGIN