Select Git revision
check_ateam_separation.cwl
Forked from
ResearchAndDevelopment / LINC
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
tb_common_mem_pkg.vhd 12.08 KiB
-------------------------------------------------------------------------------
--
-- Copyright (C) 2010
-- 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/>.
--
-------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE work.common_pkg.ALL;
USE work.common_mem_pkg.ALL;
PACKAGE tb_common_mem_pkg IS
------------------------------------------------------------------------------
-- MM bus access functions
------------------------------------------------------------------------------
-- The mm_miso input needs to be declared as signal, because otherwise the
-- procedure does not notice a change (also not when the mm_clk is declared
-- as signal).
-- Write data to the MM bus
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN NATURAL; -- [31:0]
CONSTANT wr_data : IN INTEGER; -- [31:0]
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_miso : IN t_mem_miso; -- used for waitrequest
SIGNAL mm_mosi : OUT t_mem_mosi);
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN INTEGER; -- [31:0]
SIGNAL wr_data : IN STD_LOGIC_VECTOR; -- [31:0]
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_miso : IN t_mem_miso; -- used for waitrequest
SIGNAL mm_mosi : OUT t_mem_mosi);
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN NATURAL; -- [31:0]
CONSTANT wr_data : IN INTEGER; -- [31:0]
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi);
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN NATURAL; -- [31:0]
CONSTANT wr_data : IN STD_LOGIC_VECTOR; -- [31:0]
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi);
-- Read data request to the MM bus
PROCEDURE proc_mem_mm_bus_rd(CONSTANT rd_addr : IN NATURAL; -- [31:0]
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_miso : IN t_mem_miso; -- used for waitrequest
SIGNAL mm_mosi : OUT t_mem_mosi);
PROCEDURE proc_mem_mm_bus_rd(CONSTANT rd_addr : IN NATURAL; -- [31:0]
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi);
-- Wait for read data valid after read latency mm_clk cycles
PROCEDURE proc_mem_mm_bus_rd_latency(CONSTANT c_rd_latency : IN NATURAL;
SIGNAL mm_clk : IN STD_LOGIC);
-- Write array of data words to the memory
PROCEDURE proc_mem_write_ram(CONSTANT offset : IN NATURAL;
CONSTANT nof_data : IN NATURAL;
CONSTANT data_arr : IN t_slv_32_arr;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi);
PROCEDURE proc_mem_write_ram(CONSTANT data_arr : IN t_slv_32_arr;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi);
-- Read array of data words from the memory
PROCEDURE proc_mem_read_ram(CONSTANT offset : IN NATURAL;
CONSTANT nof_data : IN NATURAL;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL data_arr : OUT t_slv_32_arr);
PROCEDURE proc_mem_read_ram(SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL data_arr : OUT t_slv_32_arr);
END tb_common_mem_pkg;
PACKAGE BODY tb_common_mem_pkg IS
------------------------------------------------------------------------------
-- Private functions
------------------------------------------------------------------------------
-- Issues a rd or a wr MM access
PROCEDURE proc_mm_access(SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_access : OUT STD_LOGIC) IS
BEGIN
mm_access <= '1';
WAIT UNTIL rising_edge(mm_clk);
mm_access <= '0';
END proc_mm_access;
-- Issues a rd or a wr MM access and wait for it to have finished
PROCEDURE proc_mm_access(SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_waitreq : IN STD_LOGIC;
SIGNAL mm_access : OUT STD_LOGIC) IS
BEGIN
mm_access <= '1';
WAIT UNTIL rising_edge(mm_clk);
WHILE mm_waitreq='1' LOOP
WAIT UNTIL rising_edge(mm_clk);
END LOOP;
mm_access <= '0';
END proc_mm_access;
------------------------------------------------------------------------------
-- Public functions
------------------------------------------------------------------------------
-- Write data to the MM bus
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN NATURAL;
CONSTANT wr_data : IN INTEGER;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
BEGIN
mm_mosi.address <= TO_MEM_ADDRESS(wr_addr);
mm_mosi.wrdata <= TO_MEM_DATA(wr_data);
proc_mm_access(mm_clk, mm_miso.waitrequest, mm_mosi.wr);
END proc_mem_mm_bus_wr;
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN INTEGER;
SIGNAL wr_data : IN STD_LOGIC_VECTOR;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
BEGIN
mm_mosi.address <= TO_MEM_ADDRESS(wr_addr);
mm_mosi.wrdata <= RESIZE_MEM_DATA(wr_data);
proc_mm_access(mm_clk, mm_miso.waitrequest, mm_mosi.wr);
END proc_mem_mm_bus_wr;
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN NATURAL;
CONSTANT wr_data : IN INTEGER;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
BEGIN
mm_mosi.address <= TO_MEM_ADDRESS(wr_addr);
mm_mosi.wrdata <= TO_MEM_DATA(wr_data);
proc_mm_access(mm_clk, mm_mosi.wr);
END proc_mem_mm_bus_wr;
PROCEDURE proc_mem_mm_bus_wr(CONSTANT wr_addr : IN NATURAL;
CONSTANT wr_data : IN STD_LOGIC_VECTOR;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
BEGIN
mm_mosi.address <= TO_MEM_ADDRESS(wr_addr);
mm_mosi.wrdata <= RESIZE_UVEC(wr_data, c_mem_data_w);
proc_mm_access(mm_clk, mm_mosi.wr);
END proc_mem_mm_bus_wr;
-- Read data request to the MM bus
-- Use proc_mem_mm_bus_rd_latency() to wait for the MM MISO rd_data signal
-- to show the data after some read latency
PROCEDURE proc_mem_mm_bus_rd(CONSTANT rd_addr : IN NATURAL;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
BEGIN
mm_mosi.address <= TO_MEM_ADDRESS(rd_addr);
proc_mm_access(mm_clk, mm_miso.waitrequest, mm_mosi.rd);
END proc_mem_mm_bus_rd;
PROCEDURE proc_mem_mm_bus_rd(CONSTANT rd_addr : IN NATURAL;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
BEGIN
mm_mosi.address <= TO_MEM_ADDRESS(rd_addr);
proc_mm_access(mm_clk, mm_mosi.rd);
END proc_mem_mm_bus_rd;
-- Wait for read data valid after read latency mm_clk cycles
-- Directly assign mm_miso.rddata to capture the read data
PROCEDURE proc_mem_mm_bus_rd_latency(CONSTANT c_rd_latency : IN NATURAL;
SIGNAL mm_clk : IN STD_LOGIC) IS
BEGIN
FOR I IN 0 TO c_rd_latency-1 LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP;
END proc_mem_mm_bus_rd_latency;
-- Write array of data words to the memory
PROCEDURE proc_mem_write_ram(CONSTANT offset : IN NATURAL;
CONSTANT nof_data : IN NATURAL;
CONSTANT data_arr : IN t_slv_32_arr;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
CONSTANT c_data_arr : t_slv_32_arr(data_arr'LENGTH-1 DOWNTO 0) := data_arr; -- map to fixed range [h:0]
BEGIN
FOR I IN 0 TO nof_data-1 LOOP
proc_mem_mm_bus_wr(offset + I, c_data_arr(I), mm_clk, mm_mosi);
END LOOP;
END proc_mem_write_ram;
PROCEDURE proc_mem_write_ram(CONSTANT data_arr : IN t_slv_32_arr;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi) IS
CONSTANT c_offset : NATURAL := 0;
CONSTANT c_nof_data : NATURAL := data_arr'LENGTH;
BEGIN
proc_mem_write_ram(c_offset, c_nof_data, data_arr, mm_clk, mm_mosi);
END proc_mem_write_ram;
-- Read array of data words from the memory
PROCEDURE proc_mem_read_ram(CONSTANT offset : IN NATURAL;
CONSTANT nof_data : IN NATURAL;
SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL data_arr : OUT t_slv_32_arr) IS
BEGIN
FOR I IN 0 TO nof_data-1 LOOP
proc_mem_mm_bus_rd(offset+I, mm_clk, mm_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk); -- assume read latency is 1
data_arr(I) <= mm_miso.rddata(31 DOWNTO 0);
END LOOP;
-- wait one mm_clk cycle more to have last rddata captured in signal data_arr (otherwise this proc would need to use variable data_arr)
WAIT UNTIL rising_edge(mm_clk);
END proc_mem_read_ram;
PROCEDURE proc_mem_read_ram(SIGNAL mm_clk : IN STD_LOGIC;
SIGNAL mm_mosi : OUT t_mem_mosi;
SIGNAL mm_miso : IN t_mem_miso;
SIGNAL data_arr : OUT t_slv_32_arr) IS
CONSTANT c_offset : NATURAL := 0;
CONSTANT c_nof_data : NATURAL := data_arr'LENGTH;
BEGIN
proc_mem_read_ram(c_offset, c_nof_data, mm_clk, mm_mosi, mm_miso, data_arr);
END proc_mem_read_ram;
END tb_common_mem_pkg;