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

Moved DDR sim model to sim_ddr.vhd.

parent c85011f5
No related branches found
No related tags found
No related merge requests found
......@@ -14,6 +14,7 @@ hdl_lib_technology =
synth_files =
tech_ddr_pkg.vhd
sim_ddr.vhd
tech_ddr_component_pkg.vhd
tech_ddr_stratixiv.vhd
tech_ddr_arria10.vhd
......
--------------------------------------------------------------------------------
--
-- Copyright (C) 2015
-- 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/>.
--
--------------------------------------------------------------------------------
-- Purpose: Functional simulation model of both the DDR driver and the DDR memory.
-- Description:
-- The component also supports different types of DDR, so DDR3 and DDR4.
-- Remark:
-- . It is assumed that the user only performs burst reads/writes!
-- . Modelsim raises warning 3391 when the DDR memory set by c_nof_addr is to big to fit in PC RAM.
-- Use 'verror 3391' to display the help. This means that the computer becomes too slow due to
-- page swapping to disk. Even loading the simulation becomes slow.
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;
USE work.tech_ddr_pkg.ALL;
ENTITY sim_ddr IS
GENERIC (
g_tech_ddr : t_c_tech_ddr
);
PORT (
-- PLL reference clock
ref_clk : IN STD_LOGIC;
ref_rst : IN STD_LOGIC;
-- Controller user interface
ctlr_gen_clk : OUT STD_LOGIC;
ctlr_gen_rst : OUT STD_LOGIC;
ctlr_gen_clk_2x : OUT STD_LOGIC;
ctlr_gen_rst_2x : OUT STD_LOGIC;
ctlr_mosi : IN t_mem_ctlr_mosi;
ctlr_miso : OUT t_mem_ctlr_miso
);
END sim_ddr;
ARCHITECTURE str OF sim_ddr IS
-- DDR size and controller data width
CONSTANT c_nof_addr : NATURAL := 2**func_tech_ddr_ctlr_address_w(g_tech_ddr); --8192;
CONSTANT c_dat_w : NATURAL := func_tech_ddr_ctlr_data_w(g_tech_ddr); --256;
-- DDR memory
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
-- 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;
ctlr_miso.done <= '0' , '1' AFTER 1 ns;
ctlr_miso.cal_ok <= '0' , '1' AFTER 1 ns;
ctlr_miso.cal_fail <= '0';
-- 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 access 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 str;
......@@ -35,7 +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_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
);
......@@ -71,8 +71,8 @@ END tech_ddr;
ARCHITECTURE str OF tech_ddr IS
CONSTANT c_nof_addr : NATURAL := 8192;
CONSTANT c_dat_w : NATURAL := 256;
CONSTANT c_nof_addr : NATURAL := 2**func_tech_ddr_ctlr_address_w(g_tech_ddr); --8192;
CONSTANT c_dat_w : NATURAL := func_tech_ddr_ctlr_data_w(g_tech_ddr); --256;
TYPE t_mem_arr IS ARRAY(0 TO c_nof_addr-1) OF STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
......@@ -108,91 +108,28 @@ BEGIN
END GENERATE;
-----------------------------------------------------------------------------
-- Functional simulation model
-- . Note: is it assumed that the user only performs burst reads/writes!
-- Functional simulation model of both the DDR controller and the DDR memory
-----------------------------------------------------------------------------
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;
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
u0 : ENTITY work.sim_ddr
GENERIC MAP (
g_tech_ddr => g_tech_ddr
)
PORT MAP (
-- PLL reference clock
ref_clk => ref_clk,
ref_rst => ref_rst,
ctlr_miso.rdval <= '0';
ctlr_miso.waitrequest_n <= '1';
-- Controller user interface
ctlr_gen_clk => ctlr_gen_clk,
ctlr_gen_rst => ctlr_gen_rst,
ctlr_gen_clk_2x => ctlr_gen_clk_2x,
ctlr_gen_rst_2x => ctlr_gen_rst_2x,
-- 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;
ctlr_mosi => ctlr_mosi,
ctlr_miso => ctlr_miso
);
END GENERATE;
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