From 57034f10c6fb11782983cb45f15b8818b815126b Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Tue, 13 Jun 2017 06:21:48 +0000 Subject: [PATCH] Corrected sim_ddr model, tb_io_ddr now passes with g_sim_model = true. --- libraries/technology/ddr/sim_ddr.vhd | 168 +++++++++++++++++---------- 1 file changed, 109 insertions(+), 59 deletions(-) diff --git a/libraries/technology/ddr/sim_ddr.vhd b/libraries/technology/ddr/sim_ddr.vhd index f8ec34019b..d6fc241af7 100644 --- a/libraries/technology/ddr/sim_ddr.vhd +++ b/libraries/technology/ddr/sim_ddr.vhd @@ -67,11 +67,20 @@ ARCHITECTURE str OF sim_ddr IS -- 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; + SIGNAL sim_clk : STD_LOGIC; + SIGNAL sim_rst : STD_LOGIC; + + SIGNAL address : NATURAL; + SIGNAL burst_size : NATURAL; + SIGNAL burst_cnt : NATURAL; + SIGNAL waitrequest_n : STD_LOGIC := '1'; + SIGNAL wr_bursting : BOOLEAN := FALSE; + SIGNAL rd_bursting : BOOLEAN := FALSE; + + SIGNAL pending_wr : BOOLEAN := FALSE; + SIGNAL pending_rd : BOOLEAN := FALSE; + SIGNAL pending_address : NATURAL; + SIGNAL pending_burst_size : NATURAL; BEGIN @@ -84,73 +93,114 @@ BEGIN ctlr_miso.done <= '0' , '1' AFTER 1 ns; ctlr_miso.cal_ok <= '0' , '1' AFTER 1 ns; ctlr_miso.cal_fail <= '0'; + + ctlr_miso.waitrequest_n <= waitrequest_n; - -- 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; + p_mem_access : PROCESS(sim_clk) + -- Process variables get initalized once and then they keep their state VARIABLE v_mem_arr : t_mem_arr := (OTHERS=>(OTHERS=>'0')); - VARIABLE v_address : NATURAL := 0; + + VARIABLE v_address : NATURAL; + VARIABLE v_burst_size : NATURAL; + VARIABLE v_burst_cnt : 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; + VARIABLE v_waitrequest_n : STD_LOGIC := '1'; + 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 rising_edge(sim_clk) THEN - 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 + -- Get state + --v_address := address; + --v_burst_size := burst_size; + --v_burst_cnt := burst_cnt; + --v_waitrequest_n := waitrequest_n; + --v_wr_bursting := wr_bursting; + --v_rd_bursting := rd_bursting; + + -- Burst begin + IF ctlr_mosi.burstbegin='1' THEN + IF ctlr_mosi.wr='1' THEN + IF v_rd_bursting=FALSE 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; + v_address := TO_UINT(ctlr_mosi.address); + v_burst_size := TO_UINT(ctlr_mosi.burstsize); + v_burst_cnt := 0; + ELSE + pending_wr <= TRUE; + pending_address <= TO_UINT(ctlr_mosi.address); + pending_burst_size <= TO_UINT(ctlr_mosi.burstsize); END IF; - - IF v_burst_cnt = v_burst_size THEN - v_wr_bursting := FALSE; - v_rd_bursting := FALSE; + ELSIF ctlr_mosi.rd='1' THEN + IF v_rd_bursting=FALSE THEN + v_rd_bursting := TRUE; + v_waitrequest_n := '0'; + v_address := TO_UINT(ctlr_mosi.address); + v_burst_size := TO_UINT(ctlr_mosi.burstsize); + v_burst_cnt := 0; + ELSE + pending_rd <= TRUE; + pending_address <= TO_UINT(ctlr_mosi.address); + pending_burst_size <= TO_UINT(ctlr_mosi.burstsize); END IF; END IF; - - address <= v_address; + END IF; + + -- Pending write burst begin, after read burst + IF pending_wr=TRUE AND v_rd_bursting=FALSE THEN + pending_wr <= FALSE; + IF ctlr_mosi.wr='1' THEN -- require that user has kept wr still active + v_wr_bursting := TRUE; + v_address := pending_address; + v_burst_size := pending_burst_size; + v_burst_cnt := 0; + END IF; + END IF; + + -- Pending read burst begin, after read burst + IF pending_rd=TRUE AND v_rd_bursting=FALSE THEN + pending_rd <= FALSE; + IF ctlr_mosi.rd='1' THEN -- require that user has kept rd still active + v_rd_bursting := TRUE; + v_address := pending_address; + v_burst_size := pending_burst_size; + v_burst_cnt := 0; + v_waitrequest_n := '0'; + END IF; + END IF; + + -- Write access + IF v_wr_bursting=TRUE AND ctlr_mosi.wr='1' THEN + v_mem_arr(v_address) := ctlr_mosi.wrdata(c_dat_w-1 DOWNTO 0); + v_address := v_address + 1; + v_burst_cnt := v_burst_cnt + 1; + END IF; + + -- Read access + ctlr_miso.rdval <= '0'; + IF v_rd_bursting=TRUE THEN + ctlr_miso.rddata(c_dat_w-1 DOWNTO 0) <= v_mem_arr(v_address); + ctlr_miso.rdval <= '1'; + v_address := v_address + 1; + v_burst_cnt := v_burst_cnt + 1; + END IF; + -- Burst size count + IF v_burst_cnt = v_burst_size THEN + v_wr_bursting := FALSE; + v_rd_bursting := FALSE; + v_waitrequest_n := '1'; END IF; + + -- Show state + --address <= v_address; + --burst_size <= v_burst_size; + --burst_cnt <= v_burst_cnt; + --wr_bursting <= v_wr_bursting; + --rd_bursting <= v_rd_bursting; + + waitrequest_n <= v_waitrequest_n; END IF; END PROCESS; -- GitLab