head 1.8; access; symbols spdif_rel_1:1.6; locks; strict; comment @# @; 1.8 date 2007.10.11.19.14.16; author gedra; state Exp; branches; next 1.7; commitid 348b470e76054567; 1.7 date 2005.05.08.13.15.30; author gedra; state Exp; branches; next 1.6; commitid 6b0e427e10ef4567; 1.6 date 2004.07.19.16.57.17; author gedra; state Exp; branches; next 1.5; 1.5 date 2004.07.15.17.43.53; author gedra; state Exp; branches; next 1.4; 1.4 date 2004.07.12.17.06.08; author gedra; state Exp; branches; next 1.3; 1.3 date 2004.07.11.16.20.16; author gedra; state Exp; branches; next 1.2; 1.2 date 2004.06.26.14.11.39; author gedra; state Exp; branches; next 1.1; 1.1 date 2004.06.24.19.26.02; author gedra; state Exp; branches; next ; desc @@ 1.8 log @Code beautification @ text @---------------------------------------------------------------------- ---- ---- ---- WISHBONE SPDIF IP Core ---- ---- ---- ---- This file is part of the SPDIF project ---- ---- http://www.opencores.org/cores/spdif_interface/ ---- ---- ---- ---- Description ---- ---- Wishbone testbench funtions. ---- ---- ---- ---- ---- ---- To Do: ---- ---- - ---- ---- ---- ---- Author(s): ---- ---- - Geir Drange, gedra@@opencores.org ---- ---- ---- ---------------------------------------------------------------------- ---- ---- ---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- ---- ---- ---- 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 ---- ---- ---- ---------------------------------------------------------------------- -- -- CVS Revision History -- -- $Log: wb_tb_pack.vhd,v $ -- Revision 1.7 2005/05/08 13:15:30 gedra -- Added procedure for vector checking. -- -- Revision 1.6 2004/07/19 16:57:17 gedra -- Improved test bench package. -- -- Revision 1.5 2004/07/15 17:43:53 gedra -- Added string type casting to make ModelSim happy. -- -- Revision 1.4 2004/07/12 17:06:08 gedra -- Test bench update. -- -- Revision 1.3 2004/07/11 16:20:16 gedra -- Improved test bench. -- -- Revision 1.2 2004/06/26 14:11:39 gedra -- Converter to numeric_std and added hex functions -- -- Revision 1.1 2004/06/24 19:26:02 gedra -- Wishbone bus utilities. -- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; package wb_tb_pack is constant WRITE_TIMEOUT : integer := 20; -- Max cycles to wait during write constant READ_TIMEOUT : integer := 20; -- Max cycles to wait during read constant TIME_WIDTH : integer := 15; -- Number of chars for time field shared variable errors : integer := 0; -- error counter during simulation shared variable rd_tout : integer; -- read timeout flag used by check() shared variable no_print : integer := 0; -- no print during check() function int_2_hex (value : natural; width : natural) return string; function slv_2_hex (value : std_logic_vector) return string; procedure wb_write ( constant ADDRESS : in natural; constant DATA : in natural; signal wb_adr_o : out std_logic_vector; signal wb_dat_o : out std_logic_vector; signal wb_cyc_o : out std_logic; signal wb_sel_o : out std_logic; signal wb_we_o : out std_logic; signal wb_clk_i : in std_logic; signal wb_ack_i : in std_logic); procedure wb_read ( constant ADDRESS : in natural; variable read_data : out std_logic_vector; signal wb_adr_o : out std_logic_vector; signal wb_dat_i : in std_logic_vector; signal wb_cyc_o : out std_logic; signal wb_sel_o : out std_logic; signal wb_we_o : out std_logic; signal wb_clk_i : in std_logic; signal wb_ack_i : in std_logic); procedure wb_check ( constant ADDRESS : in natural; constant EXP_DATA : in natural; signal wb_adr_o : out std_logic_vector; signal wb_dat_i : in std_logic_vector; signal wb_cyc_o : out std_logic; signal wb_sel_o : out std_logic; signal wb_we_o : out std_logic; signal wb_clk_i : in std_logic; signal wb_ack_i : in std_logic); procedure message ( constant MSG : in string); -- message to be printed procedure wait_for_event ( constant MSG : in string; -- message constant TIMEOUT : in time; -- timeout signal trigger : in std_logic); -- trigger expression procedure signal_check ( constant MSG : in string; -- signal name constant VALUE : in std_logic; -- expected value signal sig : in std_logic); -- signal to check procedure sim_report ( constant MSG : in string); procedure vector_check ( constant MSG : in string; -- signal name constant VALUE : in std_logic_vector; -- expected value signal sig : in std_logic_vector); -- vector to check end wb_tb_pack; package body wb_tb_pack is -- convert natural to hex format. Number of digits must be specified function int_2_hex (value : natural; width : natural) return string is variable tmp : string(1 to width + 2); variable digit : integer range 0 to 15; variable invalue : integer; variable pos : integer; begin tmp(1 to 2) := "0x"; invalue := value; FL : for i in 1 to width loop digit := invalue mod 16; invalue := invalue / 16; pos := 3 + width - i; case digit is when 0 => tmp(pos) := '0'; when 1 => tmp(pos) := '1'; when 2 => tmp(pos) := '2'; when 3 => tmp(pos) := '3'; when 4 => tmp(pos) := '4'; when 5 => tmp(pos) := '5'; when 6 => tmp(pos) := '6'; when 7 => tmp(pos) := '7'; when 8 => tmp(pos) := '8'; when 9 => tmp(pos) := '9'; when 10 => tmp(pos) := 'a'; when 11 => tmp(pos) := 'b'; when 12 => tmp(pos) := 'c'; when 13 => tmp(pos) := 'd'; when 14 => tmp(pos) := 'e'; when 15 => tmp(pos) := 'f'; when others => tmp(pos) := '?'; end case; end loop FL; return(tmp); end int_2_hex; -- Convert std_logic_vector to hex format. function slv_2_hex (value : std_logic_vector) return string is variable tmp : string(1 to value'length + 2); variable subdigit : std_logic_vector(3 downto 0); variable digits, pos : integer; variable actual_length : integer; variable ext_val : std_logic_vector(value'length + 3 downto 0); begin tmp(1 to 2) := "0x"; ext_val(value'length - 1 downto 0) := value; ext_val(value'length + 3 downto value'length) := (others => '0'); -- pad with zero's if length is not a factor of 4 if value'length mod 4 /= 0 then actual_length := value'length + 4 - (value'length mod 4); else actual_length := value'length; end if; digits := actual_length / 4; -- convert 4 and 4 bits into hex digits F1 : for i in digits downto 1 loop subdigit(3 downto 0) := ext_val(i * 4 - 1 downto i * 4 - 4); pos := 3 + digits - i; case subdigit is when "0000" => tmp(pos) := '0'; when "0001" => tmp(pos) := '1'; when "0010" => tmp(pos) := '2'; when "0011" => tmp(pos) := '3'; when "0100" => tmp(pos) := '4'; when "0101" => tmp(pos) := '5'; when "0110" => tmp(pos) := '6'; when "0111" => tmp(pos) := '7'; when "1000" => tmp(pos) := '8'; when "1001" => tmp(pos) := '9'; when "1010" => tmp(pos) := 'a'; when "1011" => tmp(pos) := 'b'; when "1100" => tmp(pos) := 'c'; when "1101" => tmp(pos) := 'd'; when "1110" => tmp(pos) := 'e'; when "1111" => tmp(pos) := 'f'; when others => tmp(pos) := '?'; end case; end loop F1; return(tmp(1 to 2 + digits)); end slv_2_hex; -- Classic Wishbone write cycle procedure wb_write ( constant ADDRESS : in natural; constant DATA : in natural; signal wb_adr_o : out std_logic_vector; signal wb_dat_o : out std_logic_vector; signal wb_cyc_o : out std_logic; signal wb_sel_o : out std_logic; signal wb_we_o : out std_logic; signal wb_clk_i : in std_logic; signal wb_ack_i : in std_logic) is variable txt : line; variable adr_width, dat_width : natural; constant WEAK_BUS : std_logic_vector(wb_adr_o'range) := (others => 'W'); constant LOW_BUS : std_logic_vector(wb_dat_o'range) := (others => 'L'); begin -- determine best width for number printout if wb_adr_o'length < 9 then adr_width := 2; elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then adr_width := 4; else adr_width := 6; end if; if wb_dat_o'length < 9 then dat_width := 2; elsif wb_dat_o'length < 17 and wb_dat_o'length > 8 then dat_width := 4; else dat_width := 8; end if; -- start cycle on positive edge wait until rising_edge(wb_clk_i); write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" Wrote ")); write(txt, int_2_hex(DATA, dat_width)); write(txt, string'(" to addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); wb_adr_o <= std_logic_vector(to_unsigned(ADDRESS, wb_adr_o'length)); wb_dat_o <= std_logic_vector(to_unsigned(DATA, wb_dat_o'length)); wb_we_o <= '1'; wb_cyc_o <= '1'; wb_sel_o <= '1'; -- wait for acknowledge wait until rising_edge(wb_clk_i); if wb_ack_i /= '1' then for i in 1 to WRITE_TIMEOUT loop wait until rising_edge(wb_clk_i); exit when wb_ack_i = '1'; if (i = WRITE_TIMEOUT) then --write(txt, string'("- @@ ")); --write(txt, now, right, DEFAULT_TIMEWIDTH, DEFAULT_TIMEBASE); write (txt, string'("Warning: No acknowledge recevied!")); end if; end loop; end if; -- release bus wb_adr_o <= WEAK_BUS; wb_dat_o <= LOW_BUS; wb_we_o <= 'L'; wb_cyc_o <= 'L'; wb_sel_o <= 'L'; writeline(OUTPUT, txt); end; -- Classic Wishbone read cycle procedure wb_read ( constant ADDRESS : in natural; variable read_data : out std_logic_vector; signal wb_adr_o : out std_logic_vector; signal wb_dat_i : in std_logic_vector; signal wb_cyc_o : out std_logic; signal wb_sel_o : out std_logic; signal wb_we_o : out std_logic; signal wb_clk_i : in std_logic; signal wb_ack_i : in std_logic) is variable txt : line; variable adr_width, dat_width : natural; constant WEAK_BUS : std_logic_vector(wb_adr_o'range) := (others => 'W'); begin -- determine best width for number printout if wb_adr_o'length < 9 then adr_width := 2; elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then adr_width := 4; else adr_width := 6; end if; if wb_dat_i'length < 9 then dat_width := 2; elsif wb_dat_i'length < 17 and wb_dat_i'length > 8 then dat_width := 4; else dat_width := 8; end if; -- start cycle on positive edge wait until rising_edge(wb_clk_i); write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); wb_adr_o <= std_logic_vector(to_unsigned(ADDRESS, wb_adr_o'length)); wb_we_o <= '0'; wb_cyc_o <= '1'; wb_sel_o <= '1'; -- wait for acknowledge wait until rising_edge(wb_clk_i); rd_tout := 0; if wb_ack_i /= '1' then for i in 1 to READ_TIMEOUT loop wait until rising_edge(wb_clk_i); exit when wb_ack_i = '1'; if (i = READ_TIMEOUT) then write (txt, string'("Warning: WB_read timeout!")); if no_print = 0 then writeline(OUTPUT, txt); end if; rd_tout := 1; errors := errors + 1; end if; end loop; end if; read_data := wb_dat_i; if rd_tout = 0 then write(txt, string'(" Read ")); write(txt, slv_2_hex(wb_dat_i)); write(txt, string'(" from addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); if no_print = 0 then writeline(OUTPUT, txt); end if; end if; -- release bus wb_adr_o <= WEAK_BUS; wb_we_o <= 'L'; wb_cyc_o <= 'L'; wb_sel_o <= 'L'; end; -- Check: A read operation followed by a data compare procedure wb_check ( constant ADDRESS : in natural; constant EXP_DATA : in natural; signal wb_adr_o : out std_logic_vector; signal wb_dat_i : in std_logic_vector; signal wb_cyc_o : out std_logic; signal wb_sel_o : out std_logic; signal wb_we_o : out std_logic; signal wb_clk_i : in std_logic; signal wb_ack_i : in std_logic) is variable txt : line; variable tout : integer; variable adr_width, dat_width : natural; constant WEAK_BUS : std_logic_vector(wb_adr_o'range) := (others => 'W'); variable read_data : std_logic_vector(wb_dat_i'left downto 0); begin no_print := 1; -- stop read() from printing message wb_read (ADDRESS, read_data, wb_adr_o, wb_dat_i, wb_cyc_o, wb_sel_o, wb_we_o, wb_clk_i, wb_ack_i); no_print := 0; -- determine best width for number printout if wb_adr_o'length < 9 then adr_width := 2; elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then adr_width := 4; else adr_width := 6; end if; if wb_dat_i'length < 9 then dat_width := 2; elsif wb_dat_i'length < 17 and wb_dat_i'length > 8 then dat_width := 4; else dat_width := 8; end if; write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); if rd_tout = 0 then if read_data = std_logic_vector(to_unsigned(EXP_DATA, wb_dat_i'length)) then write(txt, string'(" Check ")); write(txt, slv_2_hex(wb_dat_i)); write(txt, string'(" at addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); write(txt, string'(" - OK!")); else write(txt, string'(" Check failed at addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); write(txt, string'("! Got ")); write(txt, slv_2_hex(wb_dat_i)); write(txt, string'(", expected ")); write(txt, int_2_hex(EXP_DATA, dat_width)); errors := errors + 1; end if; writeline(OUTPUT, txt); else write(txt, string'(" Read timeout from addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); write(txt, string'(" during check!")); writeline(OUTPUT, txt); end if; end; -- display a message with time stamp procedure message ( constant MSG : in string) is variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" -- ") & MSG); writeline(OUTPUT, txt); end; -- wait for event to happen, with timeout procedure wait_for_event ( constant MSG : in string; -- message constant TIMEOUT : in time; -- timeout signal trigger : in std_logic) is -- trigger signal variable txt : line; variable t1 : time; begin t1 := now; wait on trigger for timeout; write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" ")); write(txt, MSG); if now - t1 >= TIMEOUT then write(txt, string'(" - Timed out!")); errors := errors + 1; else write(txt, string'(" - OK!")); end if; writeline(OUTPUT, txt); end; -- check signal value procedure signal_check ( constant MSG : in string; -- signal name constant VALUE : in std_logic; -- expected value signal sig : in std_logic) is -- signal to check variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" ")); write(txt, MSG); write(txt, string'(" ")); if sig = VALUE then write(txt, string'("verified to be ")); else write(txt, string'("has incorrect value! Expected ")); errors := errors + 1; end if; if VALUE = '1' then write(txt, string'("1!")); else write(txt, string'("0!")); end if; writeline(OUTPUT, txt); end; -- Report number of errors encountered during simulation procedure sim_report ( constant MSG : in string) is variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" Simulation completed with ")); write(txt, errors); write(txt, string'(" errors!")); writeline(OUTPUT, txt); end; -- check vector value procedure vector_check ( constant MSG : in string; -- signal name constant VALUE : in std_logic_vector; -- expected value signal sig : in std_logic_vector) is -- signal to check variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" ")); write(txt, MSG); write(txt, string'(" ")); if sig = VALUE then write(txt, string'("verified to be ")); else write(txt, string'("has incorrect value! Expected ")); write(txt, slv_2_hex(VALUE)); write(txt, string'(", but got ")); errors := errors + 1; end if; write(txt, slv_2_hex(sig)); writeline(OUTPUT, txt); end; end wb_tb_pack; @ 1.7 log @Added procedure for vector checking. @ text @d48 3 d70 1 a70 1 d78 64 a141 64 constant WRITE_TIMEOUT : integer := 20; -- Max cycles to wait during write constant READ_TIMEOUT : integer := 20; -- Max cycles to wait during read constant TIME_WIDTH : integer := 15; -- Number of chars for time field shared variable errors : integer := 0; -- error counter during simulation shared variable rd_tout : integer; -- read timeout flag used by check() shared variable no_print : integer := 0; -- no print during check() function int_2_hex (value: natural; width: natural) return string; function slv_2_hex (value: std_logic_vector) return string; procedure wb_write ( constant ADDRESS: in natural; constant DATA: in natural; signal wb_adr_o: out std_logic_vector; signal wb_dat_o: out std_logic_vector; signal wb_cyc_o: out std_logic; signal wb_sel_o: out std_logic; signal wb_we_o: out std_logic; signal wb_clk_i: in std_logic; signal wb_ack_i: in std_logic); procedure wb_read ( constant ADDRESS: in natural; variable read_data: out std_logic_vector; signal wb_adr_o: out std_logic_vector; signal wb_dat_i: in std_logic_vector; signal wb_cyc_o: out std_logic; signal wb_sel_o: out std_logic; signal wb_we_o: out std_logic; signal wb_clk_i: in std_logic; signal wb_ack_i: in std_logic); procedure wb_check ( constant ADDRESS: in natural; constant EXP_DATA : in natural; signal wb_adr_o: out std_logic_vector; signal wb_dat_i: in std_logic_vector; signal wb_cyc_o: out std_logic; signal wb_sel_o: out std_logic; signal wb_we_o: out std_logic; signal wb_clk_i: in std_logic; signal wb_ack_i: in std_logic); procedure message ( constant MSG: in string); -- message to be printed procedure wait_for_event ( constant MSG : in string; -- message constant TIMEOUT: in time; -- timeout signal trigger: in std_logic); -- trigger expression procedure signal_check ( constant MSG : in string; -- signal name constant VALUE: in std_logic; -- expected value signal sig: in std_logic); -- signal to check procedure sim_report ( constant MSG : in string); procedure vector_check ( constant MSG : in string; -- signal name constant VALUE: in std_logic_vector; -- expected value signal sig: in std_logic_vector); -- vector to check d148 80 a227 80 function int_2_hex (value: natural; width: natural) return string is variable tmp: string(1 to width + 2); variable digit: integer range 0 to 15; variable invalue: integer; variable pos: integer; begin tmp(1 to 2) := "0x"; invalue := value; FL: for i in 1 to width loop digit := invalue mod 16; invalue := invalue / 16; pos := 3 + width - i; case digit is when 0 => tmp(pos) := '0'; when 1 => tmp(pos) := '1'; when 2 => tmp(pos) := '2'; when 3 => tmp(pos) := '3'; when 4 => tmp(pos) := '4'; when 5 => tmp(pos) := '5'; when 6 => tmp(pos) := '6'; when 7 => tmp(pos) := '7'; when 8 => tmp(pos) := '8'; when 9 => tmp(pos) := '9'; when 10 => tmp(pos) := 'a'; when 11 => tmp(pos) := 'b'; when 12 => tmp(pos) := 'c'; when 13 => tmp(pos) := 'd'; when 14 => tmp(pos) := 'e'; when 15 => tmp(pos) := 'f'; when others => tmp(pos) := '?'; end case; end loop FL; return(tmp); end int_2_hex; -- Convert std_logic_vector to hex format. function slv_2_hex (value: std_logic_vector) return string is variable tmp: string(1 to value'length + 2); variable subdigit: std_logic_vector(3 downto 0); variable digits, pos: integer; variable actual_length: integer; variable ext_val: std_logic_vector(value'length + 3 downto 0); begin tmp(1 to 2) := "0x"; ext_val(value'length - 1 downto 0) := value; ext_val(value'length + 3 downto value'length) := (others => '0'); -- pad with zero's if length is not a factor of 4 if value'length mod 4 /= 0 then actual_length := value'length + 4 - (value'length mod 4); else actual_length := value'length; end if; digits := actual_length / 4; -- convert 4 and 4 bits into hex digits F1: for i in digits downto 1 loop subdigit(3 downto 0) := ext_val(i * 4 - 1 downto i * 4 - 4); pos := 3 + digits - i; case subdigit is when "0000" => tmp(pos) := '0'; when "0001" => tmp(pos) := '1'; when "0010" => tmp(pos) := '2'; when "0011" => tmp(pos) := '3'; when "0100" => tmp(pos) := '4'; when "0101" => tmp(pos) := '5'; when "0110" => tmp(pos) := '6'; when "0111" => tmp(pos) := '7'; when "1000" => tmp(pos) := '8'; when "1001" => tmp(pos) := '9'; when "1010" => tmp(pos) := 'a'; when "1011" => tmp(pos) := 'b'; when "1100" => tmp(pos) := 'c'; when "1101" => tmp(pos) := 'd'; when "1110" => tmp(pos) := 'e'; when "1111" => tmp(pos) := 'f'; when others => tmp(pos) := '?'; end case; end loop F1; return(tmp(1 to 2 + digits)); end slv_2_hex; d229 64 a292 64 procedure wb_write ( constant ADDRESS: in natural; constant DATA: in natural; signal wb_adr_o: out std_logic_vector; signal wb_dat_o: out std_logic_vector; signal wb_cyc_o: out std_logic; signal wb_sel_o: out std_logic; signal wb_we_o: out std_logic; signal wb_clk_i: in std_logic; signal wb_ack_i: in std_logic) is variable txt : line; variable adr_width, dat_width : natural; constant WEAK_BUS: std_logic_vector(wb_adr_o'range) := (others => 'W'); constant LOW_BUS: std_logic_vector(wb_dat_o'range) := (others => 'L'); begin -- determine best width for number printout if wb_adr_o'length < 9 then adr_width := 2; elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then adr_width := 4; else adr_width := 6; end if; if wb_dat_o'length < 9 then dat_width := 2; elsif wb_dat_o'length < 17 and wb_dat_o'length > 8 then dat_width := 4; else dat_width := 8; end if; -- start cycle on positive edge wait until rising_edge(wb_clk_i); write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" Wrote ")); write(txt, int_2_hex(DATA, dat_width)); write(txt, string'(" to addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); wb_adr_o <= std_logic_vector(to_unsigned(ADDRESS, wb_adr_o'length)); wb_dat_o <= std_logic_vector(to_unsigned(DATA, wb_dat_o'length)); wb_we_o <= '1'; wb_cyc_o <= '1'; wb_sel_o <= '1'; -- wait for acknowledge wait until rising_edge(wb_clk_i); if wb_ack_i /= '1' then for i in 1 to WRITE_TIMEOUT loop wait until rising_edge(wb_clk_i); exit when wb_ack_i = '1'; if (i = WRITE_TIMEOUT) then --write(txt, string'("- @@ ")); --write(txt, now, right, DEFAULT_TIMEWIDTH, DEFAULT_TIMEBASE); write (txt, string'("Warning: No acknowledge recevied!")); end if; end loop; end if; -- release bus wb_adr_o <= WEAK_BUS; wb_dat_o <= LOW_BUS; wb_we_o <= 'L'; wb_cyc_o <= 'L'; wb_sel_o <= 'L'; writeline(OUTPUT, txt); end; d295 61 a355 47 procedure wb_read ( constant ADDRESS: in natural; variable read_data : out std_logic_vector; signal wb_adr_o: out std_logic_vector; signal wb_dat_i: in std_logic_vector; signal wb_cyc_o: out std_logic; signal wb_sel_o: out std_logic; signal wb_we_o: out std_logic; signal wb_clk_i: in std_logic; signal wb_ack_i: in std_logic) is variable txt : line; variable adr_width, dat_width : natural; constant WEAK_BUS: std_logic_vector(wb_adr_o'range) := (others => 'W'); begin -- determine best width for number printout if wb_adr_o'length < 9 then adr_width := 2; elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then adr_width := 4; else adr_width := 6; end if; if wb_dat_i'length < 9 then dat_width := 2; elsif wb_dat_i'length < 17 and wb_dat_i'length > 8 then dat_width := 4; else dat_width := 8; end if; -- start cycle on positive edge wait until rising_edge(wb_clk_i); write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); wb_adr_o <= std_logic_vector(to_unsigned(ADDRESS, wb_adr_o'length)); wb_we_o <= '0'; wb_cyc_o <= '1'; wb_sel_o <= '1'; -- wait for acknowledge wait until rising_edge(wb_clk_i); rd_tout := 0; if wb_ack_i /= '1' then for i in 1 to READ_TIMEOUT loop wait until rising_edge(wb_clk_i); exit when wb_ack_i = '1'; if (i = READ_TIMEOUT) then write (txt, string'("Warning: WB_read timeout!")); if no_print = 0 then d357 1 a357 14 end if; rd_tout := 1; errors := errors + 1; end if; end loop; end if; read_data := wb_dat_i; if rd_tout = 0 then write(txt, string'(" Read ")); write(txt, slv_2_hex(wb_dat_i)); write(txt, string'(" from addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); if no_print = 0 then writeline(OUTPUT, txt); d359 6 a364 7 end if; -- release bus wb_adr_o <= WEAK_BUS; wb_we_o <= 'L'; wb_cyc_o <= 'L'; wb_sel_o <= 'L'; end; d367 62 a428 62 procedure wb_check ( constant ADDRESS: in natural; constant EXP_DATA : in natural; signal wb_adr_o: out std_logic_vector; signal wb_dat_i: in std_logic_vector; signal wb_cyc_o: out std_logic; signal wb_sel_o: out std_logic; signal wb_we_o: out std_logic; signal wb_clk_i: in std_logic; signal wb_ack_i: in std_logic) is variable txt : line; variable tout : integer; variable adr_width, dat_width : natural; constant WEAK_BUS: std_logic_vector(wb_adr_o'range) := (others => 'W'); variable read_data : std_logic_vector(wb_dat_i'left downto 0); begin no_print := 1; -- stop read() from printing message wb_read (ADDRESS, read_data, wb_adr_o, wb_dat_i, wb_cyc_o, wb_sel_o, wb_we_o, wb_clk_i, wb_ack_i); no_print := 0; -- determine best width for number printout if wb_adr_o'length < 9 then adr_width := 2; elsif wb_adr_o'length < 17 and wb_adr_o'length > 8 then adr_width := 4; else adr_width := 6; end if; if wb_dat_i'length < 9 then dat_width := 2; elsif wb_dat_i'length < 17 and wb_dat_i'length > 8 then dat_width := 4; else dat_width := 8; end if; write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); if rd_tout = 0 then if read_data = std_logic_vector(to_unsigned(EXP_DATA, wb_dat_i'length)) then write(txt, string'(" Check ")); write(txt, slv_2_hex(wb_dat_i)); write(txt, string'(" at addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); write(txt, string'(" - OK!")); else write(txt, string'(" Check failed at addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); write(txt, string'("! Got ")); write(txt, slv_2_hex(wb_dat_i)); write(txt, string'(", expected ")); write(txt, int_2_hex(EXP_DATA, dat_width)); errors := errors + 1; end if; writeline(OUTPUT, txt); else write(txt, string'(" Read timeout from addr. ")); write(txt, int_2_hex(ADDRESS, adr_width)); write(txt, string'(" during check!")); writeline(OUTPUT, txt); end if; end; d431 9 a439 9 procedure message ( constant MSG: in string) is variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" -- ") & MSG); writeline(OUTPUT, txt); end; d442 21 a462 21 procedure wait_for_event ( constant MSG : in string; -- message constant TIMEOUT: in time; -- timeout signal trigger: in std_logic) is -- trigger signal variable txt : line; variable t1 : time; begin t1 := now; wait on trigger for timeout; write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" ")); write(txt, MSG); if now - t1 >= TIMEOUT then write(txt, string'(" - Timed out!")); errors := errors + 1; else write(txt, string'(" - OK!")); end if; writeline(OUTPUT, txt); end; d465 24 a488 24 procedure signal_check ( constant MSG : in string; -- signal name constant VALUE: in std_logic; -- expected value signal sig: in std_logic) is -- signal to check variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" ")); write(txt, MSG); write(txt, string'(" ")); if sig = VALUE then write(txt, string'("verified to be ")); else write(txt, string'("has incorrect value! Expected ")); errors := errors + 1; end if; if VALUE = '1' then write(txt, string'("1!")); else write(txt, string'("0!")); end if; writeline(OUTPUT, txt); end; d491 11 a501 11 procedure sim_report ( constant MSG : in string) is variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" Simulation completed with ")); write(txt, errors); write(txt, string'(" errors!")); writeline(OUTPUT, txt); end; d504 23 a526 23 procedure vector_check ( constant MSG : in string; -- signal name constant VALUE: in std_logic_vector; -- expected value signal sig: in std_logic_vector) is -- signal to check variable txt : line; begin write(txt, string'("@@")); write(txt, now, right, TIME_WIDTH); write(txt, string'(" ")); write(txt, MSG); write(txt, string'(" ")); if sig = VALUE then write(txt, string'("verified to be ")); else write(txt, string'("has incorrect value! Expected ")); write(txt, slv_2_hex(VALUE)); write(txt, string'(", but got ")); errors := errors + 1; end if; write(txt, slv_2_hex(sig)); writeline(OUTPUT, txt); end; @ 1.6 log @Improved test bench package. @ text @d48 3 d130 1 a130 1 signal sig: in std_logic); -- signal to check d135 5 d498 25 a522 1 end; @ 1.5 log @Added string type casting to make ModelSim happy. @ text @d48 3 d73 6 a78 2 constant READ_TIMEOUT : integer := 20; -- Max cycles to wait during read constant TIME_WIDTH : integer := 15; -- Number of chars for time field d96 1 a96 1 variable READ_DATA : out std_logic_vector; d129 3 d286 1 a286 1 variable READ_DATA : out std_logic_vector; a294 1 variable tout : integer; d323 1 a323 1 tout := 0; a328 2 --write(txt, string'("- @@ ")); --write(txt, now, right, DEFAULT_TIMEWIDTH, DEFAULT_TIMEBASE); d330 5 a334 2 writeline(OUTPUT, txt); tout := 1; d338 2 a339 2 --READ_DATA := wb_dat_i; if tout = 0 then d344 3 a346 1 writeline(OUTPUT, txt); d370 1 a370 1 variable RData : std_logic_vector(wb_dat_i'left downto 0); d372 4 d390 1 a390 3 end if; -- start cycle on positive edge wait until rising_edge(wb_clk_i); d393 3 a395 22 wb_adr_o <= std_logic_vector(to_unsigned(ADDRESS, wb_adr_o'length)); wb_we_o <= '0'; wb_cyc_o <= '1'; wb_sel_o <= '1'; -- wait for acknowledge wait until rising_edge(wb_clk_i); tout := 0; if wb_ack_i /= '1' then for i in 1 to READ_TIMEOUT loop wait until rising_edge(wb_clk_i); exit when wb_ack_i = '1'; if (i = READ_TIMEOUT) then --write(txt, string'("- @@ ")); --write(txt, now, right, DEFAULT_TIMEWIDTH, DEFAULT_TIMEBASE); write (txt, string'(" Warning: WB_check timeout!")); writeline(OUTPUT, txt); tout := 1; end if; end loop; end if; if tout = 0 then if wb_dat_i = std_logic_vector(to_unsigned(EXP_DATA, wb_dat_i'length)) then d408 1 d411 5 a416 9 -- release bus wb_adr_o <= WEAK_BUS; wb_we_o <= 'L'; wb_cyc_o <= 'L'; wb_sel_o <= 'L'; --if RData /= EXP_DATA then -- write (txt, string'("Error: WB_check failed!")); -- writeline(OUTPUT, txt); --end if; d446 1 d469 1 d478 13 @ 1.4 log @Test bench update. @ text @d48 3 d240 1 a240 1 write(txt, "@@"); d242 1 a242 1 write(txt, " Wrote "); d244 1 a244 1 write(txt, " to addr. "); d306 1 a306 1 write(txt, "@@"); d330 1 a330 1 write(txt, " Read "); d332 1 a332 1 write(txt, " from addr. "); d377 1 a377 1 write(txt, "@@"); d401 1 a401 1 write(txt, " Check "); d403 1 a403 1 write(txt, " at addr. "); d405 1 a405 1 write(txt, " - OK!"); d407 1 a407 1 write(txt, " Check failed at addr. "); d409 1 a409 1 write(txt, "! Got "); d411 1 a411 1 write(txt, ", expected "); d432 1 a432 1 write(txt, "@@"); d434 1 a434 1 write(txt, " -- " & MSG); d448 1 a448 1 write(txt, "@@"); d450 1 a450 1 write(txt, " "); d453 1 a453 1 write(txt, " - Timed out!"); d455 1 a455 1 write(txt, " - OK!"); d467 1 a467 1 write(txt, "@@"); d469 1 a469 1 write(txt, " "); d471 1 a471 1 write(txt, " "); d473 1 a473 1 write(txt, "verified to be "); d475 1 a475 1 write(txt, "has incorrect value! Expected "); d478 1 a478 1 write(txt, "1!"); d480 1 a480 1 write(txt, "0!"); @ 1.3 log @Improved test bench. @ text @d48 3 d66 3 a68 2 constant WRITE_TIMEOUT : integer := 20; -- Max cycles to wait during write operation constant READ_TIMEOUT : integer := 20; -- Max cycles to wait during read operation d238 1 a238 1 write(txt, now, right, 12); d304 1 a304 1 write(txt, now, right, 12); d375 1 a375 1 write(txt, now, right, 12); d430 1 a430 1 write(txt, now, right, 12); d446 1 a446 1 write(txt, now, right, 12); d465 1 a465 1 write(txt, now, right, 12); @ 1.2 log @Converter to numeric_std and added hex functions @ text @d48 3 d103 11 a113 1 constant MSG: in string); d423 1 a423 1 variable txt : line; d430 48 a477 1 @ 1.1 log @Wishbone bus utilities. @ text @d47 4 a50 1 -- $Log$ d53 3 a55 5 library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_textio.all; d63 2 a64 2 function str(slv: std_logic_vector) return string; function chr(sl: std_logic) return character; d66 3 a68 3 procedure WB_write ( constant ADDRESS: in integer; constant DATA: in std_logic_vector; d77 2 a78 2 procedure WB_read ( constant ADDRESS: in integer; d88 3 a90 3 procedure WB_check ( constant ADDRESS: in integer; constant EXP_DATA : in std_logic_vector; d99 3 d106 6 a111 3 -- converts std_logic into a character function chr(sl: std_logic) return character is variable c: character; d113 36 a148 21 case sl is when 'U' => c:= 'U'; when 'X' => c:= 'X'; when '0' => c:= '0'; when '1' => c:= '1'; when 'Z' => c:= 'Z'; when 'W' => c:= 'W'; when 'L' => c:= 'L'; when 'H' => c:= 'H'; when '-' => c:= '-'; end case; return c; end chr; -- converts std_logic_vector into a string (binary base) -- (this also takes care of the fact that the range of -- a string is natural while a std_logic_vector may -- have an integer range) function str(slv: std_logic_vector) return string is variable result : string (1 to slv'length); variable r : integer; d150 36 a185 7 r := 1; for i in slv'range loop result(r) := chr(slv(i)); r := r + 1; end loop; return result; end str; d188 3 a190 3 procedure WB_write ( constant ADDRESS: in integer; constant DATA: in std_logic_vector; a197 1 --variable ResizeAdr : unsigned(wb_adr_o'high downto 0); d199 1 a199 1 --variable tmp : integer; d203 16 d223 5 a227 6 write(txt, str(DATA)); write(txt, "b to addr. "); write(txt, str(CONV_STD_LOGIC_VECTOR(ADDRESS, wb_adr_o'length))); write(txt, "b "); wb_adr_o <= CONV_STD_LOGIC_VECTOR(ADDRESS, wb_adr_o'length); wb_dat_o <= DATA; d254 2 a255 2 procedure WB_read ( constant ADDRESS: in integer; d266 1 d269 16 a284 1 -- start cycle d288 1 a288 1 wb_adr_o <= CONV_STD_LOGIC_VECTOR(ADDRESS, wb_adr_o'length); d310 4 a313 5 write(txt, " Read "); write(txt, str(wb_dat_i)); write(txt, "b from addr. "); write(txt, str(CONV_STD_LOGIC_VECTOR(ADDRESS, wb_adr_o'length))); write(txt, "b "); d324 3 a326 3 procedure WB_check ( constant ADDRESS: in integer; constant EXP_DATA : in std_logic_vector; d336 1 d338 1 a338 1 variable RData : std_logic_vector(EXP_DATA'left downto 0); d340 16 a355 1 -- start cycle d359 1 a359 1 wb_adr_o <= CONV_STD_LOGIC_VECTOR(ADDRESS, wb_adr_o'length); a378 1 --READ_DATA := wb_dat_i; d380 1 a380 1 if wb_dat_i = EXP_DATA then d382 4 a385 4 write(txt, str(wb_dat_i)); write(txt, "b at addr. "); write(txt, str(CONV_STD_LOGIC_VECTOR(ADDRESS, wb_adr_o'length))); write(txt, "b "); d388 5 a392 6 write(txt, str(CONV_STD_LOGIC_VECTOR(ADDRESS, wb_adr_o'length))); write(txt, "b! Got "); write(txt, str(wb_dat_i)); write(txt, "b, expected "); write(txt, str(EXP_DATA)); write(txt, "b"); d405 11 @