Select Git revision
fix_long_baselines.cwl
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
mm_pipeline.vhd 5.66 KiB
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Author: E. Kooistra
-- Purpose: Pipeline MM mosi
-- Description:
-- The mm_pipeline mosi registers the in_mosi if g_pipeline = TRUE, else it
-- defaults to wires.
--
-- Background information
-- The MM waitrequest resembles the behaviour of the streaming backpressure
-- ready for ready latency RL = 0. For RL = 0 the ready acts as an
-- acknowledge to pending data. For RL > 0 the ready acts as a request for
-- new data. The miso.waitrequest is defined for RL = 0 but for analysis
-- the timing diagrams below show an example of both RL = 0 and RL = 1.
--
-- * RL=1
-- _ _ _ _ _ _ _ _ _ _ _ _
-- clk _| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
--
-- in_dat |a |b |c |d
-- _________ ___ ___
-- in_val |_______| |_______| |_______________
-- _____ ___ _______ ___________
-- ready |_______| |___|... |_______|...........
-- _________ ___ _______ _______
-- reg_ready |_______| |___|... |_______|.......
--
-- reg_dat |a |b |c |d
-- _____________________________ ___________
-- reg_val |___| |___
-- _________ ___ ___ ___
-- out_val |a |_______|b |___|c |___________|d |___
--
--
-- * RL=0
-- _ _ _ _ _ _ _ _ _ _ _ _ _
-- clk _| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
--
-- in_dat |a |b |c |d |e
-- _________ _______________ ___
-- in_val |_______| |_______| |_______
-- _____________ ___ _______ ___________
-- ack |_______| |___| |___|
--
-- reg_dat |a |b |c |d |e
-- _____________ ___________ ___
-- reg_val |___________| |_______| |___
-- _____________ _______ ___
-- out_val |a |b |_______________|c |d |_______|e |___
--
-- In these timing diagrams the out_ready is wired to the in_ready, so
-- therefore they are identical and called ready.
-- The ready for RL = 0 or the reg_ready for RL = 1 is used to gate the
-- out_val. The ready/reg_ready is used and not the in_val, because by
-- using the ready/reg_ready the pipeline register is emptied as soon
-- as the ready is active, rather than to wait for a next in_val to push
-- it out.
--
-- Remark:
-- * The mm_pipeline could be optimized regarding the miso.waitrequest flow
-- control if it would be implemented similar as dp_pipeline.vhd. This
-- involves using the pipeline register to accept an access when it is
-- empty. In this way the waitrequest to the in_mosi only needs to apply
-- when the out_miso is not ready and the pipeline is full. The advantage
-- of simply registering in_mosi and wiring in_miso is that it is simpler
-- and does not put extra logic into the combinatorial miso.waitrequest
-- path.
LIBRARY IEEE, common_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
ENTITY mm_pipeline IS
GENERIC (
g_pipeline : BOOLEAN := TRUE
);
PORT (
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
in_mosi : IN t_mem_mosi;
in_miso : OUT t_mem_miso;
out_mosi : OUT t_mem_mosi;
out_miso : IN t_mem_miso
);
END mm_pipeline;
ARCHITECTURE rtl OF mm_pipeline IS
SIGNAL mosi_reg : t_mem_mosi := c_mem_mosi_rst;
SIGNAL nxt_mosi_reg : t_mem_mosi;
SIGNAL ready : STD_LOGIC;
BEGIN
-- Pass on miso
in_miso <= out_miso;
-- Pipeline the mosi when g_pipeline = TRUE, else default to wires
gen_wires : IF g_pipeline = FALSE GENERATE
out_mosi <= in_mosi;
END GENERATE;
gen_pipeline : IF g_pipeline = TRUE GENERATE
p_reg : PROCESS(mm_rst, mm_clk)
BEGIN
IF mm_rst = '1' THEN
mosi_reg <= c_mem_mosi_rst;
ELSIF rising_edge(mm_clk) THEN
mosi_reg <= nxt_mosi_reg;
END IF;
END PROCESS;
ready <= NOT out_miso.waitrequest;
nxt_mosi_reg <= in_mosi WHEN ready = '1' ELSE mosi_reg;
p_out_mosi : PROCESS(mosi_reg, ready)
BEGIN
out_mosi <= mosi_reg;
IF ready /= '1' THEN
out_mosi.wr <= '0'; -- out_mosi.wr = mosi_reg.wr AND ready
out_mosi.rd <= '0'; -- out_mosi.rd = mosi_reg.rd AND ready
END IF;
END PROCESS;
END GENERATE;
END rtl;