Select Git revision
mm_waitrequest_model.vhd
-
Eric Kooistra authoredEric Kooistra authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
mm_waitrequest_model.vhd 5.40 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: Provide waitrequest stimuli to model a slave with MM flow control
-- Description:
-- The model applies random waitrequest stimuli for a MM slave that does not
-- need MM flow control. In this way the MM slave acts like a MM slave that
-- does need MM flow control.
-- * The model only controls the bus_miso.waitrequest. The other slave_miso
-- fields are wired to the bus_miso. The bus master will act upon the
-- waitrequest, so model can rely on that regarding the bus_mosi. However
-- towards the MM slave that has no flow control the model has to gate the
-- bus_mosi wr and rd with the waitrequest, so that the MM slave only gets
-- a ram_mosi rd or wr when it was acknowledged.
-- * When g_waitrequest = TRUE then the waitrequest model is applied to the
-- bus_miso. Use g_waitrequest = FALSE to bypass the waitrequest model,
-- so then bus_miso.waitrequest is fixed '0'.
-- * The g_seed is used to initalize the random PRSG, e.g use slave instance
-- index as g_seed to have different stimuli per instance.
-- * The maximum number of cycles that waitrequest depends on the period of
-- the LFSR random sequence generator and can be:
-- . '1' for g_prsg_w mm_clk cycles
-- . '0' for g_prsg_w-1 mm_clk cycles
-- Remarks:
-- . To some extend the ASSERTs check the flow control. The testbench has to
-- verify the rddata to ensure more test coverage.
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
ENTITY mm_waitrequest_model IS
GENERIC (
g_waitrequest : BOOLEAN;
g_seed : NATURAL := 0;
g_prsg_w : NATURAL := 16
);
PORT (
mm_clk : IN STD_LOGIC;
bus_mosi : IN t_mem_mosi;
bus_miso : OUT t_mem_miso;
slave_mosi : OUT t_mem_mosi;
slave_miso : IN t_mem_miso
);
END mm_waitrequest_model;
ARCHITECTURE rtl OF mm_waitrequest_model IS
CONSTANT c_prsg_init : NATURAL := g_seed + 1; -- PRSG init must be > 0
SIGNAL prsg : STD_LOGIC_VECTOR(g_prsg_w-1 DOWNTO 0) := TO_UVEC(c_prsg_init, g_prsg_w);
SIGNAL waitrequest : STD_LOGIC;
SIGNAL prev_bus_mosi : t_mem_mosi;
SIGNAL prev_waitrequest : STD_LOGIC;
BEGIN
no_waitrequest : IF g_waitrequest=FALSE GENERATE
slave_mosi <= bus_mosi;
p_waitrequest : PROCESS(slave_miso)
BEGIN
bus_miso <= slave_miso;
bus_miso.waitrequest <= '0';
END PROCESS;
END GENERATE;
gen_waitrequest : IF g_waitrequest=TRUE GENERATE
-- Model MM flow control using random waitrequest
p_reg : PROCESS(mm_clk)
BEGIN
IF rising_edge(mm_clk) THEN
-- random waitrequest flow control
prsg <= func_common_random(prsg);
-- check MM access
prev_bus_mosi <= bus_mosi;
prev_waitrequest <= waitrequest;
END IF;
END PROCESS;
waitrequest <= prsg(0);
-- Apply MM flow control to bus master using waitrequest
p_bus_miso : PROCESS(waitrequest, slave_miso)
BEGIN
bus_miso <= slave_miso;
bus_miso.waitrequest <= waitrequest;
END PROCESS;
-- Gate MM rd and wr access to RAM slave that has no flow control
p_slave_mosi : PROCESS(waitrequest, bus_mosi)
BEGIN
slave_mosi <= bus_mosi;
slave_mosi.wr <= bus_mosi.wr AND NOT waitrequest;
slave_mosi.rd <= bus_mosi.rd AND NOT waitrequest;
END PROCESS;
-- Verify that MM access is not removed before it is acknowledged by waitrequest
p_verify : PROCESS(bus_mosi, prev_bus_mosi, prev_waitrequest)
BEGIN
IF prev_waitrequest = '1' THEN
IF prev_bus_mosi.wr = '1' AND bus_mosi.wr = '0' THEN REPORT "Aborted slave write." SEVERITY ERROR; END IF;
IF prev_bus_mosi.rd = '1' AND bus_mosi.rd = '0' THEN REPORT "Aborted slave read." SEVERITY ERROR; END IF;
IF prev_bus_mosi.wr = '1' AND bus_mosi.address /= prev_bus_mosi.address THEN REPORT "Address change during pending slave write." SEVERITY ERROR; END IF;
IF prev_bus_mosi.rd = '1' AND bus_mosi.address /= prev_bus_mosi.address THEN REPORT "Address change during pending slave read." SEVERITY ERROR; END IF;
END IF;
END PROCESS;
END GENERATE;
END rtl;