OpenCores
URL https://opencores.org/ocsvn/astron_mm/astron_mm/trunk

Subversion Repositories astron_mm

[/] [astron_mm/] [trunk/] [tb_common_mem_pkg.vhd] - Rev 3

Go to most recent revision | Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
--
-- 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.
--
-------------------------------------------------------------------------------
 
LIBRARY IEEE, common_pkg_lib, common_ram_lib;
USE IEEE.std_logic_1164.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE common_ram_lib.common_ram_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  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  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;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.