diff --git a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd index 771b6ace6f76fbb22079481055a6791ada71d8c9..7ba7531c4987a8d314f1a0efb2663291a09f8ea5 100644 --- a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd +++ b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd @@ -27,7 +27,8 @@ ENTITY apertif_unb1_fn_beamformer_tp_bg IS GENERIC ( g_design_name : STRING := "apertif_unb1_fn_beamformer_tp_bg"; g_design_note : STRING := "transpose revision with BGs"; - g_sim : BOOLEAN := FALSE; + g_sim : BOOLEAN := FALSE; + g_sim_model : BOOLEAN := FALSE; -- Use fast DDR3 sim model g_sim_unb_nr : NATURAL := 0; g_sim_node_nr : NATURAL := 0; g_stamp_date : NATURAL := 0; @@ -101,7 +102,8 @@ BEGIN GENERIC MAP ( g_design_name => g_design_name, g_design_note => g_design_note, - g_sim => g_sim, + g_sim => g_sim, + g_sim_model => g_sim_model, g_sim_unb_nr => g_sim_unb_nr, g_sim_node_nr => g_sim_node_nr, g_stamp_date => g_stamp_date, diff --git a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd index 64318f84b37e5412996866d87b72e699b5b2a07e..df21cd03c3dec547a6e2dda79093dd64d4628f82 100644 --- a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd +++ b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd @@ -39,6 +39,7 @@ END tb_apertif_unb1_fn_beamformer_tp_bg; ARCHITECTURE tb OF tb_apertif_unb1_fn_beamformer_tp_bg IS CONSTANT c_sim : BOOLEAN := TRUE; + CONSTANT c_sim_model : BOOLEAN := TRUE; --Use fast DDR3 sim model CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 CONSTANT c_node_nr : NATURAL := 0; -- Front node 0 @@ -111,6 +112,7 @@ BEGIN u_apertif_unb1_fn_beamformer : ENTITY work.apertif_unb1_fn_beamformer_tp_bg GENERIC MAP ( g_sim => c_sim, + g_sim_model => c_sim_model, g_sim_unb_nr => c_unb_nr, g_sim_node_nr => c_node_nr ) @@ -159,15 +161,16 @@ BEGIN ------------------------------------------------------------------------------ -- DDR3 memory model ------------------------------------------------------------------------------ - u_tech_ddr_memory_model : ENTITY tech_ddr_lib.tech_ddr_memory_model - GENERIC MAP ( - g_tech_ddr => c_ddr - ) - PORT MAP ( - mem3_in => phy_ou, - mem3_io => phy_io, - mem3_ou => phy_in - ); - + gen_tech_ddr_memory_model : IF c_sim_model = FALSE GENERATE + u_tech_ddr_memory_model : ENTITY tech_ddr_lib.tech_ddr_memory_model + GENERIC MAP ( + g_tech_ddr => c_ddr + ) + PORT MAP ( + mem3_in => phy_ou, + mem3_io => phy_io, + mem3_ou => phy_in + ); + END GENERATE; END tb; diff --git a/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd b/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd index 3f725a3758e69c5f45f3bd8b6bc7010aae2d072a..768ef9b138de804469bba1f84667553da87eff1f 100644 --- a/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd +++ b/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd @@ -43,6 +43,7 @@ ENTITY apertif_unb1_fn_beamformer IS g_design_name : STRING := "apertif_unb1_fn_beamformer"; --"apertif_unb1_fn_beamformer"; g_design_note : STRING := "revision info"; --"UNUSED"; g_sim : BOOLEAN := FALSE; --Overridden by TB + g_sim_model : BOOLEAN := FALSE; -- Use fast DDR3 model g_sim_unb_nr : NATURAL := 0; g_sim_node_nr : NATURAL := 0; g_stamp_date : NATURAL := 0; -- Date (YYYYMMDD) -- set by QSF @@ -529,6 +530,7 @@ BEGIN u_ddr_mem_ctrl : ENTITY io_ddr_lib.io_ddr GENERIC MAP( + g_sim_model => g_sim_model, g_technology => c_tech_select_default, g_tech_ddr => c_tech_ddr, g_cross_domain_dvr_ctlr => FALSE, diff --git a/libraries/io/ddr/src/vhdl/io_ddr.vhd b/libraries/io/ddr/src/vhdl/io_ddr.vhd index 4fe304f12f1f2eb828b9545c285d168428ea66cc..1a4a516dfca2e8a38163c37ee9085a7b6d704bef 100644 --- a/libraries/io/ddr/src/vhdl/io_ddr.vhd +++ b/libraries/io/ddr/src/vhdl/io_ddr.vhd @@ -154,6 +154,7 @@ USE dp_lib.dp_stream_pkg.ALL; ENTITY io_ddr IS GENERIC( + g_sim_model : BOOLEAN := FALSE; g_technology : NATURAL := c_tech_select_default; g_tech_ddr : t_c_tech_ddr; g_cross_domain_dvr_ctlr : BOOLEAN := TRUE; @@ -441,6 +442,7 @@ BEGIN u_tech_ddr : ENTITY tech_ddr_lib.tech_ddr GENERIC MAP ( + g_sim_model => g_sim_model, g_technology => g_technology, g_tech_ddr => g_tech_ddr ) diff --git a/libraries/technology/ddr/tech_ddr.vhd b/libraries/technology/ddr/tech_ddr.vhd index 79dcd05a1165e8aba6c659dedb6a291c129feca4..03961ea0085e885f76acecd6d7d76ecc2ea39c9c 100644 --- a/libraries/technology/ddr/tech_ddr.vhd +++ b/libraries/technology/ddr/tech_ddr.vhd @@ -27,6 +27,7 @@ LIBRARY IEEE, common_lib, technology_lib; USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; USE common_lib.common_mem_pkg.ALL; USE technology_lib.technology_pkg.ALL; USE technology_lib.technology_select_pkg.ALL; @@ -34,6 +35,7 @@ USE work.tech_ddr_pkg.ALL; ENTITY tech_ddr IS GENERIC ( + g_sim_model : BOOLEAN := FALSE; -- TRUE: use fast behavioural model, requires no external memory (uses memory array). g_technology : NATURAL := c_tech_select_default; g_tech_ddr : t_c_tech_ddr ); @@ -69,25 +71,128 @@ END tech_ddr; ARCHITECTURE str OF tech_ddr IS + CONSTANT c_nof_addr : NATURAL := 8192; + CONSTANT c_dat_w : NATURAL := 256; + + TYPE t_mem_arr IS ARRAY(0 TO c_nof_addr-1) OF STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0); + + SIGNAL sim_clk : STD_LOGIC; + SIGNAL sim_rst : STD_LOGIC; + SIGNAL sim_ctlr_mosi : t_mem_ctlr_mosi; + + SIGNAL address : NATURAL; + BEGIN - - gen_ip_stratixiv : IF g_technology=c_tech_stratixiv GENERATE - u0 : ENTITY work.tech_ddr_stratixiv - GENERIC MAP (g_tech_ddr) - PORT MAP (ref_clk, ref_rst, - ctlr_gen_clk, ctlr_gen_rst, ctlr_gen_clk_2x, ctlr_gen_rst_2x, - ctlr_mosi, ctlr_miso, term_ctrl_out, term_ctrl_in, - phy3_in, phy3_io, phy3_ou); + + ----------------------------------------------------------------------------- + -- Technology IP cores + ----------------------------------------------------------------------------- + gen_ip: IF g_sim_model = FALSE GENERATE + gen_ip_stratixiv : IF g_technology=c_tech_stratixiv GENERATE + u0 : ENTITY work.tech_ddr_stratixiv + GENERIC MAP (g_tech_ddr) + PORT MAP (ref_clk, ref_rst, + ctlr_gen_clk, ctlr_gen_rst, ctlr_gen_clk_2x, ctlr_gen_rst_2x, + ctlr_mosi, ctlr_miso, term_ctrl_out, term_ctrl_in, + phy3_in, phy3_io, phy3_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 (ref_clk, ref_rst, + ctlr_gen_clk, ctlr_gen_rst, + ctlr_mosi, ctlr_miso, + phy4_in, phy4_io, phy4_ou); + END GENERATE; END GENERATE; + + ----------------------------------------------------------------------------- + -- Functional simulation model + -- . Note: is it assumed that the user only performs burst reads/writes! + ----------------------------------------------------------------------------- + gen_sim_model : IF g_sim_model=TRUE GENERATE + -- Prevent delta delay issues by using a re-assigned clk both internally + -- (sim_clk) and externally (ctrl_gen_clk) + ctlr_gen_clk <= ref_clk; + ctlr_gen_rst <= ref_rst; + sim_clk <= ref_clk; + sim_rst <= ref_rst; - gen_ip_arria10 : IF g_technology=c_tech_arria10 GENERATE - u0 : ENTITY work.tech_ddr_arria10 - GENERIC MAP (g_tech_ddr) - PORT MAP (ref_clk, ref_rst, - ctlr_gen_clk, ctlr_gen_rst, - ctlr_mosi, ctlr_miso, - phy4_in, phy4_io, phy4_ou); - END GENERATE; + ctlr_miso.done <= '0' , '1' AFTER 1000 ps; + ctlr_miso.cal_ok <= '0' , '1' AFTER 1000 ps; + -- Delay the control one cycle here so p_mem_access can update its outputs + -- immediately + p_clk : PROCESS(sim_clk) + BEGIN + IF rising_edge(sim_clk) THEN + sim_ctlr_mosi <= ctlr_mosi; + END IF; + END PROCESS; + + p_mem_access : PROCESS(sim_clk, sim_ctlr_mosi) + VARIABLE v_enable_model : BOOLEAN := FALSE; + VARIABLE v_mem_arr : t_mem_arr := (OTHERS=>(OTHERS=>'0')); + VARIABLE v_address : NATURAL := 0; + VARIABLE v_wr_bursting : BOOLEAN := FALSE; + VARIABLE v_rd_bursting : BOOLEAN := FALSE; + VARIABLE v_burst_cnt : NATURAL := 0; + VARIABLE v_burst_size : NATURAL := 0; + BEGIN + + -- Don't waste simulation time when user does not use the model anyway + IF v_enable_model = FALSE THEN + ctlr_miso.waitrequest_n <= '1'; + IF sim_ctlr_mosi.burstbegin='1' THEN + v_enable_model := TRUE; + END IF; + END IF; + + IF v_enable_model = TRUE THEN + IF rising_edge(sim_clk) THEN + + ctlr_miso.rdval <= '0'; + ctlr_miso.waitrequest_n <= '1'; + + -- Access: burst begin + IF sim_ctlr_mosi.burstbegin='1' THEN + IF sim_ctlr_mosi.wr='1' THEN + v_wr_bursting := TRUE; + ELSIF sim_ctlr_mosi.rd='1' THEN + v_rd_bursting := TRUE; + END IF; + v_address := TO_UINT(sim_ctlr_mosi.address); + v_burst_size := TO_UINT(sim_ctlr_mosi.burstsize); + v_burst_cnt := 0; + END IF; + + IF v_wr_bursting=TRUE OR v_rd_bursting=TRUE THEN + IF sim_ctlr_mosi.wr='1' THEN -- Write + v_mem_arr(v_address) := sim_ctlr_mosi.wrdata(c_dat_w-1 DOWNTO 0); + v_address := v_address+1; + v_burst_cnt := v_burst_cnt +1; + ELSIF v_rd_bursting=TRUE THEN -- Read + ctlr_miso.rddata(c_dat_w-1 DOWNTO 0) <= v_mem_arr(v_address); + ctlr_miso.rdval <= '1'; + ctlr_miso.waitrequest_n <= '0'; + v_address := v_address+1; + v_burst_cnt := v_burst_cnt +1; + END IF; + + IF v_burst_cnt = v_burst_size THEN + v_wr_bursting := FALSE; + v_rd_bursting := FALSE; + END IF; + END IF; + + address <= v_address; + + END IF; + END IF; + + END PROCESS; + END GENERATE; + END str;