Skip to content
Snippets Groups Projects
Commit 87345d92 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Instantiate tech_ddr_lib.tech_ddr. Keep ctlr_gen_clk internal.diff

parent aee1a240
No related branches found
No related tags found
No related merge requests found
......@@ -32,11 +32,11 @@ ENTITY io_ddr IS
GENERIC(
g_technology : NATURAL := c_tech_select_default;
g_tech_ddr : t_c_tech_ddr;
g_wr_data_w : NATURAL := c_tech_ddr_ctlr.data_w;
g_wr_data_w : NATURAL := 32;
g_wr_use_ctrl : BOOLEAN := FALSE; -- TRUE to allow filling the WR FIFO (by disabling flush) after an EOP
g_wr_fifo_depth : NATURAL := 128; -- >=16 AND >c_tech_ddr_ctlr.maxburstsize , defined at read side of write FIFO.
g_rd_fifo_depth : NATURAL := 256; -- >=16 AND >c_tech_ddr_ctlr.maxburstsize > c_ddr_ctrl_nof_latent_reads, defined at write side of read FIFO.
g_rd_data_w : NATURAL := c_tech_ddr_ctlr.data_w;
g_wr_fifo_depth : NATURAL := 128; -- >=16 AND >g_tech_ddr.maxburstsize , defined at read side of write FIFO.
g_rd_fifo_depth : NATURAL := 256; -- >=16 AND >g_tech_ddr.maxburstsize > c_ddr_ctrl_nof_latent_reads, defined at write side of read FIFO.
g_rd_data_w : NATURAL := 32;
g_flush_wr_fifo : BOOLEAN := FALSE; -- TRUE instantiates a dp_flush + controller to flush the write fifo when the driver is not ready to write
g_flush_sop : BOOLEAN := FALSE;
g_flush_sop_channel : BOOLEAN := FALSE;
......@@ -47,11 +47,6 @@ ENTITY io_ddr IS
ctlr_ref_clk : IN STD_LOGIC;
ctlr_ref_rst : IN STD_LOGIC;
ctlr_gen_clk : OUT STD_LOGIC; -- Controller generated clock
ctlr_gen_rst : OUT STD_LOGIC;
ctlr_gen_clk_2x : OUT STD_LOGIC; -- Controller generated double frequency clock
ctlr_gen_rst_2x : OUT STD_LOGIC; -- ctlr_gen_rst synchronized to ctlr_gen_clk_2x
ctlr_init_done : OUT STD_LOGIC;
ctlr_rdy : OUT STD_LOGIC;
......@@ -74,7 +69,7 @@ ENTITY io_ddr IS
rd_clk : IN STD_LOGIC;
rd_rst : IN STD_LOGIC;
rd_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_rd_fifo_depth * (g_tech_ddr.data_w/g_rd_data_w) )-1 DOWNTO 0);
rd_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_rd_fifo_depth * (func_tech_ddr_ctrl_data_w(g_tech_ddr)/g_rd_data_w) )-1 DOWNTO 0);
phy_in : IN t_tech_ddr_phy_in;
phy_io : INOUT t_tech_ddr_phy_io;
......@@ -85,26 +80,25 @@ END io_ddr;
ARCHITECTURE str OF io_ddr IS
CONSTANT c_wr_fifo_depth : NATURAL := g_wr_fifo_depth * (g_tech_ddr.data_w/g_wr_data_w); -- Multiply fifo depth by the fifo's rd/wr width ratio to get write side depth
CONSTANT c_ctrl_address_w : NATURAL := func_tech_ddr_ctrl_address_w(g_tech_ddr);
CONSTANT c_ctlr_data_w : NATURAL := func_tech_ddr_ctrl_data_w( g_tech_ddr);
CONSTANT c_wr_fifo_depth : NATURAL := g_wr_fifo_depth * (c_ctlr_data_w/g_wr_data_w); -- Multiply fifo depth by the fifo's rd/wr width ratio to get write side depth
CONSTANT c_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_latency : NATURAL := 1;
SIGNAL ctlr_burst : STD_LOGIC;
SIGNAL ctlr_burst_size : STD_LOGIC_VECTOR(g_tech_ddr.maxburstsize_w-1 DOWNTO 0);
SIGNAL ctlr_address : STD_LOGIC_VECTOR(ceil_log2(g_tech_ddr.cs_w-1) + g_tech_ddr.ba_w + g_tech_ddr.a_w + g_tech_ddr.a_col_w - g_tech_ddr.rsl_w-1 DOWNTO 0); -- ceil_log2(..-1) because the chip select lines are converted to a logical address
SIGNAL ctlr_rd_req : STD_LOGIC;
SIGNAL ctlr_wr_req : STD_LOGIC;
SIGNAL ctlr_ref_rst_n : STD_LOGIC;
SIGNAL ctlr_gen_rst_n : STD_LOGIC;
SIGNAL i_ctlr_gen_clk : STD_LOGIC;
SIGNAL i_ctlr_gen_rst : STD_LOGIC;
SIGNAL i_ctlr_gen_clk_2x : STD_LOGIC;
SIGNAL i_ctlr_init_done : STD_LOGIC;
SIGNAL i_ctlr_rdy : STD_LOGIC;
SIGNAL i_dvr_done : STD_LOGIC;
SIGNAL ctlr_gen_clk : STD_LOGIC;
SIGNAL ctlr_gen_rst : STD_LOGIC;
SIGNAL ctlr_mosi : t_tech_ddr_mosi;
SIGNAL ctlr_miso : t_tech_ddr_miso;
SIGNAL dvr_cur_addr : t_tech_ddr_addr;
SIGNAL dvr_flush : STD_LOGIC := '0';
......@@ -121,21 +115,14 @@ ARCHITECTURE str OF io_ddr IS
BEGIN
ctlr_init_done <= i_ctlr_init_done;
ctlr_rdy <= ctlr_miso.waitrequest_n;
dvr_done <= i_dvr_done;
ctlr_ref_rst_n <= NOT(ctlr_ref_rst);
i_ctlr_gen_rst <= NOT(ctlr_gen_rst_n);
ctlr_gen_clk <= i_ctlr_gen_clk;
ctlr_gen_rst <= i_ctlr_gen_rst;
ctlr_gen_clk_2x <= i_ctlr_gen_clk_2x;
ctlr_rdy <= i_ctlr_rdy;
ctlr_init_done <= i_ctlr_init_done;
u_wr_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
GENERIC MAP (
g_wr_data_w => g_wr_data_w,
g_rd_data_w => g_tech_ddr.data_w,
g_rd_data_w => c_ctlr_data_w,
g_use_ctrl => g_wr_use_ctrl,
g_wr_fifo_size => c_wr_fifo_depth,
g_wr_fifo_af_margin => 4 + c_latency, --default (4) + c_latency to compensate for latency introduced by registering wr_siso.ready
......@@ -144,8 +131,8 @@ BEGIN
PORT MAP (
wr_rst => wr_rst,
wr_clk => wr_clk,
rd_rst => i_ctlr_gen_rst,
rd_clk => i_ctlr_gen_clk,
rd_rst => ctlr_gen_rst,
rd_clk => ctlr_gen_clk,
snk_out => wr_siso,
snk_in => wr_sosi,
......@@ -165,20 +152,20 @@ BEGIN
g_framed_xoff => FALSE -- immediately start flushing when dvr_flush goes high
)
PORT MAP (
rst => i_ctlr_gen_rst,
clk => i_ctlr_gen_clk,
rst => ctlr_gen_rst,
clk => ctlr_gen_clk,
snk_in => flush_wr_sosi,
snk_out => flush_wr_siso,
src_out => ctlr_wr_sosi,
src_in => ctlr_wr_siso, -- fixed streaming xon='1'
src_in => ctlr_wr_siso,
flush_en => dvr_flush -- memory mapped xon/xoff control
flush_en => dvr_flush
);
gen_flush : IF g_flush_wr_fifo = TRUE GENERATE
u_flush_ctrl : ENTITY work.ddr_flush_ctrl
gen_io_ddr_driver_flush_ctrl : IF g_flush_wr_fifo = TRUE GENERATE
u_io_ddr_driver_flush_ctrl : ENTITY work.io_ddr_driver_flush_ctrl
GENERIC MAP (
g_sop => g_flush_sop,
g_sop_channel => g_flush_sop_channel,
......@@ -201,7 +188,7 @@ BEGIN
u_rd_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
GENERIC MAP (
g_wr_data_w => g_tech_ddr.data_w,
g_wr_data_w => c_ctlr_data_w,
g_rd_data_w => g_rd_data_w,
g_use_ctrl => FALSE,
g_wr_fifo_size => g_rd_fifo_depth,
......@@ -209,8 +196,8 @@ BEGIN
g_rd_fifo_rl => 1
)
PORT MAP (
wr_rst => i_ctlr_gen_rst,
wr_clk => i_ctlr_gen_clk,
wr_rst => ctlr_gen_rst,
wr_clk => ctlr_gen_clk,
rd_rst => rd_rst,
rd_clk => rd_clk,
......@@ -231,15 +218,15 @@ BEGIN
g_wr_fifo_depth => g_wr_fifo_depth
)
PORT MAP (
rst => i_ctlr_gen_rst,
clk => i_ctlr_gen_clk,
rst => ctlr_gen_rst,
clk => ctlr_gen_clk,
ctlr_rdy => i_ctlr_rdy,
ctlr_rdy => ctlr_miso.waitrequest_n,
ctlr_init_done => i_ctlr_init_done,
ctlr_wr_req => ctlr_wr_req,
ctlr_rd_req => ctlr_rd_req,
ctlr_burst => ctlr_burst,
ctlr_burst_size => ctlr_burst_size,
ctlr_wr_req => ctlr_mosi.wr,
ctlr_rd_req => ctlr_mosi.rd,
ctlr_burst => ctlr_mosi.burstbegin,
ctlr_burst_size => ctlr_mosi.burstsize,
wr_val => ctlr_wr_sosi.valid,
wr_rdy => ctlr_wr_siso.ready,
......@@ -256,62 +243,42 @@ BEGIN
wr_fifo_usedw => wr_fifo_usedw
);
ctlr_address <= dvr_cur_addr.chip &
dvr_cur_addr.bank &
dvr_cur_addr.row(g_tech_ddr.a_w-1 DOWNTO 0) &
dvr_cur_addr.column(g_tech_ddr.a_col_w-1 DOWNTO g_tech_ddr.rsl_w);
ctlr_mosi.address(c_ctrl_address_w-1 DOWNTO 0) <= dvr_cur_addr.chip &
dvr_cur_addr.bank &
dvr_cur_addr.row(g_tech_ddr.a_w-1 DOWNTO 0) &
dvr_cur_addr.column(g_tech_ddr.a_col_w-1 DOWNTO g_tech_ddr.rsl_w);
ctlr_mosi.wrdata(c_ctlr_data_w-1 DOWNTO 0) <= ctlr_wr_sosi.data(c_ctlr_data_w-1 DOWNTO 0);
ctlr_rd_sosi.valid <= ctlr_miso.rdval;
ctlr_rd_sosi.data(c_ctlr_data_w-1 DOWNTO 0) <= ctlr_miso.rddata(c_ctlr_data_w-1 DOWNTO 0);
gen_uphy_4g_800_master : IF func_tech_ddr_module_size(c_tech_ddr)=4 AND g_tech_ddr.mts=800 GENERATE
u_uphy_4g_800_master : COMPONENT uphy_4g_800_master
PORT MAP (
pll_ref_clk => ctlr_ref_clk,
global_reset_n => ctlr_ref_rst_n,
soft_reset_n => '1',
afi_clk => i_ctlr_gen_clk,
afi_half_clk => OPEN,
afi_reset_n => ctlr_gen_rst_n,
mem_a => phy_ou.a(g_tech_ddr.a_w-1 DOWNTO 0),
mem_ba => phy_ou.ba(g_tech_ddr.ba_w-1 DOWNTO 0),
mem_ck => phy_io.clk(g_tech_ddr.clk_w-1 DOWNTO 0),
mem_ck_n => phy_io.clk_n(g_tech_ddr.clk_w-1 DOWNTO 0),
mem_cke => phy_ou.cke(g_tech_ddr.clk_w-1 DOWNTO 0),
mem_cs_n => phy_ou.cs_n(g_tech_ddr.cs_w-1 DOWNTO 0),
mem_dm => phy_ou.dm(g_tech_ddr.dm_w-1 DOWNTO 0),
mem_ras_n => phy_ou.ras_n,
mem_cas_n => phy_ou.cas_n,
mem_we_n => phy_ou.we_n,
mem_reset_n => phy_ou.reset_n,
mem_dq => phy_io.dq(g_tech_ddr.dq_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_tech_ddr.dqs_w-1 DOWNTO 0),
mem_dqs_n => phy_io.dqs_n(g_tech_ddr.dqs_w-1 DOWNTO 0),
mem_odt => phy_ou.odt(g_tech_ddr.cs_w-1 DOWNTO 0),
avl_ready => i_ctlr_rdy,
avl_burstbegin => ctlr_burst,
avl_addr => ctlr_address,
avl_rdata_valid => ctlr_rd_sosi.valid,
avl_rdata => ctlr_rd_sosi.data(g_tech_ddr.data_w-1 DOWNTO 0),
avl_wdata => ctlr_wr_sosi.data(g_tech_ddr.data_w-1 DOWNTO 0),
avl_be => (OTHERS => '1'),
avl_read_req => ctlr_rd_req,
avl_write_req => ctlr_wr_req,
avl_size => ctlr_burst_size,
local_init_done => i_ctlr_init_done,
local_cal_success => OPEN,
local_cal_fail => OPEN,
oct_rdn => phy_in.oct_rdn,
oct_rup => phy_in.oct_rup,
seriesterminationcontrol => OPEN,
parallelterminationcontrol => OPEN,
pll_mem_clk => i_ctlr_gen_clk_2x,
pll_write_clk => OPEN,
pll_write_clk_pre_phy_clk => OPEN,
pll_addr_cmd_clk => OPEN,
pll_locked => OPEN,
pll_avl_clk => OPEN,
pll_config_clk => OPEN,
dll_delayctrl => OPEN
);
END GENERATE;
u_tech_ddr : ENTITY tech_ddr_lib.tech_ddr
GENERIC MAP (
g_technology => g_technology,
g_tech_ddr => g_tech_ddr
)
PORT MAP (
-- PLL reference clock
ctlr_ref_clk => ctlr_ref_clk,
ctlr_ref_rst => ctlr_ref_rst,
-- Controller user interface
ctlr_gen_clk => ctlr_gen_clk,
ctlr_gen_rst => ctlr_gen_rst,
ctlr_gen_clk_2x => OPEN,
ctlr_gen_rst_2x => OPEN,
ctlr_init_done => i_ctlr_init_done,
ctrl_mosi => ctlr_mosi,
ctrl_miso => ctlr_miso,
-- PHY interface
phy_in => phy_in,
phy_io => phy_io,
phy_ou => phy_ou
);
END str;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment