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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [basic_tester/] [1.0/] [vhd/] [basic_tester_rx.vhd] - Rev 145

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : A block which reads and checks data coming via HIBI
-- Project    : 
-------------------------------------------------------------------------------
-- File       : basic_tester_rx.vhd
-- Author     : ege
-- Created    : 2010-03-30
-- Last update: 2012-02-06
--
-- Description: Reads ASCII file where each line describes reception of 1 word.
--              Each transfers needs 4 hexadecimal parameters:
--               - 4 max delay (clock cycles) after previous 
--               - expected incoming address
--               - expected incoming data value
--               - expected incoming command
--              Mismatches will be reported into stdout.
-------------------------------------------------------------------------------
-- Copyright (c) 2010
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011            1.0     ege     First version
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
--
--
-- This source file may be used and distributed without
-- restriction provided that this copyright statement is not
-- removed from the file and that any derivative work contains
-- the original copyright notice and the associated disclaimer.
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source 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 Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.opencores.org/lgpl.shtml
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library std;
use std.textio.all;
use work.txt_util.all;                  -- for function sgtr(std_log_vec)
 
use work.basic_tester_pkg.all;            -- read_conf_file()
 
entity basic_tester_rx is
 
  generic (
    conf_file_g  : string  := "";
    comm_width_g : integer := 5;
    data_width_g : integer := 0
    );
  port (
    clk   : in std_logic;
    rst_n : in std_logic;
 
    done_out : out std_logic;           -- if this has finished
 
    -- HIBI wrapper ports
    agent_av_in    : in  std_logic;
    agent_data_in  : in  std_logic_vector (data_width_g-1 downto 0);
    agent_comm_in  : in  std_logic_vector (comm_width_g-1 downto 0);
    agent_re_out   : out std_logic;
    agent_empty_in : in  std_logic;
    agent_one_d_in : in  std_logic
    );
 
end basic_tester_rx;
 
 
architecture rtl of basic_tester_rx is
 
  -- Keep reading even if cannot check the data?
  constant allow_more_data_than_in_file_c : integer := 0;
 
  -- State machine
  type   control_states is (read_conf, wait_data, rd_addr, rd_data, finish);
  signal curr_state_r : control_states := read_conf;
 
  -- Registers for parameters
  signal delay_r    : integer;
  signal dst_addr_r : integer;
  signal data_val_r : integer;
  signal comm_r     : integer;
 
  -- Other registers
  signal re_r            : std_logic;
  signal last_addr_r     : std_logic_vector (data_width_g-1 downto 0);
  signal cycle_counter_r : integer;     -- measure delay
  signal n_addr_r        : integer;     -- count words
  signal n_data_r        : integer;     -- count words
  signal addr_correct_r  : std_logic; 
  signal error_r         : std_logic;
 
  -- Registers may be reset to 'Z' to 'X' so that reset state is clearly
  -- distinguished from active state. Using dbg_level+Rst_Value array, the rst value may
  -- be easily set to '0'=no debug for synthesis.
  constant dbg_level_c   : integer range 0 to 3          := 0;
  constant rst_val_arr_c : std_logic_vector (6 downto 0) :=
    'X' & 'Z' & 'X' & 'Z' & 'X' & 'Z' & '0';
  -- Right now gives a lot of warnings when other than 0
 
 
begin  -- rtl
 
  agent_re_out <= re_r;
 
  main : process (clk, rst_n)
    file conf_data_file : text open read_mode is conf_file_g;
 
    -- The read values from file are stored into these
    variable delay_v    : integer;
    variable dst_ag_v   : integer;
    variable data_val_v : integer;
    variable cmd_v      : integer;
 
  begin  -- process main
 
    if rst_n = '0' then                 -- asynchronous reset (active low)
 
      curr_state_r    <= read_conf;
      last_addr_r     <= (others => rst_val_arr_c (dbg_level_c * 1));
      cycle_counter_r <= 0;
      re_r            <= '0';
      done_out        <= '0';
 
      n_addr_r       <= 0;
      n_data_r       <= 0;
      addr_correct_r <= '0';
      error_r        <= '0';
 
      delay_v    := 0;
      dst_ag_v   := 0;
      data_val_v := 0;
      cmd_v      := 0;
 
    elsif clk'event and clk = '1' then  -- rising clock edge
 
      case curr_state_r is
 
        when read_conf =>
          -- Read the file to see what data should arrive next
 
          if endfile(conf_data_file) then
            curr_state_r   <= finish;
            re_r           <= '1';
            addr_correct_r <= '0';
            error_r        <= '0';
            assert false report "End of the configuration file reached"
              severity note;
          else
            read_conf_file (
              delay        => delay_v,
              dest_agent_n => dst_ag_v,
              value        => data_val_v,
              cmd          => cmd_v,
              conf_dat     => conf_data_file);
 
            delay_r         <= delay_v;
            dst_addr_r      <= dst_ag_v;
            data_val_r      <= data_val_v;
            comm_r          <= cmd_v;
            error_r         <= '0';
            re_r            <= '0';
            cycle_counter_r <= 0;
            curr_state_r    <= wait_data;
 
            if dst_ag_v /= 0 then
              addr_correct_r <= '0';
              -- else keep the the old value  
            end if;            
          end if;  -- endfile
 
 
        when wait_data =>
 
          if agent_empty_in = '0' then
            if agent_av_in = '1' then
              curr_state_r <= rd_addr;
            else
              if addr_correct_r = '1' then
                curr_state_r <= rd_data;
              else
                error_r      <= '1';
                assert false
                  report "Data received but addr could not be checked"
                  severity warning;
                curr_state_r <= read_conf;
              end if;
            end if;
            re_r <= '1';
 
          else
            re_r <= '0';
          end if;
 
          -- Increment the delay counter
          cycle_counter_r <= cycle_counter_r +1;
 
 
        when rd_addr =>
 
          -- Check the incoming address: a) no change, b) as in file
          addr_correct_r <= '1';        -- default that may be overriden
 
          if dst_addr_r = 0 then
            -- Assume that addr has not changed
 
            if agent_data_in /= last_addr_r then
              addr_correct_r <= '0';
              error_r        <= '1';
 
              assert false
                report "Addr does not match. Expected "
                & str(to_integer(signed(last_addr_r)))
                & " but got " & str(to_integer(unsigned(agent_data_in)))
                severity warning;
 
            end if;
 
 
          elsif dst_addr_r /= -1 then
            --  Expected addr was given in the file
 
            if to_integer(unsigned(agent_data_in)) /= dst_addr_r then
              addr_correct_r <= '0';
              error_r        <= '1';
 
              assert false
                report "Addr does not match. Expected 0d"
                & str(dst_addr_r) & " but got 0d"
                & str(to_integer(unsigned(agent_data_in)))
                severity warning;
 
            end if;
          end if;
 
          -- Check the incoming command
          if comm_r /= -1 then
 
            if to_integer(unsigned(agent_comm_in)) /= comm_r then
              error_r <= '1';
 
              assert false
                report "Comm does not match  Expected 0d"
                & str(comm_r) & " but got 0d"
                & str(to_integer(unsigned(agent_comm_in)))
                severity warning;
            end if;
          end if;
 
          last_addr_r     <= agent_data_in;
          n_addr_r        <= n_addr_r +1;
          cycle_counter_r <= cycle_counter_r +1;
 
          if agent_empty_in = '0' then
            re_r         <= '1';
            curr_state_r <= rd_data;
          else
            re_r         <= '0';
            curr_state_r <= wait_data;
          end if;
 
 
        when rd_data =>
          if agent_empty_in = '0' then
 
            re_r         <= '0';
            n_data_r     <= n_data_r +1;
            curr_state_r <= read_conf;
 
            -- Check
            --  a) if data arrived before wait time has expired
            if delay_r /= -1 then
 
              if delay_r < cycle_counter_r then
                error_r <= '1';
 
                assert false
                  report "Data arrived too late. Expected duration "
                  & str(delay_r) & " cycles, but it took "
                  & str(cycle_counter_r) & " cycles."
                  severity warning;
              end if;
            end if;
 
            --  b) if value is as expected
            if data_val_r /= -1 then
              if to_integer(signed(agent_data_in)) /= data_val_r then
                error_r <= '1';
 
                assert false
                  report "Wrong data value.  Expected 0d"
                  & str(data_val_r) & " but got 0d"
                  & str(to_integer(unsigned(agent_data_in)))
                  severity warning;
              end if;
            end if;
 
            --  c) command is as expected
            if comm_r /= -1 then
 
              if to_integer(unsigned(agent_comm_in)) /= comm_r then
                error_r <= '1';
 
                assert false
                  report "Comm does not match  Expected 0d"
                  & str(comm_r) & " but got 0d"
                  & str(to_integer(unsigned(agent_comm_in)))
                  severity warning;
              end if;
            end if;
 
          end if;
 
 
        when finish =>
          -- Notify that we're done.
          done_out        <= '1';
          cycle_counter_r <= 0;
          delay_r         <= 0;
          dst_addr_r      <= 0;
          data_val_r      <= 0;
          comm_r          <= 0;
          re_r            <= '1';
 
          if allow_more_data_than_in_file_c = 1 then
            -- Keep reading and counting if some data still arrives
            -- but cannot check anything
 
            if agent_empty_in = '0' and re_r = '1' then
              if agent_av_in = '1' then
                n_addr_r    <= n_addr_r +1;
                last_addr_r <= agent_data_in;
              else
                n_data_r <= n_data_r +1;
              end if;
            end if;
          else
            -- There should not be anymore data
            if agent_empty_in = '0' then
              error_r <= '1';
              assert false report "Unexpected data arrives"
                severity warning;
            end if;
 
          end if;
 
        when others => null;
      end case;                         -- curr_state_r
 
    end if;                             -- rst_n / clk'event
  end process main;  
 
end rtl;
 

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.