URL
https://opencores.org/ocsvn/vhld_tb/vhld_tb/trunk
Subversion Repositories vhld_tb
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 13 to Rev 14
- ↔ Reverse comparison
Rev 13 → Rev 14
/tags/rel_001/source/tb_pkg_body.vhd
File deleted
/tags/rel_001/source/tb_pkg_header.vhd
File deleted
/tags/rel_001/source/template_tb_bhv.vhd
File deleted
/tags/rel_001/ttb_gen/ttb_gen_gui.tcl
File deleted
/tags/rel_001/Doc/VHDLtbusers.odt
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
tags/rel_001/Doc/VHDLtbusers.odt
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: tags/rel_001/GNU_GPL.txt
===================================================================
--- tags/rel_001/GNU_GPL.txt (revision 13)
+++ tags/rel_001/GNU_GPL.txt (nonexistent)
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- 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 2 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, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
Index: trunk/source/tb_pkg_header.vhd
===================================================================
--- trunk/source/tb_pkg_header.vhd (revision 13)
+++ trunk/source/tb_pkg_header.vhd (nonexistent)
@@ -1,239 +0,0 @@
--------------------------------------------------------------------------------
--- Copyright 2007 Ken Campbell
--------------------------------------------------------------------------------
--- $Author: sckoarn $
---
--- $Date: 2008-02-24 01:34:11 $
---
--- $Name: not supported by cvs2svn $
---
--- $Id: tb_pkg_header.vhd,v 1.4 2008-02-24 01:34:11 sckoarn Exp $
---
--- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/tb_pkg_header.vhd,v $
---
--- Description : The the testbench package header file.
--- Initial GNU release.
---
-------------------------------------------------------------------------------
---This file is part of The VHDL Test Bench.
---
--- The VHDL Test Bench 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 2 of the License, or
--- (at your option) any later version.
---
--- The VHDL Test Bench 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 The VHDL Test Bench; if not, write to the Free Software
--- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------------
--- Revision History:
--- $Log: not supported by cvs2svn $
--- Revision 1.3 2007/09/02 04:04:04 sckoarn
--- Update of version 1.2 tb_pkg
--- See documentation for details
---
--- Revision 1.2 2007/08/21 02:43:14 sckoarn
--- Fix package definition to match with body
---
--- Revision 1.1.1.1 2007/04/06 04:06:48 sckoarn
--- Import of the vhld_tb
---
---
--------------------------------------------------------------------------------
-library IEEE;
-
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_ARITH.all;
-use std.textio.all;
-library ieee_proposed;
-use ieee_proposed.STD_LOGIC_1164_additions.all;
-
-package tb_pkg is
-
- -- Constants
- constant max_str_len : integer := 256;
- constant max_field_len : integer := 48;
- constant c_stm_text_len : integer := 200;
- -- file handles
- file stimulus : text; -- file main file
- file include_file : text; -- file declaration for includes
-
- -- Type Def's
- type base is (bin, oct, hex, dec);
--- subtype stack_element is integer range 0 to 8192;
- type stack_register is array(7 downto 0) of integer;
- type state_register is array(7 downto 0) of boolean;
- type int_array is array(1 to 16) of integer;
-
- subtype text_line is string(1 to max_str_len);
- subtype text_field is string(1 to max_field_len);
- subtype stm_text is string(1 to c_stm_text_len);
- type stm_text_ptr is access stm_text;
- -- define the stimulus line record and access
- type stim_line;
- type stim_line_ptr is access stim_line; -- Pointer to stim_line record
- type stim_line is record
- instruction: text_field;
- inst_field_1: text_field;
- inst_field_2: text_field;
- inst_field_3: text_field;
- inst_field_4: text_field;
- inst_field_5: text_field;
- inst_field_6: text_field;
- txt: stm_text_ptr;
- line_number: integer; -- sequence line
- num_of_lines: integer; -- total number of lines
- file_line: integer; -- file line number
- file_idx: integer;
- next_rec: stim_line_ptr;
- end record;
- -- define the variables field and pointer
- type var_field;
- type var_field_ptr is access var_field; -- pointer to var_field
- type var_field is record
- var_name: text_field;
- var_index: integer;
- var_value: integer;
- next_rec: var_field_ptr;
- end record;
- -- define the instruction structure
- type inst_def;
- type inst_def_ptr is access inst_def;
- type inst_def is record
- instruction: text_field;
- instruction_l: integer;
- params: integer;
- next_rec: inst_def_ptr;
- end record;
- -- define the file handle record
- type file_def;
- type file_def_ptr is access file_def;
- type file_def is record
- rec_idx: integer;
- file_name: text_line;
- next_rec: file_def_ptr;
- end record;
-
----*****************************************************************************
- -- Function Declaration
--- function str_len(variable line: text_line) return text_field;
--- function fld_len(s : in text_field) integer;
-
- function c2std_vec(c: in character) return std_logic_vector;
-
---------------------------------------------------------------------------------
- -- Procedure declarations
---------------------------------------------------------------------------
--- define_instruction
--- inputs file_name the file to be read from
---
--- output file_line a line of text from the file
- procedure define_instruction(variable inst_set: inout inst_def_ptr;
- constant inst: in string;
- constant args: in integer);
-
---------------------------------------------------------------------------------
--- index_variable
--- inputs:
--- index: the index of the variable being accessed
--- outputs:
--- Variable Value
--- valid is 1 if valid 0 if not
- procedure index_variable(variable var_list : in var_field_ptr;
- variable index : in integer;
- variable value : out integer;
- variable valid : out integer);
-
---------------------------------------------------------------------------------
--- update_variable
--- inputs:
--- index: the index of the variable being accessed
--- outputs:
--- Variable Value
--- valid is 1 if valid 0 if not
- procedure update_variable(variable var_list : in var_field_ptr;
- variable index : in integer;
- variable value : in integer;
- variable valid : out integer);
-
--------------------------------------------------------------------------------
--- read_instruction_file
--- This procedure reads the instruction file, name passed throught file_name.
--- Pointers to records are passed in and out. A table of variables is created
--- with variable name and value (converted to integer). The instructions are
--- parsesed into the inst_sequ list. Instructions are validated against the
--- inst_set which must have been set up prior to loading the instruction file.
- procedure read_instruction_file(constant file_name: string;
- variable inst_set: inout inst_def_ptr;
- variable var_list: inout var_field_ptr;
- variable inst_sequ: inout stim_line_ptr;
- variable file_list: inout file_def_ptr);
-
-------------------------------------------------------------------------------
--- access_inst_sequ
--- This procedure retreeves an instruction from the sequence of instructions.
--- Based on the line number you pass to it, it returns the instruction with
--- any variables substituted as integers.
- procedure access_inst_sequ(variable inst_sequ : in stim_line_ptr;
- variable var_list : in var_field_ptr;
- variable file_list : in file_def_ptr;
- variable sequ_num : in integer;
- variable inst : out text_field;
- variable p1 : out integer;
- variable p2 : out integer;
- variable p3 : out integer;
- variable p4 : out integer;
- variable p5 : out integer;
- variable p6 : out integer;
- variable txt : out stm_text_ptr;
- variable inst_len : out integer;
- variable fname : out text_line;
- variable file_line : out integer;
- variable last_num : inout integer;
- variable last_ptr : inout stim_line_ptr
- );
-------------------------------------------------------------------------
--- tokenize_line
--- This procedure takes a type text_line in and returns up to 6
--- tokens and the count in integer valid, as well if text string
--- is found the pointer to that is returned.
- procedure tokenize_line(variable text_line: in text_line;
- variable token1: out text_field;
- variable token2: out text_field;
- variable token3: out text_field;
- variable token4: out text_field;
- variable token5: out text_field;
- variable token6: out text_field;
- variable token7: out text_field;
- variable txt_ptr: out stm_text_ptr;
- variable valid: out integer);
--------------------------------------------------------------------------
--- string convertion
- function ew_to_str(int: integer; b: base) return text_field;
- function to_str(int: integer) return string;
-
--------------------------------------------------------------------------
--- Procedre print
--- print to stdout string
- procedure print(s: in string);
--------------------------------------------------------------------------
--- Procedure print stim txt
- procedure txt_print(variable ptr: in stm_text_ptr);
--------------------------------------------------------------------------
--- Procedure print stim txt sub variables found
- procedure txt_print_wvar(variable var_list : in var_field_ptr;
- variable ptr : in stm_text_ptr;
- constant b : in base);
--------------------------------------------------------------------------
--- dump inst_sequ
--- This procedure dumps to the simulation window the current instruction
--- sequence. The whole thing will be dumped, which could be big.
--- ** intended for testbench development debug**
--- procedure dump_inst_sequ(variable inst_sequ : in stim_line_ptr);
-
-end tb_pkg;
Index: trunk/source/template_tb_bhv.vhd
===================================================================
--- trunk/source/template_tb_bhv.vhd (revision 13)
+++ trunk/source/template_tb_bhv.vhd (nonexistent)
@@ -1,525 +0,0 @@
--------------------------------------------------------------------------------
--- Copyright 2007 Ken Campbell
--------------------------------------------------------------------------------
--- $Author: sckoarn $
---
--- $Date: 2008-02-24 01:34:11 $
---
--- $Name: not supported by cvs2svn $
---
--- $Id: template_tb_bhv.vhd,v 1.4 2008-02-24 01:34:11 sckoarn Exp $
---
--- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/template_tb_bhv.vhd,v $
---
--- Description : The the testbench package template behave file.
--- Initial GNU release.
---
-------------------------------------------------------------------------------
---This file is part of The VHDL Test Bench.
---
--- The VHDL Test Bench 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 2 of the License, or
--- (at your option) any later version.
---
--- The VHDL Test Bench 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 The VHDL Test Bench; if not, write to the Free Software
--- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------------
--- Revision History:
--- $Log: not supported by cvs2svn $
--- Revision 1.3 2007/11/14 02:35:56 sckoarn
--- Fix to WHILE instruction: Change if_state typo to wh_state
---
--- Revision 1.2 2007/09/02 04:04:04 sckoarn
--- Update of version 1.2 tb_pkg
--- See documentation for details
---
--- Revision 1.1.1.1 2007/04/06 04:06:48 sckoarn
--- Import of the vhld_tb
---
---
--------------------------------------------------------------------------------
-
-architecture bhv of tb_Top is
-
-
- signal tb_clk : std_logic;
-
--------------------------------------------------------------------------
--- Component defintion
-
--------------------------------------------------------------------------------
--- USER Component instantiations
---for all: Arbitor use entity tb_objects.arbitor(bhv);
-
-
- begin
-
--------------------------------------------------------------------------------
--- clock driver process
--- the main clock generator
-clock_driver:
- process
- begin
- tb_clk <= '0';
- wait for 5 ns;
- tb_clk <= '1';
- wait for 5 ns;
- end process clock_driver;
-
- --------------------------------------------------------------------------
- -- Read_file Process:
- --
- -- This process is the main process of the testbench. This process reads
- -- the stumulus file, parses it, creates lists of records, then uses these
- -- lists to exicute user instructions. There are two passes through the
- -- script. Pass one reads in the stimulus text file, checks it, creates
- -- lists of valid instructions, valid list of variables and finialy a list
- -- of user instructions(the sequence). The second pass through the file,
- -- records are drawn from the user instruction list, variables are converted
- -- to integers and put through the elsif structure for exicution.
- --------------------------------------------------------------------------
- Read_file: process
- variable current_line : text_line; -- The current input line
- variable inst_list : inst_def_ptr; -- the instruction list
- variable defined_vars : var_field_ptr; -- defined variables
- variable inst_sequ : stim_line_ptr; -- the instruction sequence
- variable file_list : file_def_ptr; -- pointer to the list of file names
- variable last_sequ_num: integer;
- variable last_sequ_ptr: stim_line_ptr;
-
- variable instruction : text_field; -- instruction field
- variable par1 : integer; -- paramiter 1
- variable par2 : integer; -- paramiter 2
- variable par3 : integer; -- paramiter 3
- variable par4 : integer; -- paramiter 4
- variable par5 : integer; -- paramiter 5
- variable par6 : integer; -- paramiter 6
- variable txt : stm_text_ptr;
- variable nbase : base; -- the number base to use
- variable len : integer; -- length of the instruction field
- variable file_line : integer; -- Line number in the stimulus file
- variable file_name : text_line; -- the file name the line came from
- variable v_line : integer := 0; -- sequence number
- variable stack : stack_register; -- Call stack
- variable stack_ptr : integer := 0; -- call stack pointer
- variable wh_stack : stack_register; -- while stack
- variable wh_dpth : integer := 0; -- while depth
- variable wh_ptr : integer := 0; -- while pointer
- variable loop_num : integer := 0;
- variable curr_loop_count : int_array := (others => 0);
- variable term_loop_count : int_array := (others => 0);
- variable loop_line : int_array := (others => 0);
-
- variable messages : boolean := TRUE;
- variable if_state : boolean := FALSE;
- variable wh_state : boolean := FALSE;
- variable wh_end : boolean := FALSE;
- variable rand : std_logic_vector(31 downto 0);
- variable rand_back : std_logic_vector(31 downto 0);
- variable valid : integer;
-
- -- scratchpad variables
- variable temp_int : integer;
- variable temp_index : integer;
- variable temp_str : text_field;
- variable v_temp_vec1 : std_logic_vector(31 downto 0);
- variable v_temp_vec2 : std_logic_vector(31 downto 0);
-
- --------------------------------------------------------------------------
- -- Area for Procedures which may be usefull to more than one instruction.
- -- By coding here commonly used code sections ...
- -- you know the benifits.
- ---------------------------------------------------------------------
- -----------------------------------------------------------------
- -- This procedure writes to the arbitor model access port
--- procedure arb_write(add: in integer; .....
--- end arb_write;
-
-
- begin -- process Read_file
--- parse_tb1 start input initialization
- -----------------------------------------------------------------------
- -- Stimulus file instruction definition
- -- This is where the instructions used in the stimulus file are defined.
- -- Syntax is
- -- define_instruction(inst_def_ptr, instruction, paramiters)
- -- inst_def_ptr: is a record pointer defined in tb_pkg_header
- -- instruction: the text instruction name ie. "DEFINE_VAR"
- -- paramiters: the number of fields or paramiters passed
- --
- -- Some basic instruction are created here, the user should create new
- -- instructions below the standard ones.
- ------------------------------------------------------------------------
- define_instruction(inst_list, "DEFINE_VAR", 2); -- Define a Variable
- define_instruction(inst_list, "EQU_VAR", 2);
- define_instruction(inst_list, "ADD_VAR", 2);
- define_instruction(inst_list, "SUB_VAR", 2);
- define_instruction(inst_list, "CALL", 1);
- define_instruction(inst_list, "RETURN_CALL", 0);
- define_instruction(inst_list, "JUMP", 1);
- define_instruction(inst_list, "LOOP", 1);
- define_instruction(inst_list, "END_LOOP", 0);
- define_instruction(inst_list, "IF", 3);
- define_instruction(inst_list, "ELSEIF", 3);
- define_instruction(inst_list, "ELSE", 0);
- define_instruction(inst_list, "END_IF", 0);
- define_instruction(inst_list, "WHILE", 3);
- define_instruction(inst_list, "END_WHILE", 0);
- define_instruction(inst_list, "MESSAGES_OFF", 0);
- define_instruction(inst_list, "MESSAGES_ON", 0);
- define_instruction(inst_list, "ABORT", 0); -- Error exit from sim
- define_instruction(inst_list, "FINISH", 0); -- Normal exit from sim
- define_instruction(inst_list, "INCLUDE", 1); -- Define a Variable
-
- -- User defined instructions
-
- ------------------------------------------------------------------------
- -- Read, test, and load the stimulus file
- read_instruction_file(stimulus_file, inst_list, defined_vars, inst_sequ,
- file_list);
-
- -- initialize last info
- last_sequ_num := 0;
- last_sequ_ptr := inst_sequ;
-------------------------------------------------------------------------
--- Using the Instruction record list, get the instruction and implement
--- it as per the statements in the elsif tree.
- while(v_line < inst_sequ.num_of_lines) loop
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
-
---------------------------------------------------------------------------
- --if(instruction(1 to len) = "DEFINE_VAR") then
- -- null; -- This instruction was implemented while reading the file
-
---------------------------------------------------------------------------
- if(instruction(1 to len) = "INCLUDE") then
- null; -- This instruction was implemented while reading the file
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "ABORT") then
- assert (false)
- report "The test has aborted due to an error!!"
- severity failure;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "FINISH") then
- assert (false)
- report "Test Finished with NO errors!!"
- severity failure;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "EQU_VAR") then
- update_variable(defined_vars, par1, par2, valid);
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "ADD_VAR") then
- index_variable(defined_vars, par1, temp_int, valid);
- if(valid /= 0) then
- temp_int := temp_int + par2;
- update_variable(defined_vars, par1, temp_int, valid);
- else
- assert (false)
- report "ADD_VAR Error: Not a valid Variable??"
- severity failure;
- end if;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "SUB_VAR") then
- index_variable(defined_vars, par1, temp_int, valid);
- if(valid /= 0) then
- temp_int := temp_int - par2;
- update_variable(defined_vars, par1, temp_int, valid);
- else
- assert (false)
- report "SUB_VAR Error: Not a valid Variable??"
- severity failure;
- end if;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "CALL") then
- if(stack_ptr >= 7) then
- assert (false)
- report "Call Error: Stack over run, calls to deeply nested!!"
- severity failure;
- end if;
- stack(stack_ptr) := v_line;
- stack_ptr := stack_ptr + 1;
- v_line := par1 - 1;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "RETURN_CALL") then
- if(stack_ptr <= 0) then
- assert (false)
- report "Call Error: Stack under run??"
- severity failure;
- end if;
- stack_ptr := stack_ptr - 1;
- v_line := stack(stack_ptr);
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "JUMP") then
- v_line := par1 - 1;
- wh_state := false;
- wh_stack := (others => 0);
- wh_dpth := 0;
- wh_ptr := 0;
- stack := (others => 0);
- stack_ptr := 0;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "LOOP") then
- loop_num := loop_num + 1;
- loop_line(loop_num) := v_line;
- curr_loop_count(loop_num) := 0;
- term_loop_count(loop_num) := par1;
- assert (messages)
- report LF & "Executing LOOP Command" &
- LF & " Nested Loop:" & HT & integer'image(loop_num) &
- LF & " Loop Length:" & HT & integer'image(par1)
- severity note;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "END_LOOP") then
- curr_loop_count(loop_num) := curr_loop_count(loop_num) + 1;
- if (curr_loop_count(loop_num) = term_loop_count(loop_num)) then
- loop_num := loop_num - 1;
- else
- v_line := loop_line(loop_num);
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "IF") then
- if_state := false;
- case par2 is
- when 0 => if(par1 = par3) then if_state := true; end if;
- when 1 => if(par1 > par3) then if_state := true; end if;
- when 2 => if(par1 < par3) then if_state := true; end if;
- when 3 => if(par1 /= par3) then if_state := true; end if;
- when 4 => if(par1 >= par3) then if_state := true; end if;
- when 5 => if(par1 <= par3) then if_state := true; end if;
- when others =>
- assert (false)
- report LF & "ERROR: IF instruction got an unexpected value" &
- LF & " in parameter 2!" & LF &
- "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
- severity failure;
- end case;
-
- if(if_state = false) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- while(instruction(1 to len) /= "ELSE" and
- instruction(1 to len) /= "ELSEIF" and
- instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- else
- assert (false)
- report LF & "ERROR: IF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "ELSEIF") then
- if(if_state = true) then -- if the if_state is true then skip to the end
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- while(instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- else
- assert (false)
- report LF & "ERROR: IF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
-
- else
- case par2 is
- when 0 => if(par1 = par3) then if_state := true; end if;
- when 1 => if(par1 > par3) then if_state := true; end if;
- when 2 => if(par1 < par3) then if_state := true; end if;
- when 3 => if(par1 /= par3) then if_state := true; end if;
- when 4 => if(par1 >= par3) then if_state := true; end if;
- when 5 => if(par1 <= par3) then if_state := true; end if;
- when others =>
- assert (false)
- report LF & "ERROR: ELSEIF instruction got an unexpected value" &
- LF & " in parameter 2!" & LF &
- "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
- severity failure;
- end case;
-
- if(if_state = false) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- while(instruction(1 to len) /= "ELSE" and
- instruction(1 to len) /= "ELSEIF" and
- instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- else
- assert (false)
- report LF & "ERROR: ELSEIF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
- end if;
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "ELSE") then
- if(if_state = true) then -- if the if_state is true then skip the else
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- while(instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- else
- assert (false)
- report LF & "ERROR: IF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "END_IF") then
- null; -- instruction is a place holder for finding the end of IF.
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "WHILE") then
- wh_state := false;
- case par2 is
- when 0 => if(par1 = par3) then wh_state := true; end if;
- when 1 => if(par1 > par3) then wh_state := true; end if;
- when 2 => if(par1 < par3) then wh_state := true; end if;
- when 3 => if(par1 /= par3) then wh_state := true; end if;
- when 4 => if(par1 >= par3) then wh_state := true; end if;
- when 5 => if(par1 <= par3) then wh_state := true; end if;
- when others =>
- assert (false)
- report LF & "ERROR: WHILE instruction got an unexpected value" &
- LF & " in parameter 2!" & LF &
- "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
- severity failure;
- end case;
-
- if(wh_state = true) then
- wh_stack(wh_ptr) := v_line;
- wh_ptr := wh_ptr + 1;
- else
- wh_end := false;
- while(wh_end /= true) loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
- last_sequ_num, last_sequ_ptr);
- else
- assert (false)
- report LF & "ERROR: WHILE instruction unable to find terminating" &
- LF & " END_WHILE statement."
- severity failure;
- end if;
-
- -- if is a while need to escape it
- if(instruction(1 to len) = "WHILE") then
- wh_dpth := wh_dpth + 1;
- -- if is the end_while we are looking for
- elsif(instruction(1 to len) = "END_WHILE") then
- if(wh_dpth = 0) then
- wh_end := true;
- else
- wh_dpth := wh_dpth - 1;
- end if;
- end if;
- end loop;
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "END_WHILE") then
- if(wh_ptr > 0) then
- v_line := wh_stack(wh_ptr - 1) - 1;
- wh_ptr := wh_ptr - 1;
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "MESSAGES_OFF") then
- messages := TRUE;
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "MESSAGES_ON") then
- messages := FALSE;
-
-
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
--- USER Istruction area. Add all user instructions below this
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
--- elsif (instruction(1 to len) = "RESET_SYS") then
-
-
---------------------------------------------------------------------------------
--- USER Istruction area. Add all user instructions above this
---------------------------------------------------------------------------------
- --------------------------------------------------------------------------
- -- catch those little mistakes
- else
- assert (false)
- report LF & "ERROR: Seems the command " & instruction(1 to len) & " was defined but" & LF &
- "was not found in the elsif chain, please check spelling."
- severity failure;
- end if; -- else if structure end
- -- after the instruction is finished print out any txt and sub vars
- txt_print_wvar(defined_vars, txt, hex);
- end loop; -- Main Loop end
-
- assert (false)
- report LF & "The end of the simulation! It was not terminated as expected." & LF
- severity failure;
-
- end process Read_file;
-
-
-end bhv;
Index: trunk/source/std_logic_1164_additions/std_logic_1164_additions.vhdl
===================================================================
--- trunk/source/std_logic_1164_additions/std_logic_1164_additions.vhdl (revision 13)
+++ trunk/source/std_logic_1164_additions/std_logic_1164_additions.vhdl (nonexistent)
@@ -1,1737 +0,0 @@
-------------------------------------------------------------------------------
--- "std_logic_1164_additions" package contains the additions to the standard
--- "std_logic_1164" package proposed by the VHDL-200X-ft working group.
--- This package should be compiled into "ieee_proposed" and used as follows:
--- use ieee.std_logic_1164.all;
--- use ieee_proposed.std_logic_1164_additions.all;
--- Last Modified: $Date: 2007-08-21 03:20:14 $
--- RCS ID: $Id: std_logic_1164_additions.vhdl,v 1.1 2007-08-21 03:20:14 sckoarn Exp $
---
--- Created for VHDL-200X par, David Bishop (dbishop@vhdl.org)
-------------------------------------------------------------------------------
-library ieee;
-use ieee.std_logic_1164.all;
-use std.textio.all;
-package std_logic_1164_additions is
-
- -- NOTE that in the new std_logic_1164, STD_LOGIC_VECTOR is a resolved
- -- subtype of STD_ULOGIC_VECTOR. Thus there is no need for funcitons which
- -- take inputs in STD_LOGIC_VECTOR.
- -- For compatability with VHDL-2002, I have replicated all of these funcitons
- -- here for STD_LOGIC_VECTOR.
- -- new aliases
- alias to_bv is ieee.std_logic_1164.To_bitvector [STD_LOGIC_VECTOR, BIT return BIT_VECTOR];
- alias to_bv is ieee.std_logic_1164.To_bitvector [STD_ULOGIC_VECTOR, BIT return BIT_VECTOR];
- alias to_bit_vector is ieee.std_logic_1164.To_bitvector [STD_LOGIC_VECTOR, BIT return BIT_VECTOR];
- alias to_bit_vector is ieee.std_logic_1164.To_bitvector [STD_ULOGIC_VECTOR, BIT return BIT_VECTOR];
- alias to_slv is ieee.std_logic_1164.To_StdLogicVector [BIT_VECTOR return STD_LOGIC_VECTOR];
- alias to_slv is ieee.std_logic_1164.To_StdLogicVector [STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR];
- alias to_std_logic_vector is ieee.std_logic_1164.To_StdLogicVector [BIT_VECTOR return STD_LOGIC_VECTOR];
- alias to_std_logic_vector is ieee.std_logic_1164.To_StdLogicVector [STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR];
- alias to_suv is ieee.std_logic_1164.To_StdULogicVector [BIT_VECTOR return STD_ULOGIC_VECTOR];
- alias to_suv is ieee.std_logic_1164.To_StdULogicVector [STD_LOGIC_VECTOR return STD_ULOGIC_VECTOR];
- alias to_std_ulogic_vector is ieee.std_logic_1164.To_StdULogicVector [BIT_VECTOR return STD_ULOGIC_VECTOR];
- alias to_std_ulogic_vector is ieee.std_logic_1164.To_StdULogicVector [STD_LOGIC_VECTOR return STD_ULOGIC_VECTOR];
-
- -------------------------------------------------------------------
- -- overloaded shift operators
- -------------------------------------------------------------------
-
- function "sll" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
- function "sll" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
-
- function "srl" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
- function "srl" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
-
- function "rol" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
- function "rol" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
-
- function "ror" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
- function "ror" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
- -------------------------------------------------------------------
- -- vector/scalar overloaded logical operators
- -------------------------------------------------------------------
- function "and" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
- function "and" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
- function "and" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function "and" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
- function "nand" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
- function "nand" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
- function "nand" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function "nand" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
- function "or" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
- function "or" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
- function "or" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function "or" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
- function "nor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
- function "nor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
- function "nor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function "nor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
- function "xor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
- function "xor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
- function "xor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function "xor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
- function "xnor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
- function "xnor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
- function "xnor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
-
- -------------------------------------------------------------------
- -- vector-reduction functions.
- -- "and" functions default to "1", or defaults to "0"
- -------------------------------------------------------------------
- -----------------------------------------------------------------------------
- -- %%% Replace the "_reduce" functions with the ones commented out below.
- -----------------------------------------------------------------------------
- -- function "and" ( l : std_logic_vector ) RETURN std_ulogic;
- -- function "and" ( l : std_ulogic_vector ) RETURN std_ulogic;
- -- function "nand" ( l : std_logic_vector ) RETURN std_ulogic;
- -- function "nand" ( l : std_ulogic_vector ) RETURN std_ulogic;
- -- function "or" ( l : std_logic_vector ) RETURN std_ulogic;
- -- function "or" ( l : std_ulogic_vector ) RETURN std_ulogic;
- -- function "nor" ( l : std_logic_vector ) RETURN std_ulogic;
- -- function "nor" ( l : std_ulogic_vector ) RETURN std_ulogic;
- -- function "xor" ( l : std_logic_vector ) RETURN std_ulogic;
- -- function "xor" ( l : std_ulogic_vector ) RETURN std_ulogic;
- -- function "xnor" ( l : std_logic_vector ) RETURN std_ulogic;
- -- function "xnor" ( l : std_ulogic_vector ) RETURN std_ulogic;
- function and_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function and_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- function nand_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function nand_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- function or_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function or_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- function nor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function nor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- function xor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function xor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- function xnor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function xnor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- -------------------------------------------------------------------
- -- ?= operators, same functionality as 1076.3 1994 std_match
- -------------------------------------------------------------------
--- FUNCTION "?=" ( l, r : std_ulogic ) RETURN std_ulogic;
--- FUNCTION "?=" ( l, r : std_logic_vector ) RETURN std_ulogic;
--- FUNCTION "?=" ( l, r : std_ulogic_vector ) RETURN std_ulogic;
--- FUNCTION "?/=" ( l, r : std_ulogic ) RETURN std_ulogic;
--- FUNCTION "?/=" ( l, r : std_logic_vector ) RETURN std_ulogic;
--- FUNCTION "?/=" ( l, r : std_ulogic_vector ) RETURN std_ulogic;
--- FUNCTION "?>" ( l, r : std_ulogic ) RETURN std_ulogic;
--- FUNCTION "?>=" ( l, r : std_ulogic ) RETURN std_ulogic;
--- FUNCTION "?<" ( l, r : std_ulogic ) RETURN std_ulogic;
--- FUNCTION "?<=" ( l, r : std_ulogic ) RETURN std_ulogic;
-
- function \?=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
- function \?=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function \?=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- function \?/=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
- function \?/=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC;
- function \?/=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC;
- function \?>\ (l, r : STD_ULOGIC) return STD_ULOGIC;
- function \?>=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
- function \?<\ (l, r : STD_ULOGIC) return STD_ULOGIC;
- function \?<=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
-
-
- -- "??" operator, converts a std_ulogic to a boolean.
- --%%% Uncomment the following operators
- -- FUNCTION "??" (S : STD_ULOGIC) RETURN BOOLEAN;
- --%%% REMOVE the following funciton (for testing only)
- function \??\ (S : STD_ULOGIC) return BOOLEAN;
-
- -- rtl_synthesis off
- function to_string (value : STD_ULOGIC) return STRING;
- function to_string (value : STD_ULOGIC_VECTOR) return STRING;
- function to_string (value : STD_LOGIC_VECTOR) return STRING;
-
- -- explicitly defined operations
-
- alias TO_BSTRING is TO_STRING [STD_ULOGIC_VECTOR return STRING];
- alias TO_BINARY_STRING is TO_STRING [STD_ULOGIC_VECTOR return STRING];
- function TO_OSTRING (VALUE : STD_ULOGIC_VECTOR) return STRING;
- alias TO_OCTAL_STRING is TO_OSTRING [STD_ULOGIC_VECTOR return STRING];
- function TO_HSTRING (VALUE : STD_ULOGIC_VECTOR) return STRING;
- alias TO_HEX_STRING is TO_HSTRING [STD_ULOGIC_VECTOR return STRING];
-
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC; GOOD : out BOOLEAN);
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC);
-
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN);
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR);
-
- procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
-
- procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
-
- alias BREAD is READ [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
- alias BREAD is READ [LINE, STD_ULOGIC_VECTOR];
- alias BINARY_READ is READ [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
- alias BINARY_READ is READ [LINE, STD_ULOGIC_VECTOR];
-
- procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN);
- procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR);
- alias OCTAL_READ is OREAD [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
- alias OCTAL_READ is OREAD [LINE, STD_ULOGIC_VECTOR];
-
- procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN);
- procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR);
- alias HEX_READ is HREAD [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
- alias HEX_READ is HREAD [LINE, STD_ULOGIC_VECTOR];
-
- alias BWRITE is WRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
- alias BINARY_WRITE is WRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
-
- procedure OWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
- alias OCTAL_WRITE is OWRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
-
- procedure HWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
- alias HEX_WRITE is HWRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
-
- alias TO_BSTRING is TO_STRING [STD_LOGIC_VECTOR return STRING];
- alias TO_BINARY_STRING is TO_STRING [STD_LOGIC_VECTOR return STRING];
- function TO_OSTRING (VALUE : STD_LOGIC_VECTOR) return STRING;
- alias TO_OCTAL_STRING is TO_OSTRING [STD_LOGIC_VECTOR return STRING];
- function TO_HSTRING (VALUE : STD_LOGIC_VECTOR) return STRING;
- alias TO_HEX_STRING is TO_HSTRING [STD_LOGIC_VECTOR return STRING];
-
- procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR; GOOD : out BOOLEAN);
- procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR);
-
- procedure WRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
-
- alias BREAD is READ [LINE, STD_LOGIC_VECTOR, BOOLEAN];
- alias BREAD is READ [LINE, STD_LOGIC_VECTOR];
- alias BINARY_READ is READ [LINE, STD_LOGIC_VECTOR, BOOLEAN];
- alias BINARY_READ is READ [LINE, STD_LOGIC_VECTOR];
-
- procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR; GOOD : out BOOLEAN);
- procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR);
- alias OCTAL_READ is OREAD [LINE, STD_LOGIC_VECTOR, BOOLEAN];
- alias OCTAL_READ is OREAD [LINE, STD_LOGIC_VECTOR];
-
- procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR; GOOD : out BOOLEAN);
- procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR);
- alias HEX_READ is HREAD [LINE, STD_LOGIC_VECTOR, BOOLEAN];
- alias HEX_READ is HREAD [LINE, STD_LOGIC_VECTOR];
-
- alias BWRITE is WRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
- alias BINARY_WRITE is WRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
-
- procedure OWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
- alias OCTAL_WRITE is OWRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
-
- procedure HWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
- alias HEX_WRITE is HWRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
- -- rtl_synthesis on
- function maximum (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
- function maximum (l, r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function maximum (l, r : STD_ULOGIC) return STD_ULOGIC;
- function minimum (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
- function minimum (l, r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
- function minimum (l, r : STD_ULOGIC) return STD_ULOGIC;
-end package std_logic_1164_additions;
-
-package body std_logic_1164_additions is
- type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;
- -----------------------------------------------------------------------------
- -- New/updated funcitons for VHDL-200X fast track
- -----------------------------------------------------------------------------
- -------------------------------------------------------------------
- -- overloaded shift operators
- -------------------------------------------------------------------
-
- -------------------------------------------------------------------
- -- sll
- -------------------------------------------------------------------
- function "sll" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length) := (others => '0');
- begin
- if r >= 0 then
- result(1 to l'length - r) := lv(r + 1 to l'length);
- else
- result := l srl -r;
- end if;
- return result;
- end function "sll";
- -------------------------------------------------------------------
- function "sll" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0');
- begin
- if r >= 0 then
- result(1 to l'length - r) := lv(r + 1 to l'length);
- else
- result := l srl -r;
- end if;
- return result;
- end function "sll";
-
- -------------------------------------------------------------------
- -- srl
- -------------------------------------------------------------------
- function "srl" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length) := (others => '0');
- begin
- if r >= 0 then
- result(r + 1 to l'length) := lv(1 to l'length - r);
- else
- result := l sll -r;
- end if;
- return result;
- end function "srl";
- -------------------------------------------------------------------
- function "srl" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0');
- begin
- if r >= 0 then
- result(r + 1 to l'length) := lv(1 to l'length - r);
- else
- result := l sll -r;
- end if;
- return result;
- end function "srl";
-
- -------------------------------------------------------------------
- -- rol
- -------------------------------------------------------------------
- function "rol" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length);
- constant rm : INTEGER := r mod l'length;
- begin
- if r >= 0 then
- result(1 to l'length - rm) := lv(rm + 1 to l'length);
- result(l'length - rm + 1 to l'length) := lv(1 to rm);
- else
- result := l ror -r;
- end if;
- return result;
- end function "rol";
- -------------------------------------------------------------------
- function "rol" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length);
- constant rm : INTEGER := r mod l'length;
- begin
- if r >= 0 then
- result(1 to l'length - rm) := lv(rm + 1 to l'length);
- result(l'length - rm + 1 to l'length) := lv(1 to rm);
- else
- result := l ror -r;
- end if;
- return result;
- end function "rol";
-
- -------------------------------------------------------------------
- -- ror
- -------------------------------------------------------------------
- function "ror" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length) := (others => '0');
- constant rm : INTEGER := r mod l'length;
- begin
- if r >= 0 then
- result(rm + 1 to l'length) := lv(1 to l'length - rm);
- result(1 to rm) := lv(l'length - rm + 1 to l'length);
- else
- result := l rol -r;
- end if;
- return result;
- end function "ror";
- -------------------------------------------------------------------
- function "ror" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0');
- constant rm : INTEGER := r mod l'length;
- begin
- if r >= 0 then
- result(rm + 1 to l'length) := lv(1 to l'length - rm);
- result(1 to rm) := lv(l'length - rm + 1 to l'length);
- else
- result := l rol -r;
- end if;
- return result;
- end function "ror";
- -------------------------------------------------------------------
- -- vector/scalar overloaded logical operators
- -------------------------------------------------------------------
-
- -------------------------------------------------------------------
- -- and
- -------------------------------------------------------------------
- function "and" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "and" (lv(i), r);
- end loop;
- return result;
- end function "and";
- -------------------------------------------------------------------
- function "and" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "and" (lv(i), r);
- end loop;
- return result;
- end function "and";
- -------------------------------------------------------------------
- function "and" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_LOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "and" (l, rv(i));
- end loop;
- return result;
- end function "and";
- -------------------------------------------------------------------
- function "and" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_ULOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "and" (l, rv(i));
- end loop;
- return result;
- end function "and";
-
- -------------------------------------------------------------------
- -- nand
- -------------------------------------------------------------------
- function "nand" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "not"("and" (lv(i), r));
- end loop;
- return result;
- end function "nand";
- -------------------------------------------------------------------
- function "nand" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "not"("and" (lv(i), r));
- end loop;
- return result;
- end function "nand";
- -------------------------------------------------------------------
- function "nand" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_LOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "not"("and" (l, rv(i)));
- end loop;
- return result;
- end function "nand";
- -------------------------------------------------------------------
- function "nand" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_ULOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "not"("and" (l, rv(i)));
- end loop;
- return result;
- end function "nand";
-
- -------------------------------------------------------------------
- -- or
- -------------------------------------------------------------------
- function "or" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "or" (lv(i), r);
- end loop;
- return result;
- end function "or";
- -------------------------------------------------------------------
- function "or" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "or" (lv(i), r);
- end loop;
- return result;
- end function "or";
- -------------------------------------------------------------------
- function "or" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_LOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "or" (l, rv(i));
- end loop;
- return result;
- end function "or";
- -------------------------------------------------------------------
- function "or" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_ULOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "or" (l, rv(i));
- end loop;
- return result;
- end function "or";
-
- -------------------------------------------------------------------
- -- nor
- -------------------------------------------------------------------
- function "nor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "not"("or" (lv(i), r));
- end loop;
- return result;
- end function "nor";
- -------------------------------------------------------------------
- function "nor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "not"("or" (lv(i), r));
- end loop;
- return result;
- end function "nor";
- -------------------------------------------------------------------
- function "nor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_LOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "not"("or" (l, rv(i)));
- end loop;
- return result;
- end function "nor";
- -------------------------------------------------------------------
- function "nor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_ULOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "not"("or" (l, rv(i)));
- end loop;
- return result;
- end function "nor";
-
- -------------------------------------------------------------------
- -- xor
- -------------------------------------------------------------------
- function "xor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "xor" (lv(i), r);
- end loop;
- return result;
- end function "xor";
- -------------------------------------------------------------------
- function "xor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "xor" (lv(i), r);
- end loop;
- return result;
- end function "xor";
- -------------------------------------------------------------------
- function "xor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_LOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "xor" (l, rv(i));
- end loop;
- return result;
- end function "xor";
- -------------------------------------------------------------------
- function "xor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_ULOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "xor" (l, rv(i));
- end loop;
- return result;
- end function "xor";
-
- -------------------------------------------------------------------
- -- xnor
- -------------------------------------------------------------------
- function "xnor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
- alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_LOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "not"("xor" (lv(i), r));
- end loop;
- return result;
- end function "xnor";
- -------------------------------------------------------------------
- function "xnor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
- alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
- variable result : STD_ULOGIC_VECTOR (1 to l'length);
- begin
- for i in result'range loop
- result(i) := "not"("xor" (lv(i), r));
- end loop;
- return result;
- end function "xnor";
- -------------------------------------------------------------------
- function "xnor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_LOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "not"("xor" (l, rv(i)));
- end loop;
- return result;
- end function "xnor";
- -------------------------------------------------------------------
- function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
- variable result : STD_ULOGIC_VECTOR (1 to r'length);
- begin
- for i in result'range loop
- result(i) := "not"("xor" (l, rv(i)));
- end loop;
- return result;
- end function "xnor";
-
- -------------------------------------------------------------------
- -- vector-reduction functions
- -------------------------------------------------------------------
-
- -------------------------------------------------------------------
- -- and
- -------------------------------------------------------------------
- function and_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
- begin
- return and_reduce (to_StdULogicVector (l));
- end function and_reduce;
- -------------------------------------------------------------------
- function and_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- variable result : STD_ULOGIC := '1';
- begin
- for i in l'reverse_range loop
- result := (l(i) and result);
- end loop;
- return result;
- end function and_reduce;
-
- -------------------------------------------------------------------
- -- nand
- -------------------------------------------------------------------
- function nand_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
- begin
- return not (and_reduce(to_StdULogicVector(l)));
- end function nand_reduce;
- -------------------------------------------------------------------
- function nand_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- begin
- return not (and_reduce(l));
- end function nand_reduce;
-
- -------------------------------------------------------------------
- -- or
- -------------------------------------------------------------------
- function or_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
- begin
- return or_reduce (to_StdULogicVector (l));
- end function or_reduce;
- -------------------------------------------------------------------
- function or_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- variable result : STD_ULOGIC := '0';
- begin
- for i in l'reverse_range loop
- result := (l(i) or result);
- end loop;
- return result;
- end function or_reduce;
-
- -------------------------------------------------------------------
- -- nor
- -------------------------------------------------------------------
- function nor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
- begin
- return "not"(or_reduce(To_StdULogicVector(l)));
- end function nor_reduce;
- -------------------------------------------------------------------
- function nor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- begin
- return "not"(or_reduce(l));
- end function nor_reduce;
-
- -------------------------------------------------------------------
- -- xor
- -------------------------------------------------------------------
- function xor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
- begin
- return xor_reduce (to_StdULogicVector (l));
- end function xor_reduce;
- -------------------------------------------------------------------
- function xor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- variable result : STD_ULOGIC := '0';
- begin
- for i in l'reverse_range loop
- result := (l(i) xor result);
- end loop;
- return result;
- end function xor_reduce;
-
- -------------------------------------------------------------------
- -- xnor
- -------------------------------------------------------------------
- function xnor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
- begin
- return "not"(xor_reduce(To_StdULogicVector(l)));
- end function xnor_reduce;
- -------------------------------------------------------------------
- function xnor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- begin
- return "not"(xor_reduce(l));
- end function xnor_reduce;
- -- %%% End "remove the following functions"
-
-
- -- The following functions are implicity in 1076-2006
- -- truth table for "?=" function
- constant match_logic_table : stdlogic_table := (
- -----------------------------------------------------
- -- U X 0 1 Z W L H - | |
- -----------------------------------------------------
- ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '1'), -- | U |
- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | X |
- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'), -- | 0 |
- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'), -- | 1 |
- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | Z |
- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | W |
- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'), -- | L |
- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'), -- | H |
- ('1', '1', '1', '1', '1', '1', '1', '1', '1') -- | - |
- );
-
- constant no_match_logic_table : stdlogic_table := (
- -----------------------------------------------------
- -- U X 0 1 Z W L H - | |
- -----------------------------------------------------
- ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '0'), -- | U |
- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | X |
- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'), -- | 0 |
- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'), -- | 1 |
- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | Z |
- ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | W |
- ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'), -- | L |
- ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'), -- | H |
- ('0', '0', '0', '0', '0', '0', '0', '0', '0') -- | - |
- );
-
- -------------------------------------------------------------------
- -- ?= functions, Similar to "std_match", but returns "std_ulogic".
- -------------------------------------------------------------------
- -- %%% FUNCTION "?=" ( l, r : std_ulogic ) RETURN std_ulogic IS
- function \?=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
- begin
- return match_logic_table (l, r);
- end function \?=\;
- -- %%% END FUNCTION "?=";
- -------------------------------------------------------------------
- -- %%% FUNCTION "?=" ( l, r : std_logic_vector ) RETURN std_ulogic IS
- function \?=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC is
- alias lv : STD_LOGIC_VECTOR(1 to l'length) is l;
- alias rv : STD_LOGIC_VECTOR(1 to r'length) is r;
- variable result, result1 : STD_ULOGIC; -- result
- begin
- -- Logically identical to an "=" operator.
- if ((l'length < 1) or (r'length < 1)) then
- report "STD_LOGIC_1164.""?="": null detected, returning X"
- severity warning;
- return 'X';
- end if;
- if lv'length /= rv'length then
- report "STD_LOGIC_1164.""?="": L'LENGTH /= R'LENGTH, returning X"
- severity warning;
- return 'X';
- else
- result := '1';
- for i in lv'low to lv'high loop
- result1 := match_logic_table(lv(i), rv(i));
- if result1 = 'U' then
- return 'U';
- elsif result1 = 'X' or result = 'X' then
- result := 'X';
- else
- result := result and result1;
- end if;
- end loop;
- return result;
- end if;
- end function \?=\;
- -- %%% END FUNCTION "?=";
- -------------------------------------------------------------------
- -- %%% FUNCTION "?=" ( l, r : std_ulogic_vector ) RETURN std_ulogic IS
- function \?=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- alias lv : STD_ULOGIC_VECTOR(1 to l'length) is l;
- alias rv : STD_ULOGIC_VECTOR(1 to r'length) is r;
- variable result, result1 : STD_ULOGIC;
- begin
- if ((l'length < 1) or (r'length < 1)) then
- report "STD_LOGIC_1164.""?="": null detected, returning X"
- severity warning;
- return 'X';
- end if;
- if lv'length /= rv'length then
- report "STD_LOGIC_1164.""?="": L'LENGTH /= R'LENGTH, returning X"
- severity warning;
- return 'X';
- else
- result := '1';
- for i in lv'low to lv'high loop
- result1 := match_logic_table(lv(i), rv(i));
- if result1 = 'U' then
- return 'U';
- elsif result1 = 'X' or result = 'X' then
- result := 'X';
- else
- result := result and result1;
- end if;
- end loop;
- return result;
- end if;
- end function \?=\;
- -- %%% END FUNCTION "?=";
- -- %%% FUNCTION "?/=" ( l, r : std_ulogic ) RETURN std_ulogic is
- function \?/=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
- begin
- return no_match_logic_table (l, r);
- end function \?/=\;
- -- %%% END FUNCTION "?/=";
- -- %%% FUNCTION "?/=" ( l, r : std_logic_vector ) RETURN std_ulogic is
- function \?/=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC is
- alias lv : STD_LOGIC_VECTOR(1 to l'length) is l;
- alias rv : STD_LOGIC_VECTOR(1 to r'length) is r;
- variable result, result1 : STD_ULOGIC; -- result
- begin
- if ((l'length < 1) or (r'length < 1)) then
- report "STD_LOGIC_1164.""?/="": null detected, returning X"
- severity warning;
- return 'X';
- end if;
- if lv'length /= rv'length then
- report "STD_LOGIC_1164.""?/="": L'LENGTH /= R'LENGTH, returning X"
- severity warning;
- return 'X';
- else
- result := '0';
- for i in lv'low to lv'high loop
- result1 := no_match_logic_table(lv(i), rv(i));
- if result1 = 'U' then
- return 'U';
- elsif result1 = 'X' or result = 'X' then
- result := 'X';
- else
- result := result or result1;
- end if;
- end loop;
- return result;
- end if;
- end function \?/=\;
- -- %%% END FUNCTION "?/=";
- -- %%% FUNCTION "?/=" ( l, r : std_ulogic_vector ) RETURN std_ulogic is
- function \?/=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC is
- alias lv : STD_ULOGIC_VECTOR(1 to l'length) is l;
- alias rv : STD_ULOGIC_VECTOR(1 to r'length) is r;
- variable result, result1 : STD_ULOGIC;
- begin
- if ((l'length < 1) or (r'length < 1)) then
- report "STD_LOGIC_1164.""?/="": null detected, returning X"
- severity warning;
- return 'X';
- end if;
- if lv'length /= rv'length then
- report "STD_LOGIC_1164.""?/="": L'LENGTH /= R'LENGTH, returning X"
- severity warning;
- return 'X';
- else
- result := '0';
- for i in lv'low to lv'high loop
- result1 := no_match_logic_table(lv(i), rv(i));
- if result1 = 'U' then
- return 'U';
- elsif result1 = 'X' or result = 'X' then
- result := 'X';
- else
- result := result or result1;
- end if;
- end loop;
- return result;
- end if;
- end function \?/=\;
- -- %%% END FUNCTION "?/=";
- -- %%% FUNCTION "?>" ( l, r : std_ulogic ) RETURN std_ulogic is
- function \?>\ (l, r : STD_ULOGIC) return STD_ULOGIC is
- variable lx, rx : STD_ULOGIC;
- begin
- if (l = '-') or (r = '-') then
- report "STD_LOGIC_1164.""?>"": '-' found in compare string"
- severity error;
- return 'X';
- else
- lx := to_x01 (l);
- rx := to_x01 (r);
- if lx = 'X' or rx = 'X' then
- return 'X';
- elsif lx > rx then
- return '1';
- else
- return '0';
- end if;
- end if;
- end function \?>\;
- -- %%% END FUNCTION "?>";
-
- -- %%% FUNCTION "?>=" ( l, r : std_ulogic ) RETURN std_ulogic is
- function \?>=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
- variable lx, rx : STD_ULOGIC;
- begin
- if (l = '-') or (r = '-') then
- report "STD_LOGIC_1164.""?>="": '-' found in compare string"
- severity error;
- return 'X';
- else
- lx := to_x01 (l);
- rx := to_x01 (r);
- if lx = 'X' or rx = 'X' then
- return 'X';
- elsif lx >= rx then
- return '1';
- else
- return '0';
- end if;
- end if;
- end function \?>=\;
- -- %%% END FUNCTION "?/>=";
-
- -- %%% FUNCTION "?<" ( l, r : std_ulogic ) RETURN std_ulogic is
- function \?<\ (l, r : STD_ULOGIC) return STD_ULOGIC is
- variable lx, rx : STD_ULOGIC;
- begin
- if (l = '-') or (r = '-') then
- report "STD_LOGIC_1164.""?<"": '-' found in compare string"
- severity error;
- return 'X';
- else
- lx := to_x01 (l);
- rx := to_x01 (r);
- if lx = 'X' or rx = 'X' then
- return 'X';
- elsif lx < rx then
- return '1';
- else
- return '0';
- end if;
- end if;
- end function \?<\;
- -- %%% END FUNCTION "?/<";
-
- -- %%% FUNCTION "?<=" ( l, r : std_ulogic ) RETURN std_ulogic is
- function \?<=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
- variable lx, rx : STD_ULOGIC;
- begin
- if (l = '-') or (r = '-') then
- report "STD_LOGIC_1164.""?<="": '-' found in compare string"
- severity error;
- return 'X';
- else
- lx := to_x01 (l);
- rx := to_x01 (r);
- if lx = 'X' or rx = 'X' then
- return 'X';
- elsif lx <= rx then
- return '1';
- else
- return '0';
- end if;
- end if;
- end function \?<=\;
- -- %%% END FUNCTION "?/<=";
-
- -- "??" operator, converts a std_ulogic to a boolean.
--- %%% FUNCTION "??"
- function \??\ (S : STD_ULOGIC) return BOOLEAN is
- begin
- return S = '1' or S = 'H';
- end function \??\;
--- %%% END FUNCTION "??";
-
- -- rtl_synthesis off
- -----------------------------------------------------------------------------
- -- This section copied from "std_logic_textio"
- -----------------------------------------------------------------------------
- -- Type and constant definitions used to map STD_ULOGIC values
- -- into/from character values.
- type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
- type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
- type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
- type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
- constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
- constant char_to_MVL9 : MVL9_indexed_by_char :=
- ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
- 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
- constant char_to_MVL9plus : MVL9plus_indexed_by_char :=
- ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
- 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error);
-
- constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
- constant NUS : STRING(2 to 1) := (others => ' '); -- null STRING
-
- -- purpose: Skips white space
- procedure skip_whitespace (
- L : inout LINE) is
- variable readOk : BOOLEAN;
- variable c : CHARACTER;
- begin
- while L /= null and L.all'length /= 0 loop
- if (L.all(1) = ' ' or L.all(1) = NBSP or L.all(1) = HT) then
- read (l, c, readOk);
- else
- exit;
- end if;
- end loop;
- end procedure skip_whitespace;
-
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC;
- GOOD : out BOOLEAN) is
- variable c : CHARACTER;
- variable readOk : BOOLEAN;
- begin
- VALUE := 'U'; -- initialize to a "U"
- Skip_whitespace (L);
- read (l, c, readOk);
- if not readOk then
- good := false;
- else
- if char_to_MVL9plus(c) = error then
- good := false;
- else
- VALUE := char_to_MVL9(c);
- good := true;
- end if;
- end if;
- end procedure READ;
-
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
- GOOD : out BOOLEAN) is
- variable m : STD_ULOGIC;
- variable c : CHARACTER;
- variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1);
- variable readOk : BOOLEAN;
- variable i : INTEGER;
- variable lastu : BOOLEAN := false; -- last character was an "_"
- begin
- VALUE := (VALUE'range => 'U'); -- initialize to a "U"
- Skip_whitespace (L);
- if VALUE'length > 0 then
- read (l, c, readOk);
- i := 0;
- good := false;
- while i < VALUE'length loop
- if not readOk then -- Bail out if there was a bad read
- return;
- elsif c = '_' then
- if i = 0 then -- Begins with an "_"
- return;
- elsif lastu then -- "__" detected
- return;
- else
- lastu := true;
- end if;
- elsif (char_to_MVL9plus(c) = error) then -- Illegal character
- return;
- else
- mv(i) := char_to_MVL9(c);
- i := i + 1;
- if i > mv'high then -- reading done
- good := true;
- VALUE := mv;
- return;
- end if;
- lastu := false;
- end if;
- read(L, c, readOk);
- end loop;
- else
- good := true; -- read into a null array
- end if;
- end procedure READ;
-
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC) is
- variable c : CHARACTER;
- variable readOk : BOOLEAN;
- begin
- VALUE := 'U'; -- initialize to a "U"
- Skip_whitespace (L);
- read (l, c, readOk);
- if not readOk then
- report "STD_LOGIC_1164.READ(STD_ULOGIC) "
- & "End of string encountered"
- severity error;
- return;
- elsif char_to_MVL9plus(c) = error then
- report
- "STD_LOGIC_1164.READ(STD_ULOGIC) Error: Character '" &
- c & "' read, expected STD_ULOGIC literal."
- severity error;
- else
- VALUE := char_to_MVL9(c);
- end if;
- end procedure READ;
-
- procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
- variable m : STD_ULOGIC;
- variable c : CHARACTER;
- variable readOk : BOOLEAN;
- variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1);
- variable i : INTEGER;
- variable lastu : BOOLEAN := false; -- last character was an "_"
- begin
- VALUE := (VALUE'range => 'U'); -- initialize to a "U"
- Skip_whitespace (L);
- if VALUE'length > 0 then -- non Null input string
- read (l, c, readOk);
- i := 0;
- while i < VALUE'length loop
- if readOk = false then -- Bail out if there was a bad read
- report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
- & "End of string encountered"
- severity error;
- return;
- elsif c = '_' then
- if i = 0 then
- report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
- & "String begins with an ""_""" severity error;
- return;
- elsif lastu then
- report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
- & "Two underscores detected in input string ""__"""
- severity error;
- return;
- else
- lastu := true;
- end if;
- elsif c = ' ' or c = NBSP or c = HT then -- reading done.
- report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
- & "Short read, Space encounted in input string"
- severity error;
- return;
- elsif char_to_MVL9plus(c) = error then
- report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
- & "Error: Character '" &
- c & "' read, expected STD_ULOGIC literal."
- severity error;
- return;
- else
- mv(i) := char_to_MVL9(c);
- i := i + 1;
- if i > mv'high then
- VALUE := mv;
- return;
- end if;
- lastu := false;
- end if;
- read(L, c, readOk);
- end loop;
- end if;
- end procedure READ;
-
- procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
- begin
- write(l, MVL9_to_char(VALUE), justified, field);
- end procedure WRITE;
-
- procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
- variable s : STRING(1 to VALUE'length);
- variable m : STD_ULOGIC_VECTOR(1 to VALUE'length) := VALUE;
- begin
- for i in 1 to VALUE'length loop
- s(i) := MVL9_to_char(m(i));
- end loop;
- write(l, s, justified, field);
- end procedure WRITE;
-
- -- Read and Write procedures for STD_LOGIC_VECTOR
-
- procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR;
- GOOD : out BOOLEAN) is
- variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
- begin
- READ (L => L, VALUE => ivalue, GOOD => GOOD);
- VALUE := to_stdlogicvector (ivalue);
- end procedure READ;
-
- procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR) is
- variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
- begin
- READ (L => L, VALUE => ivalue);
- VALUE := to_stdlogicvector (ivalue);
- end procedure READ;
-
- procedure WRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
- variable s : STRING(1 to VALUE'length);
- variable m : STD_LOGIC_VECTOR(1 to VALUE'length) := VALUE;
- begin
- for i in 1 to VALUE'length loop
- s(i) := MVL9_to_char(m(i));
- end loop;
- write(L, s, justified, field);
- end procedure WRITE;
-
- -----------------------------------------------------------------------
- -- Alias for bread and bwrite are provided with call out the read and
- -- write functions.
- -----------------------------------------------------------------------
-
- -- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
- -- Modified from the original to be more forgiving.
-
- procedure Char2QuadBits (C : CHARACTER;
- RESULT : out STD_ULOGIC_VECTOR(3 downto 0);
- GOOD : out BOOLEAN;
- ISSUE_ERROR : in BOOLEAN) is
- begin
- case c is
- when '0' => result := x"0"; good := true;
- when '1' => result := x"1"; good := true;
- when '2' => result := x"2"; good := true;
- when '3' => result := x"3"; good := true;
- when '4' => result := x"4"; good := true;
- when '5' => result := x"5"; good := true;
- when '6' => result := x"6"; good := true;
- when '7' => result := x"7"; good := true;
- when '8' => result := x"8"; good := true;
- when '9' => result := x"9"; good := true;
- when 'A' | 'a' => result := x"A"; good := true;
- when 'B' | 'b' => result := x"B"; good := true;
- when 'C' | 'c' => result := x"C"; good := true;
- when 'D' | 'd' => result := x"D"; good := true;
- when 'E' | 'e' => result := x"E"; good := true;
- when 'F' | 'f' => result := x"F"; good := true;
- when 'Z' => result := "ZZZZ"; good := true;
- when 'X' => result := "XXXX"; good := true;
- when others =>
- assert not ISSUE_ERROR
- report
- "STD_LOGIC_1164.HREAD Read a '" & c &
- "', expected a Hex character (0-F)."
- severity error;
- good := false;
- end case;
- end procedure Char2QuadBits;
-
- procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
- GOOD : out BOOLEAN) is
- variable ok : BOOLEAN;
- variable c : CHARACTER;
- constant ne : INTEGER := (VALUE'length+3)/4;
- constant pad : INTEGER := ne*4 - VALUE'length;
- variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
- variable i : INTEGER;
- variable lastu : BOOLEAN := false; -- last character was an "_"
- begin
- VALUE := (VALUE'range => 'U'); -- initialize to a "U"
- Skip_whitespace (L);
- if VALUE'length > 0 then
- read (l, c, ok);
- i := 0;
- while i < ne loop
- -- Bail out if there was a bad read
- if not ok then
- good := false;
- return;
- elsif c = '_' then
- if i = 0 then
- good := false; -- Begins with an "_"
- return;
- elsif lastu then
- good := false; -- "__" detected
- return;
- else
- lastu := true;
- end if;
- else
- Char2QuadBits(c, sv(4*i to 4*i+3), ok, false);
- if not ok then
- good := false;
- return;
- end if;
- i := i + 1;
- lastu := false;
- end if;
- if i < ne then
- read(L, c, ok);
- end if;
- end loop;
- if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
- good := false; -- vector was truncated.
- else
- good := true;
- VALUE := sv (pad to sv'high);
- end if;
- else
- good := true; -- Null input string, skips whitespace
- end if;
- end procedure HREAD;
-
- procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
- variable ok : BOOLEAN;
- variable c : CHARACTER;
- constant ne : INTEGER := (VALUE'length+3)/4;
- constant pad : INTEGER := ne*4 - VALUE'length;
- variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
- variable i : INTEGER;
- variable lastu : BOOLEAN := false; -- last character was an "_"
- begin
- VALUE := (VALUE'range => 'U'); -- initialize to a "U"
- Skip_whitespace (L);
- if VALUE'length > 0 then -- non Null input string
- read (l, c, ok);
- i := 0;
- while i < ne loop
- -- Bail out if there was a bad read
- if not ok then
- report "STD_LOGIC_1164.HREAD "
- & "End of string encountered"
- severity error;
- return;
- end if;
- if c = '_' then
- if i = 0 then
- report "STD_LOGIC_1164.HREAD "
- & "String begins with an ""_""" severity error;
- return;
- elsif lastu then
- report "STD_LOGIC_1164.HREAD "
- & "Two underscores detected in input string ""__"""
- severity error;
- return;
- else
- lastu := true;
- end if;
- else
- Char2QuadBits(c, sv(4*i to 4*i+3), ok, true);
- if not ok then
- return;
- end if;
- i := i + 1;
- lastu := false;
- end if;
- if i < ne then
- read(L, c, ok);
- end if;
- end loop;
- if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
- report "STD_LOGIC_1164.HREAD Vector truncated"
- severity error;
- else
- VALUE := sv (pad to sv'high);
- end if;
- end if;
- end procedure HREAD;
-
- procedure HWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
- begin
- write (L, to_hstring (VALUE), JUSTIFIED, FIELD);
- end procedure HWRITE;
-
-
- -- Octal Read and Write procedures for STD_ULOGIC_VECTOR.
- -- Modified from the original to be more forgiving.
-
- procedure Char2TriBits (C : CHARACTER;
- RESULT : out STD_ULOGIC_VECTOR(2 downto 0);
- GOOD : out BOOLEAN;
- ISSUE_ERROR : in BOOLEAN) is
- begin
- case c is
- when '0' => result := o"0"; good := true;
- when '1' => result := o"1"; good := true;
- when '2' => result := o"2"; good := true;
- when '3' => result := o"3"; good := true;
- when '4' => result := o"4"; good := true;
- when '5' => result := o"5"; good := true;
- when '6' => result := o"6"; good := true;
- when '7' => result := o"7"; good := true;
- when 'Z' => result := "ZZZ"; good := true;
- when 'X' => result := "XXX"; good := true;
- when others =>
- assert not ISSUE_ERROR
- report
- "STD_LOGIC_1164.OREAD Error: Read a '" & c &
- "', expected an Octal character (0-7)."
- severity error;
- good := false;
- end case;
- end procedure Char2TriBits;
-
- procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
- GOOD : out BOOLEAN) is
- variable ok : BOOLEAN;
- variable c : CHARACTER;
- constant ne : INTEGER := (VALUE'length+2)/3;
- constant pad : INTEGER := ne*3 - VALUE'length;
- variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
- variable i : INTEGER;
- variable lastu : BOOLEAN := false; -- last character was an "_"
- begin
- VALUE := (VALUE'range => 'U'); -- initialize to a "U"
- Skip_whitespace (L);
- if VALUE'length > 0 then
- read (l, c, ok);
- i := 0;
- while i < ne loop
- -- Bail out if there was a bad read
- if not ok then
- good := false;
- return;
- elsif c = '_' then
- if i = 0 then
- good := false; -- Begins with an "_"
- return;
- elsif lastu then
- good := false; -- "__" detected
- return;
- else
- lastu := true;
- end if;
- else
- Char2TriBits(c, sv(3*i to 3*i+2), ok, false);
- if not ok then
- good := false;
- return;
- end if;
- i := i + 1;
- lastu := false;
- end if;
- if i < ne then
- read(L, c, ok);
- end if;
- end loop;
- if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
- good := false; -- vector was truncated.
- else
- good := true;
- VALUE := sv (pad to sv'high);
- end if;
- else
- good := true; -- read into a null array
- end if;
- end procedure OREAD;
-
- procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
- variable c : CHARACTER;
- variable ok : BOOLEAN;
- constant ne : INTEGER := (VALUE'length+2)/3;
- constant pad : INTEGER := ne*3 - VALUE'length;
- variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
- variable i : INTEGER;
- variable lastu : BOOLEAN := false; -- last character was an "_"
- begin
- VALUE := (VALUE'range => 'U'); -- initialize to a "U"
- Skip_whitespace (L);
- if VALUE'length > 0 then
- read (l, c, ok);
- i := 0;
- while i < ne loop
- -- Bail out if there was a bad read
- if not ok then
- report "STD_LOGIC_1164.OREAD "
- & "End of string encountered"
- severity error;
- return;
- elsif c = '_' then
- if i = 0 then
- report "STD_LOGIC_1164.OREAD "
- & "String begins with an ""_""" severity error;
- return;
- elsif lastu then
- report "STD_LOGIC_1164.OREAD "
- & "Two underscores detected in input string ""__"""
- severity error;
- return;
- else
- lastu := true;
- end if;
- else
- Char2TriBits(c, sv(3*i to 3*i+2), ok, true);
- if not ok then
- return;
- end if;
- i := i + 1;
- lastu := false;
- end if;
- if i < ne then
- read(L, c, ok);
- end if;
- end loop;
- if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
- report "STD_LOGIC_1164.OREAD Vector truncated"
- severity error;
- else
- VALUE := sv (pad to sv'high);
- end if;
- end if;
- end procedure OREAD;
-
- procedure OWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
- begin
- write (L, to_ostring(VALUE), JUSTIFIED, FIELD);
- end procedure OWRITE;
-
- -- Hex Read and Write procedures for STD_LOGIC_VECTOR
-
- procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR;
- GOOD : out BOOLEAN) is
- variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
- begin
- HREAD (L => L, VALUE => ivalue, GOOD => GOOD);
- VALUE := to_stdlogicvector (ivalue);
- end procedure HREAD;
-
- procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR) is
- variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
- begin
- HREAD (L => L, VALUE => ivalue);
- VALUE := to_stdlogicvector (ivalue);
- end procedure HREAD;
-
- procedure HWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
- begin
- write (L, to_hstring(VALUE), JUSTIFIED, FIELD);
- end procedure HWRITE;
-
- -- Octal Read and Write procedures for STD_LOGIC_VECTOR
-
- procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR;
- GOOD : out BOOLEAN) is
- variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
- begin
- OREAD (L => L, VALUE => ivalue, GOOD => GOOD);
- VALUE := to_stdlogicvector (ivalue);
- end procedure OREAD;
-
- procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR) is
- variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
- begin
- OREAD (L => L, VALUE => ivalue);
- VALUE := to_stdlogicvector (ivalue);
- end procedure OREAD;
-
- procedure OWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
- JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
- begin
- write (L, to_ostring(VALUE), JUSTIFIED, FIELD);
- end procedure OWRITE;
-
- -----------------------------------------------------------------------------
- -- New string functions for vhdl-200x fast track
- -----------------------------------------------------------------------------
- function to_string (value : STD_ULOGIC) return STRING is
- variable result : STRING (1 to 1);
- begin
- result (1) := MVL9_to_char (value);
- return result;
- end function to_string;
- -------------------------------------------------------------------
- -- TO_STRING (an alias called "to_bstring" is provide)
- -------------------------------------------------------------------
- function to_string (value : STD_ULOGIC_VECTOR) return STRING is
- alias ivalue : STD_ULOGIC_VECTOR(1 to value'length) is value;
- variable result : STRING(1 to value'length);
- begin
- if value'length < 1 then
- return NUS;
- else
- for i in ivalue'range loop
- result(i) := MVL9_to_char(iValue(i));
- end loop;
- return result;
- end if;
- end function to_string;
-
- -------------------------------------------------------------------
- -- TO_HSTRING
- -------------------------------------------------------------------
- function to_hstring (value : STD_ULOGIC_VECTOR) return STRING is
- constant ne : INTEGER := (value'length+3)/4;
- variable pad : STD_ULOGIC_VECTOR(0 to (ne*4 - value'length) - 1);
- variable ivalue : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
- variable result : STRING(1 to ne);
- variable quad : STD_ULOGIC_VECTOR(0 to 3);
- begin
- if value'length < 1 then
- return NUS;
- else
- if value (value'left) = 'Z' then
- pad := (others => 'Z');
- else
- pad := (others => '0');
- end if;
- ivalue := pad & value;
- for i in 0 to ne-1 loop
- quad := To_X01Z(ivalue(4*i to 4*i+3));
- case quad is
- when x"0" => result(i+1) := '0';
- when x"1" => result(i+1) := '1';
- when x"2" => result(i+1) := '2';
- when x"3" => result(i+1) := '3';
- when x"4" => result(i+1) := '4';
- when x"5" => result(i+1) := '5';
- when x"6" => result(i+1) := '6';
- when x"7" => result(i+1) := '7';
- when x"8" => result(i+1) := '8';
- when x"9" => result(i+1) := '9';
- when x"A" => result(i+1) := 'A';
- when x"B" => result(i+1) := 'B';
- when x"C" => result(i+1) := 'C';
- when x"D" => result(i+1) := 'D';
- when x"E" => result(i+1) := 'E';
- when x"F" => result(i+1) := 'F';
- when "ZZZZ" => result(i+1) := 'Z';
- when others => result(i+1) := 'X';
- end case;
- end loop;
- return result;
- end if;
- end function to_hstring;
-
- -------------------------------------------------------------------
- -- TO_OSTRING
- -------------------------------------------------------------------
- function to_ostring (value : STD_ULOGIC_VECTOR) return STRING is
- constant ne : INTEGER := (value'length+2)/3;
- variable pad : STD_ULOGIC_VECTOR(0 to (ne*3 - value'length) - 1);
- variable ivalue : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
- variable result : STRING(1 to ne);
- variable tri : STD_ULOGIC_VECTOR(0 to 2);
- begin
- if value'length < 1 then
- return NUS;
- else
- if value (value'left) = 'Z' then
- pad := (others => 'Z');
- else
- pad := (others => '0');
- end if;
- ivalue := pad & value;
- for i in 0 to ne-1 loop
- tri := To_X01Z(ivalue(3*i to 3*i+2));
- case tri is
- when o"0" => result(i+1) := '0';
- when o"1" => result(i+1) := '1';
- when o"2" => result(i+1) := '2';
- when o"3" => result(i+1) := '3';
- when o"4" => result(i+1) := '4';
- when o"5" => result(i+1) := '5';
- when o"6" => result(i+1) := '6';
- when o"7" => result(i+1) := '7';
- when "ZZZ" => result(i+1) := 'Z';
- when others => result(i+1) := 'X';
- end case;
- end loop;
- return result;
- end if;
- end function to_ostring;
-
- function to_string (value : STD_LOGIC_VECTOR) return STRING is
- begin
- return to_string (to_stdulogicvector (value));
- end function to_string;
-
- function to_hstring (value : STD_LOGIC_VECTOR) return STRING is
- begin
- return to_hstring (to_stdulogicvector (value));
- end function to_hstring;
-
- function to_ostring (value : STD_LOGIC_VECTOR) return STRING is
- begin
- return to_ostring (to_stdulogicvector (value));
- end function to_ostring;
-
- -- rtl_synthesis on
- function maximum (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- begin -- function maximum
- if L > R then return L;
- else return R;
- end if;
- end function maximum;
-
- -- std_logic_vector output
- function minimum (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
- begin -- function minimum
- if L > R then return R;
- else return L;
- end if;
- end function minimum;
-
- function maximum (L, R : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- begin -- function maximum
- if L > R then return L;
- else return R;
- end if;
- end function maximum;
-
- -- std_logic_vector output
- function minimum (L, R : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
- begin -- function minimum
- if L > R then return R;
- else return L;
- end if;
- end function minimum;
-
- function maximum (L, R : STD_ULOGIC) return STD_ULOGIC is
- begin -- function maximum
- if L > R then return L;
- else return R;
- end if;
- end function maximum;
-
- -- std_logic_vector output
- function minimum (L, R : STD_ULOGIC) return STD_ULOGIC is
- begin -- function minimum
- if L > R then return R;
- else return L;
- end if;
- end function minimum;
-end package body std_logic_1164_additions;
Index: trunk/source/tb_pkg_body.vhd
===================================================================
--- trunk/source/tb_pkg_body.vhd (revision 13)
+++ trunk/source/tb_pkg_body.vhd (nonexistent)
@@ -1,1871 +0,0 @@
--------------------------------------------------------------------------------
--- Copyright 2007 Ken Campbell
--------------------------------------------------------------------------------
--- $Author: sckoarn $
---
--- $Date: 2008-02-24 01:34:11 $
---
--- $Name: not supported by cvs2svn $
---
--- $Id: tb_pkg_body.vhd,v 1.3 2008-02-24 01:34:11 sckoarn Exp $
---
--- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/tb_pkg_body.vhd,v $
---
--- Description : The the testbench package body file.
--- Initial GNU release.
---
-------------------------------------------------------------------------------
---This file is part of The VHDL Test Bench.
---
--- The VHDL Test Bench 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 2 of the License, or
--- (at your option) any later version.
---
--- The VHDL Test Bench 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 The VHDL Test Bench; if not, write to the Free Software
--- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------------
--- Revision History:
--- $Log: not supported by cvs2svn $
--- Revision 1.2 2007/09/02 04:04:04 sckoarn
--- Update of version 1.2 tb_pkg
--- See documentation for details
---
--- Revision 1.1.1.1 2007/04/06 04:06:48 sckoarn
--- Import of the vhld_tb
---
---
--------------------------------------------------------------------------------
-
-package body tb_pkg is
-
--------------------------------------------------------------------------------
--- FUNCTION Defs
--------------------------------------------------------------------------------
--- is_digit
- function is_digit(constant c: in character) return boolean is
- variable rtn : boolean;
- begin
- if (c >= '0' and c <= '9') then
- rtn := true;
- else
- rtn := false;
- end if;
- return rtn;
- end is_digit;
---------------------------------------
--- is_space
- function is_space(constant c: in character) return boolean is
- variable rtn : boolean;
- begin
- if(c = ' ' or c = ht) then
- rtn := true;
- else
- rtn := false;
- end if;
- return rtn;
- end is_space;
-------------------------------------------------------------------------------
--- to_char
- function ew_to_char(int: integer) return character is
- variable c: character;
- begin
- c := nul;
- case int is
- when 0 => c := '0';
- when 1 => c := '1';
- when 2 => c := '2';
- when 3 => c := '3';
- when 4 => c := '4';
- when 5 => c := '5';
- when 6 => c := '6';
- when 7 => c := '7';
- when 8 => c := '8';
- when 9 => c := '9';
- when 10 => c := 'A';
- when 11 => c := 'B';
- when 12 => c := 'C';
- when 13 => c := 'D';
- when 14 => c := 'E';
- when 15 => c := 'F';
- when others =>
- assert(false)
- report LF & "Error: ew_to_char was given a non Number didgit."
- severity failure;
- end case;
-
- return c;
- end ew_to_char;
-
--------------------------------------------------------------------------------
--- to_string function integer
- function to_str(int: integer) return string is
- begin
- return ew_to_str(int,dec) ;
- end to_str ;
-
--------------------------------------------------------------------------------
--- ew_str_cat
- function ew_str_cat(s1: stm_text;
- s2: text_field) return stm_text is
-
- variable i: integer;
- variable j: integer;
- variable sc: stm_text;
-
- begin
- sc := s1;
- i := 1;
- while(sc(i) /= nul) loop
- i := i + 1;
- end loop;
- j := 1;
- while(s2(j) /= nul) loop
- sc(i) := s2(j);
- i := i + 1;
- j := j + 1;
- end loop;
-
- return sc;
- end ew_str_cat;
-
--------------------------------------------------------------------------------
--- fld_len field length
--- inputs : string of type text_field
--- return : integer number of non 'nul' chars
-function fld_len(s : in text_field) return integer is
- variable i: integer := 1;
- begin
- while(s(i) /= nul) loop
- i := i + 1;
- end loop;
- return (i - 1);
- end fld_len;
-------------------------------------------------------------------------------
--- c2int convert character to integer
-function c2int(c: in character) return integer is
- variable i: integer;
-begin
- i := -1;
- case c is
- when '0' => i := 0;
- when '1' => i := 1;
- when '2' => i := 2;
- when '3' => i := 3;
- when '4' => i := 4;
- when '5' => i := 5;
- when '6' => i := 6;
- when '7' => i := 7;
- when '8' => i := 8;
- when '9' => i := 9;
- when others =>
- assert(false)
- report LF & "Error: c2int was given a non Number didgit."
- severity failure;
- end case;
- return i;
-end c2int;
--------------------------------------------------------------------------------
--- str2integer Convert a string to integer number.
--- inputs : string
--- output : int value
-function str2integer(str: in string) return integer is
- variable l: integer;
- variable j: integer := 1;
- variable rtn: integer := 0;
-begin
- l := fld_len(str);
-
- for i in l downto 1 loop
- rtn := rtn + (c2int(str(j)) *(10**(i - 1)));
- j := j + 1;
- end loop;
-
- return rtn;
-end str2integer;
--------------------------------------------------------------------------------
--- hex2integer convert hex Stimulus field to integer
--- inputs : string of type text_field containing only Hex numbers
--- return : integer value
-function hex2integer(hex_number: in text_field;
- file_name: in text_line;
- line: in integer) return integer is
- variable len: integer;
- variable temp_field: text_field;
- variable temp_int: integer;
- variable power: integer;
- variable int_number: integer;
- begin
- len := fld_len(hex_number);
- power := 0;
- temp_int := 0;
- for i in len downto 1 loop
- case hex_number(i) is
- when '0' =>
- int_number := 0;
- when '1' =>
- int_number := 1;
- when '2' =>
- int_number := 2;
- when '3' =>
- int_number := 3;
- when '4' =>
- int_number := 4;
- when '5' =>
- int_number := 5;
- when '6' =>
- int_number := 6;
- when '7' =>
- int_number := 7;
- when '8' =>
- int_number := 8;
- when '9' =>
- int_number := 9;
- when 'a' | 'A'=>
- int_number := 10;
- when 'b' | 'B'=>
- int_number := 11;
- when 'c' | 'C'=>
- int_number := 12;
- when 'd' | 'D'=>
- int_number := 13;
- when 'e' | 'E'=>
- int_number := 14;
- when 'f' | 'F'=>
- int_number := 15;
- when others =>
- assert(false)
- report LF & "Error: hex2integer found non Hex didgit on line "
- & (integer'image(line)) & " of file " & file_name
- severity failure;
- end case;
-
- temp_int := temp_int + (int_number *(16 ** power));
- power := power + 1;
- end loop;
-
- return temp_int;
- end hex2integer;
--------------------------------------------------------------------------------
--- convert character to 4 bit vector
--- input character
--- output std_logic_vector 4 bits
-function c2std_vec(c: in character) return std_logic_vector is
-begin
- case c is
- when '0' => return "0000";
- when '1' => return "0001";
- when '2' => return "0010";
- when '3' => return "0011";
- when '4' => return "0100";
- when '5' => return "0101";
- when '6' => return "0110";
- when '7' => return "0111";
- when '8' => return "1000";
- when '9' => return "1001";
- when 'a' | 'A' => return "1010";
- when 'b' | 'B' => return "1011";
- when 'c' | 'C' => return "1100";
- when 'd' | 'D' => return "1101";
- when 'e' | 'E' => return "1110";
- when 'f' | 'F' => return "1111";
- when others =>
- assert(false)
- report LF & "Error: c2std_vec found non Hex didgit on file line "
- severity failure;
- return "XXXX";
- end case;
-end c2std_vec;
--------------------------------------------------------------------------------
--- std_vec2c convert 4 bit std_vector to a character
--- input std_logic_vector 4 bits
--- output character
-function std_vec2c(vec: in std_logic_vector(3 downto 0)) return character is
-begin
- case vec is
- when "0000" => return '0';
- when "0001" => return '1';
- when "0010" => return '2';
- when "0011" => return '3';
- when "0100" => return '4';
- when "0101" => return '5';
- when "0110" => return '6';
- when "0111" => return '7';
- when "1000" => return '8';
- when "1001" => return '9';
- when "1010" => return 'A';
- when "1011" => return 'B';
- when "1100" => return 'C';
- when "1101" => return 'D';
- when "1110" => return 'E';
- when "1111" => return 'F';
- when others =>
- assert(false)
- report LF & "Error: std_vec2c found non-binary didgit in vec "
- severity failure;
- return 'X';
- end case;
-end std_vec2c;
--------------------------------------------------------------------------------
--- bin2integer convert bin Stimulus field to integer
--- inputs : string of type text_field containing only binary numbers
--- return : integer value
-function bin2integer(bin_number: in text_field;
- file_name: in text_line;
- line: in integer) return integer is
- variable len: integer;
- variable temp_field: text_field;
- variable temp_int: integer;
- variable power: integer;
- variable int_number: integer;
- begin
- len := fld_len(bin_number);
- power := 0;
- temp_int := 0;
- for i in len downto 1 loop
- case bin_number(i) is
- when '0' =>
- int_number := 0;
- when '1' =>
- int_number := 1;
- when others =>
- assert(false)
- report LF & "Error: bin2integer found non Binary didgit on line "
- & (integer'image(line)) & " of file " & file_name
- severity failure;
- end case;
-
- temp_int := temp_int + (int_number *(2 ** power));
- power := power + 1;
- end loop;
-
- return temp_int;
- end bin2integer;
--------------------------------------------------------------------------------
--- stim_to_integer convert Stimulus field to integer
--- inputs : string of type text_field "stimulus format of number"
--- return : integer value
-function stim_to_integer(field: in text_field;
- file_name: in text_line;
- line: in integer) return integer is
- variable len: integer;
- variable text: text_field;
- variable value: integer := 1;
- variable temp_str : string(1 to 48);
- begin
- len := fld_len(field);
-
- case field(1) is
- when 'x' | 'h' =>
- value := 2;
- while(field(value) /= nul) loop
- temp_str(value - 1) := field(value);
- value := value + 1;
- end loop;
- value := hex2integer(temp_str,file_name,line);
- when 'b' =>
- value := 2;
- while(field(value) /= nul) loop
- temp_str(value - 1) := field(value);
- value := value + 1;
- end loop;
- value := bin2integer(temp_str,file_name,line);
- when others =>
--- value := from_string(field(1 to len));
- value := str2integer(field);
- end case;
- return value;
- end stim_to_integer;
-
--------------------------------------------------------------------------------
--- to_str function with base parameter
--- Convert integer to number base
- function ew_to_str(int: integer; b: base) return text_field is
-
- variable temp : text_field ;
- variable temp1 : text_field ;
- variable radix : integer := 0;
- variable num : integer := 0;
- variable power : integer := 1;
- variable len : integer := 1;
- variable pre : string(1 to 2);
- variable i : integer;
- variable j : integer;
- variable vec : std_logic_vector(31 downto 0);
-
- begin
-
- num := int;
- temp := (others => nul);
- case b is
- when bin =>
- radix := 2; -- depending on what
- pre := "0b";
- when oct =>
- radix := 8; -- base the number is
- pre := "0o";
- when hex =>
- radix := 16; -- to be displayed as
- pre := "0x";
- when dec =>
- radix := 10; -- choose a radix range
- pre := (others => nul);
- end case ;
- -- Now jump through Hoops because of sign
- if(num < 0 and b = hex) then
- vec := std_logic_vector(conv_unsigned(int, 32));
- temp(1) := std_vec2c(vec(31 downto 28));
- temp(2) := std_vec2c(vec(27 downto 24));
- temp(3) := std_vec2c(vec(23 downto 20));
- temp(4) := std_vec2c(vec(19 downto 16));
- temp(5) := std_vec2c(vec(15 downto 12));
- temp(6) := std_vec2c(vec(11 downto 8));
- temp(7) := std_vec2c(vec(7 downto 4));
- temp(8) := std_vec2c(vec(3 downto 0));
- else
- while num >= radix loop -- determine how many
- len := len + 1; -- characters required
- num := num / radix; -- to represent the
- end loop ; -- number.
- for i in len downto 1 loop -- convert the number to
- temp(i) := ew_to_char(int/power mod radix); -- a string starting
- power := power * radix; -- with the right hand
- end loop ; -- side.
- end if;
- -- add prefix if is one
- if(pre(1) /= nul) then
- temp1 := temp;
- i := 1;
- j := 3;
- temp(1 to 2) := pre;
- while(temp1(i) /= nul) loop
- temp(j) := temp1(i);
- i := i + 1;
- j := j + 1;
- end loop;
- end if;
-
- return temp;
-
- end ew_to_str ;
-
--------------------------------------------------------------------------------
--- Procedure to print instruction records to stdout *for debug*
- procedure print_inst(variable inst : in stim_line_ptr) is
- variable l: text_line;
- variable l_i: integer := 1;
- variable j: integer := 1;
- begin
- while (inst.instruction(j) /= nul) loop
- l(l_i) := inst.instruction(j);
- j := j +1;
- l_i := l_i + 1;
- end loop;
-
- l(l_i) := ' ';
- l_i := l_i + 1;
- j := 1;
- -- field one
- if(inst.inst_field_1(1) /= nul) then
- while (inst.inst_field_1(j) /= nul) loop
- l(l_i) := inst.inst_field_1(j);
- j := j +1;
- l_i := l_i + 1;
- end loop;
- l(l_i) := ' ';
- l_i := l_i + 1;
- j := 1;
- -- field two
- if(inst.inst_field_2(1) /= nul) then
- while (inst.inst_field_2(j) /= nul) loop
- l(l_i) := inst.inst_field_2(j);
- j := j +1;
- l_i := l_i + 1;
- end loop;
- l(l_i) := ' ';
- l_i := l_i + 1;
- j := 1;
- -- field three
- if(inst.inst_field_3(1) /= nul) then
- while (inst.inst_field_3(j) /= nul) loop
- l(l_i) := inst.inst_field_3(j);
- j := j +1;
- l_i := l_i + 1;
- end loop;
- l(l_i) := ' ';
- l_i := l_i + 1;
- j := 1;
- -- field four
- if(inst.inst_field_4(1) /= nul) then
- while (inst.inst_field_4(j) /= nul) loop
- l(l_i) := inst.inst_field_4(j);
- j := j +1;
- l_i := l_i + 1;
- end loop;
- end if;
- end if;
- end if;
- end if;
- print(l);
-
- print(" Sequence Number: " & to_str(inst.line_number) &
- " File Line Number: " & to_str(inst.file_line));
- if(inst.num_of_lines > 0) then
- print(" Number of Lines: " & to_str(inst.num_of_lines));
- end if;
- end print_inst;
-
---------------------------------------------------------------------------------
--- access_variable
--- inputs:
--- Text field containing variable
--- outputs:
--- value $VAR returns Value of VAR
--- value VAR returns index of VAR
---
--- valid is 1 if valid 0 if not
- procedure access_variable(variable var_list : in var_field_ptr;
- variable var : in text_field;
- variable value : out integer;
- variable valid : out integer) is
- variable l : integer;
- variable l_2 : integer;
- variable var_ptr : var_field_ptr;
- variable temp_field : text_field;
- variable ptr : integer := 0; -- 0 is index, 1 is pointer
- begin
- l := fld_len(var);
- valid := 0;
- -- if the variable is a special
- if(var(1) = '=') then
- value := 0;
- valid := 1;
- elsif(var(1 to 2) = ">=") then
- value := 4;
- valid := 1;
- elsif(var(1 to 2) = "<=") then
- value := 5;
- valid := 1;
- elsif(var(1) = '>') then
- value := 1;
- valid := 1;
- elsif(var(1) = '<') then
- value := 2;
- valid := 1;
- elsif(var(1 to 2) = "!=") then
- value := 3;
- valid := 1;
-
- else
- if(var(1) = '$') then
- ptr := 1; -- this is a pointer
- for i in 2 to l loop
- temp_field(i-1) := var(i);
- end loop;
- else
- temp_field := var;
- end if;
-
- var_ptr := var_list;
- while(var_ptr.next_rec /= null) loop
- -- if we have a match
- if(temp_field = var_ptr.var_name) then
- if(ptr = 1) then
- value := var_ptr.var_value;
- valid := 1;
- else
- value := var_ptr.var_index;
- valid := 1;
- end if;
- exit;
- end if;
- var_ptr := var_ptr.next_rec;
- end loop;
-
- -- if we have a match and was the last record
- if(var_ptr.next_rec = null and temp_field = var_ptr.var_name) then
- if(ptr = 1) then
- value := var_ptr.var_value;
- valid := 1;
- else
- value := var_ptr.var_index;
- valid := 1;
- end if;
- end if;
- end if;
- end access_variable;
---------------------------------------------------------------------------------
--- index_variable
--- inputs:
--- index: the index of the variable being accessed
--- outputs:
--- Variable Value
--- valid is 1 if valid 0 if not
- procedure index_variable(variable var_list : in var_field_ptr;
- variable index : in integer;
- variable value : out integer;
- variable valid : out integer) is
- variable ptr: var_field_ptr;
- begin
- ptr := var_list;
- valid := 0;
- while(ptr.next_rec /= null) loop
- if(ptr.var_index = index) then
- value := ptr.var_value;
- valid := 1;
- exit;
- end if;
- ptr := ptr.next_rec;
- end loop;
- if(ptr.var_index = index) then
- value := ptr.var_value;
- valid := 1;
- end if;
- end index_variable;
-
---------------------------------------------------------------------------------
--- update_variable
--- inputs:
--- index: the index of the variable being updated
--- outputs:
--- valid is 1 if valid 0 if not
- procedure update_variable(variable var_list : in var_field_ptr;
- variable index : in integer;
- variable value : in integer;
- variable valid : out integer) is
- variable ptr: var_field_ptr;
- begin
- ptr := var_list;
- valid := 0;
- while(ptr.next_rec /= null) loop
- if(ptr.var_index = index) then
- ptr.var_value := value;
- valid := 1;
- exit;
- end if;
- ptr := ptr.next_rec;
- end loop;
- -- check the current one
- if(ptr.var_index = index) then
- ptr.var_value := value;
- valid := 1;
- end if;
- end update_variable;
-
--------------------------------------------------------------------------------
--- Read a line from a file
--- inputs : file of type text
--- outputs : The line of type text_line
- procedure file_read_line(file file_name: text;
- variable file_line: out text_line
- ) is
- variable index: integer; -- index into string
- variable rline: line;
-
- begin
-
- index := 1; -- set index to begin of string
- file_line := (others => nul);
- if(not endfile(file_name)) then
- readline(file_name,rline);
-
- while(rline'right /= (index - 1) and rline'length /= 0) loop
- file_line(index) := rline(index);
- index := index + 1;
- end loop;
- end if;
- end file_read_line;
-
- ------------------------------------------------------------------------------
- -- procedure to break a line down in to text fields
- procedure tokenize_line(variable text_line: in text_line;
- variable token1: out text_field;
- variable token2: out text_field;
- variable token3: out text_field;
- variable token4: out text_field;
- variable token5: out text_field;
- variable token6: out text_field;
- variable token7: out text_field;
- variable txt_ptr: out stm_text_ptr;
- variable valid: out integer) is
- variable token_index: integer := 0;
- variable current_token: text_field;
- variable token_number: integer := 0;
- variable c: string(1 to 2);
- variable comment_found: integer := 0;
- variable txt_found: integer := 0;
- variable j: integer;
-
- begin
- -- null outputs
- token1 := (others => nul);
- token2 := (others => nul);
- token3 := (others => nul);
- token4 := (others => nul);
- token5 := (others => nul);
- token6 := (others => nul);
- token7 := (others => nul);
- txt_ptr := null;
- valid := 0;
- txt_found := 0;
- j := 1;
-
- -- loop for max number of char
- for i in 1 to text_line'high loop
- -- collect for comment test ** assumed no line will be max 256
- c(1) := text_line(i);
- c(2) := text_line(i + 1); -- or this line will blow up
- if(c = "--") then
- comment_found := 1;
- exit;
- end if;
- -- if is begin text char '"'
- if(c(1) = '"') then --" <-- this double quote is just to fix highlighting.
- txt_found := 1;
- txt_ptr := new stm_text;
- next;
- end if;
-
- -- if we have found a txt string
- if (txt_found = 1 and text_line(i) /= nul) then
- -- if string too long, prevent tool hang, truncate and notify
- if(j > c_stm_text_len) then
- print("tokenize_line: truncated txt line, it was larger than c_stm_text_len");
- exit;
- end if;
- txt_ptr(j) := text_line(i);
- j := j + 1;
- -- if is a character store in the right token
- elsif(is_space(text_line(i)) = false and text_line(i) /= nul) then
- token_index := token_index + 1;
- current_token(token_index) := text_line(i);
- -- else is a space, deal with pointers
- elsif(is_space(text_line(i + 1)) = false and text_line(i + 1) /= nul) then
- case token_number is
- when 0 =>
- if(token_index /= 0) then
- token1 := current_token;
- current_token := (others => nul);
- token_number := 1;
- valid := 1;
- token_index := 0;
- end if;
- when 1 =>
- token2 := current_token;
- current_token := (others => nul);
- token_number := 2;
- valid := 2;
- token_index := 0;
- when 2 =>
- token3 := current_token;
- current_token := (others => nul);
- token_number := 3;
- valid := 3;
- token_index := 0;
- when 3 =>
- token4 := current_token;
- current_token := (others => nul);
- token_number := 4;
- valid := 4;
- token_index := 0;
- when 4 =>
- token5 := current_token;
- current_token := (others => nul);
- token_number := 5;
- valid := 5;
- token_index := 0;
- when 5 =>
- token6 := current_token;
- current_token := (others => nul);
- token_number := 6;
- valid := 6;
- token_index := 0;
- when 6 =>
- token7 := current_token;
- current_token := (others => nul);
- token_number := 7;
- valid := 7;
- token_index := 0;
- when 7 =>
- when others =>
- null;
- end case;
- end if;
- -- break from loop if is null
- if(text_line(i) = nul) then
- if(token_index /= 0) then
- case token_number is
- when 0 =>
- token1 := current_token;
- valid := 1;
- when 1 =>
- token2 := current_token;
- valid := 2;
- when 2 =>
- token3 := current_token;
- valid := 3;
- when 3 =>
- token4 := current_token;
- valid := 4;
- when 4 =>
- token5 := current_token;
- valid := 5;
- when 5 =>
- token6 := current_token;
- valid := 6;
- when 6 =>
- token7 := current_token;
- valid := 7;
- when others =>
- null;
- end case;
- end if;
- exit;
- end if;
- end loop;
- -- did we find a comment and there is a token
- if(comment_found = 1) then
- if(token_index /= 0) then
- case token_number is
- when 0 =>
- token1 := current_token;
- valid := 1;
- when 1 =>
- token2 := current_token;
- valid := 2;
- when 2 =>
- token3 := current_token;
- valid := 3;
- when 3 =>
- token4 := current_token;
- valid := 4;
- when 4 =>
- token5 := current_token;
- valid := 5;
- when 5 =>
- token6 := current_token;
- valid := 6;
- when 6 =>
- token7 := current_token;
- valid := 7;
- when others =>
- null;
- end case;
- end if;
- end if;
- end tokenize_line;
--------------------------------------------------------------------------------
--- Add a new instruction to the instruction list
--- inputs : the linked list of instructions
--- the instruction
--- the number of args
--- outputs : Updated instruction set linked list
- procedure define_instruction(variable inst_set: inout inst_def_ptr;
- constant inst: in string;
- constant args: in integer) is
- variable v_inst_ptr: inst_def_ptr;
- variable v_prev_ptr: inst_def_ptr;
- variable v_new_ptr: inst_def_ptr;
- variable v_temp_inst: inst_def_ptr;
- variable v_length: integer;
- variable v_list_size: integer;
- variable v_dup_error: boolean;
-
- begin
- assert(inst'high <= max_field_len)
- report LF & "Error: Creation of Instruction of length greater than Max_field_len attemped!!" &
- LF & "This Max is currently set to " & (integer'image(max_field_len))
- severity failure;
- -- get to the last element and test is not exsiting
- v_temp_inst := inst_set;
- v_inst_ptr := inst_set;
- -- zero the size
- v_list_size := 0;
- while(v_inst_ptr /= null) loop
- -- if there is a chance of a duplicate command
- if(v_inst_ptr.instruction_l = inst'high) then
- v_dup_error := true;
- for i in 1 to inst'high loop
- if(v_inst_ptr.instruction(i) /= inst(i)) then
- v_dup_error := false;
- end if;
- end loop;
- -- if we find a duplicate, die
- assert(v_dup_error = false)
- report LF & "Error: Duplicate instruction definition attempted!"
- severity failure;
- end if;
- v_prev_ptr := v_inst_ptr; -- store for pointer updates
- v_inst_ptr := v_inst_ptr.next_rec;
- v_list_size := v_list_size + 1;
- end loop;
-
- -- add the new instruction
- v_new_ptr := new inst_def;
- -- if this is the first command return new pointer
- if(v_list_size = 0) then
- v_temp_inst := v_new_ptr;
- -- else write new pointer to next_rec
- else
- v_prev_ptr.next_rec := v_new_ptr;
- end if;
- v_new_ptr.instruction_l := inst'high;
- v_new_ptr.params := args;
- -- copy the instruction text into field
- for i in 1 to v_new_ptr.instruction_l loop
- v_new_ptr.instruction(i) := inst(i);
- end loop;
- -- return the pointer
- inst_set := v_temp_inst;
-
- end define_instruction;
-
---------------------------------------------------------------------------------
--- Check for valid instruction in the list of instructions
-procedure check_valid_inst(variable inst : in text_field;
- variable inst_set : in inst_def_ptr;
- variable token_num: in integer;
- variable line_num : in integer;
- variable name : in text_line) is
- variable l : integer := 0;
- variable seti: inst_def_ptr;
- variable match: integer := 0;
- variable ilv: integer := 0; -- inline variable
- begin
- -- create useable pointer
- seti := inst_set;
- -- count up the characters in inst
- l := fld_len(inst);
- -- if this is a referance variable -- handle in add variable Proc
- if(inst(l) = ':') then
- match := 1;
- ilv := 1;
- else
- -- process list till null next
- while (seti.next_rec /= null) loop
- if(seti.instruction_l = l) then
- match := 1;
- for j in 1 to l loop
- if(seti.instruction(j) /= inst(j)) then
- match := 0;
- end if;
- end loop;
- end if;
- if(match = 0) then
- seti := seti.next_rec;
- else
- exit;
- end if;
- end loop;
- -- check current one
- if(seti.instruction_l = l and match = 0) then
- match := 1;
- for j in 1 to l loop
- if(seti.instruction(j) /= inst(j)) then
- match := 0;
- end if;
- end loop;
- end if;
- end if;
-
- -- if we had a match, check the number of paramiters
- if(match = 1 and ilv = 0) then
- assert(seti.params = (token_num - 1))
- report LF & "Error: Undefined Instruction was found, incorrect number of fields passed!" & LF &
- "This is found on line " & (integer'image(line_num)) & " in file " & name & LF
- severity failure;
- end if;
-
- -- if we find a duplicate, die
- assert(match = 1)
- report LF & "Error: Undefined Instruction on line " & (integer'image(line_num)) &
- " found in input file " & name & LF
- severity failure;
- end check_valid_inst;
-
---------------------------------------------------------------------------------
--- add_variable
--- This procedure adds a variable to the variable list. This is localy
--- available at this time.
-procedure add_variable(variable var_list : inout var_field_ptr;
- variable p1 : in text_field; -- should be var name
- variable p2 : in text_field; -- should be value
- variable token_num : in integer;
- variable sequ_num : in integer;
- variable line_num : in integer;
- variable name : in text_line;
- variable length : in integer) is
-
- variable temp_var: var_field_ptr;
- variable current_ptr: var_field_ptr;
- variable index: integer := 1;
-
- begin
- -- if this is NOT the first one
- if(var_list /= null) then
- current_ptr := var_list;
- index := index + 1;
- if(p1(length) /= ':') then -- is not an inline variable
- while(current_ptr.next_rec /= null) loop
- -- if we have defined the current before then die
- assert(current_ptr.var_name /= p1)
- report LF & "Error: Attemping to add a duplicate Variable definition "
- & " on line " & (integer'image(line_num)) & " of file " & name
- severity failure;
-
- current_ptr := current_ptr.next_rec;
- index := index + 1;
- end loop;
- -- if we have defined the current before then die. This checks the last one
- assert(current_ptr.var_name /= p1)
- report LF & "Error: Attemping to add a duplicate Variable definition "
- & " on line " & (integer'image(line_num)) & " of file " & name
- severity failure;
-
- temp_var := new var_field;
- temp_var.var_name := p1; -- direct write of text_field
- temp_var.var_value := stim_to_integer(p2,name,line_num); -- convert text_field to integer
- temp_var.var_index := index;
- current_ptr.next_rec := temp_var;
- else
- while(current_ptr.next_rec /= null) loop
- -- if we have defined the current before then die
- assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
- report LF & "Error: Attemping to add a duplicate Inline Variable definition "
- & " on line " & (integer'image(line_num)) & " of file " & name
- severity failure;
-
- current_ptr := current_ptr.next_rec;
- index := index + 1;
- end loop;
- -- if we have defined the current before then die. This checks the last one
- assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
- report LF & "Error: Attemping to add a duplicate Inline Variable definition "
- & " on line " & (integer'image(line_num)) & " of file " & name
- severity failure;
-
- temp_var := new var_field;
- temp_var.var_name(1 to (length - 1)) := p1(1 to (length - 1));
- temp_var.var_value := sequ_num;
- temp_var.var_index := index;
- current_ptr.next_rec := temp_var;
- end if;
- -- this is the first one
- else
- if(p1(length) /= ':') then -- is not an inline variable
- temp_var := new var_field;
- temp_var.var_name := p1; -- direct write of text_field
- temp_var.var_index := index;
- temp_var.var_value := stim_to_integer(p2,name,line_num); -- convert text_field to integer
- var_list := temp_var;
- else
- temp_var := new var_field;
- temp_var.var_name(1 to (length - 1)) := p1(1 to (length - 1));
- temp_var.var_value := sequ_num;
- temp_var.var_index := index;
- var_list := temp_var;
- end if;
- end if;
- end add_variable;
---------------------------------------------------------------------------------
--- add_instruction
--- This is the procedure that adds the instruction to the linked list of
--- instructions. Also Variable addition are called and or handled.
--- the instruction sequence Link list.
--- inputs:
--- stim_line_ptr is the pointer to the instruction List
--- inst is the instruction token
--- p1 paramitor one, corrisponds to field one of stimulus
--- p2 paramitor one, corrisponds to field two of stimulus
--- p3 paramitor one, corrisponds to field three of stimulus
--- p4 paramitor one, corrisponds to field four of stimulus
--- p5 paramitor one, corrisponds to field three of stimulus
--- p6 paramitor one, corrisponds to field four of stimulus
--- str_ptr pointer to string for print instruction
--- token_num the number of tokens, including instruction
--- sequ_num is the stimulus file line referance ie program line number
--- line_num Line number in the text file
--- outputs:
--- none. Error will terminate sim
- procedure add_instruction(variable inst_list : inout stim_line_ptr;
- variable var_list : inout var_field_ptr;
- variable inst : in text_field;
- variable p1 : in text_field;
- variable p2 : in text_field;
- variable p3 : in text_field;
- variable p4 : in text_field;
- variable p5 : in text_field;
- variable p6 : in text_field;
- variable str_ptr : in stm_text_ptr;
- variable token_num : in integer;
- variable sequ_num : inout integer;
- variable line_num : in integer;
- variable file_name : in text_line;
- variable file_idx : in integer) is
- variable temp_stim_line: stim_line_ptr;
- variable temp_current: stim_line_ptr;
- variable valid: integer;
- variable l: integer;
- begin
- valid := 1;
- l := fld_len(inst);
- temp_current := inst_list;
- -- take care of special cases
- if(inst(1 to l) = "DEFINE_VAR") then
- l := fld_len(p1);
- -- Add the variable to the Variable pool, not considered an instruction
- add_variable(var_list,p1,p2,token_num,sequ_num,line_num,file_name,l);
- valid := 0; --Removes this from the instruction list
- elsif(inst(l) = ':') then
- add_variable(var_list,inst,p1,token_num,sequ_num,line_num,file_name,l);
- valid := 0;
- end if;
-
- if(valid = 1) then
- -- prepare the new record
- temp_stim_line := new stim_line;
- temp_stim_line.instruction := inst;
- temp_stim_line.inst_field_1 := p1;
- temp_stim_line.inst_field_2 := p2;
- temp_stim_line.inst_field_3 := p3;
- temp_stim_line.inst_field_4 := p4;
- temp_stim_line.inst_field_5 := p5;
- temp_stim_line.inst_field_6 := p6;
- temp_stim_line.txt := str_ptr;
- temp_stim_line.line_number := sequ_num;
- temp_stim_line.file_idx := file_idx;
- temp_stim_line.file_line := line_num;
-
- -- if is not the first instruction
- if(inst_list /= null) then
- while(temp_current.next_rec /= null) loop
- temp_current := temp_current.next_rec;
- end loop;
- temp_current.next_rec := temp_stim_line;
- inst_list.num_of_lines := inst_list.num_of_lines + 1;
- -- other wise is first instruction to be added
- else
- inst_list := temp_stim_line;
- inst_list.num_of_lines := 1;
- end if;
- sequ_num := sequ_num + 1;
--- print_inst(temp_stim_line); -- for debug
- end if;
-
- end add_instruction;
-------------------------------------------------------------------------------
--- test_inst_sequ
--- This procedure accesses the full instruction sequence and checks for valid
--- variables. This is prior to the simulation run start.
- procedure test_inst_sequ(variable inst_sequ : in stim_line_ptr;
- variable file_list : in file_def_ptr;
- variable var_list : in var_field_ptr
- ) is
- variable temp_text_field: text_field;
- variable temp_var: text_field;
- variable inst_ptr: stim_line_ptr;
- variable valid: integer;
- variable line: integer; -- value of the file_line
- variable file_name: text_line;
- variable v_p: integer;
- variable inst : text_field;
- variable txt : stm_text_ptr;
- variable inst_len : integer;
- variable fname : text_line;
- variable file_line : integer;
- variable temp_fn_prt: file_def_ptr;
- variable tmp_int : integer;
-
- begin
- inst_ptr := inst_sequ;
- -- go through all the instructions
- while(inst_ptr.next_rec /= null) loop
- inst := inst_ptr.instruction;
- inst_len := fld_len(inst_ptr.instruction);
- file_line := inst_ptr.file_line;
- line := inst_ptr.file_line;
- -- recover the file name this line came from
- temp_fn_prt := file_list;
- tmp_int := inst_ptr.file_idx;
- while (temp_fn_prt.next_rec /= null) loop
- if(temp_fn_prt.rec_idx = tmp_int) then
- exit;
- end if;
- temp_fn_prt := temp_fn_prt.next_rec;
- end loop;
- for i in 1 to fname'high loop
- file_name(i) := temp_fn_prt.file_name(i);
- end loop;
-
- txt := inst_ptr.txt;
- -- load parameter one
- temp_text_field := inst_ptr.inst_field_1;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric do nothing
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
- null;
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,v_p,valid);
- assert(valid = 1)
- report LF & "Error: First variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter two
- temp_text_field := inst_ptr.inst_field_2;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric do nothing
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
- null;
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,v_p,valid);
- assert(valid = 1)
- report LF & "Error: Second variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter three
- temp_text_field := inst_ptr.inst_field_3;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric do nothing
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
- null;
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,v_p,valid);
- assert(valid = 1)
- report LF & "Error: Third variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter four
- temp_text_field := inst_ptr.inst_field_4;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric do nothing
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b'or is_digit(temp_text_field(1)) = true) then
- null;
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,v_p,valid);
- assert(valid = 1)
- report LF & "Error: Forth variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter five
- temp_text_field := inst_ptr.inst_field_5;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric do nothing
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
- null;
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,v_p,valid);
- assert(valid = 1)
- report LF & "Error: Fifth variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter six
- temp_text_field := inst_ptr.inst_field_6;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric field convert to integer
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
- null;
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,v_p,valid);
- assert(valid = 1)
- report LF & "Error: Sixth variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- point to next record
- inst_ptr := inst_ptr.next_rec;
- end loop;
-
- end test_inst_sequ;
---------------------------------------------------------------------------------
--- The read include file procedure
--- This is the main procedure for reading, parcing, checking and returning
--- the instruction sequence Link list.
- procedure read_include_file(variable name: text_line;
- variable sequ_numb: inout integer;
- variable file_list: inout file_def_ptr;
- variable inst_set: inout inst_def_ptr;
- variable var_list: inout var_field_ptr;
- variable inst_sequ: inout stim_line_ptr;
- variable status: inout integer) is
- variable l: text_line; -- the line
- variable l_num: integer; -- line number file
- variable sequ_line: integer; -- line number program
- variable t1: text_field;
- variable t2: text_field;
- variable t3: text_field;
- variable t4: text_field;
- variable t5: text_field;
- variable t6: text_field;
- variable t7: text_field;
- variable t_txt: stm_text_ptr;
- variable valid: integer;
- variable v_inst_ptr: inst_def_ptr;
- variable v_var_prt: var_field_ptr;
- variable v_sequ_ptr: stim_line_ptr;
- variable v_len: integer;
- variable v_stat: file_open_status;
- variable idx: integer;
- variable v_tmp: text_line;
-
- variable v_tmp_fn_ptr: file_def_ptr;
- variable v_new_fn: integer;
- variable v_tmp_fn: file_def_ptr;
- variable v_txt: stm_text; --stm_text_ptr;
-
- begin
- sequ_line := sequ_numb;
- v_tmp_fn_ptr := file_list;
- -- for linux systems, trailing spaces need to be removed
- -- from file names
- -- copy text string to temp
- for i in 1 to c_stm_text_len loop
- if(name(i) = nul) then
- v_tmp(i) := name(i);
- exit;
- else
- v_tmp(i) := name(i);
- end if;
- end loop;
- --fix up any trailing white space in txt
- idx := 0;
- -- get to the end of the string
- for i in 1 to c_stm_text_len loop
- if(v_tmp(i) /= nul) then
- idx := idx + 1;
- else
- exit;
- end if;
- end loop;
- -- now nul out spaces
- for i in idx downto 1 loop
- if(is_space(v_tmp(i)) = true) then
- v_tmp(i) := nul;
- else
- exit;
- end if;
- end loop;
- -- open include file
- file_open(v_stat, include_file, v_tmp, read_mode);
- if(v_stat /= open_ok) then
- print("Error: Unable to open include file " & name);
- status := 1;
- return;
- end if;
- l_num := 1; -- initialize line number
-
- -- the file is opened, put it on the file name LL
- while (v_tmp_fn_ptr.next_rec /= null) loop
- v_tmp_fn_ptr := v_tmp_fn_ptr.next_rec;
- end loop;
- v_new_fn := v_tmp_fn_ptr.rec_idx + 1;
- v_tmp_fn := new file_def;
- v_tmp_fn_ptr.next_rec := v_tmp_fn;
- v_tmp_fn.rec_idx := v_new_fn;
-
- -- nul the text line
- v_tmp_fn.file_name := (others => nul);
- for i in 1 to name'high loop
- v_tmp_fn.file_name(i) := name(i);
- end loop;
- v_tmp_fn.next_rec := null;
-
-
- v_inst_ptr := inst_set;
- v_var_prt := var_list;
- v_sequ_ptr := inst_sequ;
-
- -- while not the end of file read it
- while(not endfile(include_file)) loop
- file_read_line(include_file,l);
- -- tokenize the line
- tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
- v_len := fld_len(t1);
- if(t1(1 to v_len) = "INCLUDE") then
- print("Nested INCLUDE statement found in " & v_tmp & " on line " &
- (integer'image(l_num)));
- assert(false)
- report LF & "Error: Nested INCLUDE statements are not supported at this time."
- severity failure;
-
- -- if there was valid tokens
- elsif(valid /= 0) then
- check_valid_inst(t1, v_inst_ptr, valid, l_num, name);
- add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,
- sequ_line,l_num,name,v_new_fn);
- end if;
- l_num := l_num + 1;
- end loop; -- end loop read file
- file_close(include_file);
- sequ_numb := sequ_line;
- inst_set := v_inst_ptr;
- var_list := v_var_prt;
- inst_sequ := v_sequ_ptr;
- end read_include_file;
-
---------------------------------------------------------------------------------
--- The read instruction file procedure
--- This is the main procedure for reading, parcing, checking and returning
--- the instruction sequence Link list.
- procedure read_instruction_file(constant file_name: string;
- variable inst_set: inout inst_def_ptr;
- variable var_list: inout var_field_ptr;
- variable inst_sequ: inout stim_line_ptr;
- variable file_list: inout file_def_ptr) is
- variable l: text_line; -- the line
- variable l_num: integer; -- line number file
- variable sequ_line: integer; -- line number program
- variable t1: text_field;
- variable t2: text_field;
- variable t3: text_field;
- variable t4: text_field;
- variable t5: text_field;
- variable t6: text_field;
- variable t7: text_field;
- variable t_txt: stm_text_ptr;
- variable valid: integer;
- variable v_ostat: integer;
- variable v_inst_ptr: inst_def_ptr;
- variable v_var_prt: var_field_ptr;
- variable v_sequ_ptr: stim_line_ptr;
- variable v_len: integer;
- variable v_stat: file_open_status;
- variable v_name: text_line;
- variable v_iname: text_line;
- variable v_tmp_fn: file_def_ptr;
- variable v_fn_idx: integer;
- variable v_idx: integer;
-
- begin
- -- open the stimulus_file and check
- file_open(v_stat, stimulus, file_name, read_mode);
- assert(v_stat = open_ok)
- report LF & "Error: Unable to open stimulus_file " & file_name
- severity failure;
- -- copy file name to type text_line
- for i in 1 to file_name'high loop
- v_name(i) := file_name(i);
- end loop;
- -- the first item on the file names link list
- file_list := null;
- v_tmp_fn := new file_def;
- v_tmp_fn.rec_idx := 1;
- v_fn_idx := 1;
- v_idx := 1;
- -- nul the text line
- v_tmp_fn.file_name := (others => nul);
- for i in 1 to file_name'high loop
- v_tmp_fn.file_name(i) := file_name(i);
- end loop;
- v_tmp_fn.next_rec := null;
-
- l_num := 1;
- sequ_line := 1;
- v_ostat := 0;
-
- v_inst_ptr := inst_set;
- v_var_prt := var_list;
- v_sequ_ptr := inst_sequ;
-
- -- while not the end of file read it
- while(not endfile(stimulus)) loop
- file_read_line(stimulus,l);
- -- tokenize the line
- tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
- v_len := fld_len(t1);
- -- if there is an INCLUDE instruction
- if(t1(1 to v_len) = "INCLUDE") then
- -- if file name is in par2
- if(valid = 2) then
- v_iname := (others => nul);
- for i in 1 to max_field_len loop
- v_iname(i) := t2(i);
- end loop;
- -- elsif the text string is not null
- elsif(t_txt /= null) then
- v_iname := (others => nul);
- for i in 1 to c_stm_text_len loop
- v_iname(i) := t_txt(i);
- if(t_txt(i) = nul) then
- exit;
- end if;
- end loop;
- else
- assert(false)
- report LF & "Error: INCLUDE instruction has not file name included. Found on" & LF &
- "line " & (integer'image(l_num)) & " in file " & file_name & LF
- severity failure;
- end if;
- print("INCLUDE found: Loading file " & v_iname);
- read_include_file(v_iname,sequ_line,v_tmp_fn,v_inst_ptr,v_var_prt,v_sequ_ptr,v_ostat);
- -- if include file not found
- if(v_ostat = 1) then
- exit;
- end if;
- -- if there was valid tokens
- elsif(valid /= 0) then
- check_valid_inst(t1, v_inst_ptr, valid, l_num, v_name);
- add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,
- sequ_line,l_num,v_name,v_fn_idx);
- end if;
- l_num := l_num + 1;
- end loop; -- end loop read file
-
- file_close(stimulus); -- close the file when done
-
- assert(v_ostat = 0)
- report LF & "Include file specified on line " & (integer'image(l_num)) &
- " in file " & file_name &
- " was not found! Test Terminated" & LF
- severity failure;
-
- inst_set := v_inst_ptr;
- var_list := v_var_prt;
- inst_sequ := v_sequ_ptr;
- file_list := v_tmp_fn;
-
- -- Now that all the stimulus is loaded, test for invalid variables
- test_inst_sequ(inst_sequ, v_tmp_fn, var_list);
-
- end read_instruction_file;
-
-------------------------------------------------------------------------------
--- access_inst_sequ
--- This procedure accesses the instruction sequence and returns the parameters
--- as they exsist related to the variables state.
--- INPUTS: inst_sequ link list of instructions from stimulus
--- var_list link list of variables
--- file_list link list of file names
--- sequ_num the sequence number to recover
---
--- OUTPUTS: inst instruction text
--- p1 paramiter 1 in integer form
--- p2 paramiter 2 in integer form
--- p3 paramiter 3 in integer form
--- p4 paramiter 4 in integer form
--- p5 paramiter 5 in integer form
--- p6 paramiter 6 in integer form
--- txt pointer to any text string of this sequence
--- inst_len the lenth of inst in characters
--- fname file name this sequence came from
--- file_line the line number in fname this sequence came from
---
- procedure access_inst_sequ(variable inst_sequ : in stim_line_ptr;
- variable var_list : in var_field_ptr;
- variable file_list : in file_def_ptr;
- variable sequ_num : in integer;
- variable inst : out text_field;
- variable p1 : out integer;
- variable p2 : out integer;
- variable p3 : out integer;
- variable p4 : out integer;
- variable p5 : out integer;
- variable p6 : out integer;
- variable txt : out stm_text_ptr;
- variable inst_len : out integer;
- variable fname : out text_line;
- variable file_line : out integer;
- variable last_num : inout integer;
- variable last_ptr : inout stim_line_ptr
- ) is
- variable temp_text_field: text_field;
- variable temp_var: text_field;
- variable inst_ptr: stim_line_ptr;
- variable valid: integer;
- variable line: integer; -- value of the file_line
- variable file_name: text_line;
- variable tmp_int: integer;
- variable temp_fn_prt: file_def_ptr;
- begin
- -- get to the instruction indicated by sequ_num
- -- check to see if this sequence is before the last
- -- so search from start
- if(last_num > sequ_num) then
- inst_ptr := inst_sequ;
- while(inst_ptr.next_rec /= null) loop
- if(inst_ptr.line_number = sequ_num) then
- exit;
- else
- inst_ptr := inst_ptr.next_rec;
- end if;
- end loop;
- -- else is equal or greater, so search forward
- else
- inst_ptr := last_ptr;
- while(inst_ptr.next_rec /= null) loop
- if(inst_ptr.line_number = sequ_num) then
- exit;
- else
- inst_ptr := inst_ptr.next_rec;
- end if;
- end loop;
- end if;
-
- -- update the last sequence number and record pointer
- last_num := sequ_num;
- last_ptr := inst_ptr;
-
- -- output the instruction and its length
- inst := inst_ptr.instruction;
- inst_len := fld_len(inst_ptr.instruction);
- file_line := inst_ptr.file_line;
- line := inst_ptr.file_line;
- -- recover the file name this line came from
- temp_fn_prt := file_list;
- tmp_int := inst_ptr.file_idx;
- while (temp_fn_prt.next_rec /= null) loop
- if(temp_fn_prt.rec_idx = tmp_int) then
- exit;
- end if;
- temp_fn_prt := temp_fn_prt.next_rec;
- end loop;
- for i in 1 to fname'high loop
- file_name(i) := temp_fn_prt.file_name(i);
- end loop;
-
- txt := inst_ptr.txt;
- -- load parameter one
- temp_text_field := inst_ptr.inst_field_1;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric field convert to integer
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b') then
- p1 := stim_to_integer(temp_text_field,file_name,line);
- elsif(is_digit(temp_text_field(1)) = true) then
- p1 := stim_to_integer(temp_text_field,file_name,line);
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,p1,valid);
- assert(valid = 1)
- report LF & "Error: First variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter two
- temp_text_field := inst_ptr.inst_field_2;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric field convert to integer
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b') then
- p2 := stim_to_integer(temp_text_field,file_name,line);
- elsif(is_digit(temp_text_field(1)) = true) then
- p2 := stim_to_integer(temp_text_field,file_name,line);
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,p2,valid);
- assert(valid = 1)
- report LF & "Error: Second variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter three
- temp_text_field := inst_ptr.inst_field_3;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric field convert to integer
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b') then
- p3 := stim_to_integer(temp_text_field,file_name,line);
- elsif(is_digit(temp_text_field(1)) = true) then
- p3 := stim_to_integer(temp_text_field,file_name,line);
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,p3,valid);
- assert(valid = 1)
- report LF & "Error: Third variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter four
- temp_text_field := inst_ptr.inst_field_4;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric field convert to integer
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b') then
- p4 := stim_to_integer(temp_text_field,file_name,line);
- elsif(is_digit(temp_text_field(1)) = true) then
- p4 := stim_to_integer(temp_text_field,file_name,line);
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,p4,valid);
- assert(valid = 1)
- report LF & "Error: Forth variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter five
- temp_text_field := inst_ptr.inst_field_5;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric field convert to integer
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b') then
- p5 := stim_to_integer(temp_text_field,file_name,line);
- elsif(is_digit(temp_text_field(1)) = true) then
- p5 := stim_to_integer(temp_text_field,file_name,line);
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,p5,valid);
- assert(valid = 1)
- report LF & "Error: Fifth variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- -- load parameter six
- temp_text_field := inst_ptr.inst_field_6;
- if(temp_text_field(1) /= nul) then
- -- if this is a numaric field convert to integer
- if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
- temp_text_field(1) = 'b') then
- p6 := stim_to_integer(temp_text_field,file_name,line);
- elsif(is_digit(temp_text_field(1)) = true) then
- p6 := stim_to_integer(temp_text_field,file_name,line);
- else -- else is a variable, get the value or halt incase of error
- access_variable(var_list,temp_text_field,p6,valid);
- assert(valid = 1)
- report LF & "Error: Sixth variable on stimulus line " & (integer'image(line))
- & " is not valid!!" & LF & "In file " & file_name
- severity failure;
- end if;
- end if;
- end access_inst_sequ;
-
--------------------------------------------------------------------------
--- dump inst_sequ
--- This procedure dumps to the simulation window the current instruction
--- sequence. The whole thing will be dumped, which could be big.
--- ** intended for testbench development debug **
--- procedure dump_inst_sequ(variable inst_sequ : in stim_line_ptr) is
--- variable v_sequ : stim_line_ptr;
--- begin
--- v_sequ := inst_sequ;
--- while(v_sequ.next_rec /= null) loop
--- print("-----------------------------------------------------------------");
--- print("Instruction is " & v_sequ.instruction &
--- " Par1: " & v_sequ.inst_field_1 &
--- " Par2: " & v_sequ.inst_field_2 &
--- " Par3: " & v_sequ.inst_field_3 &
--- " Par4: " & v_sequ.inst_field_4);
--- print("Line Number: " & to_str(v_sequ.line_number) & " File Line Number: " & to_str(v_sequ.file_line) &
--- " File Name: " & v_sequ.file_name);
---
--- v_sequ := v_sequ.next_rec;
--- end loop;
--- -- get the last one
--- print("-----------------------------------------------------------------");
--- print("Instruction is " & v_sequ.instruction & " Par1: " & v_sequ.inst_field_1 &
--- " Par2: " & v_sequ.inst_field_2 & " Par3: " & v_sequ.inst_field_3 &
--- " Par4: " & v_sequ.inst_field_4);
--- print("Line Number: " & to_str(v_sequ.line_number) & " File Line Number: " & to_str(v_sequ.file_line) &
--- " File Name: " & v_sequ.file_name);
--- end dump_inst_sequ;
-
--------------------------------------------------------------------------------
--- Procedure to print messages to stdout
- procedure print(s: in string) is
- variable l: line;
- begin
- write(l, s);
- writeline(output,l);
- end print;
-
--------------------------------------------------------------------------------
--- procedure to print to the stdout the txt pointer
- procedure txt_print(variable ptr: in stm_text_ptr) is
- variable txt_str : stm_text;
- begin
-
- if (ptr /= null) then
- txt_str := (others => nul);
- for i in 1 to c_stm_text_len loop
- if (ptr(i) = nul) then
- exit;
- end if;
- txt_str(i) := ptr(i);
- end loop;
- print(txt_str);
- end if;
- end txt_print;
-
--------------------------------------------------------------------------------
--- procedure to print to the stdout the txt pointer, and
--- sub any variables found
- procedure txt_print_wvar(variable var_list : in var_field_ptr;
- variable ptr : in stm_text_ptr;
- constant b : in base) is
-
- variable i: integer;
- variable j: integer;
- variable k: integer;
- variable txt_str: stm_text;
- variable tmp_str: stm_text;
- variable v1: integer;
- variable valid: integer;
- variable tmp_field: text_field;
- variable tmp_i: integer;
-
- begin
- if(ptr /= null) then
- i := 1;
- j := 1;
- txt_str := (others => nul);
- while(i <= c_stm_text_len and j <= c_stm_text_len) loop
- if(ptr(i) /= '$') then
- txt_str(j) := ptr(i);
- i := i + 1;
- j := j + 1;
- else
- tmp_field := (others => nul);
- tmp_i := 1;
- tmp_field(tmp_i) := ptr(i);
- i := i + 1;
- tmp_i := tmp_i + 1;
- -- parse to the next space
- while(ptr(i) /= ' ' and ptr(i) /= nul) loop
- tmp_field(tmp_i) := ptr(i);
- i := i + 1;
- tmp_i := tmp_i + 1;
- end loop;
- access_variable(var_list,tmp_field,v1,valid);
- assert(valid = 1)
- report LF & "Invalid Variable found in stm_text_ptr: ignoring."
- severity warning;
-
- if(valid = 1) then
-
- txt_str := ew_str_cat(txt_str, ew_to_str(v1, b));
- k := 1;
- while(txt_str(k) /= nul) loop
- k := k + 1;
- end loop;
- j := k;
- end if;
- end if;
- end loop;
- -- print the created string
- print(txt_str);
- end if;
- end txt_print_wvar;
-
-end tb_pkg;
-
Index: trunk/ttb_gen/ttb_gen_plus.tcl
===================================================================
--- trunk/ttb_gen/ttb_gen_plus.tcl (revision 13)
+++ trunk/ttb_gen/ttb_gen_plus.tcl (nonexistent)
@@ -1,907 +0,0 @@
-#! /usr/bin/env wish
-##-------------------------------------------------------------------------------
-##-- Copyright 2007 Ken Campbell
-##-- All Rights Reserved
-##
-## 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 2 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, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-##-------------------------------------------------------------------------------
-##-- $Author: sckoarn $
-##--
-##-- $Date: 2007-09-02 04:01:43 $
-##--
-##-- $Name: not supported by cvs2svn $
-##--
-##-- $Id: ttb_gen_plus.tcl,v 1.1 2007-09-02 04:01:43 sckoarn Exp $
-##--
-##-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/ttb_gen/ttb_gen_plus.tcl,v $
-##--
-##-- Description :
-##-- This application takes a text file containing the definition of a VHDL
-## entity, parses that entity and generates the VHDL Test Bench starting
-## file set. It is a rewrite of the previous ttb_gen_gui to include
-## view of the file.
-##--
-##------------------------------------------------------------------------------
-
-## package requires
-package require Iwidgets 4.0
-
-## set the current version info
-set version "v1.0"
-## put up a title on the main window boarder
-wm title . "TTB Gen Plus $version"
-
-## the location of the template by default
-set template "../source/template_tb_bhv.vhd"
-
-set use_list 0
-
-## Working Directory or vhdl directory
-set workd [frame .wdf]
-set ent_dir [iwidgets::entryfield $workd.cen1 -labeltext "Working Directory"]
-button $workd.br0 -text "Browse" -command {fill_list}
-pack $workd.br0 -side right
-pack $ent_dir -fill x
-pack $workd -fill x -pady 6
-
-## Output directory
-set tlist [frame .lstf]
-set odir [iwidgets::entryfield $tlist.ent1 -labeltext "Output Directory"]
-set lbut [button $tlist.br1 -text "Browse" -command {browsed_from_set $odir $odir}]
-pack $lbut -side right
-pack $odir -fill x
-pack $tlist -fill x
-
-## Template location
-set tdirf [frame .tmpf]
-set tdir [iwidgets::entryfield $tdirf.ent2 -width 60 -labeltext "Template Location"]
-set tbut [button $tdirf.br2 -text "Browse" -command {browse_set_entry $tdir}]
-pack $tbut -side right
-pack $tdir -fill x
-pack $tdirf -fill x -pady 6
-$tdir delete 0 end
-$tdir insert end $template
-$tdir configure -state readonly
-
-## type spec
-set tsf [frame .tsfr]
-set load_but [button $tsf.bt1 -text "Generate" -command ttb_gen]
-set mo_sel [iwidgets::optionmenu $tsf.mode -labeltext "Mode"]
-##$mo_sel insert end Work Recurse List
-$mo_sel insert end "No bhv" "bhv"
-set p_view [iwidgets::feedback $tsf.fb1 -labeltext "Generation Status" -barheight 10]
-set statsVar ""
-##set stat_txt [label $tsf.lb1 -textvariable statsVar]
-set stat_txt [label .lb1 -textvariable statsVar]
-
-pack $load_but -side left
-pack $mo_sel -side left
-pack $p_view -side left
-pack $tsf
-pack $stat_txt -fill x
-
-## create paned window
-set win [iwidgets::panedwindow .pw -width 200 -height 300]
-$win add top -margin 4 -minimum 100
-$win add middle -margin 4 -minimum 100
-$win configure -orient vertical
-$win fraction 80 20
-$win paneconfigure 1 -minimum 60
-## create two locations for objects
-set wtop [$win childsite 0]
-set wbot [$win childsite 1]
-pack $win -fill both -expand yes
-## create two object boxes
-set list_win [iwidgets::selectionbox $wtop.sb -margin 2 -itemscommand load_ent_file \
- -itemslabel "VHDL Files" -selectionlabel "Selected VHDL File"]
-set view_win [iwidgets::scrolledtext $wbot.rts -borderwidth 2 -wrap none]
-pack $list_win -fill both -expand yes
-pack $view_win -fill both -expand yes
-
-## some tags for the view window
-##$view_win tag configure highlite -background #a0b7ce
-$view_win tag configure highlite -background grey80
-
-###########################################################################
-## some debug and help procs
-## Message Error, terminate
-proc msg_error { msg } {
- tk_messageBox -message $msg -type ok
- exit
-}
-###########################################################################
-## Message, continue
-proc dbg_msg { msg } {
- tk_messageBox -message $msg -type ok
-}
-#########################################################################
-## browse and get directory
-## Using extfileselectiondialog get a directory and update the
-## field passed to it
-proc browsed_from_set { src dest } {
- set wdir [$src get]
- if {$wdir == ""} {
- iwidgets::extfileselectiondialog .dsb -modality application -fileson false
- } else {
- iwidgets::extfileselectiondialog .dsb -modality application -fileson false \
- -directory $wdir
- }
-
- if {[.dsb activate]} {
- set dchoice [.dsb get]
- $dest configure -state normal
- $dest delete 0 end
- $dest insert 0 "$dchoice"
- $dest configure -state readonly
- }
- destroy .dsb
-}
-#########################################################################
-## browse and get file name
-## Using extfileselectiondialog get a directory and update the
-## field passed to it
-proc browse_set_entry { dest } {
-iwidgets::extfileselectiondialog .dsb -modality application
-
- if {[.dsb activate]} {
- set dchoice [.dsb get]
- $dest configure -state normal
- $dest delete 0 end
- $dest insert 0 "$dchoice"
- $dest configure -state readonly
- }
- destroy .dsb
-}
-##########################################################################
-## proc pars_pindef
-proc pars_pindef { pin } {
- set pdirection ""
-# dbg_msg $pin
- set spin [split $pin ":"]
- set pname_str [lindex $spin 0]
- set pname [lindex $pname_str 0]
-# dbg_msg "Pin name is $pname"
- set pdirection_str [lindex $spin 1]
-# dbg_msg $pdirection_str
- ## parce out the direction, supporting only 3
- set direction [string first "in " $pdirection_str]
- if {$direction >= 0} {
- set pdirection "in"
- }
- set direction [string first "out " $pdirection_str]
- if {$direction >= 0} {
- set pdirection "out"
- }
- set direction [string first "inout " $pdirection_str]
- if {$direction >= 0} {
- set pdirection "inout"
- }
- if {$pdirection == ""} {
- dbg_msg "Unsuported Pin direction found. \n Suported are IN OUT and INOUT."
- }
-# dbg_msg "Pin direction is $pdirection"
- ## now parce out the type
- ## to overcome the std_logic_vector( # to #); vs (# to #); syntax
- ## check and see if there is a vector spec in this pin with space after
- ## the first bracket
- set vect [string first "( " $pdirection_str]
- if {$vect < 0} {
- set ptype1 [lindex $pdirection_str 1]
- set ptype2 [lindex $pdirection_str 2]
- set ptype3 [lindex $pdirection_str 3]
- set ptype "$ptype1 $ptype2 $ptype3"
- } else {
- set ptype1 [lindex $pdirection_str 1]
- set ptype2 [lindex $pdirection_str 2]
- set ptype3 [lindex $pdirection_str 3]
- set ptype4 [lindex $pdirection_str 4]
- set ptype "$ptype1 $ptype2 $ptype3 $ptype4"
- }
- ##puts $ptype
-
- set last_pin [string first \; $ptype]
- if {$last_pin >= 0} {
- set is_vector [string first ( $ptype]
- ## if there is a vector def
- if {$is_vector >= 0} {
- set temp_v [string first )) $ptype]
- if {$temp_v >= 0} {
- set s_e [expr $last_pin - 2]
- set ptype [string range $ptype 0 $s_e]
- } else {
- set s_e [expr $last_pin - 1]
- set ptype [string range $ptype 0 $s_e]
- }
- } else {
- set temp_v [string first ) $ptype]
- ## found a ); in the last pin def
- if {$temp_v >= 0} {
- set s_e [expr $last_pin - 2]
- set ptype [string range $ptype 0 $s_e]
- } else {
- set s_e [expr $last_pin - 1]
- set ptype [string range $ptype 0 $s_e]
- }
- }
- }
- set ptype [string trim $ptype]
-# dbg_msg "The type is $ptype"
- lappend pdef $pname $pdirection $ptype
- return $pdef
-}
-## end pars_pindef
-
-##--------------------------------------------------------------------------------
-## Write header to file passed
-proc write_header { handle } {
- global version
- ##global scan_date
- set raw_date [clock scan now]
- set scan_date [clock format $raw_date -format "%d %b %Y %T"]
-
- ## so CVS will not modify selections, they have to be chopped up
- set auth "-- \$Auth"
- append auth "or: \$"
- set cvs_date "-- \$dat"
- append cvs_date "e: \$"
- set cvs_name "-- \$Nam"
- append cvs_name "e: \$"
- set cvs_id "-- \$I"
- append cvs_id "d: \$"
- set cvs_source "-- \$Sour"
- append cvs_source "ce: \$"
- set cvs_log "-- \$Lo"
- append cvs_log "g: \$"
-
- puts $handle "-------------------------------------------------------------------------------"
- puts $handle "-- Copyright -----------------------------------"
- puts $handle "-- All Rights Reserved"
- puts $handle "-------------------------------------------------------------------------------"
- puts $handle "$auth"
- puts $handle "--"
- puts $handle "$cvs_date"
- puts $handle "--"
- puts $handle "$cvs_name"
- puts $handle "--"
- puts $handle "$cvs_id"
- puts $handle "--"
- puts $handle "$cvs_source"
- puts $handle "--"
- puts $handle "-- Description :"
- puts $handle "-- This file was generated by TTB Gen Plus $version"
- puts $handle "-- on $scan_date"
- puts $handle "------------------------------------------------------------------------------"
- puts $handle "-- This software contains concepts confidential to ----------------"
- puts $handle "-- ---------. and is only made available within the terms of a written"
- puts $handle "-- agreement."
- puts $handle "-------------------------------------------------------------------------------"
- puts $handle "-- Revision History:"
- puts $handle "$cvs_log"
- puts $handle "--"
- puts $handle "-------------------------------------------------------------------------------"
- puts $handle ""
- }
-
-##########################################################################
-## write Library and use statements
-proc write_lib_statements { handle } {
- puts $handle "library IEEE;"
- puts $handle "library ieee_proposed;"
- puts $handle "library tb_pkg;"
- puts $handle "--possible users libs;"
- puts $handle "use IEEE.STD_LOGIC_1164.all;"
- puts $handle "use IEEE.STD_LOGIC_ARITH.all;"
- puts $handle "use ieee_proposed.STD_LOGIC_1164_additions.all;"
- puts $handle "use std.textio.all;"
- puts $handle "use tb_pkg.tb_pkg.all;"
- puts $handle "--possible users use statement;"
- puts $handle ""
-}
-
-#####################################################################
-## A directory has been selected now fill the list win with VHDL files
-proc fill_list {} {
- global ent_dir odir
- global tlist_ent use_list list_win ts_ent statsVar
- global view_win mo_sel
-
- ## get the user selection
- browsed_from_set $ent_dir $ent_dir
- ## as a default make output dir = input dir
- set tmp_dir [$ent_dir get]
- $odir delete 0 end
- $odir insert end $tmp_dir
- $odir configure -state readonly
-
- ## clear the list window and selection
- $list_win clear items
- $list_win clear selection
- $view_win clear
- ## get the working directory
- set dir [$ent_dir get]
- ## get the list of VHDL files in working directory
- set ftype ".vhd*"
- set file_lst ""
- set file_lst [glob -directory $dir *$ftype]
-
-##puts $file_lst
-
- ## for each of the files in the file_lst
- foreach l $file_lst {
- ## creat string that is just the file name: no path
- set testt $l
- set nstart [string last "/" $l]
- incr nstart
- set name_str [string range $l $nstart end]
- ## insert item on list
- $list_win insert items 1 $name_str
- }
-}
-
-######################################################################
-## load the vhdl file that has just been selected from list_win
-proc load_ent_file {} {
- global ent_dir list_win view_win statsVar
-
- ## update selection with selected item
- $list_win selectitem
- set sel_dx [$list_win curselection]
- if {$sel_dx == ""} {
- return
- }
- ## recover the selected item
- set ln [$list_win get]
- ## Get the working directory
- #puts $ln
- set lp [$ent_dir get]
- ## append the file name
- append lp "/" $ln
- ## if the file does not exist return
- set fexist [file exist $lp]
- if {$fexist == 0} {
- return
- }
- set ent_file [open $lp r]
- ## clear the view_win
- $view_win clear
- set file_list {}
- ## load file to memory
- while {![eof $ent_file]} {
- ## Get a line
- set rline [gets $ent_file]
- lappend file_list $rline
- }
- ## put file in text window and highlite the entity part
- set ent_found 0
- set in_ent 0
- set statsVar ""
- foreach l $file_list {
- if {$in_ent == 0} {
- set ent_def [string first entity $l]
- set ent_is [string first is $l]
- if {$ent_def >= 0 && $ent_is >= 0} {
- set ent_name [lindex $l 1]
- set statsVar "Entity $ent_name found"
- set ent_found 1
- set in_ent 1
- $view_win insert end "$l\n" highlite
- } else {
- $view_win insert end "$l\n"
- }
- } else {
- set ent_def [string first "end $ent_name" $l]
- if {$ent_def >= 0} {
- set end_name [lindex $l 1]
- set end_found 1
- set in_ent 0
- $view_win insert end "$l\n" highlite
- } elseif {[string first "end entity $ent_name" $l] >= 0} {
- set end_name [lindex $l 1]
- set end_found 1
- set in_ent 0
- $view_win insert end "$l\n" highlite
- } else {
- $view_win insert end "$l\n" highlite
- }
- }
- }
- if {$ent_found == 0} {
- set statsVar "No Entity found!!"
- }
-
- ##$view_win import $lp
- ##$view_win yview moveto 1
- ##puts $lp
-}
-
-#########################################################################
-proc ttb_gen {} {
- global mo_sel template ent_dir list_win odir p_view tdir
-
- set template [$tdir get]
-
- $p_view configure -steps 7
- $p_view reset
- ## recover the selected item
- set ln [$list_win get]
- ## Get the working directory
- #puts $ln
- set lp [$ent_dir get]
- ## append the file name
- append lp "/" $ln
-
- set path_text $lp
- set destin_text [$odir get]
- set infile [open $path_text r]
- set file_list list
-
- set tmpcnt 0
-
-##################################################################
-## Read in the file and strip comments as we do
- while {![eof $infile]} {
- ## Get a line
- set rline [gets $infile]
- ## get rid of white space
- set rline [string trim $rline]
- ## Find comment if there
- set cindex [string first -- $rline]
- ## if a comment was found at the start of the line
- if {$cindex == 0 || $rline == ""} {
- set rline [string range $rline 0 [expr $cindex - 1]]
- ##dbg_msg $rline
- if {[llength $rline] > 0} {
- lappend file_list [string tolower $rline]
- }
- ## else was not found so put line in list
- } else {
- lappend file_list [string tolower $rline]
- }
- incr tmpcnt
- }
- $p_view step
- ## collect the library statements
- foreach l $file_list {
- set libpos [string first library $l]
- if {$libpos >= 0} {
- lappend libs_list $l
- }
- }
- ## collect the use statements
- foreach l $file_list {
- set usepos [string first use $l]
- if {$usepos >= 0} {
- lappend use_list $l
- }
- }
- ## check for the entity def
- set ent_found 0
- foreach l $file_list {
- set ent_def [string first entity $l]
- if {$ent_def >= 0} {
- set ent_name [lindex $l 1]
- break
- }
- }
- ## if no ent die
- if {$ent_def < 0} {
- dbg_msg "An entity definition was not found in the file provided."
- ## exit
- }
- $p_view step
- ## check for end entity
- foreach l $file_list {
- lappend ent_list $l
- set end_def [string first end $l]
- if {$end_def >= 0} {
- set end_ent [string first "end $ent_name" $l]
- if {$end_ent >= 0} {
- break
- }
- set end_ent [string first "end entity $ent_name" $l]
- if {$end_ent >= 0} {
- break
- }
- }
- }
- ## if no end die
- if {$end_def < 0} {
- dbg_msg "no end statement found for this entity"
- ## exit
- }
-
- set port_found 0
- ####################################################################
- ## a few checks have been done, and non-relevant stuff stripped off.
- ## now create an arrry of just the pin names and related info
- foreach l $ent_list {
- ## look for the port statement
- if {$port_found == 0} {
- set pfound [string first port $l]
- ## found one now check if there is a pin def in the same line
- if {$pfound >= 0} {
- set port_found 1
- set efound [string first : $l]
- if {$efound >= 0} {
- set line_test [split $l "("]
- if {[llength $line_test] > 1} {
- lappend port_list [lindex $line_test 1]
- }
- }
- }
- } else {
- set efound [string first : $l]
- if {$efound >= 0} {
- lappend port_list $l
- }
- }
- }
- #dbg_msg $port_list
- ## Change the port list into a pin info list
- foreach l $port_list {
- lappend split_pin [pars_pindef $l]
- }
- # dbg_msg $split_pin
- ## calculate the longest pin name in characters
- set name_length 0
- foreach l $split_pin {
- set temp_length [string length [lindex $l 0]]
- if {$temp_length > $name_length} {
- set name_length $temp_length
- }
- }
- #dbg_msg $name_length
- ## Make the name length one bigger
- incr name_length
-
- $p_view step
-#########################################################################
-## Generate the test bench entity.
- ## Create the file name
- set file_type "_tb_ent.vhd"
- set ent_file_name $destin_text
- append ent_file_name "/" $ent_name $file_type
- # dbg_msg $ent_file_name
- ## Create the tb entity name
- set tb_ent_name $ent_name
- set tb_sufix "_tb"
- append tb_ent_name $tb_sufix
-
- ## open and write the header
- set ent_file [open $ent_file_name w+]
- write_header $ent_file
-
- ## write out Library and use statements
- write_lib_statements $ent_file
-
- puts $ent_file "entity $tb_ent_name is"
- puts $ent_file " generic ("
- puts $ent_file " stimulus_file: in string"
- puts $ent_file " )\;"
- puts $ent_file " port ("
-
- ##-----------------------------------------
- # for each pin in the list output the TB ent pin
- set plist_size [llength $split_pin]
- #dbg_msg $plist_size
- set i 1
- foreach l $split_pin {
- set pdirection [lindex $l 1]
- # puts $pdirection
- ## switch on the source pin direction
- switch -exact $pdirection {
- "in" {set tb_ptype "buffer"}
- "out" {set tb_ptype "in"}
- "inout" {set tb_ptype "inout"}
- default {
- msg_error "Should have not got here .. pin direction in entity creation!!"
- }
- }
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- set new_ptype [format ": %-8s" $tb_ptype]
- if {$i != $plist_size} {
- append new_pname $new_ptype [lindex $l 2] ";"
- } else {
- append new_pname $new_ptype [lindex $l 2]
- }
- puts $ent_file $new_pname
- incr i
- }
-
- puts $ent_file " )\;"
- puts $ent_file "end $tb_ent_name;"
- close $ent_file
-
- $p_view step
-##################################################################
-## Generate the top level test bench entity
- ## Create the file name
- set file_type "_ttb_ent.vhd"
- set ent_file_name $destin_text
- append ent_file_name "/" $ent_name $file_type
- # dbg_msg $ent_file_name
- ## Create the tb entity name
- set ttb_ent_name $ent_name
- set ttb_sufix "_ttb"
- append ttb_ent_name $ttb_sufix
-
- ## open and write the header
- set ttb_ent_file [open $ent_file_name w+]
- write_header $ttb_ent_file
-
- puts $ttb_ent_file "library IEEE;"
- puts $ttb_ent_file "library dut_lib;"
- puts $ttb_ent_file "use IEEE.STD_LOGIC_1164.all;"
- puts $ttb_ent_file "use dut_lib.all;"
- puts $ttb_ent_file ""
- puts $ttb_ent_file "entity $ttb_ent_name is"
- puts $ttb_ent_file " generic ("
- puts $ttb_ent_file " stimulus_file: string := \"stm/stimulus_file.stm\""
- puts $ttb_ent_file " )\;"
- puts $ttb_ent_file "end $ttb_ent_name\;"
-
- close $ttb_ent_file
-
- $p_view step
-#################################################################
-## Generate the top level structure
- ## Create the file name
- set file_type "_ttb_str.vhd"
- set str_file_name $destin_text
- append str_file_name "/" $ent_name $file_type
- # dbg_msg $ent_file_name
- ## Create the tb entity name
- set ttb_ent_name $ent_name
- set ttb_sufix "_ttb"
- append ttb_ent_name $ttb_sufix
-
- ## open and write the header
- set ttb_str_file [open $str_file_name w+]
- write_header $ttb_str_file
-
- puts $ttb_str_file ""
- puts $ttb_str_file "architecture struct of $ttb_ent_name is"
- puts $ttb_str_file ""
- puts $ttb_str_file "component $ent_name"
- puts $ttb_str_file " port ("
- ## put out the dut component def
- ###################################################
- # for each pin in the list output the TB ent pin
- set i 1
- foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- set new_ptype [format ": %-8s" [lindex $l 1]]
- if {$i != $plist_size} {
- append new_pname $new_ptype [lindex $l 2] ";"
- } else {
- append new_pname $new_ptype [lindex $l 2]
- }
- puts $ttb_str_file $new_pname
- incr i
- }
- puts $ttb_str_file " )\;"
- puts $ttb_str_file "end component\;"
-
- puts $ttb_str_file ""
- puts $ttb_str_file "component $tb_ent_name"
- puts $ttb_str_file " generic ("
- puts $ttb_str_file " stimulus_file: in string"
- puts $ttb_str_file " )\;"
- puts $ttb_str_file " port ("
- ## put out the tb component def
- ####################################################
- # for each pin in the list output the TB ent pin
- set i 1
- foreach l $split_pin {
- set pdirection [lindex $l 1]
-# dbg_msg $pdirection
- ## switch on the source pin direction
- switch -exact $pdirection {
- "in" {set tb_ptype "buffer"}
- "out" {set tb_ptype "in"}
- "inout" {set tb_ptype "inout"}
- default {
- msg_error "Should have not got here .. pin direction in entity creation!!"
- }
- }
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- set new_ptype [format ": %-8s" $tb_ptype]
- if {$i != $plist_size} {
- append new_pname $new_ptype [lindex $l 2] ";"
- } else {
- append new_pname $new_ptype [lindex $l 2]
- }
- puts $ttb_str_file $new_pname
- incr i
- }
- puts $ttb_str_file " )\;"
- puts $ttb_str_file "end component\;"
- puts $ttb_str_file ""
-
- puts $ttb_str_file "for all: $ent_name use entity dut_lib.$ent_name\(str)\;"
- puts $ttb_str_file "for all: $tb_ent_name use entity work.$tb_ent_name\(bhv)\;"
-
- puts $ttb_str_file ""
- #####################################################
- # for each pin in the list output the TB ent pin
- # generate a signal name
- foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " signal temp_%-${name_length}s" [lindex $l 0]]
- append new_pname ": " [lindex $l 2] ";"
- puts $ttb_str_file $new_pname
- }
-
- puts $ttb_str_file ""
- puts $ttb_str_file "begin"
- puts $ttb_str_file ""
- puts $ttb_str_file "dut: $ent_name"
- puts $ttb_str_file " port map("
- ##-----------------------------------------
- # for each pin in the list output the TB ent pin
- # Generate port map for DUT
- set i 1
- foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- if {$i != $plist_size} {
- append new_pname "=> temp_" [lindex $l 0] ","
- } else {
- append new_pname "=> temp_" [lindex $l 0]
- }
- puts $ttb_str_file $new_pname
- incr i
- }
-
- puts $ttb_str_file " )\;"
- puts $ttb_str_file ""
- puts $ttb_str_file "tb: $tb_ent_name"
- puts $ttb_str_file " generic map("
- puts $ttb_str_file " stimulus_file => stimulus_file"
- puts $ttb_str_file " )"
- puts $ttb_str_file " port map("
- ##-----------------------------------------
- # for each pin in the list output the TB ent pin
- # Generate port map for DUT
- set i 1
- foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- if {$i != $plist_size} {
- append new_pname "=> temp_" [lindex $l 0] ","
- } else {
- append new_pname "=> temp_" [lindex $l 0]
- }
- puts $ttb_str_file $new_pname
- incr i
- }
-
- puts $ttb_str_file " )\;"
- puts $ttb_str_file ""
- puts $ttb_str_file "end struct\;"
- close $ttb_str_file
-
- ######################################################################
- ## Now generate the bhv file from template
-
- if {[$mo_sel get] == "bhv"} {
-
- $p_view step
- set infile [open "$template" r]
-
- while {![eof $infile]} {
- ## Get a line
- set rline [gets $infile]
- lappend temp_file_list $rline
- }
- close $infile
-
- ## strip off the header
- set end_header 0
- foreach l $temp_file_list {
- set comment [string first -- $l]
- if {$comment < 0} {
- set end_header 1
- }
- ## if we found the end of the header
- if {$end_header == 1} {
- lappend template_list $l
- }
- }
-
- ## split the file into two peices, to the point of input initialization
- set i 1
- foreach l $template_list {
- ## check for parsing point
- set mid_point [string first parse_tb1 $l]
- if {$mid_point >= 0} {
- break
- }
-
- if {$i > 2} {
- lappend top_half $l
- }
- incr i
- }
-
- set found 0
- foreach l $template_list {
- if {$found == 1} {
- lappend bottom_half $l
- }
- ## check for parsing point
- set mid_point [string first parse_tb1 $l]
- if {$mid_point >= 0} {
- set found 1
- }
- }
-
- ## Create the file name
- set file_type "_tb_bhv.vhd"
- set bhv_file_name $destin_text
- append bhv_file_name "/" $ent_name $file_type
- # dbg_msg $ent_file_name
-
- ## open and write the header
- set bhv_file [open $bhv_file_name w+]
- write_header $bhv_file
-
- puts $bhv_file ""
- puts $bhv_file "architecture bhv of $tb_ent_name is"
- puts $bhv_file ""
- foreach l $top_half {
- puts $bhv_file $l
- }
-
- puts $bhv_file ""
- ## now generate and write out input initialization
- foreach l $split_pin {
- set temp_def [lindex $l 1]
- set input_def [string first in $temp_def]
- if {$input_def >= 0} {
- set vector [string first vector $l]
- set init_def [format " %-${name_length}s" [lindex $l 0]]
- if {$vector >= 0} {
- append init_def "<= (others => '0')\;"
- } else {
- append init_def "<= '0'\;"
- }
- puts $bhv_file $init_def
- }
- }
- puts $bhv_file ""
- ## now write out the bottem half and termination
- foreach l $bottom_half {
- puts $bhv_file $l
- }
-
- close $bhv_file
- }
- ## put out a terminating message for the user
- dbg_msg "Test bench files were generated in directory:\n $destin_text"
- $p_view step
-}
-## enable pop up console for debug
-bind . {catch {console show}}
-
-##-------------------------------------------------------------------------------
-##-- Revision History:
-##-- $Log: not supported by cvs2svn $
-##--
-##--
-##----------------------------------------------------------------------------
Index: trunk/ttb_gen/ttb_gen_gui.tcl
===================================================================
--- trunk/ttb_gen/ttb_gen_gui.tcl (revision 13)
+++ trunk/ttb_gen/ttb_gen_gui.tcl (nonexistent)
@@ -1,754 +0,0 @@
-##-------------------------------------------------------------------------------
-##-- Copyright 2007 Ken Campbell
-##-- All Rights Reserved
-##
-## 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 2 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, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-##-------------------------------------------------------------------------------
-##-- $Author: sckoarn $
-##--
-##-- $Date: 2007-04-06 04:06:49 $
-##--
-##-- $Name: not supported by cvs2svn $
-##--
-##-- $Id: ttb_gen_gui.tcl,v 1.1.1.1 2007-04-06 04:06:49 sckoarn Exp $
-##--
-##-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/ttb_gen/ttb_gen_gui.tcl,v $
-##--
-##-- Description :
-##-- This application takes a text file containing the definition of a VHDL
-## entity, parses that entity and generates the VHDL Test Bench starting
-## file set. ( This was the first application written by the author
-## in the tcl\tk language, forgive the style.)
-##--
-##------------------------------------------------------------------------------
-## set the current version info
-set ttbgen_version "v1.0"
-## get the time and date from the system
-set raw_date [clock scan now]
-set scan_date [clock format $raw_date -format "%d %b %Y %T"]
-## title and version info for window
-set msg_txt [label .l1 -text "Test Bench Generation Tool $ttbgen_version"];
-pack $msg_txt
-
-## destination spec frame
-set g [frame .dest]
-label $g.lab -text "Destination Directory: " -anchor e
-entry $g.ent -width 20
-pack $g.lab -side left
-pack $g.ent -side left -expand yes -fill x
-
-## source spec frame with browser
-set f [frame .sour]
-label $f.lab -text "Select Generation Source: " -anchor e
-entry $f.ent -width 20
-button $f.but -text "Browse ..." -command "fileDialog $f $f.ent $g.ent"
-pack $f.lab -side left
-pack $f.ent -side left -expand yes -fill x
-pack $f.but -side left
-pack $f -fill x -padx 1c -pady 3
-## pack destination frame
-pack $g -fill x -padx 1c -pady 3
-## check button for optional bhv generation
-checkbutton .b1 -text "Generate the bhv file?" -variable bhv
-pack .b1
-## create and place the buttons frame
-frame .buttons
-pack .buttons -side bottom -fill x -pady 2m
-button .buttons.exit -text "Exit" -command exit
-button .buttons.help -text "Help" -command "show_help $msg_txt"
-button .buttons.gene -text "Generate" -command "ttb_gen $f.ent $g.ent"
-pack .buttons.gene -side left -expand 1
-pack .buttons.help -side left -expand 1
-pack .buttons.exit -side left -expand 1
-
-
-###########################################################################
-## some debug and help procs
-## Message Error, terminate
-proc msg_error { msg } {
- tk_messageBox -message $msg -type ok
- exit
-}
-###########################################################################
-## Message, continue
-proc dbg_msg { msg } {
- tk_messageBox -message $msg -type ok
-}
-##-----------------------------------------------------------------------
-## Help display proc. It changes the Lable at the top of the window to
-## have the following text
-proc show_help { h } {
- $h configure -justify left -text "Test Bench Generation Help \n \n \
- 1) Use Browse to select a source entity VHDL file \n \
- 2) Provide the path to the destination directory \n \
- 3) Check Generate bhv, if behave file should be generated \n \
- 4) Hit the Generate button"
-}
-
-##---------------------------------------------------------------
-## File dialog handler
-proc fileDialog {f ent des} {
- # Type names Extension
- #
- #---------------------------------------------------------
- set types {
- {"VHDL Code" {.vhd .vhdl} }
- {"Text files" {.txt} }
- {"Tcl Scripts" {.tcl} TEXT}
- {"All files" *}
- }
-
- set file [tk_getOpenFile -filetypes $types -parent $f]
-
- if {[string compare $file ""]} {
- $ent delete 0 end
- $ent insert 0 $file
- $ent xview end
-
- set des_directory [string last / $file]
- $des delete 0 end
- $des insert 0 [string range $file 0 $des_directory]
- $des xview end
- }
-}
-
-##-----------------------------------------------------------------------
-## proc pars_pindef
-proc pars_pindef { pin } {
- set pdirection ""
-# dbg_msg $pin
- set spin [split $pin ":"]
- set pname_str [lindex $spin 0]
- set pname [lindex $pname_str 0]
-# dbg_msg "Pin name is $pname"
- set pdirection_str [lindex $spin 1]
-# dbg_msg $pdirection_str
- ## parce out the direction, supporting only 3
- set direction [string first "in " $pdirection_str]
- if {$direction >= 0} {
- set pdirection "in"
- }
- set direction [string first "out " $pdirection_str]
- if {$direction >= 0} {
- set pdirection "out"
- }
- set direction [string first "inout " $pdirection_str]
- if {$direction >= 0} {
- set pdirection "inout"
- }
- if {$pdirection == ""} {
- msg_error "Unsuported Pin direction found. \n Suported are IN OUT and INOUT."
- }
-# dbg_msg "Pin direction is $pdirection"
- ## now parce out the type
- ## to overcome the std_logic_vector( # to #); vs (# to #); syntax
- ## check and see if there is a vector spec in this pin with space after
- ## the first bracket
- set vect [string first "( " $pdirection_str]
- if {$vect < 0} {
- set ptype1 [lindex $pdirection_str 1]
- set ptype2 [lindex $pdirection_str 2]
- set ptype3 [lindex $pdirection_str 3]
- set ptype "$ptype1 $ptype2 $ptype3"
- } else {
- set ptype1 [lindex $pdirection_str 1]
- set ptype2 [lindex $pdirection_str 2]
- set ptype3 [lindex $pdirection_str 3]
- set ptype4 [lindex $pdirection_str 4]
- set ptype "$ptype1 $ptype2 $ptype3 $ptype4"
- }
- ##puts $ptype
-
- set last_pin [string first \; $ptype]
- if {$last_pin >= 0} {
- set is_vector [string first ( $ptype]
- ## if there is a vector def
- if {$is_vector >= 0} {
- set temp_v [string first )) $ptype]
-
- if {$temp_v >= 0} {
- set s_e [expr $last_pin - 2]
- set ptype [string range $ptype 0 $s_e]
- } else {
- set s_e [expr $last_pin - 1]
- set ptype [string range $ptype 0 $s_e]
- }
- } else {
- set temp_v [string first ) $ptype]
- ## found a ); in the last pin def
- if {$temp_v >= 0} {
- set s_e [expr $last_pin - 2]
- set ptype [string range $ptype 0 $s_e]
- } else {
- set s_e [expr $last_pin - 1]
- set ptype [string range $ptype 0 $s_e]
- }
- }
- }
- set ptype [string trim $ptype]
-# dbg_msg "The type is $ptype"
- lappend pdef $pname $pdirection $ptype
- return $pdef
-}
-
-##--------------------------------------------------------------------------------
-## Write header to file passed
-proc write_header { handle } {
- global ttbgen_version
- global scan_date
-
- ## so CVS will not modify selections, they have to be chopped up
- set auth "-- \$Auth"
- append auth "or: \$"
- set cvs_date "-- \$dat"
- append cvs_date "e: \$"
- set cvs_name "-- \$Nam"
- append cvs_name "e: \$"
- set cvs_id "-- \$I"
- append cvs_id "d: \$"
- set cvs_source "-- \$Sour"
- append cvs_source "ce: \$"
- set cvs_log "-- \$Lo"
- append cvs_log "g: \$"
-
- puts $handle "-------------------------------------------------------------------------------"
- puts $handle "-- Copyright 2007 xxxx"
- puts $handle "-- All Rights Reserved"
- puts $handle "-------------------------------------------------------------------------------"
- puts $handle "$auth"
- puts $handle "--"
- puts $handle "$cvs_date"
- puts $handle "--"
- puts $handle "$cvs_name"
- puts $handle "--"
- puts $handle "$cvs_id"
- puts $handle "--"
- puts $handle "$cvs_source"
- puts $handle "--"
- puts $handle "-- Description :"
- puts $handle "-- This file was generated by ttb_gen2_gui $ttbgen_version"
- puts $handle "-- on $scan_date"
- puts $handle "------------------------------------------------------------------------------"
-# puts $handle "-- This software contains concepts confidential to ------------------"
-# puts $handle "-- -----------. and is only made available within the terms of a written"
-# puts $handle "-- agreement."
-# puts $handle "-------------------------------------------------------------------------------"
- puts $handle "-- Revision History:"
- puts $handle "$cvs_log"
- puts $handle "--"
- puts $handle "-------------------------------------------------------------------------------"
- puts $handle ""
-}
-
-##-------------------------------------------------------------------------
-## write Library and use statements
-proc write_lib_statements { handle } {
-puts $handle "library IEEE;"
-puts $handle "library ieee_proposed;"
-puts $handle "--library modelsim_lib;"
-puts $handle "use IEEE.STD_LOGIC_1164.all;"
-puts $handle "use IEEE.STD_LOGIC_ARITH.all;"
-puts $handle "use ieee_proposed.STD_LOGIC_1164_additions.all;"
-puts $handle "use std.textio.all;"
-puts $handle "--use modelsim_lib.util.all;"
-puts $handle ""
-}
-
-
-#########################################################################
-##
-## START of main program
-##
-#########################################################################
-proc ttb_gen { source destin } {
-
-global bhv
-
-set path_text [$source get]
-set destin_text [$destin get]
-
-set infile [open "$path_text" r]
-set file_list list
-
-##########################################
-## Path needs to be set up for the some usage cases
-## set the path to the template behave file
-set template "template_tb_bhv.vhd"
-#set template "\\\\Gs1\\public\\fpga_projects\\verification_docs\\html\\vhdltb\\template2_tb_bhv.vhd"
-
-set tmpcnt 0
-
-## -------------------------------------------------------------
-## Read in the file and strip comments as we do
-while {![eof $infile]} {
- ## Get a line
- set rline [gets $infile]
- ## get rid of white space
- set rline [string trim $rline]
- ## Find comment if there
- set cindex [string first -- $rline]
- ## if a comment was found at the start of the line
- if {$cindex == 0 || $rline == ""} {
- set rline [string range $rline 0 [expr $cindex - 1]]
- ##dbg_msg $rline
- if {[llength $rline] > 0} {
- lappend file_list [string tolower $rline]
- }
- ## else was not found so put line in list
- } else {
- lappend file_list [string tolower $rline]
- # if {$tmpcnt > 490} {
- # dbg_msg "$rline $tmpcnt"
- # }
- }
- incr tmpcnt
-}
-
-## collect the library statements
-foreach l $file_list {
- set libpos [string first library $l]
- if {$libpos >= 0} {
- lappend libs_list $l
- }
-}
-
-## collect the use statements
-foreach l $file_list {
- set usepos [string first use $l]
- if {$usepos >= 0} {
- lappend use_list $l
- }
-}
-## check for the entity def
-set ent_found 0
-foreach l $file_list {
- set ent_def [string first entity $l]
- if {$ent_def >= 0} {
-## set ent_found 1
- set ent_name [lindex $l 1]
- break
- }
-}
-## if no ent die
-if {$ent_def < 0} {
- msg_error "An entity definition was not found in the file provided."
-## exit
-}
-
-## check for end entity
-foreach l $file_list {
- lappend ent_list $l
- set end_def [string first end $l]
- if {$end_def >= 0} {
- set end_ent [string first "end $ent_name" $l]
- if {$end_ent >= 0} {
- break
- }
- set end_ent [string first "end entity $ent_name" $l]
- if {$end_ent >= 0} {
- break
- }
- }
-}
-## if no end die
-if {$end_def < 0} {
- msg_error "no end statement found for this entity"
-## exit
-}
-
-set port_found 0
-#######----------------------------------------------------------------
-## a few checks have been done, and non-relevant stuff stripped off.
-## now create an arrry of just the pin names and related info
-foreach l $ent_list {
- ## look for the port statement
- if {$port_found == 0} {
- set pfound [string first port $l]
- ## found one now check if there is a pin def in the same line
- if {$pfound >= 0} {
- set port_found 1
- set efound [string first : $l]
- if {$efound >= 0} {
- set line_test [split $l "("]
- if {[llength $line_test] > 1} {
- lappend port_list [lindex $line_test 1]
- }
- }
- }
- } else {
- set efound [string first : $l]
- if {$efound >= 0} {
- lappend port_list $l
- }
- }
-}
-#dbg_msg $port_list
-## Change the port list into a pin info list
-foreach l $port_list {
- lappend split_pin [pars_pindef $l]
-}
-# dbg_msg $split_pin
-
-## calculate the longest pin name in characters
-set name_length 0
-foreach l $split_pin {
- set temp_length [string length [lindex $l 0]]
- if {$temp_length > $name_length} {
- set name_length $temp_length
- }
-}
-#dbg_msg $name_length
-## Make the name length one bigger
-incr name_length
-
-#########################################################################
-## Generate the test bench entity.
-
-## Create the file name
-set file_type "_tb_ent.vhd"
-set ent_file_name $destin_text
-append ent_file_name "/" $ent_name $file_type
-# dbg_msg $ent_file_name
-## Create the tb entity name
-set tb_ent_name $ent_name
-set tb_sufix "_tb"
-append tb_ent_name $tb_sufix
-
-## open and write the header
-set ent_file [open $ent_file_name w+]
-write_header $ent_file
-
-## write out Library and use statements
-write_lib_statements $ent_file
-
-puts $ent_file "entity $tb_ent_name is"
-puts $ent_file " generic ("
-puts $ent_file " stimulus_file: in string"
-puts $ent_file " )\;"
-puts $ent_file " port ("
-
-##-----------------------------------------
-# for each pin in the list output the TB ent pin
-set plist_size [llength $split_pin]
-#dbg_msg $plist_size
-set i 1
-foreach l $split_pin {
- set pdirection [lindex $l 1]
-# puts $pdirection
- ## switch on the source pin direction
- switch -exact $pdirection {
- "in" {set tb_ptype "buffer"}
- "out" {set tb_ptype "in"}
- "inout" {set tb_ptype "inout"}
- default {
- msg_error "Should have not got here .. pin direction in entity creation!!"
- }
- }
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- set new_ptype [format ": %-8s" $tb_ptype]
- if {$i != $plist_size} {
- append new_pname $new_ptype [lindex $l 2] ";"
- } else {
- append new_pname $new_ptype [lindex $l 2]
- }
- puts $ent_file $new_pname
- incr i
-}
-
-puts $ent_file " )\;"
-puts $ent_file "end $tb_ent_name;"
-
-close $ent_file
-
-##################################################################
-## Generate the top level test bench entity
-## Create the file name
-set file_type "_ttb_ent.vhd"
-set ent_file_name $destin_text
-append ent_file_name "/" $ent_name $file_type
-# dbg_msg $ent_file_name
-## Create the tb entity name
-set ttb_ent_name $ent_name
-set ttb_sufix "_ttb"
-append ttb_ent_name $ttb_sufix
-
-## open and write the header
-set ttb_ent_file [open $ent_file_name w+]
-write_header $ttb_ent_file
-
-puts $ttb_ent_file "library IEEE;"
-puts $ttb_ent_file "library dut_lib;"
-puts $ttb_ent_file "use IEEE.STD_LOGIC_1164.all;"
-puts $ttb_ent_file "use dut_lib.all;"
-puts $ttb_ent_file ""
-puts $ttb_ent_file "entity $ttb_ent_name is"
-puts $ttb_ent_file " generic ("
-puts $ttb_ent_file " stimulus_file: string := \"stm/stimulus_file.stm\""
-puts $ttb_ent_file " )\;"
-puts $ttb_ent_file "end $ttb_ent_name\;"
-
-close $ttb_ent_file
-
-#################################################################
-## Generate the top level structure
-## Create the file name
-set file_type "_ttb_str.vhd"
-set str_file_name $destin_text
-append str_file_name "/" $ent_name $file_type
-# dbg_msg $ent_file_name
-## Create the tb entity name
-set ttb_ent_name $ent_name
-set ttb_sufix "_ttb"
-append ttb_ent_name $ttb_sufix
-
-## open and write the header
-set ttb_str_file [open $str_file_name w+]
-write_header $ttb_str_file
-
-puts $ttb_str_file ""
-puts $ttb_str_file "architecture struct of $ttb_ent_name is"
-puts $ttb_str_file ""
-puts $ttb_str_file "component $ent_name"
-puts $ttb_str_file " port ("
-## put out the dut component def
-##-----------------------------------------
-# for each pin in the list output the TB ent pin
-set i 1
-foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- set new_ptype [format ": %-8s" [lindex $l 1]]
- if {$i != $plist_size} {
- append new_pname $new_ptype [lindex $l 2] ";"
- } else {
- append new_pname $new_ptype [lindex $l 2]
- }
- puts $ttb_str_file $new_pname
- incr i
-}
-puts $ttb_str_file " )\;"
-puts $ttb_str_file "end component\;"
-
-puts $ttb_str_file ""
-puts $ttb_str_file "component $tb_ent_name"
-puts $ttb_str_file " generic ("
-puts $ttb_str_file " stimulus_file: in string"
-puts $ttb_str_file " )\;"
-puts $ttb_str_file " port ("
-## put out the tb component def
-##-----------------------------------------
-# for each pin in the list output the TB ent pin
-set i 1
-foreach l $split_pin {
- set pdirection [lindex $l 1]
-# dbg_msg $pdirection
- ## switch on the source pin direction
- switch -exact $pdirection {
- "in" {set tb_ptype "buffer"}
- "out" {set tb_ptype "in"}
- "inout" {set tb_ptype "inout"}
- default {
- msg_error "Should have not got here .. pin direction in entity creation!!"
- }
- }
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- set new_ptype [format ": %-8s" $tb_ptype]
- if {$i != $plist_size} {
- append new_pname $new_ptype [lindex $l 2] ";"
- } else {
- append new_pname $new_ptype [lindex $l 2]
- }
- puts $ttb_str_file $new_pname
- incr i
-}
-puts $ttb_str_file " )\;"
-puts $ttb_str_file "end component\;"
-puts $ttb_str_file ""
-
-puts $ttb_str_file "for all: $ent_name use entity dut_lib.$ent_name\(str)\;"
-puts $ttb_str_file "for all: $tb_ent_name use entity work.$tb_ent_name\(bhv)\;"
-
-puts $ttb_str_file ""
-##-----------------------------------------
-# for each pin in the list output the TB ent pin
-# generate a signal name
-foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " signal temp_%-${name_length}s" [lindex $l 0]]
- append new_pname ": " [lindex $l 2] ";"
- puts $ttb_str_file $new_pname
-}
-
-puts $ttb_str_file ""
-puts $ttb_str_file "begin"
-puts $ttb_str_file ""
-puts $ttb_str_file "dut: $ent_name"
-puts $ttb_str_file " port map("
-##-----------------------------------------
-# for each pin in the list output the TB ent pin
-# Generate port map for DUT
-set i 1
-foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- if {$i != $plist_size} {
- append new_pname "=> temp_" [lindex $l 0] ","
- } else {
- append new_pname "=> temp_" [lindex $l 0]
- }
- puts $ttb_str_file $new_pname
- incr i
-}
-
-puts $ttb_str_file " )\;"
-puts $ttb_str_file ""
-puts $ttb_str_file "tb: $tb_ent_name"
-puts $ttb_str_file " generic map("
-puts $ttb_str_file " stimulus_file => stimulus_file"
-puts $ttb_str_file " )"
-puts $ttb_str_file " port map("
-##-----------------------------------------
-# for each pin in the list output the TB ent pin
-# Generate port map for DUT
-set i 1
-foreach l $split_pin {
- ## creat some formats for appending
- set new_pname [format " %-${name_length}s" [lindex $l 0]]
- if {$i != $plist_size} {
- append new_pname "=> temp_" [lindex $l 0] ","
- } else {
- append new_pname "=> temp_" [lindex $l 0]
- }
- puts $ttb_str_file $new_pname
- incr i
-}
-
-puts $ttb_str_file " )\;"
-puts $ttb_str_file ""
-puts $ttb_str_file "end struct\;"
-
-close $ttb_str_file
-
-######################################################################
-## Now generate the bhv file from template
-
-if {$bhv == 1} {
-
- set infile [open "$template" r]
-
- while {![eof $infile]} {
- ## Get a line
- set rline [gets $infile]
- lappend temp_file_list $rline
- }
-
- close $infile
-
- ## strip off the header
- set end_header 0
- foreach l $temp_file_list {
- set comment [string first -- $l]
- if {$comment < 0} {
- set end_header 1
- }
- ## if we found the end of the header
- if {$end_header == 1} {
- lappend template_list $l
- }
- }
-
- ## split the file into two peices, to the point of input initialization
- set i 1
- foreach l $template_list {
- ## check for parsing point
- set mid_point [string first parse_tb1 $l]
- if {$mid_point >= 0} {
- break
- }
-
- if {$i > 2} {
- lappend top_half $l
- }
- incr i
- }
-
- set found 0
- foreach l $template_list {
- if {$found == 1} {
- lappend bottom_half $l
- }
- ## check for parsing point
- set mid_point [string first parse_tb1 $l]
- if {$mid_point >= 0} {
- set found 1
- }
- }
-
- ## Create the file name
- set file_type "_tb_bhv.vhd"
- set bhv_file_name $destin_text
- append bhv_file_name "/" $ent_name $file_type
- # dbg_msg $ent_file_name
-
- ## open and write the header
- set bhv_file [open $bhv_file_name w+]
- write_header $bhv_file
-
- puts $bhv_file ""
- puts $bhv_file "architecture bhv of $tb_ent_name is"
- puts $bhv_file ""
- foreach l $top_half {
- puts $bhv_file $l
- }
-
- puts $bhv_file ""
- ## now generate and write out input initialization
- foreach l $split_pin {
- set temp_def [lindex $l 1]
- set input_def [string first in $temp_def]
- if {$input_def >= 0} {
- set vector [string first vector $l]
- set init_def [format " %-${name_length}s" [lindex $l 0]]
- if {$vector >= 0} {
- append init_def "<= (others => '0')\;"
- } else {
- append init_def "<= '0'\;"
- }
- puts $bhv_file $init_def
- }
- }
- puts $bhv_file ""
- ## now write out the bottem half and termination
- foreach l $bottom_half {
- puts $bhv_file $l
- }
-
- close $bhv_file
- }
- ## put out a terminating message for the user
- dbg_msg "Test bench files were generated in directory:\n $destin_text"
-
-}
-
-bind . {catch {console show}}
-
-##-------------------------------------------------------------------------------
-##-- Revision History:
-##-- $Log: not supported by cvs2svn $
-##--
-##----------------------------------------------------------------------------
-
Index: trunk/Doc/VHDLtbusers.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/Doc/VHDLtbusers.odt
===================================================================
--- trunk/Doc/VHDLtbusers.odt (revision 13)
+++ trunk/Doc/VHDLtbusers.odt (nonexistent)
trunk/Doc/VHDLtbusers.odt
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: trunk/Doc/VHDLtbusers.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/Doc/VHDLtbusers.pdf
===================================================================
--- trunk/Doc/VHDLtbusers.pdf (revision 13)
+++ trunk/Doc/VHDLtbusers.pdf (nonexistent)
trunk/Doc/VHDLtbusers.pdf
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: trunk/GNU_GPL.txt
===================================================================
--- trunk/GNU_GPL.txt (revision 13)
+++ trunk/GNU_GPL.txt (nonexistent)
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- 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 2 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, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
Index: trunk/examples/example1/build_tb.bat
===================================================================
--- trunk/examples/example1/build_tb.bat (revision 13)
+++ trunk/examples/example1/build_tb.bat (nonexistent)
@@ -1,5 +0,0 @@
-
-vcom vhdl/example_dut_ent.vhd vhdl/example_dut_bhv.vhd
-
-vcom vhdl/example_dut_tb_ent.vhd vhdl/example_dut_tb_bhv.vhd
-vcom vhdl/example_dut_ttb_ent.vhd vhdl/example_dut_ttb_str.vhd
Index: trunk/examples/example1/vhdl/example_dut_bhv.vhd
===================================================================
--- trunk/examples/example1/vhdl/example_dut_bhv.vhd (revision 13)
+++ trunk/examples/example1/vhdl/example_dut_bhv.vhd (nonexistent)
@@ -1,202 +0,0 @@
-
-architecture bhv of example_dut is
-
- -----------------------------------------------------------------------------
- -- driven by STIM_access
- signal stim_addr: std_logic_vector(31 downto 0);
- signal stim_write_dat: std_logic_vector(31 downto 0);
- signal rd_req: std_logic := '0';
- signal wr_req: std_logic := '0';
- -----------------------------------------------------------------------------
- -- driven by REG_access
- signal stim_read_dat: std_logic_vector(31 downto 0);
- signal req_ack: std_logic := '0';
-
- -- the addressable register set
- signal ctl_reg: std_logic_vector(31 downto 0);
- signal seed_reg: std_logic_vector(31 downto 0) := "00010001000111000011000010000100";
- signal config_reg: std_logic_vector(31 downto 0);
- signal errors_reg: std_logic_vector(31 downto 0);
- signal sample_edge: std_logic := '1';
- signal drive_edge: std_logic := '0';
- signal access0_word: std_logic_vector(31 downto 0);
- signal access1_word: std_logic_vector(31 downto 0);
- signal action_trig: std_logic := '0';
- signal clear_trig: std_logic := '0';
-
- --- Driven by Drive_out
- signal clock_enable: std_logic := '0';
-
-begin
-
-------------------------------------------------
--- Example process to drive outputs.
-output_drive:
- process(EX_RESET_N, ctl_reg, access0_word, access1_word)
- begin
- if(EX_RESET_N = '0') then
- EX_DATA1 <= (others => 'Z');
- EX_DATA2 <= (others => 'Z');
- elsif(access0_word'event) then
- EX_DATA1 <= access0_word;
- elsif(access1_word'event) then
- EX_DATA2 <= access1_word;
- end if;
-end process output_drive;
-
-
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--- STIM Reg Access process
-REG_access:
- process
-
- variable v_temp_int: integer;
- variable v_reload: integer := 0;
- variable v_tmp_int: integer;
-
- begin
- if(EX_RESET_N'event and EX_RESET_N = '0') then
- v_reload := 0;
- -- standard registers
- stim_read_dat <= (others => '0');
- req_ack <= '0';
- ctl_reg <= (others => '0');
- config_reg <= (others => '0');
- errors_reg <= (others => '0');
-
- -- application registers
- access0_word <= (others => 'Z');
- access1_word <= (others => 'Z');
- action_trig <= '0';
-
- ---------------------------------------------------------
-
- -- if is a write access
- elsif(wr_req' event and wr_req = '1') then
- -- create index 0 to 63
- v_temp_int := conv_integer(unsigned(stim_addr(5 downto 0)));
- -- create first level of addressing
- case stim_addr(31 downto 12) is
- -- first level decode
- when "00000000000000000000" =>
- -- create register access level of addressing
- -- seconde level of decode
- case stim_addr(11 downto 0) is
- when "000000000000" =>
- ctl_reg <= stim_write_dat;
- when "000000000001" =>
- config_reg <= stim_write_dat;
- when "000000000010" =>
- assert(false)
- report ">>>> ERROR: The errors register is read only!!" & LF
- severity note;
--- errors_reg <= stim_write_dat;
- when "000000000011" =>
- seed_reg <= stim_write_dat;
-
- when "000000000100" =>
- access0_word <= stim_write_dat;
- action_trig <= '1';
- when "000000000101" =>
- access1_word <= stim_write_dat;
-
- when others =>
- assert(false)
- report "This area of object address is not valid" & LF
- severity note;
- end case;
-
- when others =>
- assert(false)
- report "This area of object address is not valid" & LF
- severity note;
- end case;
- -- acknowlage the request
- req_ack <= '1';
- wait until wr_req'event and wr_req = '0';
- req_ack <= '0';
-
- -- if is a read
- elsif (rd_req' event and rd_req = '1') then
- -- create first level of addressing
- case stim_addr(31 downto 12) is
- -- first level decode
- when "00000000000000000000" =>
- -- create register access level of addressing
- -- seconde level of decode
- case stim_addr(11 downto 0) is
- when "000000000010" =>
- stim_read_dat <= errors_reg;
- errors_reg <= (others => '0');
- when others =>
- assert(false)
- report "Read Location access ERROR: Arb model: No action taken!" & LF
- severity note;
- end case;
- when others =>
- assert(false)
- report "Read Location access ERROR: Arb model: No action taken!" & LF
- severity note;
- end case;
- -- acknowlage the request
- req_ack <= '1';
- wait until rd_req'event and rd_req = '0';
- req_ack <= '0';
-
- end if;
- -- clear the trigger signal
- if(clear_trig'event) then
- action_trig <= '0';
- end if;
-
- wait on rd_req, wr_req, EX_RESET_N, clear_trig;
- end process REG_access;
-
--------------------------------------------------------------------------------
--- STIM Access port processes
---
-STIM_access:
- process
- begin
- if(EX_RESET_N' event) then
- STM_DAT <= (others => 'Z');
- STM_ACK_N <= '1';
- -- if read cycle
- elsif(STM_REQ_N' event and STM_REQ_N = '0' and STM_RWN = '1') then
- stim_addr <= STM_ADD;
- rd_req <= '1';
- wait until req_ack' event and req_ack = '1';
- STM_DAT <= stim_read_dat;
- rd_req <= '0';
- wait for 1 ps;
- STM_ACK_N <= '0';
- wait until STM_REQ_N' event and STM_REQ_N = '1';
- wait for 1 ps;
- STM_DAT <= (others => 'Z');
- STM_ACK_N <= '1';
-
- -- if Write
- elsif(STM_REQ_N' event and STM_REQ_N = '0' and STM_RWN = '0') then
- STM_DAT <= (others => 'Z');
- wait for 1 ps;
- stim_addr <= STM_ADD;
- stim_write_dat <= STM_DAT;
-
- wr_req <= '1';
- wait until req_ack' event and req_ack = '1';
- wait for 1 ps;
- wr_req <= '0';
- wait for 1 ps;
- STM_ACK_N <= '0';
- wait until STM_REQ_N' event and STM_REQ_N = '1';
- wait for 1 ps;
- STM_ACK_N <= '1';
- end if;
-
- wait on STM_REQ_N, EX_RESET_N;
- end process STIM_access;
-
-end bhv;
Index: trunk/examples/example1/vhdl/example_dut_ttb_ent.vhd
===================================================================
--- trunk/examples/example1/vhdl/example_dut_ttb_ent.vhd (revision 13)
+++ trunk/examples/example1/vhdl/example_dut_ttb_ent.vhd (nonexistent)
@@ -1,11 +0,0 @@
-
-library IEEE;
---library dut_lib;
-use IEEE.STD_LOGIC_1164.all;
---use dut_lib.all;
-
-entity example_dut_ttb is
- generic (
- stimulus_file: string := "stm/stimulus_file.stm"
- );
-end example_dut_ttb;
Index: trunk/examples/example1/vhdl/example_dut_ttb_str.vhd
===================================================================
--- trunk/examples/example1/vhdl/example_dut_ttb_str.vhd (revision 13)
+++ trunk/examples/example1/vhdl/example_dut_ttb_str.vhd (nonexistent)
@@ -1,79 +0,0 @@
--- structure file generated by ttb_gen
-architecture struct of example_dut_ttb is
-
-component example_dut
- port (
- ex_reset_n : in std_logic;
- ex_clk_in : in std_logic;
- ex_data1 : out std_logic_vector(31 downto 0);
- ex_data2 : out std_logic_vector(31 downto 0);
- stm_add : in std_logic_vector(31 downto 0);
- stm_dat : inout std_logic_vector(31 downto 0);
- stm_rwn : in std_logic;
- stm_req_n : in std_logic;
- stm_ack_n : out std_logic
- );
-end component;
-
-component example_dut_tb
- generic (
- stimulus_file: in string
- );
- port (
- ex_reset_n : buffer std_logic;
- ex_clk_in : buffer std_logic;
- ex_data1 : in std_logic_vector(31 downto 0);
- ex_data2 : in std_logic_vector(31 downto 0);
- stm_add : buffer std_logic_vector(31 downto 0);
- stm_dat : inout std_logic_vector(31 downto 0);
- stm_rwn : buffer std_logic;
- stm_req_n : buffer std_logic;
- stm_ack_n : in std_logic
- );
-end component;
-
---for all: example_dut use entity dut_lib.example_dut(str);
---for all: example_dut_tb use entity work.example_dut_tb(bhv);
-
- signal temp_ex_reset_n : std_logic;
- signal temp_ex_clk_in : std_logic;
- signal temp_ex_data1 : std_logic_vector(31 downto 0);
- signal temp_ex_data2 : std_logic_vector(31 downto 0);
- signal temp_stm_add : std_logic_vector(31 downto 0);
- signal temp_stm_dat : std_logic_vector(31 downto 0);
- signal temp_stm_rwn : std_logic;
- signal temp_stm_req_n : std_logic;
- signal temp_stm_ack_n : std_logic;
-
-begin
-
-dut: example_dut
- port map(
- ex_reset_n => temp_ex_reset_n,
- ex_clk_in => temp_ex_clk_in,
- ex_data1 => temp_ex_data1,
- ex_data2 => temp_ex_data2,
- stm_add => temp_stm_add,
- stm_dat => temp_stm_dat,
- stm_rwn => temp_stm_rwn,
- stm_req_n => temp_stm_req_n,
- stm_ack_n => temp_stm_ack_n
- );
-
-tb: example_dut_tb
- generic map(
- stimulus_file => stimulus_file
- )
- port map(
- ex_reset_n => temp_ex_reset_n,
- ex_clk_in => temp_ex_clk_in,
- ex_data1 => temp_ex_data1,
- ex_data2 => temp_ex_data2,
- stm_add => temp_stm_add,
- stm_dat => temp_stm_dat,
- stm_rwn => temp_stm_rwn,
- stm_req_n => temp_stm_req_n,
- stm_ack_n => temp_stm_ack_n
- );
-
-end struct;
Index: trunk/examples/example1/vhdl/example_dut_tb_bhv.vhd
===================================================================
--- trunk/examples/example1/vhdl/example_dut_tb_bhv.vhd (revision 13)
+++ trunk/examples/example1/vhdl/example_dut_tb_bhv.vhd (nonexistent)
@@ -1,543 +0,0 @@
--- this file generated from template by ttb_gen
-
-architecture bhv of example_dut_tb is
-
-
-
- signal tb_clk : std_logic;
-
--------------------------------------------------------------------------
--- Component defintion
-
--------------------------------------------------------------------------------
--- USER Component instantiations
---for all: Arbitor use entity tb_objects.arbitor(bhv);
-
-
- begin
-
--------------------------------------------------------------------------------
--- clock driver process
--- the main clock generator
-clock_driver:
- process
- begin
- tb_clk <= '0';
- wait for 5 ns;
- tb_clk <= '1';
- wait for 5 ns;
- end process clock_driver;
-
-
- ex_clk_in <= tb_clk;
-
- --------------------------------------------------------------------------
- -- Read_file Process:
- --
- -- This process is the main process of the testbench. This process reads
- -- the stumulus file, parses it, creates lists of records, then uses these
- -- lists to exicute user instructions. There are two passes through the
- -- script. Pass one reads in the stimulus text file, checks it, creates
- -- lists of valid instructions, valid list of variables and finialy a list
- -- of user instructions(the sequence). The second pass through the file,
- -- records are drawn from the user instruction list, variables are converted
- -- to integers and put through the elsif structure for exicution.
- --------------------------------------------------------------------------
- Read_file: process
- variable current_line : text_line; -- The current input line
- variable inst_list : inst_def_ptr; -- the instruction list
- variable defined_vars : var_field_ptr; -- defined variables
- variable inst_sequ : stim_line_ptr; -- the instruction sequence
- variable file_list : file_def_ptr; -- pointer to the list of file names
-
- variable instruction : text_field; -- instruction field
- variable par1 : integer; -- paramiter 1
- variable par2 : integer; -- paramiter 2
- variable par3 : integer; -- paramiter 3
- variable par4 : integer; -- paramiter 4
- variable par5 : integer; -- paramiter 5
- variable par6 : integer; -- paramiter 6
- variable txt : stm_text_ptr;
- variable nbase : base; -- the number base to use
- variable len : integer; -- length of the instruction field
- variable file_line : integer; -- Line number in the stimulus file
- variable file_name : text_line; -- the file name the line came from
- variable v_line : integer := 0; -- sequence number
- variable stack : stack_register; -- Call stack
- variable stack_ptr : integer := 0; -- call stack pointer
- variable wh_stack : stack_register; -- while stack
- variable wh_dpth : integer := 0; -- while depth
- variable wh_ptr : integer := 0; -- while pointer
- variable loop_num : integer := 0;
- variable curr_loop_count : int_array := (others => 0);
- variable term_loop_count : int_array := (others => 0);
- variable loop_line : int_array := (others => 0);
-
- variable messages : boolean := TRUE;
- variable if_state : boolean := FALSE;
- variable wh_state : boolean := FALSE;
- variable wh_end : boolean := FALSE;
- variable rand : std_logic_vector(31 downto 0);
- variable rand_back : std_logic_vector(31 downto 0);
-
- variable temp_int : integer;
- variable temp_index : integer;
- variable temp_str : text_field;
- variable valid : integer;
- variable v_temp_vec1 : std_logic_vector(31 downto 0);
- variable v_temp_vec2 : std_logic_vector(31 downto 0);
-
- variable v_read_data : std_logic_vector(31 downto 0);
- --------------------------------------------------------------------------
- -- Area for Procedures which may be usefull to more than one instruction.
- -- By coding here commonly used code sections ...
- -- you know the benifits.
- ---------------------------------------------------------------------
- -----------------------------------------------------------------
- -- This procedure writes to the arbitor model access port
--- procedure arb_write(add: in integer; .....
--- end arb_write;
-
-
- begin -- process Read_file
-
- ex_reset_n <= '1';
--- ex_clk_in <= '0';
- stm_add <= (others => 'Z');
- stm_dat <= (others => 'Z');
- stm_rwn <= '1';
- stm_req_n <= '1';
-
- -----------------------------------------------------------------------
- -- Stimulus file instruction definition
- -- This is where the instructions used in the stimulus file are defined.
- -- Syntax is
- -- define_instruction(inst_def_ptr, instruction, paramiters)
- -- inst_def_ptr: is a record pointer defined in tb_pkg_header
- -- instruction: the text instruction name ie. "DEFINE_VAR"
- -- paramiters: the number of fields or paramiters passed
- --
- -- Some basic instruction are created here, the user should create new
- -- instructions below the standard ones.
- ------------------------------------------------------------------------
- define_instruction(inst_list, "DEFINE_VAR", 2); -- Define a Variable
- define_instruction(inst_list, "EQU_VAR", 2);
- define_instruction(inst_list, "ADD_VAR", 2);
- define_instruction(inst_list, "SUB_VAR", 2);
- define_instruction(inst_list, "CALL", 1);
- define_instruction(inst_list, "RETURN_CALL", 0);
- define_instruction(inst_list, "JUMP", 1);
- define_instruction(inst_list, "LOOP", 1);
- define_instruction(inst_list, "END_LOOP", 0);
- define_instruction(inst_list, "IF", 3);
- define_instruction(inst_list, "ELSE", 0);
- define_instruction(inst_list, "ELSEIF", 3);
- define_instruction(inst_list, "END_IF", 0);
- define_instruction(inst_list, "WHILE", 3);
- define_instruction(inst_list, "END_WHILE", 0);
- define_instruction(inst_list, "MESSAGES_OFF", 0);
- define_instruction(inst_list, "MESSAGES_ON", 0);
- define_instruction(inst_list, "ABORT", 0); -- Error exit from sim
- define_instruction(inst_list, "FINISH", 0); -- Normal exit from sim
- define_instruction(inst_list, "INCLUDE", 1); -- Define a Variable
-
- -- User defined instructions
- define_instruction(inst_list, "RESET_SYS", 0);
- define_instruction(inst_list, "READ_PINS", 1);
- define_instruction(inst_list, "WRITE_DUT", 2);
- define_instruction(inst_list, "VERIFY", 1);
-
-
- ------------------------------------------------------------------------
- -- Read, test, and load the stimulus file
- read_instruction_file(stimulus_file, inst_list, defined_vars, inst_sequ,
- file_list);
-
-------------------------------------------------------------------------
--- Using the Instruction record list, get the instruction and implement
--- it as per the statements in the elsif tree.
- while(v_line < inst_sequ.num_of_lines) loop
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
-
---------------------------------------------------------------------------
- if(instruction(1 to len) = "DEFINE_VAR") then
- null; -- This instruction was implemented while reading the file
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "INCLUDE") then
- null; -- This instruction was implemented while reading the file
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "ABORT") then
- assert (false)
- report "The test has aborted due to an error!!"
- severity failure;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "FINISH") then
- assert (false)
- report "Test Finished with NO errors!!"
- severity failure;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "EQU_VAR") then
- update_variable(defined_vars, par1, par2, valid);
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "ADD_VAR") then
- index_variable(defined_vars, par1, temp_int, valid);
- if(valid /= 0) then
- temp_int := temp_int + par2;
- update_variable(defined_vars, par1, temp_int, valid);
- else
- assert (false)
- report "ADD_VAR Error: Not a valid Variable??"
- severity failure;
- end if;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "SUB_VAR") then
- index_variable(defined_vars, par1, temp_int, valid);
- if(valid /= 0) then
- temp_int := temp_int - par2;
- update_variable(defined_vars, par1, temp_int, valid);
- else
- assert (false)
- report "SUB_VAR Error: Not a valid Variable??"
- severity failure;
- end if;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "CALL") then
- if(stack_ptr >= 7) then
- assert (false)
- report "Call Error: Stack over run, calls to deeply nested!!"
- severity failure;
- end if;
- stack(stack_ptr) := v_line;
- stack_ptr := stack_ptr + 1;
- v_line := par1 - 1;
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "RETURN_CALL") then
- if(stack_ptr <= 0) then
- assert (false)
- report "Call Error: Stack under run??"
- severity failure;
- end if;
- stack_ptr := stack_ptr - 1;
- v_line := stack(stack_ptr);
-
---------------------------------------------------------------------------
- elsif(instruction(1 to len) = "JUMP") then
- v_line := par1 - 1;
- wh_state := false;
- wh_stack := (others => 0);
- wh_dpth := 0;
- wh_ptr := 0;
- stack := (others => 0);
- stack_ptr := 0;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "LOOP") then
- loop_num := loop_num + 1;
- loop_line(loop_num) := v_line;
- curr_loop_count(loop_num) := 0;
- term_loop_count(loop_num) := par1;
- assert (messages)
- report LF & "Executing LOOP Command" &
- LF & " Nested Loop:" & HT & integer'image(loop_num) &
- LF & " Loop Length:" & HT & integer'image(par1)
- severity note;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "END_LOOP") then
- curr_loop_count(loop_num) := curr_loop_count(loop_num) + 1;
- if (curr_loop_count(loop_num) = term_loop_count(loop_num)) then
- loop_num := loop_num - 1;
- else
- v_line := loop_line(loop_num);
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "IF") then
- if_state := false;
- case par2 is
- when 0 => if(par1 = par3) then if_state := true; end if;
- when 1 => if(par1 > par3) then if_state := true; end if;
- when 2 => if(par1 < par3) then if_state := true; end if;
- when 3 => if(par1 /= par3) then if_state := true; end if;
- when 4 => if(par1 >= par3) then if_state := true; end if;
- when 5 => if(par1 <= par3) then if_state := true; end if;
- when others =>
- assert (false)
- report LF & "ERROR: IF instruction got an unexpected value" &
- LF & " in parameter 2!" & LF &
- "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
- severity failure;
- end case;
-
- if(if_state = false) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- while(instruction(1 to len) /= "ELSE" and
- instruction(1 to len) /= "ELSEIF" and
- instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- else
- assert (false)
- report LF & "ERROR: IF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "ELSEIF") then
- if(if_state = true) then -- if the if_state is true then skip to the end
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- while(instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- else
- assert (false)
- report LF & "ERROR: IF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
-
- else
- case par2 is
- when 0 => if(par1 = par3) then if_state := true; end if;
- when 1 => if(par1 > par3) then if_state := true; end if;
- when 2 => if(par1 < par3) then if_state := true; end if;
- when 3 => if(par1 /= par3) then if_state := true; end if;
- when 4 => if(par1 >= par3) then if_state := true; end if;
- when 5 => if(par1 <= par3) then if_state := true; end if;
- when others =>
- assert (false)
- report LF & "ERROR: ELSEIF instruction got an unexpected value" &
- LF & " in parameter 2!" & LF &
- "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
- severity failure;
- end case;
-
- if(if_state = false) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- while(instruction(1 to len) /= "ELSE" and
- instruction(1 to len) /= "ELSEIF" and
- instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- else
- assert (false)
- report LF & "ERROR: ELSEIF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
- end if;
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "ELSE") then
- if(if_state = true) then -- if the if_state is true then skip the else
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- while(instruction(1 to len) /= "END_IF") loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- else
- assert (false)
- report LF & "ERROR: IF instruction unable to find terminating" &
- LF & " ELSE, ELSEIF or END_IF statement."
- severity failure;
- end if;
- end loop;
- v_line := v_line - 1; -- re-align so it will be operated on.
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "END_IF") then
- null; -- instruction is a place holder for finding the end of IF.
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "WHILE") then
- wh_state := false;
- case par2 is
- when 0 => if(par1 = par3) then if_state := true; end if;
- when 1 => if(par1 > par3) then if_state := true; end if;
- when 2 => if(par1 < par3) then if_state := true; end if;
- when 3 => if(par1 /= par3) then if_state := true; end if;
- when 4 => if(par1 >= par3) then if_state := true; end if;
- when 5 => if(par1 <= par3) then if_state := true; end if;
- when others =>
- assert (false)
- report LF & "ERROR: WHILE instruction got an unexpected value" &
- LF & " in parameter 2!" & LF &
- "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
- severity failure;
- end case;
-
- if(wh_state = true) then
- wh_stack(wh_ptr) := v_line;
- wh_ptr := wh_ptr + 1;
- else
- wh_end := false;
- while(wh_end /= true) loop
- if(v_line < inst_sequ.num_of_lines) then
- v_line := v_line + 1;
- access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
- par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
- else
- assert (false)
- report LF & "ERROR: WHILE instruction unable to find terminating" &
- LF & " END_WHILE statement."
- severity failure;
- end if;
-
- -- if is a while need to escape it
- if(instruction(1 to len) = "WHILE") then
- wh_dpth := wh_dpth + 1;
- -- if is the end_while we are looking for
- elsif(instruction(1 to len) = "END_WHILE") then
- if(wh_dpth = 0) then
- wh_end := true;
- else
- wh_dpth := wh_dpth - 1;
- end if;
- end if;
- end loop;
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "END_WHILE") then
- if(wh_ptr > 0) then
- v_line := wh_stack(wh_ptr - 1) - 1;
- wh_ptr := wh_ptr - 1;
- end if;
-
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "MESSAGES_OFF") then
- messages := TRUE;
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "MESSAGES_ON") then
- messages := FALSE;
-
-
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
--- USER Istruction area. Add all user instructions below this
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
- elsif (instruction(1 to len) = "RESET_SYS") then
- wait until tb_clk'event and tb_clk = '1';
- EX_RESET_N <= '0';
- wait until tb_clk'event and tb_clk = '1';
- wait until tb_clk'event and tb_clk = '1';
- EX_RESET_N <= '1';
- wait for 0 ns;
-
---------------------------------------------------------------------------------
--- READ_PINS
--- read one of the two output interfaces on the dut, put value in read_data
--- par1 0 read port1
--- 1 read port2
- elsif (instruction(1 to len) = "READ_PINS") then
- if(par1 = 0) then
- v_read_data := EX_DATA1;
- elsif(par1 = 1) then
- v_read_data := EX_DATA2;
- else
- assert (false)
- report LF & "Out of range message" & LF
- severity error;
- end if;
-
---------------------------------------------------------------------------------
--- VERIFY
--- par1 Data to compare
- elsif (instruction(1 to len) = "VERIFY") then
- v_temp_vec1 := std_logic_vector(conv_unsigned(par1, 32));
- -- if (sim_halt = '1') then
- assert (v_temp_vec1 = v_read_data)
- report "VERIFY instruction found missmatch!" & LF &
- "Expected data = " & to_hstring(v_temp_vec1) & LF &
- "Read data = " & to_hstring(v_read_data) & LF &
- "Found on line " & (integer'image(file_line)) & " in file " & file_name
- severity failure;
-
- -- else
- -- assert (v_temp_vec1 = v_read_data)
- -- report "VERIFY instruction found missmatch!" & LF &
- -- "Expected data = " & to_hstring(v_temp_vec1) & LF &
- -- "Read data = " & to_hstring(v_read_data) & LF &
- -- "Found on line " & (integer'image(file_line)) & " in file " & file_name
- -- severity error;
- -- end if;
-
---------------------------------------------------------------------------------
--- PCI_WRITE
--- par1 address
--- par2 data
--- This instruction I use for accessing models. which is the interface
--- on the example dut. I use that interface as a stimulus access port.
- elsif (instruction(1 to len) = "WRITE_DUT") then
- stm_add <= std_logic_vector(conv_unsigned(par1,32));
- stm_dat <= std_logic_vector(conv_unsigned(par2,32));
- stm_req_n <= '0';
- stm_rwn <= '0';
- wait until stm_ack_n'event and stm_ack_n = '0';
- stm_req_n <= '1';
- wait until stm_ack_n'event and stm_ack_n = '1';
- stm_add <= (others => 'Z');
- stm_dat <= (others => 'Z');
- stm_rwn <= '1';
- wait for 0 ns;
-
-
---------------------------------------------------------------------------------
--- USER Istruction area. Add all user instructions above this
---------------------------------------------------------------------------------
- --------------------------------------------------------------------------
- -- catch those little mistakes
- else
- assert (false)
- report LF & "ERROR: Seems the command " & instruction(1 to len) & " was defined" & LF &
- "but not found in the elsif chain, please check the spelling."
- severity failure;
- end if; -- else if structure end
- txt_print_wvar(defined_vars, txt, hex);
- end loop; -- Main Loop end
-
- assert (false)
- report LF & "The end of the simulation! It was not terminated as expected." & LF
- severity failure;
-
- end process Read_file;
-
-
-end bhv;
-
Index: trunk/examples/example1/vhdl/example_dut_ent.vhd
===================================================================
--- trunk/examples/example1/vhdl/example_dut_ent.vhd (revision 13)
+++ trunk/examples/example1/vhdl/example_dut_ent.vhd (nonexistent)
@@ -1,21 +0,0 @@
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.STD_LOGIC_UNSIGNED.ALL;
-use IEEE.STD_LOGIC_ARITH.ALL;
-use std.textio.all;
-
-entity example_dut is
- port(
- EX_RESET_N : in std_logic;
- EX_CLK_IN : in std_logic;
- -- interface pins
- EX_DATA1 : out std_logic_vector(31 downto 0);
- EX_DATA2 : out std_logic_vector(31 downto 0);
- -- env access port
- STM_ADD : in std_logic_vector(31 downto 0);
- STM_DAT : inout std_logic_vector(31 downto 0);
- STM_RWN : in std_logic;
- STM_REQ_N : in std_logic;
- STM_ACK_N : out std_logic
- );
-end example_dut;
Index: trunk/examples/example1/vhdl/example_dut_tb_ent.vhd
===================================================================
--- trunk/examples/example1/vhdl/example_dut_tb_ent.vhd (revision 13)
+++ trunk/examples/example1/vhdl/example_dut_tb_ent.vhd (nonexistent)
@@ -1,27 +0,0 @@
--- ttb_gen generated file
-library IEEE;
-library ieee_proposed;
-library work;
-use IEEE.STD_LOGIC_1164.all;
-use IEEE.STD_LOGIC_ARITH.all;
-use ieee_proposed.STD_LOGIC_1164_additions.all;
-use std.textio.all;
-use work.tb_pkg.all; -- test bench package
-
-
-entity example_dut_tb is
- generic (
- stimulus_file: in string
- );
- port (
- ex_reset_n : buffer std_logic;
- ex_clk_in : buffer std_logic;
- ex_data1 : in std_logic_vector(31 downto 0);
- ex_data2 : in std_logic_vector(31 downto 0);
- stm_add : buffer std_logic_vector(31 downto 0);
- stm_dat : inout std_logic_vector(31 downto 0);
- stm_rwn : buffer std_logic;
- stm_req_n : buffer std_logic;
- stm_ack_n : in std_logic
- );
-end example_dut_tb;
Index: trunk/examples/example1/stm/stimulus_file.stm
===================================================================
--- trunk/examples/example1/stm/stimulus_file.stm (revision 13)
+++ trunk/examples/example1/stm/stimulus_file.stm (nonexistent)
@@ -1,26 +0,0 @@
--- example stimulus file
-
-
-DEFINE_VAR DATA 0
-DEFINE_VAR ADDR1 4
-DEFINE_VAR ADDR2 5
-
-
-RESET_SYS
-
-LOOP 10
- WRITE_DUT $ADDR1 $DATA
- READ_PINS 0
- VERIFY $DATA
- ADD_VAR DATA 1
-
- WRITE_DUT $ADDR2 $DATA
- READ_PINS 1
- VERIFY $DATA
- ADD_VAR DATA 1
-
-END_LOOP
-
-
-
-FINISH
\ No newline at end of file
Index: vhld_tb/trunk/source/template_tb_bhv.vhd
===================================================================
--- vhld_tb/trunk/source/template_tb_bhv.vhd (nonexistent)
+++ vhld_tb/trunk/source/template_tb_bhv.vhd (revision 14)
@@ -0,0 +1,525 @@
+-------------------------------------------------------------------------------
+-- Copyright 2007 Ken Campbell
+-------------------------------------------------------------------------------
+-- $Author: sckoarn $
+--
+-- $Date: 2008-02-24 01:34:11 $
+--
+-- $Name: not supported by cvs2svn $
+--
+-- $Id: template_tb_bhv.vhd,v 1.4 2008-02-24 01:34:11 sckoarn Exp $
+--
+-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/template_tb_bhv.vhd,v $
+--
+-- Description : The the testbench package template behave file.
+-- Initial GNU release.
+--
+------------------------------------------------------------------------------
+--This file is part of The VHDL Test Bench.
+--
+-- The VHDL Test Bench 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 2 of the License, or
+-- (at your option) any later version.
+--
+-- The VHDL Test Bench 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 The VHDL Test Bench; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-------------------------------------------------------------------------------
+-- Revision History:
+-- $Log: not supported by cvs2svn $
+-- Revision 1.3 2007/11/14 02:35:56 sckoarn
+-- Fix to WHILE instruction: Change if_state typo to wh_state
+--
+-- Revision 1.2 2007/09/02 04:04:04 sckoarn
+-- Update of version 1.2 tb_pkg
+-- See documentation for details
+--
+-- Revision 1.1.1.1 2007/04/06 04:06:48 sckoarn
+-- Import of the vhld_tb
+--
+--
+-------------------------------------------------------------------------------
+
+architecture bhv of tb_Top is
+
+
+ signal tb_clk : std_logic;
+
+-------------------------------------------------------------------------
+-- Component defintion
+
+-------------------------------------------------------------------------------
+-- USER Component instantiations
+--for all: Arbitor use entity tb_objects.arbitor(bhv);
+
+
+ begin
+
+-------------------------------------------------------------------------------
+-- clock driver process
+-- the main clock generator
+clock_driver:
+ process
+ begin
+ tb_clk <= '0';
+ wait for 5 ns;
+ tb_clk <= '1';
+ wait for 5 ns;
+ end process clock_driver;
+
+ --------------------------------------------------------------------------
+ -- Read_file Process:
+ --
+ -- This process is the main process of the testbench. This process reads
+ -- the stumulus file, parses it, creates lists of records, then uses these
+ -- lists to exicute user instructions. There are two passes through the
+ -- script. Pass one reads in the stimulus text file, checks it, creates
+ -- lists of valid instructions, valid list of variables and finialy a list
+ -- of user instructions(the sequence). The second pass through the file,
+ -- records are drawn from the user instruction list, variables are converted
+ -- to integers and put through the elsif structure for exicution.
+ --------------------------------------------------------------------------
+ Read_file: process
+ variable current_line : text_line; -- The current input line
+ variable inst_list : inst_def_ptr; -- the instruction list
+ variable defined_vars : var_field_ptr; -- defined variables
+ variable inst_sequ : stim_line_ptr; -- the instruction sequence
+ variable file_list : file_def_ptr; -- pointer to the list of file names
+ variable last_sequ_num: integer;
+ variable last_sequ_ptr: stim_line_ptr;
+
+ variable instruction : text_field; -- instruction field
+ variable par1 : integer; -- paramiter 1
+ variable par2 : integer; -- paramiter 2
+ variable par3 : integer; -- paramiter 3
+ variable par4 : integer; -- paramiter 4
+ variable par5 : integer; -- paramiter 5
+ variable par6 : integer; -- paramiter 6
+ variable txt : stm_text_ptr;
+ variable nbase : base; -- the number base to use
+ variable len : integer; -- length of the instruction field
+ variable file_line : integer; -- Line number in the stimulus file
+ variable file_name : text_line; -- the file name the line came from
+ variable v_line : integer := 0; -- sequence number
+ variable stack : stack_register; -- Call stack
+ variable stack_ptr : integer := 0; -- call stack pointer
+ variable wh_stack : stack_register; -- while stack
+ variable wh_dpth : integer := 0; -- while depth
+ variable wh_ptr : integer := 0; -- while pointer
+ variable loop_num : integer := 0;
+ variable curr_loop_count : int_array := (others => 0);
+ variable term_loop_count : int_array := (others => 0);
+ variable loop_line : int_array := (others => 0);
+
+ variable messages : boolean := TRUE;
+ variable if_state : boolean := FALSE;
+ variable wh_state : boolean := FALSE;
+ variable wh_end : boolean := FALSE;
+ variable rand : std_logic_vector(31 downto 0);
+ variable rand_back : std_logic_vector(31 downto 0);
+ variable valid : integer;
+
+ -- scratchpad variables
+ variable temp_int : integer;
+ variable temp_index : integer;
+ variable temp_str : text_field;
+ variable v_temp_vec1 : std_logic_vector(31 downto 0);
+ variable v_temp_vec2 : std_logic_vector(31 downto 0);
+
+ --------------------------------------------------------------------------
+ -- Area for Procedures which may be usefull to more than one instruction.
+ -- By coding here commonly used code sections ...
+ -- you know the benifits.
+ ---------------------------------------------------------------------
+ -----------------------------------------------------------------
+ -- This procedure writes to the arbitor model access port
+-- procedure arb_write(add: in integer; .....
+-- end arb_write;
+
+
+ begin -- process Read_file
+-- parse_tb1 start input initialization
+ -----------------------------------------------------------------------
+ -- Stimulus file instruction definition
+ -- This is where the instructions used in the stimulus file are defined.
+ -- Syntax is
+ -- define_instruction(inst_def_ptr, instruction, paramiters)
+ -- inst_def_ptr: is a record pointer defined in tb_pkg_header
+ -- instruction: the text instruction name ie. "DEFINE_VAR"
+ -- paramiters: the number of fields or paramiters passed
+ --
+ -- Some basic instruction are created here, the user should create new
+ -- instructions below the standard ones.
+ ------------------------------------------------------------------------
+ define_instruction(inst_list, "DEFINE_VAR", 2); -- Define a Variable
+ define_instruction(inst_list, "EQU_VAR", 2);
+ define_instruction(inst_list, "ADD_VAR", 2);
+ define_instruction(inst_list, "SUB_VAR", 2);
+ define_instruction(inst_list, "CALL", 1);
+ define_instruction(inst_list, "RETURN_CALL", 0);
+ define_instruction(inst_list, "JUMP", 1);
+ define_instruction(inst_list, "LOOP", 1);
+ define_instruction(inst_list, "END_LOOP", 0);
+ define_instruction(inst_list, "IF", 3);
+ define_instruction(inst_list, "ELSEIF", 3);
+ define_instruction(inst_list, "ELSE", 0);
+ define_instruction(inst_list, "END_IF", 0);
+ define_instruction(inst_list, "WHILE", 3);
+ define_instruction(inst_list, "END_WHILE", 0);
+ define_instruction(inst_list, "MESSAGES_OFF", 0);
+ define_instruction(inst_list, "MESSAGES_ON", 0);
+ define_instruction(inst_list, "ABORT", 0); -- Error exit from sim
+ define_instruction(inst_list, "FINISH", 0); -- Normal exit from sim
+ define_instruction(inst_list, "INCLUDE", 1); -- Define a Variable
+
+ -- User defined instructions
+
+ ------------------------------------------------------------------------
+ -- Read, test, and load the stimulus file
+ read_instruction_file(stimulus_file, inst_list, defined_vars, inst_sequ,
+ file_list);
+
+ -- initialize last info
+ last_sequ_num := 0;
+ last_sequ_ptr := inst_sequ;
+------------------------------------------------------------------------
+-- Using the Instruction record list, get the instruction and implement
+-- it as per the statements in the elsif tree.
+ while(v_line < inst_sequ.num_of_lines) loop
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+
+--------------------------------------------------------------------------
+ --if(instruction(1 to len) = "DEFINE_VAR") then
+ -- null; -- This instruction was implemented while reading the file
+
+--------------------------------------------------------------------------
+ if(instruction(1 to len) = "INCLUDE") then
+ null; -- This instruction was implemented while reading the file
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "ABORT") then
+ assert (false)
+ report "The test has aborted due to an error!!"
+ severity failure;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "FINISH") then
+ assert (false)
+ report "Test Finished with NO errors!!"
+ severity failure;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "EQU_VAR") then
+ update_variable(defined_vars, par1, par2, valid);
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "ADD_VAR") then
+ index_variable(defined_vars, par1, temp_int, valid);
+ if(valid /= 0) then
+ temp_int := temp_int + par2;
+ update_variable(defined_vars, par1, temp_int, valid);
+ else
+ assert (false)
+ report "ADD_VAR Error: Not a valid Variable??"
+ severity failure;
+ end if;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "SUB_VAR") then
+ index_variable(defined_vars, par1, temp_int, valid);
+ if(valid /= 0) then
+ temp_int := temp_int - par2;
+ update_variable(defined_vars, par1, temp_int, valid);
+ else
+ assert (false)
+ report "SUB_VAR Error: Not a valid Variable??"
+ severity failure;
+ end if;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "CALL") then
+ if(stack_ptr >= 7) then
+ assert (false)
+ report "Call Error: Stack over run, calls to deeply nested!!"
+ severity failure;
+ end if;
+ stack(stack_ptr) := v_line;
+ stack_ptr := stack_ptr + 1;
+ v_line := par1 - 1;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "RETURN_CALL") then
+ if(stack_ptr <= 0) then
+ assert (false)
+ report "Call Error: Stack under run??"
+ severity failure;
+ end if;
+ stack_ptr := stack_ptr - 1;
+ v_line := stack(stack_ptr);
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "JUMP") then
+ v_line := par1 - 1;
+ wh_state := false;
+ wh_stack := (others => 0);
+ wh_dpth := 0;
+ wh_ptr := 0;
+ stack := (others => 0);
+ stack_ptr := 0;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "LOOP") then
+ loop_num := loop_num + 1;
+ loop_line(loop_num) := v_line;
+ curr_loop_count(loop_num) := 0;
+ term_loop_count(loop_num) := par1;
+ assert (messages)
+ report LF & "Executing LOOP Command" &
+ LF & " Nested Loop:" & HT & integer'image(loop_num) &
+ LF & " Loop Length:" & HT & integer'image(par1)
+ severity note;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_LOOP") then
+ curr_loop_count(loop_num) := curr_loop_count(loop_num) + 1;
+ if (curr_loop_count(loop_num) = term_loop_count(loop_num)) then
+ loop_num := loop_num - 1;
+ else
+ v_line := loop_line(loop_num);
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "IF") then
+ if_state := false;
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: IF instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(if_state = false) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ while(instruction(1 to len) /= "ELSE" and
+ instruction(1 to len) /= "ELSEIF" and
+ instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "ELSEIF") then
+ if(if_state = true) then -- if the if_state is true then skip to the end
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ while(instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+
+ else
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: ELSEIF instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(if_state = false) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ while(instruction(1 to len) /= "ELSE" and
+ instruction(1 to len) /= "ELSEIF" and
+ instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ else
+ assert (false)
+ report LF & "ERROR: ELSEIF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "ELSE") then
+ if(if_state = true) then -- if the if_state is true then skip the else
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ while(instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_IF") then
+ null; -- instruction is a place holder for finding the end of IF.
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "WHILE") then
+ wh_state := false;
+ case par2 is
+ when 0 => if(par1 = par3) then wh_state := true; end if;
+ when 1 => if(par1 > par3) then wh_state := true; end if;
+ when 2 => if(par1 < par3) then wh_state := true; end if;
+ when 3 => if(par1 /= par3) then wh_state := true; end if;
+ when 4 => if(par1 >= par3) then wh_state := true; end if;
+ when 5 => if(par1 <= par3) then wh_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: WHILE instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(wh_state = true) then
+ wh_stack(wh_ptr) := v_line;
+ wh_ptr := wh_ptr + 1;
+ else
+ wh_end := false;
+ while(wh_end /= true) loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line,
+ last_sequ_num, last_sequ_ptr);
+ else
+ assert (false)
+ report LF & "ERROR: WHILE instruction unable to find terminating" &
+ LF & " END_WHILE statement."
+ severity failure;
+ end if;
+
+ -- if is a while need to escape it
+ if(instruction(1 to len) = "WHILE") then
+ wh_dpth := wh_dpth + 1;
+ -- if is the end_while we are looking for
+ elsif(instruction(1 to len) = "END_WHILE") then
+ if(wh_dpth = 0) then
+ wh_end := true;
+ else
+ wh_dpth := wh_dpth - 1;
+ end if;
+ end if;
+ end loop;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_WHILE") then
+ if(wh_ptr > 0) then
+ v_line := wh_stack(wh_ptr - 1) - 1;
+ wh_ptr := wh_ptr - 1;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "MESSAGES_OFF") then
+ messages := TRUE;
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "MESSAGES_ON") then
+ messages := FALSE;
+
+
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- USER Istruction area. Add all user instructions below this
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- elsif (instruction(1 to len) = "RESET_SYS") then
+
+
+--------------------------------------------------------------------------------
+-- USER Istruction area. Add all user instructions above this
+--------------------------------------------------------------------------------
+ --------------------------------------------------------------------------
+ -- catch those little mistakes
+ else
+ assert (false)
+ report LF & "ERROR: Seems the command " & instruction(1 to len) & " was defined but" & LF &
+ "was not found in the elsif chain, please check spelling."
+ severity failure;
+ end if; -- else if structure end
+ -- after the instruction is finished print out any txt and sub vars
+ txt_print_wvar(defined_vars, txt, hex);
+ end loop; -- Main Loop end
+
+ assert (false)
+ report LF & "The end of the simulation! It was not terminated as expected." & LF
+ severity failure;
+
+ end process Read_file;
+
+
+end bhv;
Index: vhld_tb/trunk/source/tb_pkg_body.vhd
===================================================================
--- vhld_tb/trunk/source/tb_pkg_body.vhd (nonexistent)
+++ vhld_tb/trunk/source/tb_pkg_body.vhd (revision 14)
@@ -0,0 +1,1871 @@
+-------------------------------------------------------------------------------
+-- Copyright 2007 Ken Campbell
+-------------------------------------------------------------------------------
+-- $Author: sckoarn $
+--
+-- $Date: 2008-02-24 01:34:11 $
+--
+-- $Name: not supported by cvs2svn $
+--
+-- $Id: tb_pkg_body.vhd,v 1.3 2008-02-24 01:34:11 sckoarn Exp $
+--
+-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/tb_pkg_body.vhd,v $
+--
+-- Description : The the testbench package body file.
+-- Initial GNU release.
+--
+------------------------------------------------------------------------------
+--This file is part of The VHDL Test Bench.
+--
+-- The VHDL Test Bench 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 2 of the License, or
+-- (at your option) any later version.
+--
+-- The VHDL Test Bench 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 The VHDL Test Bench; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-------------------------------------------------------------------------------
+-- Revision History:
+-- $Log: not supported by cvs2svn $
+-- Revision 1.2 2007/09/02 04:04:04 sckoarn
+-- Update of version 1.2 tb_pkg
+-- See documentation for details
+--
+-- Revision 1.1.1.1 2007/04/06 04:06:48 sckoarn
+-- Import of the vhld_tb
+--
+--
+-------------------------------------------------------------------------------
+
+package body tb_pkg is
+
+-------------------------------------------------------------------------------
+-- FUNCTION Defs
+-------------------------------------------------------------------------------
+-- is_digit
+ function is_digit(constant c: in character) return boolean is
+ variable rtn : boolean;
+ begin
+ if (c >= '0' and c <= '9') then
+ rtn := true;
+ else
+ rtn := false;
+ end if;
+ return rtn;
+ end is_digit;
+--------------------------------------
+-- is_space
+ function is_space(constant c: in character) return boolean is
+ variable rtn : boolean;
+ begin
+ if(c = ' ' or c = ht) then
+ rtn := true;
+ else
+ rtn := false;
+ end if;
+ return rtn;
+ end is_space;
+------------------------------------------------------------------------------
+-- to_char
+ function ew_to_char(int: integer) return character is
+ variable c: character;
+ begin
+ c := nul;
+ case int is
+ when 0 => c := '0';
+ when 1 => c := '1';
+ when 2 => c := '2';
+ when 3 => c := '3';
+ when 4 => c := '4';
+ when 5 => c := '5';
+ when 6 => c := '6';
+ when 7 => c := '7';
+ when 8 => c := '8';
+ when 9 => c := '9';
+ when 10 => c := 'A';
+ when 11 => c := 'B';
+ when 12 => c := 'C';
+ when 13 => c := 'D';
+ when 14 => c := 'E';
+ when 15 => c := 'F';
+ when others =>
+ assert(false)
+ report LF & "Error: ew_to_char was given a non Number didgit."
+ severity failure;
+ end case;
+
+ return c;
+ end ew_to_char;
+
+-------------------------------------------------------------------------------
+-- to_string function integer
+ function to_str(int: integer) return string is
+ begin
+ return ew_to_str(int,dec) ;
+ end to_str ;
+
+-------------------------------------------------------------------------------
+-- ew_str_cat
+ function ew_str_cat(s1: stm_text;
+ s2: text_field) return stm_text is
+
+ variable i: integer;
+ variable j: integer;
+ variable sc: stm_text;
+
+ begin
+ sc := s1;
+ i := 1;
+ while(sc(i) /= nul) loop
+ i := i + 1;
+ end loop;
+ j := 1;
+ while(s2(j) /= nul) loop
+ sc(i) := s2(j);
+ i := i + 1;
+ j := j + 1;
+ end loop;
+
+ return sc;
+ end ew_str_cat;
+
+-------------------------------------------------------------------------------
+-- fld_len field length
+-- inputs : string of type text_field
+-- return : integer number of non 'nul' chars
+function fld_len(s : in text_field) return integer is
+ variable i: integer := 1;
+ begin
+ while(s(i) /= nul) loop
+ i := i + 1;
+ end loop;
+ return (i - 1);
+ end fld_len;
+------------------------------------------------------------------------------
+-- c2int convert character to integer
+function c2int(c: in character) return integer is
+ variable i: integer;
+begin
+ i := -1;
+ case c is
+ when '0' => i := 0;
+ when '1' => i := 1;
+ when '2' => i := 2;
+ when '3' => i := 3;
+ when '4' => i := 4;
+ when '5' => i := 5;
+ when '6' => i := 6;
+ when '7' => i := 7;
+ when '8' => i := 8;
+ when '9' => i := 9;
+ when others =>
+ assert(false)
+ report LF & "Error: c2int was given a non Number didgit."
+ severity failure;
+ end case;
+ return i;
+end c2int;
+-------------------------------------------------------------------------------
+-- str2integer Convert a string to integer number.
+-- inputs : string
+-- output : int value
+function str2integer(str: in string) return integer is
+ variable l: integer;
+ variable j: integer := 1;
+ variable rtn: integer := 0;
+begin
+ l := fld_len(str);
+
+ for i in l downto 1 loop
+ rtn := rtn + (c2int(str(j)) *(10**(i - 1)));
+ j := j + 1;
+ end loop;
+
+ return rtn;
+end str2integer;
+-------------------------------------------------------------------------------
+-- hex2integer convert hex Stimulus field to integer
+-- inputs : string of type text_field containing only Hex numbers
+-- return : integer value
+function hex2integer(hex_number: in text_field;
+ file_name: in text_line;
+ line: in integer) return integer is
+ variable len: integer;
+ variable temp_field: text_field;
+ variable temp_int: integer;
+ variable power: integer;
+ variable int_number: integer;
+ begin
+ len := fld_len(hex_number);
+ power := 0;
+ temp_int := 0;
+ for i in len downto 1 loop
+ case hex_number(i) is
+ when '0' =>
+ int_number := 0;
+ when '1' =>
+ int_number := 1;
+ when '2' =>
+ int_number := 2;
+ when '3' =>
+ int_number := 3;
+ when '4' =>
+ int_number := 4;
+ when '5' =>
+ int_number := 5;
+ when '6' =>
+ int_number := 6;
+ when '7' =>
+ int_number := 7;
+ when '8' =>
+ int_number := 8;
+ when '9' =>
+ int_number := 9;
+ when 'a' | 'A'=>
+ int_number := 10;
+ when 'b' | 'B'=>
+ int_number := 11;
+ when 'c' | 'C'=>
+ int_number := 12;
+ when 'd' | 'D'=>
+ int_number := 13;
+ when 'e' | 'E'=>
+ int_number := 14;
+ when 'f' | 'F'=>
+ int_number := 15;
+ when others =>
+ assert(false)
+ report LF & "Error: hex2integer found non Hex didgit on line "
+ & (integer'image(line)) & " of file " & file_name
+ severity failure;
+ end case;
+
+ temp_int := temp_int + (int_number *(16 ** power));
+ power := power + 1;
+ end loop;
+
+ return temp_int;
+ end hex2integer;
+-------------------------------------------------------------------------------
+-- convert character to 4 bit vector
+-- input character
+-- output std_logic_vector 4 bits
+function c2std_vec(c: in character) return std_logic_vector is
+begin
+ case c is
+ when '0' => return "0000";
+ when '1' => return "0001";
+ when '2' => return "0010";
+ when '3' => return "0011";
+ when '4' => return "0100";
+ when '5' => return "0101";
+ when '6' => return "0110";
+ when '7' => return "0111";
+ when '8' => return "1000";
+ when '9' => return "1001";
+ when 'a' | 'A' => return "1010";
+ when 'b' | 'B' => return "1011";
+ when 'c' | 'C' => return "1100";
+ when 'd' | 'D' => return "1101";
+ when 'e' | 'E' => return "1110";
+ when 'f' | 'F' => return "1111";
+ when others =>
+ assert(false)
+ report LF & "Error: c2std_vec found non Hex didgit on file line "
+ severity failure;
+ return "XXXX";
+ end case;
+end c2std_vec;
+-------------------------------------------------------------------------------
+-- std_vec2c convert 4 bit std_vector to a character
+-- input std_logic_vector 4 bits
+-- output character
+function std_vec2c(vec: in std_logic_vector(3 downto 0)) return character is
+begin
+ case vec is
+ when "0000" => return '0';
+ when "0001" => return '1';
+ when "0010" => return '2';
+ when "0011" => return '3';
+ when "0100" => return '4';
+ when "0101" => return '5';
+ when "0110" => return '6';
+ when "0111" => return '7';
+ when "1000" => return '8';
+ when "1001" => return '9';
+ when "1010" => return 'A';
+ when "1011" => return 'B';
+ when "1100" => return 'C';
+ when "1101" => return 'D';
+ when "1110" => return 'E';
+ when "1111" => return 'F';
+ when others =>
+ assert(false)
+ report LF & "Error: std_vec2c found non-binary didgit in vec "
+ severity failure;
+ return 'X';
+ end case;
+end std_vec2c;
+-------------------------------------------------------------------------------
+-- bin2integer convert bin Stimulus field to integer
+-- inputs : string of type text_field containing only binary numbers
+-- return : integer value
+function bin2integer(bin_number: in text_field;
+ file_name: in text_line;
+ line: in integer) return integer is
+ variable len: integer;
+ variable temp_field: text_field;
+ variable temp_int: integer;
+ variable power: integer;
+ variable int_number: integer;
+ begin
+ len := fld_len(bin_number);
+ power := 0;
+ temp_int := 0;
+ for i in len downto 1 loop
+ case bin_number(i) is
+ when '0' =>
+ int_number := 0;
+ when '1' =>
+ int_number := 1;
+ when others =>
+ assert(false)
+ report LF & "Error: bin2integer found non Binary didgit on line "
+ & (integer'image(line)) & " of file " & file_name
+ severity failure;
+ end case;
+
+ temp_int := temp_int + (int_number *(2 ** power));
+ power := power + 1;
+ end loop;
+
+ return temp_int;
+ end bin2integer;
+-------------------------------------------------------------------------------
+-- stim_to_integer convert Stimulus field to integer
+-- inputs : string of type text_field "stimulus format of number"
+-- return : integer value
+function stim_to_integer(field: in text_field;
+ file_name: in text_line;
+ line: in integer) return integer is
+ variable len: integer;
+ variable text: text_field;
+ variable value: integer := 1;
+ variable temp_str : string(1 to 48);
+ begin
+ len := fld_len(field);
+
+ case field(1) is
+ when 'x' | 'h' =>
+ value := 2;
+ while(field(value) /= nul) loop
+ temp_str(value - 1) := field(value);
+ value := value + 1;
+ end loop;
+ value := hex2integer(temp_str,file_name,line);
+ when 'b' =>
+ value := 2;
+ while(field(value) /= nul) loop
+ temp_str(value - 1) := field(value);
+ value := value + 1;
+ end loop;
+ value := bin2integer(temp_str,file_name,line);
+ when others =>
+-- value := from_string(field(1 to len));
+ value := str2integer(field);
+ end case;
+ return value;
+ end stim_to_integer;
+
+-------------------------------------------------------------------------------
+-- to_str function with base parameter
+-- Convert integer to number base
+ function ew_to_str(int: integer; b: base) return text_field is
+
+ variable temp : text_field ;
+ variable temp1 : text_field ;
+ variable radix : integer := 0;
+ variable num : integer := 0;
+ variable power : integer := 1;
+ variable len : integer := 1;
+ variable pre : string(1 to 2);
+ variable i : integer;
+ variable j : integer;
+ variable vec : std_logic_vector(31 downto 0);
+
+ begin
+
+ num := int;
+ temp := (others => nul);
+ case b is
+ when bin =>
+ radix := 2; -- depending on what
+ pre := "0b";
+ when oct =>
+ radix := 8; -- base the number is
+ pre := "0o";
+ when hex =>
+ radix := 16; -- to be displayed as
+ pre := "0x";
+ when dec =>
+ radix := 10; -- choose a radix range
+ pre := (others => nul);
+ end case ;
+ -- Now jump through Hoops because of sign
+ if(num < 0 and b = hex) then
+ vec := std_logic_vector(conv_unsigned(int, 32));
+ temp(1) := std_vec2c(vec(31 downto 28));
+ temp(2) := std_vec2c(vec(27 downto 24));
+ temp(3) := std_vec2c(vec(23 downto 20));
+ temp(4) := std_vec2c(vec(19 downto 16));
+ temp(5) := std_vec2c(vec(15 downto 12));
+ temp(6) := std_vec2c(vec(11 downto 8));
+ temp(7) := std_vec2c(vec(7 downto 4));
+ temp(8) := std_vec2c(vec(3 downto 0));
+ else
+ while num >= radix loop -- determine how many
+ len := len + 1; -- characters required
+ num := num / radix; -- to represent the
+ end loop ; -- number.
+ for i in len downto 1 loop -- convert the number to
+ temp(i) := ew_to_char(int/power mod radix); -- a string starting
+ power := power * radix; -- with the right hand
+ end loop ; -- side.
+ end if;
+ -- add prefix if is one
+ if(pre(1) /= nul) then
+ temp1 := temp;
+ i := 1;
+ j := 3;
+ temp(1 to 2) := pre;
+ while(temp1(i) /= nul) loop
+ temp(j) := temp1(i);
+ i := i + 1;
+ j := j + 1;
+ end loop;
+ end if;
+
+ return temp;
+
+ end ew_to_str ;
+
+-------------------------------------------------------------------------------
+-- Procedure to print instruction records to stdout *for debug*
+ procedure print_inst(variable inst : in stim_line_ptr) is
+ variable l: text_line;
+ variable l_i: integer := 1;
+ variable j: integer := 1;
+ begin
+ while (inst.instruction(j) /= nul) loop
+ l(l_i) := inst.instruction(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field one
+ if(inst.inst_field_1(1) /= nul) then
+ while (inst.inst_field_1(j) /= nul) loop
+ l(l_i) := inst.inst_field_1(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field two
+ if(inst.inst_field_2(1) /= nul) then
+ while (inst.inst_field_2(j) /= nul) loop
+ l(l_i) := inst.inst_field_2(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field three
+ if(inst.inst_field_3(1) /= nul) then
+ while (inst.inst_field_3(j) /= nul) loop
+ l(l_i) := inst.inst_field_3(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field four
+ if(inst.inst_field_4(1) /= nul) then
+ while (inst.inst_field_4(j) /= nul) loop
+ l(l_i) := inst.inst_field_4(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ end if;
+ end if;
+ end if;
+ end if;
+ print(l);
+
+ print(" Sequence Number: " & to_str(inst.line_number) &
+ " File Line Number: " & to_str(inst.file_line));
+ if(inst.num_of_lines > 0) then
+ print(" Number of Lines: " & to_str(inst.num_of_lines));
+ end if;
+ end print_inst;
+
+--------------------------------------------------------------------------------
+-- access_variable
+-- inputs:
+-- Text field containing variable
+-- outputs:
+-- value $VAR returns Value of VAR
+-- value VAR returns index of VAR
+--
+-- valid is 1 if valid 0 if not
+ procedure access_variable(variable var_list : in var_field_ptr;
+ variable var : in text_field;
+ variable value : out integer;
+ variable valid : out integer) is
+ variable l : integer;
+ variable l_2 : integer;
+ variable var_ptr : var_field_ptr;
+ variable temp_field : text_field;
+ variable ptr : integer := 0; -- 0 is index, 1 is pointer
+ begin
+ l := fld_len(var);
+ valid := 0;
+ -- if the variable is a special
+ if(var(1) = '=') then
+ value := 0;
+ valid := 1;
+ elsif(var(1 to 2) = ">=") then
+ value := 4;
+ valid := 1;
+ elsif(var(1 to 2) = "<=") then
+ value := 5;
+ valid := 1;
+ elsif(var(1) = '>') then
+ value := 1;
+ valid := 1;
+ elsif(var(1) = '<') then
+ value := 2;
+ valid := 1;
+ elsif(var(1 to 2) = "!=") then
+ value := 3;
+ valid := 1;
+
+ else
+ if(var(1) = '$') then
+ ptr := 1; -- this is a pointer
+ for i in 2 to l loop
+ temp_field(i-1) := var(i);
+ end loop;
+ else
+ temp_field := var;
+ end if;
+
+ var_ptr := var_list;
+ while(var_ptr.next_rec /= null) loop
+ -- if we have a match
+ if(temp_field = var_ptr.var_name) then
+ if(ptr = 1) then
+ value := var_ptr.var_value;
+ valid := 1;
+ else
+ value := var_ptr.var_index;
+ valid := 1;
+ end if;
+ exit;
+ end if;
+ var_ptr := var_ptr.next_rec;
+ end loop;
+
+ -- if we have a match and was the last record
+ if(var_ptr.next_rec = null and temp_field = var_ptr.var_name) then
+ if(ptr = 1) then
+ value := var_ptr.var_value;
+ valid := 1;
+ else
+ value := var_ptr.var_index;
+ valid := 1;
+ end if;
+ end if;
+ end if;
+ end access_variable;
+--------------------------------------------------------------------------------
+-- index_variable
+-- inputs:
+-- index: the index of the variable being accessed
+-- outputs:
+-- Variable Value
+-- valid is 1 if valid 0 if not
+ procedure index_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : out integer;
+ variable valid : out integer) is
+ variable ptr: var_field_ptr;
+ begin
+ ptr := var_list;
+ valid := 0;
+ while(ptr.next_rec /= null) loop
+ if(ptr.var_index = index) then
+ value := ptr.var_value;
+ valid := 1;
+ exit;
+ end if;
+ ptr := ptr.next_rec;
+ end loop;
+ if(ptr.var_index = index) then
+ value := ptr.var_value;
+ valid := 1;
+ end if;
+ end index_variable;
+
+--------------------------------------------------------------------------------
+-- update_variable
+-- inputs:
+-- index: the index of the variable being updated
+-- outputs:
+-- valid is 1 if valid 0 if not
+ procedure update_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : in integer;
+ variable valid : out integer) is
+ variable ptr: var_field_ptr;
+ begin
+ ptr := var_list;
+ valid := 0;
+ while(ptr.next_rec /= null) loop
+ if(ptr.var_index = index) then
+ ptr.var_value := value;
+ valid := 1;
+ exit;
+ end if;
+ ptr := ptr.next_rec;
+ end loop;
+ -- check the current one
+ if(ptr.var_index = index) then
+ ptr.var_value := value;
+ valid := 1;
+ end if;
+ end update_variable;
+
+-------------------------------------------------------------------------------
+-- Read a line from a file
+-- inputs : file of type text
+-- outputs : The line of type text_line
+ procedure file_read_line(file file_name: text;
+ variable file_line: out text_line
+ ) is
+ variable index: integer; -- index into string
+ variable rline: line;
+
+ begin
+
+ index := 1; -- set index to begin of string
+ file_line := (others => nul);
+ if(not endfile(file_name)) then
+ readline(file_name,rline);
+
+ while(rline'right /= (index - 1) and rline'length /= 0) loop
+ file_line(index) := rline(index);
+ index := index + 1;
+ end loop;
+ end if;
+ end file_read_line;
+
+ ------------------------------------------------------------------------------
+ -- procedure to break a line down in to text fields
+ procedure tokenize_line(variable text_line: in text_line;
+ variable token1: out text_field;
+ variable token2: out text_field;
+ variable token3: out text_field;
+ variable token4: out text_field;
+ variable token5: out text_field;
+ variable token6: out text_field;
+ variable token7: out text_field;
+ variable txt_ptr: out stm_text_ptr;
+ variable valid: out integer) is
+ variable token_index: integer := 0;
+ variable current_token: text_field;
+ variable token_number: integer := 0;
+ variable c: string(1 to 2);
+ variable comment_found: integer := 0;
+ variable txt_found: integer := 0;
+ variable j: integer;
+
+ begin
+ -- null outputs
+ token1 := (others => nul);
+ token2 := (others => nul);
+ token3 := (others => nul);
+ token4 := (others => nul);
+ token5 := (others => nul);
+ token6 := (others => nul);
+ token7 := (others => nul);
+ txt_ptr := null;
+ valid := 0;
+ txt_found := 0;
+ j := 1;
+
+ -- loop for max number of char
+ for i in 1 to text_line'high loop
+ -- collect for comment test ** assumed no line will be max 256
+ c(1) := text_line(i);
+ c(2) := text_line(i + 1); -- or this line will blow up
+ if(c = "--") then
+ comment_found := 1;
+ exit;
+ end if;
+ -- if is begin text char '"'
+ if(c(1) = '"') then --" <-- this double quote is just to fix highlighting.
+ txt_found := 1;
+ txt_ptr := new stm_text;
+ next;
+ end if;
+
+ -- if we have found a txt string
+ if (txt_found = 1 and text_line(i) /= nul) then
+ -- if string too long, prevent tool hang, truncate and notify
+ if(j > c_stm_text_len) then
+ print("tokenize_line: truncated txt line, it was larger than c_stm_text_len");
+ exit;
+ end if;
+ txt_ptr(j) := text_line(i);
+ j := j + 1;
+ -- if is a character store in the right token
+ elsif(is_space(text_line(i)) = false and text_line(i) /= nul) then
+ token_index := token_index + 1;
+ current_token(token_index) := text_line(i);
+ -- else is a space, deal with pointers
+ elsif(is_space(text_line(i + 1)) = false and text_line(i + 1) /= nul) then
+ case token_number is
+ when 0 =>
+ if(token_index /= 0) then
+ token1 := current_token;
+ current_token := (others => nul);
+ token_number := 1;
+ valid := 1;
+ token_index := 0;
+ end if;
+ when 1 =>
+ token2 := current_token;
+ current_token := (others => nul);
+ token_number := 2;
+ valid := 2;
+ token_index := 0;
+ when 2 =>
+ token3 := current_token;
+ current_token := (others => nul);
+ token_number := 3;
+ valid := 3;
+ token_index := 0;
+ when 3 =>
+ token4 := current_token;
+ current_token := (others => nul);
+ token_number := 4;
+ valid := 4;
+ token_index := 0;
+ when 4 =>
+ token5 := current_token;
+ current_token := (others => nul);
+ token_number := 5;
+ valid := 5;
+ token_index := 0;
+ when 5 =>
+ token6 := current_token;
+ current_token := (others => nul);
+ token_number := 6;
+ valid := 6;
+ token_index := 0;
+ when 6 =>
+ token7 := current_token;
+ current_token := (others => nul);
+ token_number := 7;
+ valid := 7;
+ token_index := 0;
+ when 7 =>
+ when others =>
+ null;
+ end case;
+ end if;
+ -- break from loop if is null
+ if(text_line(i) = nul) then
+ if(token_index /= 0) then
+ case token_number is
+ when 0 =>
+ token1 := current_token;
+ valid := 1;
+ when 1 =>
+ token2 := current_token;
+ valid := 2;
+ when 2 =>
+ token3 := current_token;
+ valid := 3;
+ when 3 =>
+ token4 := current_token;
+ valid := 4;
+ when 4 =>
+ token5 := current_token;
+ valid := 5;
+ when 5 =>
+ token6 := current_token;
+ valid := 6;
+ when 6 =>
+ token7 := current_token;
+ valid := 7;
+ when others =>
+ null;
+ end case;
+ end if;
+ exit;
+ end if;
+ end loop;
+ -- did we find a comment and there is a token
+ if(comment_found = 1) then
+ if(token_index /= 0) then
+ case token_number is
+ when 0 =>
+ token1 := current_token;
+ valid := 1;
+ when 1 =>
+ token2 := current_token;
+ valid := 2;
+ when 2 =>
+ token3 := current_token;
+ valid := 3;
+ when 3 =>
+ token4 := current_token;
+ valid := 4;
+ when 4 =>
+ token5 := current_token;
+ valid := 5;
+ when 5 =>
+ token6 := current_token;
+ valid := 6;
+ when 6 =>
+ token7 := current_token;
+ valid := 7;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+ end tokenize_line;
+-------------------------------------------------------------------------------
+-- Add a new instruction to the instruction list
+-- inputs : the linked list of instructions
+-- the instruction
+-- the number of args
+-- outputs : Updated instruction set linked list
+ procedure define_instruction(variable inst_set: inout inst_def_ptr;
+ constant inst: in string;
+ constant args: in integer) is
+ variable v_inst_ptr: inst_def_ptr;
+ variable v_prev_ptr: inst_def_ptr;
+ variable v_new_ptr: inst_def_ptr;
+ variable v_temp_inst: inst_def_ptr;
+ variable v_length: integer;
+ variable v_list_size: integer;
+ variable v_dup_error: boolean;
+
+ begin
+ assert(inst'high <= max_field_len)
+ report LF & "Error: Creation of Instruction of length greater than Max_field_len attemped!!" &
+ LF & "This Max is currently set to " & (integer'image(max_field_len))
+ severity failure;
+ -- get to the last element and test is not exsiting
+ v_temp_inst := inst_set;
+ v_inst_ptr := inst_set;
+ -- zero the size
+ v_list_size := 0;
+ while(v_inst_ptr /= null) loop
+ -- if there is a chance of a duplicate command
+ if(v_inst_ptr.instruction_l = inst'high) then
+ v_dup_error := true;
+ for i in 1 to inst'high loop
+ if(v_inst_ptr.instruction(i) /= inst(i)) then
+ v_dup_error := false;
+ end if;
+ end loop;
+ -- if we find a duplicate, die
+ assert(v_dup_error = false)
+ report LF & "Error: Duplicate instruction definition attempted!"
+ severity failure;
+ end if;
+ v_prev_ptr := v_inst_ptr; -- store for pointer updates
+ v_inst_ptr := v_inst_ptr.next_rec;
+ v_list_size := v_list_size + 1;
+ end loop;
+
+ -- add the new instruction
+ v_new_ptr := new inst_def;
+ -- if this is the first command return new pointer
+ if(v_list_size = 0) then
+ v_temp_inst := v_new_ptr;
+ -- else write new pointer to next_rec
+ else
+ v_prev_ptr.next_rec := v_new_ptr;
+ end if;
+ v_new_ptr.instruction_l := inst'high;
+ v_new_ptr.params := args;
+ -- copy the instruction text into field
+ for i in 1 to v_new_ptr.instruction_l loop
+ v_new_ptr.instruction(i) := inst(i);
+ end loop;
+ -- return the pointer
+ inst_set := v_temp_inst;
+
+ end define_instruction;
+
+--------------------------------------------------------------------------------
+-- Check for valid instruction in the list of instructions
+procedure check_valid_inst(variable inst : in text_field;
+ variable inst_set : in inst_def_ptr;
+ variable token_num: in integer;
+ variable line_num : in integer;
+ variable name : in text_line) is
+ variable l : integer := 0;
+ variable seti: inst_def_ptr;
+ variable match: integer := 0;
+ variable ilv: integer := 0; -- inline variable
+ begin
+ -- create useable pointer
+ seti := inst_set;
+ -- count up the characters in inst
+ l := fld_len(inst);
+ -- if this is a referance variable -- handle in add variable Proc
+ if(inst(l) = ':') then
+ match := 1;
+ ilv := 1;
+ else
+ -- process list till null next
+ while (seti.next_rec /= null) loop
+ if(seti.instruction_l = l) then
+ match := 1;
+ for j in 1 to l loop
+ if(seti.instruction(j) /= inst(j)) then
+ match := 0;
+ end if;
+ end loop;
+ end if;
+ if(match = 0) then
+ seti := seti.next_rec;
+ else
+ exit;
+ end if;
+ end loop;
+ -- check current one
+ if(seti.instruction_l = l and match = 0) then
+ match := 1;
+ for j in 1 to l loop
+ if(seti.instruction(j) /= inst(j)) then
+ match := 0;
+ end if;
+ end loop;
+ end if;
+ end if;
+
+ -- if we had a match, check the number of paramiters
+ if(match = 1 and ilv = 0) then
+ assert(seti.params = (token_num - 1))
+ report LF & "Error: Undefined Instruction was found, incorrect number of fields passed!" & LF &
+ "This is found on line " & (integer'image(line_num)) & " in file " & name & LF
+ severity failure;
+ end if;
+
+ -- if we find a duplicate, die
+ assert(match = 1)
+ report LF & "Error: Undefined Instruction on line " & (integer'image(line_num)) &
+ " found in input file " & name & LF
+ severity failure;
+ end check_valid_inst;
+
+--------------------------------------------------------------------------------
+-- add_variable
+-- This procedure adds a variable to the variable list. This is localy
+-- available at this time.
+procedure add_variable(variable var_list : inout var_field_ptr;
+ variable p1 : in text_field; -- should be var name
+ variable p2 : in text_field; -- should be value
+ variable token_num : in integer;
+ variable sequ_num : in integer;
+ variable line_num : in integer;
+ variable name : in text_line;
+ variable length : in integer) is
+
+ variable temp_var: var_field_ptr;
+ variable current_ptr: var_field_ptr;
+ variable index: integer := 1;
+
+ begin
+ -- if this is NOT the first one
+ if(var_list /= null) then
+ current_ptr := var_list;
+ index := index + 1;
+ if(p1(length) /= ':') then -- is not an inline variable
+ while(current_ptr.next_rec /= null) loop
+ -- if we have defined the current before then die
+ assert(current_ptr.var_name /= p1)
+ report LF & "Error: Attemping to add a duplicate Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ current_ptr := current_ptr.next_rec;
+ index := index + 1;
+ end loop;
+ -- if we have defined the current before then die. This checks the last one
+ assert(current_ptr.var_name /= p1)
+ report LF & "Error: Attemping to add a duplicate Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ temp_var := new var_field;
+ temp_var.var_name := p1; -- direct write of text_field
+ temp_var.var_value := stim_to_integer(p2,name,line_num); -- convert text_field to integer
+ temp_var.var_index := index;
+ current_ptr.next_rec := temp_var;
+ else
+ while(current_ptr.next_rec /= null) loop
+ -- if we have defined the current before then die
+ assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
+ report LF & "Error: Attemping to add a duplicate Inline Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ current_ptr := current_ptr.next_rec;
+ index := index + 1;
+ end loop;
+ -- if we have defined the current before then die. This checks the last one
+ assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
+ report LF & "Error: Attemping to add a duplicate Inline Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ temp_var := new var_field;
+ temp_var.var_name(1 to (length - 1)) := p1(1 to (length - 1));
+ temp_var.var_value := sequ_num;
+ temp_var.var_index := index;
+ current_ptr.next_rec := temp_var;
+ end if;
+ -- this is the first one
+ else
+ if(p1(length) /= ':') then -- is not an inline variable
+ temp_var := new var_field;
+ temp_var.var_name := p1; -- direct write of text_field
+ temp_var.var_index := index;
+ temp_var.var_value := stim_to_integer(p2,name,line_num); -- convert text_field to integer
+ var_list := temp_var;
+ else
+ temp_var := new var_field;
+ temp_var.var_name(1 to (length - 1)) := p1(1 to (length - 1));
+ temp_var.var_value := sequ_num;
+ temp_var.var_index := index;
+ var_list := temp_var;
+ end if;
+ end if;
+ end add_variable;
+--------------------------------------------------------------------------------
+-- add_instruction
+-- This is the procedure that adds the instruction to the linked list of
+-- instructions. Also Variable addition are called and or handled.
+-- the instruction sequence Link list.
+-- inputs:
+-- stim_line_ptr is the pointer to the instruction List
+-- inst is the instruction token
+-- p1 paramitor one, corrisponds to field one of stimulus
+-- p2 paramitor one, corrisponds to field two of stimulus
+-- p3 paramitor one, corrisponds to field three of stimulus
+-- p4 paramitor one, corrisponds to field four of stimulus
+-- p5 paramitor one, corrisponds to field three of stimulus
+-- p6 paramitor one, corrisponds to field four of stimulus
+-- str_ptr pointer to string for print instruction
+-- token_num the number of tokens, including instruction
+-- sequ_num is the stimulus file line referance ie program line number
+-- line_num Line number in the text file
+-- outputs:
+-- none. Error will terminate sim
+ procedure add_instruction(variable inst_list : inout stim_line_ptr;
+ variable var_list : inout var_field_ptr;
+ variable inst : in text_field;
+ variable p1 : in text_field;
+ variable p2 : in text_field;
+ variable p3 : in text_field;
+ variable p4 : in text_field;
+ variable p5 : in text_field;
+ variable p6 : in text_field;
+ variable str_ptr : in stm_text_ptr;
+ variable token_num : in integer;
+ variable sequ_num : inout integer;
+ variable line_num : in integer;
+ variable file_name : in text_line;
+ variable file_idx : in integer) is
+ variable temp_stim_line: stim_line_ptr;
+ variable temp_current: stim_line_ptr;
+ variable valid: integer;
+ variable l: integer;
+ begin
+ valid := 1;
+ l := fld_len(inst);
+ temp_current := inst_list;
+ -- take care of special cases
+ if(inst(1 to l) = "DEFINE_VAR") then
+ l := fld_len(p1);
+ -- Add the variable to the Variable pool, not considered an instruction
+ add_variable(var_list,p1,p2,token_num,sequ_num,line_num,file_name,l);
+ valid := 0; --Removes this from the instruction list
+ elsif(inst(l) = ':') then
+ add_variable(var_list,inst,p1,token_num,sequ_num,line_num,file_name,l);
+ valid := 0;
+ end if;
+
+ if(valid = 1) then
+ -- prepare the new record
+ temp_stim_line := new stim_line;
+ temp_stim_line.instruction := inst;
+ temp_stim_line.inst_field_1 := p1;
+ temp_stim_line.inst_field_2 := p2;
+ temp_stim_line.inst_field_3 := p3;
+ temp_stim_line.inst_field_4 := p4;
+ temp_stim_line.inst_field_5 := p5;
+ temp_stim_line.inst_field_6 := p6;
+ temp_stim_line.txt := str_ptr;
+ temp_stim_line.line_number := sequ_num;
+ temp_stim_line.file_idx := file_idx;
+ temp_stim_line.file_line := line_num;
+
+ -- if is not the first instruction
+ if(inst_list /= null) then
+ while(temp_current.next_rec /= null) loop
+ temp_current := temp_current.next_rec;
+ end loop;
+ temp_current.next_rec := temp_stim_line;
+ inst_list.num_of_lines := inst_list.num_of_lines + 1;
+ -- other wise is first instruction to be added
+ else
+ inst_list := temp_stim_line;
+ inst_list.num_of_lines := 1;
+ end if;
+ sequ_num := sequ_num + 1;
+-- print_inst(temp_stim_line); -- for debug
+ end if;
+
+ end add_instruction;
+------------------------------------------------------------------------------
+-- test_inst_sequ
+-- This procedure accesses the full instruction sequence and checks for valid
+-- variables. This is prior to the simulation run start.
+ procedure test_inst_sequ(variable inst_sequ : in stim_line_ptr;
+ variable file_list : in file_def_ptr;
+ variable var_list : in var_field_ptr
+ ) is
+ variable temp_text_field: text_field;
+ variable temp_var: text_field;
+ variable inst_ptr: stim_line_ptr;
+ variable valid: integer;
+ variable line: integer; -- value of the file_line
+ variable file_name: text_line;
+ variable v_p: integer;
+ variable inst : text_field;
+ variable txt : stm_text_ptr;
+ variable inst_len : integer;
+ variable fname : text_line;
+ variable file_line : integer;
+ variable temp_fn_prt: file_def_ptr;
+ variable tmp_int : integer;
+
+ begin
+ inst_ptr := inst_sequ;
+ -- go through all the instructions
+ while(inst_ptr.next_rec /= null) loop
+ inst := inst_ptr.instruction;
+ inst_len := fld_len(inst_ptr.instruction);
+ file_line := inst_ptr.file_line;
+ line := inst_ptr.file_line;
+ -- recover the file name this line came from
+ temp_fn_prt := file_list;
+ tmp_int := inst_ptr.file_idx;
+ while (temp_fn_prt.next_rec /= null) loop
+ if(temp_fn_prt.rec_idx = tmp_int) then
+ exit;
+ end if;
+ temp_fn_prt := temp_fn_prt.next_rec;
+ end loop;
+ for i in 1 to fname'high loop
+ file_name(i) := temp_fn_prt.file_name(i);
+ end loop;
+
+ txt := inst_ptr.txt;
+ -- load parameter one
+ temp_text_field := inst_ptr.inst_field_1;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric do nothing
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
+ null;
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,v_p,valid);
+ assert(valid = 1)
+ report LF & "Error: First variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter two
+ temp_text_field := inst_ptr.inst_field_2;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric do nothing
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
+ null;
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,v_p,valid);
+ assert(valid = 1)
+ report LF & "Error: Second variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter three
+ temp_text_field := inst_ptr.inst_field_3;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric do nothing
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
+ null;
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,v_p,valid);
+ assert(valid = 1)
+ report LF & "Error: Third variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter four
+ temp_text_field := inst_ptr.inst_field_4;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric do nothing
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b'or is_digit(temp_text_field(1)) = true) then
+ null;
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,v_p,valid);
+ assert(valid = 1)
+ report LF & "Error: Forth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter five
+ temp_text_field := inst_ptr.inst_field_5;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric do nothing
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
+ null;
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,v_p,valid);
+ assert(valid = 1)
+ report LF & "Error: Fifth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter six
+ temp_text_field := inst_ptr.inst_field_6;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b' or is_digit(temp_text_field(1)) = true) then
+ null;
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,v_p,valid);
+ assert(valid = 1)
+ report LF & "Error: Sixth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- point to next record
+ inst_ptr := inst_ptr.next_rec;
+ end loop;
+
+ end test_inst_sequ;
+--------------------------------------------------------------------------------
+-- The read include file procedure
+-- This is the main procedure for reading, parcing, checking and returning
+-- the instruction sequence Link list.
+ procedure read_include_file(variable name: text_line;
+ variable sequ_numb: inout integer;
+ variable file_list: inout file_def_ptr;
+ variable inst_set: inout inst_def_ptr;
+ variable var_list: inout var_field_ptr;
+ variable inst_sequ: inout stim_line_ptr;
+ variable status: inout integer) is
+ variable l: text_line; -- the line
+ variable l_num: integer; -- line number file
+ variable sequ_line: integer; -- line number program
+ variable t1: text_field;
+ variable t2: text_field;
+ variable t3: text_field;
+ variable t4: text_field;
+ variable t5: text_field;
+ variable t6: text_field;
+ variable t7: text_field;
+ variable t_txt: stm_text_ptr;
+ variable valid: integer;
+ variable v_inst_ptr: inst_def_ptr;
+ variable v_var_prt: var_field_ptr;
+ variable v_sequ_ptr: stim_line_ptr;
+ variable v_len: integer;
+ variable v_stat: file_open_status;
+ variable idx: integer;
+ variable v_tmp: text_line;
+
+ variable v_tmp_fn_ptr: file_def_ptr;
+ variable v_new_fn: integer;
+ variable v_tmp_fn: file_def_ptr;
+ variable v_txt: stm_text; --stm_text_ptr;
+
+ begin
+ sequ_line := sequ_numb;
+ v_tmp_fn_ptr := file_list;
+ -- for linux systems, trailing spaces need to be removed
+ -- from file names
+ -- copy text string to temp
+ for i in 1 to c_stm_text_len loop
+ if(name(i) = nul) then
+ v_tmp(i) := name(i);
+ exit;
+ else
+ v_tmp(i) := name(i);
+ end if;
+ end loop;
+ --fix up any trailing white space in txt
+ idx := 0;
+ -- get to the end of the string
+ for i in 1 to c_stm_text_len loop
+ if(v_tmp(i) /= nul) then
+ idx := idx + 1;
+ else
+ exit;
+ end if;
+ end loop;
+ -- now nul out spaces
+ for i in idx downto 1 loop
+ if(is_space(v_tmp(i)) = true) then
+ v_tmp(i) := nul;
+ else
+ exit;
+ end if;
+ end loop;
+ -- open include file
+ file_open(v_stat, include_file, v_tmp, read_mode);
+ if(v_stat /= open_ok) then
+ print("Error: Unable to open include file " & name);
+ status := 1;
+ return;
+ end if;
+ l_num := 1; -- initialize line number
+
+ -- the file is opened, put it on the file name LL
+ while (v_tmp_fn_ptr.next_rec /= null) loop
+ v_tmp_fn_ptr := v_tmp_fn_ptr.next_rec;
+ end loop;
+ v_new_fn := v_tmp_fn_ptr.rec_idx + 1;
+ v_tmp_fn := new file_def;
+ v_tmp_fn_ptr.next_rec := v_tmp_fn;
+ v_tmp_fn.rec_idx := v_new_fn;
+
+ -- nul the text line
+ v_tmp_fn.file_name := (others => nul);
+ for i in 1 to name'high loop
+ v_tmp_fn.file_name(i) := name(i);
+ end loop;
+ v_tmp_fn.next_rec := null;
+
+
+ v_inst_ptr := inst_set;
+ v_var_prt := var_list;
+ v_sequ_ptr := inst_sequ;
+
+ -- while not the end of file read it
+ while(not endfile(include_file)) loop
+ file_read_line(include_file,l);
+ -- tokenize the line
+ tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
+ v_len := fld_len(t1);
+ if(t1(1 to v_len) = "INCLUDE") then
+ print("Nested INCLUDE statement found in " & v_tmp & " on line " &
+ (integer'image(l_num)));
+ assert(false)
+ report LF & "Error: Nested INCLUDE statements are not supported at this time."
+ severity failure;
+
+ -- if there was valid tokens
+ elsif(valid /= 0) then
+ check_valid_inst(t1, v_inst_ptr, valid, l_num, name);
+ add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,
+ sequ_line,l_num,name,v_new_fn);
+ end if;
+ l_num := l_num + 1;
+ end loop; -- end loop read file
+ file_close(include_file);
+ sequ_numb := sequ_line;
+ inst_set := v_inst_ptr;
+ var_list := v_var_prt;
+ inst_sequ := v_sequ_ptr;
+ end read_include_file;
+
+--------------------------------------------------------------------------------
+-- The read instruction file procedure
+-- This is the main procedure for reading, parcing, checking and returning
+-- the instruction sequence Link list.
+ procedure read_instruction_file(constant file_name: string;
+ variable inst_set: inout inst_def_ptr;
+ variable var_list: inout var_field_ptr;
+ variable inst_sequ: inout stim_line_ptr;
+ variable file_list: inout file_def_ptr) is
+ variable l: text_line; -- the line
+ variable l_num: integer; -- line number file
+ variable sequ_line: integer; -- line number program
+ variable t1: text_field;
+ variable t2: text_field;
+ variable t3: text_field;
+ variable t4: text_field;
+ variable t5: text_field;
+ variable t6: text_field;
+ variable t7: text_field;
+ variable t_txt: stm_text_ptr;
+ variable valid: integer;
+ variable v_ostat: integer;
+ variable v_inst_ptr: inst_def_ptr;
+ variable v_var_prt: var_field_ptr;
+ variable v_sequ_ptr: stim_line_ptr;
+ variable v_len: integer;
+ variable v_stat: file_open_status;
+ variable v_name: text_line;
+ variable v_iname: text_line;
+ variable v_tmp_fn: file_def_ptr;
+ variable v_fn_idx: integer;
+ variable v_idx: integer;
+
+ begin
+ -- open the stimulus_file and check
+ file_open(v_stat, stimulus, file_name, read_mode);
+ assert(v_stat = open_ok)
+ report LF & "Error: Unable to open stimulus_file " & file_name
+ severity failure;
+ -- copy file name to type text_line
+ for i in 1 to file_name'high loop
+ v_name(i) := file_name(i);
+ end loop;
+ -- the first item on the file names link list
+ file_list := null;
+ v_tmp_fn := new file_def;
+ v_tmp_fn.rec_idx := 1;
+ v_fn_idx := 1;
+ v_idx := 1;
+ -- nul the text line
+ v_tmp_fn.file_name := (others => nul);
+ for i in 1 to file_name'high loop
+ v_tmp_fn.file_name(i) := file_name(i);
+ end loop;
+ v_tmp_fn.next_rec := null;
+
+ l_num := 1;
+ sequ_line := 1;
+ v_ostat := 0;
+
+ v_inst_ptr := inst_set;
+ v_var_prt := var_list;
+ v_sequ_ptr := inst_sequ;
+
+ -- while not the end of file read it
+ while(not endfile(stimulus)) loop
+ file_read_line(stimulus,l);
+ -- tokenize the line
+ tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
+ v_len := fld_len(t1);
+ -- if there is an INCLUDE instruction
+ if(t1(1 to v_len) = "INCLUDE") then
+ -- if file name is in par2
+ if(valid = 2) then
+ v_iname := (others => nul);
+ for i in 1 to max_field_len loop
+ v_iname(i) := t2(i);
+ end loop;
+ -- elsif the text string is not null
+ elsif(t_txt /= null) then
+ v_iname := (others => nul);
+ for i in 1 to c_stm_text_len loop
+ v_iname(i) := t_txt(i);
+ if(t_txt(i) = nul) then
+ exit;
+ end if;
+ end loop;
+ else
+ assert(false)
+ report LF & "Error: INCLUDE instruction has not file name included. Found on" & LF &
+ "line " & (integer'image(l_num)) & " in file " & file_name & LF
+ severity failure;
+ end if;
+ print("INCLUDE found: Loading file " & v_iname);
+ read_include_file(v_iname,sequ_line,v_tmp_fn,v_inst_ptr,v_var_prt,v_sequ_ptr,v_ostat);
+ -- if include file not found
+ if(v_ostat = 1) then
+ exit;
+ end if;
+ -- if there was valid tokens
+ elsif(valid /= 0) then
+ check_valid_inst(t1, v_inst_ptr, valid, l_num, v_name);
+ add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,
+ sequ_line,l_num,v_name,v_fn_idx);
+ end if;
+ l_num := l_num + 1;
+ end loop; -- end loop read file
+
+ file_close(stimulus); -- close the file when done
+
+ assert(v_ostat = 0)
+ report LF & "Include file specified on line " & (integer'image(l_num)) &
+ " in file " & file_name &
+ " was not found! Test Terminated" & LF
+ severity failure;
+
+ inst_set := v_inst_ptr;
+ var_list := v_var_prt;
+ inst_sequ := v_sequ_ptr;
+ file_list := v_tmp_fn;
+
+ -- Now that all the stimulus is loaded, test for invalid variables
+ test_inst_sequ(inst_sequ, v_tmp_fn, var_list);
+
+ end read_instruction_file;
+
+------------------------------------------------------------------------------
+-- access_inst_sequ
+-- This procedure accesses the instruction sequence and returns the parameters
+-- as they exsist related to the variables state.
+-- INPUTS: inst_sequ link list of instructions from stimulus
+-- var_list link list of variables
+-- file_list link list of file names
+-- sequ_num the sequence number to recover
+--
+-- OUTPUTS: inst instruction text
+-- p1 paramiter 1 in integer form
+-- p2 paramiter 2 in integer form
+-- p3 paramiter 3 in integer form
+-- p4 paramiter 4 in integer form
+-- p5 paramiter 5 in integer form
+-- p6 paramiter 6 in integer form
+-- txt pointer to any text string of this sequence
+-- inst_len the lenth of inst in characters
+-- fname file name this sequence came from
+-- file_line the line number in fname this sequence came from
+--
+ procedure access_inst_sequ(variable inst_sequ : in stim_line_ptr;
+ variable var_list : in var_field_ptr;
+ variable file_list : in file_def_ptr;
+ variable sequ_num : in integer;
+ variable inst : out text_field;
+ variable p1 : out integer;
+ variable p2 : out integer;
+ variable p3 : out integer;
+ variable p4 : out integer;
+ variable p5 : out integer;
+ variable p6 : out integer;
+ variable txt : out stm_text_ptr;
+ variable inst_len : out integer;
+ variable fname : out text_line;
+ variable file_line : out integer;
+ variable last_num : inout integer;
+ variable last_ptr : inout stim_line_ptr
+ ) is
+ variable temp_text_field: text_field;
+ variable temp_var: text_field;
+ variable inst_ptr: stim_line_ptr;
+ variable valid: integer;
+ variable line: integer; -- value of the file_line
+ variable file_name: text_line;
+ variable tmp_int: integer;
+ variable temp_fn_prt: file_def_ptr;
+ begin
+ -- get to the instruction indicated by sequ_num
+ -- check to see if this sequence is before the last
+ -- so search from start
+ if(last_num > sequ_num) then
+ inst_ptr := inst_sequ;
+ while(inst_ptr.next_rec /= null) loop
+ if(inst_ptr.line_number = sequ_num) then
+ exit;
+ else
+ inst_ptr := inst_ptr.next_rec;
+ end if;
+ end loop;
+ -- else is equal or greater, so search forward
+ else
+ inst_ptr := last_ptr;
+ while(inst_ptr.next_rec /= null) loop
+ if(inst_ptr.line_number = sequ_num) then
+ exit;
+ else
+ inst_ptr := inst_ptr.next_rec;
+ end if;
+ end loop;
+ end if;
+
+ -- update the last sequence number and record pointer
+ last_num := sequ_num;
+ last_ptr := inst_ptr;
+
+ -- output the instruction and its length
+ inst := inst_ptr.instruction;
+ inst_len := fld_len(inst_ptr.instruction);
+ file_line := inst_ptr.file_line;
+ line := inst_ptr.file_line;
+ -- recover the file name this line came from
+ temp_fn_prt := file_list;
+ tmp_int := inst_ptr.file_idx;
+ while (temp_fn_prt.next_rec /= null) loop
+ if(temp_fn_prt.rec_idx = tmp_int) then
+ exit;
+ end if;
+ temp_fn_prt := temp_fn_prt.next_rec;
+ end loop;
+ for i in 1 to fname'high loop
+ file_name(i) := temp_fn_prt.file_name(i);
+ end loop;
+
+ txt := inst_ptr.txt;
+ -- load parameter one
+ temp_text_field := inst_ptr.inst_field_1;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p1 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p1 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p1,valid);
+ assert(valid = 1)
+ report LF & "Error: First variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter two
+ temp_text_field := inst_ptr.inst_field_2;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p2 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p2 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p2,valid);
+ assert(valid = 1)
+ report LF & "Error: Second variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter three
+ temp_text_field := inst_ptr.inst_field_3;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p3 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p3 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p3,valid);
+ assert(valid = 1)
+ report LF & "Error: Third variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter four
+ temp_text_field := inst_ptr.inst_field_4;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p4 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p4 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p4,valid);
+ assert(valid = 1)
+ report LF & "Error: Forth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter five
+ temp_text_field := inst_ptr.inst_field_5;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p5 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p5 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p5,valid);
+ assert(valid = 1)
+ report LF & "Error: Fifth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter six
+ temp_text_field := inst_ptr.inst_field_6;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p6 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p6 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p6,valid);
+ assert(valid = 1)
+ report LF & "Error: Sixth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ end access_inst_sequ;
+
+-------------------------------------------------------------------------
+-- dump inst_sequ
+-- This procedure dumps to the simulation window the current instruction
+-- sequence. The whole thing will be dumped, which could be big.
+-- ** intended for testbench development debug **
+-- procedure dump_inst_sequ(variable inst_sequ : in stim_line_ptr) is
+-- variable v_sequ : stim_line_ptr;
+-- begin
+-- v_sequ := inst_sequ;
+-- while(v_sequ.next_rec /= null) loop
+-- print("-----------------------------------------------------------------");
+-- print("Instruction is " & v_sequ.instruction &
+-- " Par1: " & v_sequ.inst_field_1 &
+-- " Par2: " & v_sequ.inst_field_2 &
+-- " Par3: " & v_sequ.inst_field_3 &
+-- " Par4: " & v_sequ.inst_field_4);
+-- print("Line Number: " & to_str(v_sequ.line_number) & " File Line Number: " & to_str(v_sequ.file_line) &
+-- " File Name: " & v_sequ.file_name);
+--
+-- v_sequ := v_sequ.next_rec;
+-- end loop;
+-- -- get the last one
+-- print("-----------------------------------------------------------------");
+-- print("Instruction is " & v_sequ.instruction & " Par1: " & v_sequ.inst_field_1 &
+-- " Par2: " & v_sequ.inst_field_2 & " Par3: " & v_sequ.inst_field_3 &
+-- " Par4: " & v_sequ.inst_field_4);
+-- print("Line Number: " & to_str(v_sequ.line_number) & " File Line Number: " & to_str(v_sequ.file_line) &
+-- " File Name: " & v_sequ.file_name);
+-- end dump_inst_sequ;
+
+-------------------------------------------------------------------------------
+-- Procedure to print messages to stdout
+ procedure print(s: in string) is
+ variable l: line;
+ begin
+ write(l, s);
+ writeline(output,l);
+ end print;
+
+-------------------------------------------------------------------------------
+-- procedure to print to the stdout the txt pointer
+ procedure txt_print(variable ptr: in stm_text_ptr) is
+ variable txt_str : stm_text;
+ begin
+
+ if (ptr /= null) then
+ txt_str := (others => nul);
+ for i in 1 to c_stm_text_len loop
+ if (ptr(i) = nul) then
+ exit;
+ end if;
+ txt_str(i) := ptr(i);
+ end loop;
+ print(txt_str);
+ end if;
+ end txt_print;
+
+-------------------------------------------------------------------------------
+-- procedure to print to the stdout the txt pointer, and
+-- sub any variables found
+ procedure txt_print_wvar(variable var_list : in var_field_ptr;
+ variable ptr : in stm_text_ptr;
+ constant b : in base) is
+
+ variable i: integer;
+ variable j: integer;
+ variable k: integer;
+ variable txt_str: stm_text;
+ variable tmp_str: stm_text;
+ variable v1: integer;
+ variable valid: integer;
+ variable tmp_field: text_field;
+ variable tmp_i: integer;
+
+ begin
+ if(ptr /= null) then
+ i := 1;
+ j := 1;
+ txt_str := (others => nul);
+ while(i <= c_stm_text_len and j <= c_stm_text_len) loop
+ if(ptr(i) /= '$') then
+ txt_str(j) := ptr(i);
+ i := i + 1;
+ j := j + 1;
+ else
+ tmp_field := (others => nul);
+ tmp_i := 1;
+ tmp_field(tmp_i) := ptr(i);
+ i := i + 1;
+ tmp_i := tmp_i + 1;
+ -- parse to the next space
+ while(ptr(i) /= ' ' and ptr(i) /= nul) loop
+ tmp_field(tmp_i) := ptr(i);
+ i := i + 1;
+ tmp_i := tmp_i + 1;
+ end loop;
+ access_variable(var_list,tmp_field,v1,valid);
+ assert(valid = 1)
+ report LF & "Invalid Variable found in stm_text_ptr: ignoring."
+ severity warning;
+
+ if(valid = 1) then
+
+ txt_str := ew_str_cat(txt_str, ew_to_str(v1, b));
+ k := 1;
+ while(txt_str(k) /= nul) loop
+ k := k + 1;
+ end loop;
+ j := k;
+ end if;
+ end if;
+ end loop;
+ -- print the created string
+ print(txt_str);
+ end if;
+ end txt_print_wvar;
+
+end tb_pkg;
+
Index: vhld_tb/trunk/source/tb_pkg_header.vhd
===================================================================
--- vhld_tb/trunk/source/tb_pkg_header.vhd (nonexistent)
+++ vhld_tb/trunk/source/tb_pkg_header.vhd (revision 14)
@@ -0,0 +1,239 @@
+-------------------------------------------------------------------------------
+-- Copyright 2007 Ken Campbell
+-------------------------------------------------------------------------------
+-- $Author: sckoarn $
+--
+-- $Date: 2008-02-24 01:34:11 $
+--
+-- $Name: not supported by cvs2svn $
+--
+-- $Id: tb_pkg_header.vhd,v 1.4 2008-02-24 01:34:11 sckoarn Exp $
+--
+-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/tb_pkg_header.vhd,v $
+--
+-- Description : The the testbench package header file.
+-- Initial GNU release.
+--
+------------------------------------------------------------------------------
+--This file is part of The VHDL Test Bench.
+--
+-- The VHDL Test Bench 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 2 of the License, or
+-- (at your option) any later version.
+--
+-- The VHDL Test Bench 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 The VHDL Test Bench; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-------------------------------------------------------------------------------
+-- Revision History:
+-- $Log: not supported by cvs2svn $
+-- Revision 1.3 2007/09/02 04:04:04 sckoarn
+-- Update of version 1.2 tb_pkg
+-- See documentation for details
+--
+-- Revision 1.2 2007/08/21 02:43:14 sckoarn
+-- Fix package definition to match with body
+--
+-- Revision 1.1.1.1 2007/04/06 04:06:48 sckoarn
+-- Import of the vhld_tb
+--
+--
+-------------------------------------------------------------------------------
+library IEEE;
+
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use std.textio.all;
+library ieee_proposed;
+use ieee_proposed.STD_LOGIC_1164_additions.all;
+
+package tb_pkg is
+
+ -- Constants
+ constant max_str_len : integer := 256;
+ constant max_field_len : integer := 48;
+ constant c_stm_text_len : integer := 200;
+ -- file handles
+ file stimulus : text; -- file main file
+ file include_file : text; -- file declaration for includes
+
+ -- Type Def's
+ type base is (bin, oct, hex, dec);
+-- subtype stack_element is integer range 0 to 8192;
+ type stack_register is array(7 downto 0) of integer;
+ type state_register is array(7 downto 0) of boolean;
+ type int_array is array(1 to 16) of integer;
+
+ subtype text_line is string(1 to max_str_len);
+ subtype text_field is string(1 to max_field_len);
+ subtype stm_text is string(1 to c_stm_text_len);
+ type stm_text_ptr is access stm_text;
+ -- define the stimulus line record and access
+ type stim_line;
+ type stim_line_ptr is access stim_line; -- Pointer to stim_line record
+ type stim_line is record
+ instruction: text_field;
+ inst_field_1: text_field;
+ inst_field_2: text_field;
+ inst_field_3: text_field;
+ inst_field_4: text_field;
+ inst_field_5: text_field;
+ inst_field_6: text_field;
+ txt: stm_text_ptr;
+ line_number: integer; -- sequence line
+ num_of_lines: integer; -- total number of lines
+ file_line: integer; -- file line number
+ file_idx: integer;
+ next_rec: stim_line_ptr;
+ end record;
+ -- define the variables field and pointer
+ type var_field;
+ type var_field_ptr is access var_field; -- pointer to var_field
+ type var_field is record
+ var_name: text_field;
+ var_index: integer;
+ var_value: integer;
+ next_rec: var_field_ptr;
+ end record;
+ -- define the instruction structure
+ type inst_def;
+ type inst_def_ptr is access inst_def;
+ type inst_def is record
+ instruction: text_field;
+ instruction_l: integer;
+ params: integer;
+ next_rec: inst_def_ptr;
+ end record;
+ -- define the file handle record
+ type file_def;
+ type file_def_ptr is access file_def;
+ type file_def is record
+ rec_idx: integer;
+ file_name: text_line;
+ next_rec: file_def_ptr;
+ end record;
+
+---*****************************************************************************
+ -- Function Declaration
+-- function str_len(variable line: text_line) return text_field;
+-- function fld_len(s : in text_field) integer;
+
+ function c2std_vec(c: in character) return std_logic_vector;
+
+--------------------------------------------------------------------------------
+ -- Procedure declarations
+--------------------------------------------------------------------------
+-- define_instruction
+-- inputs file_name the file to be read from
+--
+-- output file_line a line of text from the file
+ procedure define_instruction(variable inst_set: inout inst_def_ptr;
+ constant inst: in string;
+ constant args: in integer);
+
+--------------------------------------------------------------------------------
+-- index_variable
+-- inputs:
+-- index: the index of the variable being accessed
+-- outputs:
+-- Variable Value
+-- valid is 1 if valid 0 if not
+ procedure index_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : out integer;
+ variable valid : out integer);
+
+--------------------------------------------------------------------------------
+-- update_variable
+-- inputs:
+-- index: the index of the variable being accessed
+-- outputs:
+-- Variable Value
+-- valid is 1 if valid 0 if not
+ procedure update_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : in integer;
+ variable valid : out integer);
+
+-------------------------------------------------------------------------------
+-- read_instruction_file
+-- This procedure reads the instruction file, name passed throught file_name.
+-- Pointers to records are passed in and out. A table of variables is created
+-- with variable name and value (converted to integer). The instructions are
+-- parsesed into the inst_sequ list. Instructions are validated against the
+-- inst_set which must have been set up prior to loading the instruction file.
+ procedure read_instruction_file(constant file_name: string;
+ variable inst_set: inout inst_def_ptr;
+ variable var_list: inout var_field_ptr;
+ variable inst_sequ: inout stim_line_ptr;
+ variable file_list: inout file_def_ptr);
+
+------------------------------------------------------------------------------
+-- access_inst_sequ
+-- This procedure retreeves an instruction from the sequence of instructions.
+-- Based on the line number you pass to it, it returns the instruction with
+-- any variables substituted as integers.
+ procedure access_inst_sequ(variable inst_sequ : in stim_line_ptr;
+ variable var_list : in var_field_ptr;
+ variable file_list : in file_def_ptr;
+ variable sequ_num : in integer;
+ variable inst : out text_field;
+ variable p1 : out integer;
+ variable p2 : out integer;
+ variable p3 : out integer;
+ variable p4 : out integer;
+ variable p5 : out integer;
+ variable p6 : out integer;
+ variable txt : out stm_text_ptr;
+ variable inst_len : out integer;
+ variable fname : out text_line;
+ variable file_line : out integer;
+ variable last_num : inout integer;
+ variable last_ptr : inout stim_line_ptr
+ );
+------------------------------------------------------------------------
+-- tokenize_line
+-- This procedure takes a type text_line in and returns up to 6
+-- tokens and the count in integer valid, as well if text string
+-- is found the pointer to that is returned.
+ procedure tokenize_line(variable text_line: in text_line;
+ variable token1: out text_field;
+ variable token2: out text_field;
+ variable token3: out text_field;
+ variable token4: out text_field;
+ variable token5: out text_field;
+ variable token6: out text_field;
+ variable token7: out text_field;
+ variable txt_ptr: out stm_text_ptr;
+ variable valid: out integer);
+-------------------------------------------------------------------------
+-- string convertion
+ function ew_to_str(int: integer; b: base) return text_field;
+ function to_str(int: integer) return string;
+
+-------------------------------------------------------------------------
+-- Procedre print
+-- print to stdout string
+ procedure print(s: in string);
+-------------------------------------------------------------------------
+-- Procedure print stim txt
+ procedure txt_print(variable ptr: in stm_text_ptr);
+-------------------------------------------------------------------------
+-- Procedure print stim txt sub variables found
+ procedure txt_print_wvar(variable var_list : in var_field_ptr;
+ variable ptr : in stm_text_ptr;
+ constant b : in base);
+-------------------------------------------------------------------------
+-- dump inst_sequ
+-- This procedure dumps to the simulation window the current instruction
+-- sequence. The whole thing will be dumped, which could be big.
+-- ** intended for testbench development debug**
+-- procedure dump_inst_sequ(variable inst_sequ : in stim_line_ptr);
+
+end tb_pkg;
Index: vhld_tb/trunk/source/std_logic_1164_additions/std_logic_1164_additions.vhdl
===================================================================
--- vhld_tb/trunk/source/std_logic_1164_additions/std_logic_1164_additions.vhdl (nonexistent)
+++ vhld_tb/trunk/source/std_logic_1164_additions/std_logic_1164_additions.vhdl (revision 14)
@@ -0,0 +1,1737 @@
+------------------------------------------------------------------------------
+-- "std_logic_1164_additions" package contains the additions to the standard
+-- "std_logic_1164" package proposed by the VHDL-200X-ft working group.
+-- This package should be compiled into "ieee_proposed" and used as follows:
+-- use ieee.std_logic_1164.all;
+-- use ieee_proposed.std_logic_1164_additions.all;
+-- Last Modified: $Date: 2007-08-21 03:20:14 $
+-- RCS ID: $Id: std_logic_1164_additions.vhdl,v 1.1 2007-08-21 03:20:14 sckoarn Exp $
+--
+-- Created for VHDL-200X par, David Bishop (dbishop@vhdl.org)
+------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use std.textio.all;
+package std_logic_1164_additions is
+
+ -- NOTE that in the new std_logic_1164, STD_LOGIC_VECTOR is a resolved
+ -- subtype of STD_ULOGIC_VECTOR. Thus there is no need for funcitons which
+ -- take inputs in STD_LOGIC_VECTOR.
+ -- For compatability with VHDL-2002, I have replicated all of these funcitons
+ -- here for STD_LOGIC_VECTOR.
+ -- new aliases
+ alias to_bv is ieee.std_logic_1164.To_bitvector [STD_LOGIC_VECTOR, BIT return BIT_VECTOR];
+ alias to_bv is ieee.std_logic_1164.To_bitvector [STD_ULOGIC_VECTOR, BIT return BIT_VECTOR];
+ alias to_bit_vector is ieee.std_logic_1164.To_bitvector [STD_LOGIC_VECTOR, BIT return BIT_VECTOR];
+ alias to_bit_vector is ieee.std_logic_1164.To_bitvector [STD_ULOGIC_VECTOR, BIT return BIT_VECTOR];
+ alias to_slv is ieee.std_logic_1164.To_StdLogicVector [BIT_VECTOR return STD_LOGIC_VECTOR];
+ alias to_slv is ieee.std_logic_1164.To_StdLogicVector [STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR];
+ alias to_std_logic_vector is ieee.std_logic_1164.To_StdLogicVector [BIT_VECTOR return STD_LOGIC_VECTOR];
+ alias to_std_logic_vector is ieee.std_logic_1164.To_StdLogicVector [STD_ULOGIC_VECTOR return STD_LOGIC_VECTOR];
+ alias to_suv is ieee.std_logic_1164.To_StdULogicVector [BIT_VECTOR return STD_ULOGIC_VECTOR];
+ alias to_suv is ieee.std_logic_1164.To_StdULogicVector [STD_LOGIC_VECTOR return STD_ULOGIC_VECTOR];
+ alias to_std_ulogic_vector is ieee.std_logic_1164.To_StdULogicVector [BIT_VECTOR return STD_ULOGIC_VECTOR];
+ alias to_std_ulogic_vector is ieee.std_logic_1164.To_StdULogicVector [STD_LOGIC_VECTOR return STD_ULOGIC_VECTOR];
+
+ -------------------------------------------------------------------
+ -- overloaded shift operators
+ -------------------------------------------------------------------
+
+ function "sll" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
+ function "sll" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
+
+ function "srl" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
+ function "srl" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
+
+ function "rol" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
+ function "rol" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
+
+ function "ror" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR;
+ function "ror" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR;
+ -------------------------------------------------------------------
+ -- vector/scalar overloaded logical operators
+ -------------------------------------------------------------------
+ function "and" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "and" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ function "and" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "and" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ function "nand" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "nand" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ function "nand" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "nand" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ function "or" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "or" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ function "or" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "or" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ function "nor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "nor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ function "nor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "nor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ function "xor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "xor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ function "xor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "xor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ function "xnor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR;
+ function "xnor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR;
+ function "xnor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+
+ -------------------------------------------------------------------
+ -- vector-reduction functions.
+ -- "and" functions default to "1", or defaults to "0"
+ -------------------------------------------------------------------
+ -----------------------------------------------------------------------------
+ -- %%% Replace the "_reduce" functions with the ones commented out below.
+ -----------------------------------------------------------------------------
+ -- function "and" ( l : std_logic_vector ) RETURN std_ulogic;
+ -- function "and" ( l : std_ulogic_vector ) RETURN std_ulogic;
+ -- function "nand" ( l : std_logic_vector ) RETURN std_ulogic;
+ -- function "nand" ( l : std_ulogic_vector ) RETURN std_ulogic;
+ -- function "or" ( l : std_logic_vector ) RETURN std_ulogic;
+ -- function "or" ( l : std_ulogic_vector ) RETURN std_ulogic;
+ -- function "nor" ( l : std_logic_vector ) RETURN std_ulogic;
+ -- function "nor" ( l : std_ulogic_vector ) RETURN std_ulogic;
+ -- function "xor" ( l : std_logic_vector ) RETURN std_ulogic;
+ -- function "xor" ( l : std_ulogic_vector ) RETURN std_ulogic;
+ -- function "xnor" ( l : std_logic_vector ) RETURN std_ulogic;
+ -- function "xnor" ( l : std_ulogic_vector ) RETURN std_ulogic;
+ function and_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function and_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ function nand_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function nand_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ function or_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function or_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ function nor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function nor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ function xor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function xor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ function xnor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function xnor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ -------------------------------------------------------------------
+ -- ?= operators, same functionality as 1076.3 1994 std_match
+ -------------------------------------------------------------------
+-- FUNCTION "?=" ( l, r : std_ulogic ) RETURN std_ulogic;
+-- FUNCTION "?=" ( l, r : std_logic_vector ) RETURN std_ulogic;
+-- FUNCTION "?=" ( l, r : std_ulogic_vector ) RETURN std_ulogic;
+-- FUNCTION "?/=" ( l, r : std_ulogic ) RETURN std_ulogic;
+-- FUNCTION "?/=" ( l, r : std_logic_vector ) RETURN std_ulogic;
+-- FUNCTION "?/=" ( l, r : std_ulogic_vector ) RETURN std_ulogic;
+-- FUNCTION "?>" ( l, r : std_ulogic ) RETURN std_ulogic;
+-- FUNCTION "?>=" ( l, r : std_ulogic ) RETURN std_ulogic;
+-- FUNCTION "?<" ( l, r : std_ulogic ) RETURN std_ulogic;
+-- FUNCTION "?<=" ( l, r : std_ulogic ) RETURN std_ulogic;
+
+ function \?=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
+ function \?=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function \?=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ function \?/=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
+ function \?/=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC;
+ function \?/=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC;
+ function \?>\ (l, r : STD_ULOGIC) return STD_ULOGIC;
+ function \?>=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
+ function \?<\ (l, r : STD_ULOGIC) return STD_ULOGIC;
+ function \?<=\ (l, r : STD_ULOGIC) return STD_ULOGIC;
+
+
+ -- "??" operator, converts a std_ulogic to a boolean.
+ --%%% Uncomment the following operators
+ -- FUNCTION "??" (S : STD_ULOGIC) RETURN BOOLEAN;
+ --%%% REMOVE the following funciton (for testing only)
+ function \??\ (S : STD_ULOGIC) return BOOLEAN;
+
+ -- rtl_synthesis off
+ function to_string (value : STD_ULOGIC) return STRING;
+ function to_string (value : STD_ULOGIC_VECTOR) return STRING;
+ function to_string (value : STD_LOGIC_VECTOR) return STRING;
+
+ -- explicitly defined operations
+
+ alias TO_BSTRING is TO_STRING [STD_ULOGIC_VECTOR return STRING];
+ alias TO_BINARY_STRING is TO_STRING [STD_ULOGIC_VECTOR return STRING];
+ function TO_OSTRING (VALUE : STD_ULOGIC_VECTOR) return STRING;
+ alias TO_OCTAL_STRING is TO_OSTRING [STD_ULOGIC_VECTOR return STRING];
+ function TO_HSTRING (VALUE : STD_ULOGIC_VECTOR) return STRING;
+ alias TO_HEX_STRING is TO_HSTRING [STD_ULOGIC_VECTOR return STRING];
+
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC; GOOD : out BOOLEAN);
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC);
+
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN);
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR);
+
+ procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
+
+ procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
+
+ alias BREAD is READ [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
+ alias BREAD is READ [LINE, STD_ULOGIC_VECTOR];
+ alias BINARY_READ is READ [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
+ alias BINARY_READ is READ [LINE, STD_ULOGIC_VECTOR];
+
+ procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN);
+ procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR);
+ alias OCTAL_READ is OREAD [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
+ alias OCTAL_READ is OREAD [LINE, STD_ULOGIC_VECTOR];
+
+ procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR; GOOD : out BOOLEAN);
+ procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR);
+ alias HEX_READ is HREAD [LINE, STD_ULOGIC_VECTOR, BOOLEAN];
+ alias HEX_READ is HREAD [LINE, STD_ULOGIC_VECTOR];
+
+ alias BWRITE is WRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
+ alias BINARY_WRITE is WRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
+
+ procedure OWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
+ alias OCTAL_WRITE is OWRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
+
+ procedure HWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
+ alias HEX_WRITE is HWRITE [LINE, STD_ULOGIC_VECTOR, SIDE, WIDTH];
+
+ alias TO_BSTRING is TO_STRING [STD_LOGIC_VECTOR return STRING];
+ alias TO_BINARY_STRING is TO_STRING [STD_LOGIC_VECTOR return STRING];
+ function TO_OSTRING (VALUE : STD_LOGIC_VECTOR) return STRING;
+ alias TO_OCTAL_STRING is TO_OSTRING [STD_LOGIC_VECTOR return STRING];
+ function TO_HSTRING (VALUE : STD_LOGIC_VECTOR) return STRING;
+ alias TO_HEX_STRING is TO_HSTRING [STD_LOGIC_VECTOR return STRING];
+
+ procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR; GOOD : out BOOLEAN);
+ procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR);
+
+ procedure WRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
+
+ alias BREAD is READ [LINE, STD_LOGIC_VECTOR, BOOLEAN];
+ alias BREAD is READ [LINE, STD_LOGIC_VECTOR];
+ alias BINARY_READ is READ [LINE, STD_LOGIC_VECTOR, BOOLEAN];
+ alias BINARY_READ is READ [LINE, STD_LOGIC_VECTOR];
+
+ procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR; GOOD : out BOOLEAN);
+ procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR);
+ alias OCTAL_READ is OREAD [LINE, STD_LOGIC_VECTOR, BOOLEAN];
+ alias OCTAL_READ is OREAD [LINE, STD_LOGIC_VECTOR];
+
+ procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR; GOOD : out BOOLEAN);
+ procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR);
+ alias HEX_READ is HREAD [LINE, STD_LOGIC_VECTOR, BOOLEAN];
+ alias HEX_READ is HREAD [LINE, STD_LOGIC_VECTOR];
+
+ alias BWRITE is WRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
+ alias BINARY_WRITE is WRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
+
+ procedure OWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
+ alias OCTAL_WRITE is OWRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
+
+ procedure HWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0);
+ alias HEX_WRITE is HWRITE [LINE, STD_LOGIC_VECTOR, SIDE, WIDTH];
+ -- rtl_synthesis on
+ function maximum (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ function maximum (l, r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function maximum (l, r : STD_ULOGIC) return STD_ULOGIC;
+ function minimum (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
+ function minimum (l, r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
+ function minimum (l, r : STD_ULOGIC) return STD_ULOGIC;
+end package std_logic_1164_additions;
+
+package body std_logic_1164_additions is
+ type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;
+ -----------------------------------------------------------------------------
+ -- New/updated funcitons for VHDL-200X fast track
+ -----------------------------------------------------------------------------
+ -------------------------------------------------------------------
+ -- overloaded shift operators
+ -------------------------------------------------------------------
+
+ -------------------------------------------------------------------
+ -- sll
+ -------------------------------------------------------------------
+ function "sll" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length) := (others => '0');
+ begin
+ if r >= 0 then
+ result(1 to l'length - r) := lv(r + 1 to l'length);
+ else
+ result := l srl -r;
+ end if;
+ return result;
+ end function "sll";
+ -------------------------------------------------------------------
+ function "sll" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0');
+ begin
+ if r >= 0 then
+ result(1 to l'length - r) := lv(r + 1 to l'length);
+ else
+ result := l srl -r;
+ end if;
+ return result;
+ end function "sll";
+
+ -------------------------------------------------------------------
+ -- srl
+ -------------------------------------------------------------------
+ function "srl" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length) := (others => '0');
+ begin
+ if r >= 0 then
+ result(r + 1 to l'length) := lv(1 to l'length - r);
+ else
+ result := l sll -r;
+ end if;
+ return result;
+ end function "srl";
+ -------------------------------------------------------------------
+ function "srl" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0');
+ begin
+ if r >= 0 then
+ result(r + 1 to l'length) := lv(1 to l'length - r);
+ else
+ result := l sll -r;
+ end if;
+ return result;
+ end function "srl";
+
+ -------------------------------------------------------------------
+ -- rol
+ -------------------------------------------------------------------
+ function "rol" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length);
+ constant rm : INTEGER := r mod l'length;
+ begin
+ if r >= 0 then
+ result(1 to l'length - rm) := lv(rm + 1 to l'length);
+ result(l'length - rm + 1 to l'length) := lv(1 to rm);
+ else
+ result := l ror -r;
+ end if;
+ return result;
+ end function "rol";
+ -------------------------------------------------------------------
+ function "rol" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length);
+ constant rm : INTEGER := r mod l'length;
+ begin
+ if r >= 0 then
+ result(1 to l'length - rm) := lv(rm + 1 to l'length);
+ result(l'length - rm + 1 to l'length) := lv(1 to rm);
+ else
+ result := l ror -r;
+ end if;
+ return result;
+ end function "rol";
+
+ -------------------------------------------------------------------
+ -- ror
+ -------------------------------------------------------------------
+ function "ror" (l : STD_LOGIC_VECTOR; r : INTEGER) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length) := (others => '0');
+ constant rm : INTEGER := r mod l'length;
+ begin
+ if r >= 0 then
+ result(rm + 1 to l'length) := lv(1 to l'length - rm);
+ result(1 to rm) := lv(l'length - rm + 1 to l'length);
+ else
+ result := l rol -r;
+ end if;
+ return result;
+ end function "ror";
+ -------------------------------------------------------------------
+ function "ror" (l : STD_ULOGIC_VECTOR; r : INTEGER) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length) := (others => '0');
+ constant rm : INTEGER := r mod l'length;
+ begin
+ if r >= 0 then
+ result(rm + 1 to l'length) := lv(1 to l'length - rm);
+ result(1 to rm) := lv(l'length - rm + 1 to l'length);
+ else
+ result := l rol -r;
+ end if;
+ return result;
+ end function "ror";
+ -------------------------------------------------------------------
+ -- vector/scalar overloaded logical operators
+ -------------------------------------------------------------------
+
+ -------------------------------------------------------------------
+ -- and
+ -------------------------------------------------------------------
+ function "and" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "and" (lv(i), r);
+ end loop;
+ return result;
+ end function "and";
+ -------------------------------------------------------------------
+ function "and" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "and" (lv(i), r);
+ end loop;
+ return result;
+ end function "and";
+ -------------------------------------------------------------------
+ function "and" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_LOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "and" (l, rv(i));
+ end loop;
+ return result;
+ end function "and";
+ -------------------------------------------------------------------
+ function "and" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_ULOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "and" (l, rv(i));
+ end loop;
+ return result;
+ end function "and";
+
+ -------------------------------------------------------------------
+ -- nand
+ -------------------------------------------------------------------
+ function "nand" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("and" (lv(i), r));
+ end loop;
+ return result;
+ end function "nand";
+ -------------------------------------------------------------------
+ function "nand" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("and" (lv(i), r));
+ end loop;
+ return result;
+ end function "nand";
+ -------------------------------------------------------------------
+ function "nand" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_LOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("and" (l, rv(i)));
+ end loop;
+ return result;
+ end function "nand";
+ -------------------------------------------------------------------
+ function "nand" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_ULOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("and" (l, rv(i)));
+ end loop;
+ return result;
+ end function "nand";
+
+ -------------------------------------------------------------------
+ -- or
+ -------------------------------------------------------------------
+ function "or" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "or" (lv(i), r);
+ end loop;
+ return result;
+ end function "or";
+ -------------------------------------------------------------------
+ function "or" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "or" (lv(i), r);
+ end loop;
+ return result;
+ end function "or";
+ -------------------------------------------------------------------
+ function "or" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_LOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "or" (l, rv(i));
+ end loop;
+ return result;
+ end function "or";
+ -------------------------------------------------------------------
+ function "or" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_ULOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "or" (l, rv(i));
+ end loop;
+ return result;
+ end function "or";
+
+ -------------------------------------------------------------------
+ -- nor
+ -------------------------------------------------------------------
+ function "nor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("or" (lv(i), r));
+ end loop;
+ return result;
+ end function "nor";
+ -------------------------------------------------------------------
+ function "nor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("or" (lv(i), r));
+ end loop;
+ return result;
+ end function "nor";
+ -------------------------------------------------------------------
+ function "nor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_LOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("or" (l, rv(i)));
+ end loop;
+ return result;
+ end function "nor";
+ -------------------------------------------------------------------
+ function "nor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_ULOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("or" (l, rv(i)));
+ end loop;
+ return result;
+ end function "nor";
+
+ -------------------------------------------------------------------
+ -- xor
+ -------------------------------------------------------------------
+ function "xor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "xor" (lv(i), r);
+ end loop;
+ return result;
+ end function "xor";
+ -------------------------------------------------------------------
+ function "xor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "xor" (lv(i), r);
+ end loop;
+ return result;
+ end function "xor";
+ -------------------------------------------------------------------
+ function "xor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_LOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "xor" (l, rv(i));
+ end loop;
+ return result;
+ end function "xor";
+ -------------------------------------------------------------------
+ function "xor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_ULOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "xor" (l, rv(i));
+ end loop;
+ return result;
+ end function "xor";
+
+ -------------------------------------------------------------------
+ -- xnor
+ -------------------------------------------------------------------
+ function "xnor" (l : STD_LOGIC_VECTOR; r : STD_ULOGIC) return STD_LOGIC_VECTOR is
+ alias lv : STD_LOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_LOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("xor" (lv(i), r));
+ end loop;
+ return result;
+ end function "xnor";
+ -------------------------------------------------------------------
+ function "xnor" (l : STD_ULOGIC_VECTOR; r : STD_ULOGIC) return STD_ULOGIC_VECTOR is
+ alias lv : STD_ULOGIC_VECTOR (1 to l'length) is l;
+ variable result : STD_ULOGIC_VECTOR (1 to l'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("xor" (lv(i), r));
+ end loop;
+ return result;
+ end function "xnor";
+ -------------------------------------------------------------------
+ function "xnor" (l : STD_ULOGIC; r : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ alias rv : STD_LOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_LOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("xor" (l, rv(i)));
+ end loop;
+ return result;
+ end function "xnor";
+ -------------------------------------------------------------------
+ function "xnor" (l : STD_ULOGIC; r : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ alias rv : STD_ULOGIC_VECTOR (1 to r'length) is r;
+ variable result : STD_ULOGIC_VECTOR (1 to r'length);
+ begin
+ for i in result'range loop
+ result(i) := "not"("xor" (l, rv(i)));
+ end loop;
+ return result;
+ end function "xnor";
+
+ -------------------------------------------------------------------
+ -- vector-reduction functions
+ -------------------------------------------------------------------
+
+ -------------------------------------------------------------------
+ -- and
+ -------------------------------------------------------------------
+ function and_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return and_reduce (to_StdULogicVector (l));
+ end function and_reduce;
+ -------------------------------------------------------------------
+ function and_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ variable result : STD_ULOGIC := '1';
+ begin
+ for i in l'reverse_range loop
+ result := (l(i) and result);
+ end loop;
+ return result;
+ end function and_reduce;
+
+ -------------------------------------------------------------------
+ -- nand
+ -------------------------------------------------------------------
+ function nand_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return not (and_reduce(to_StdULogicVector(l)));
+ end function nand_reduce;
+ -------------------------------------------------------------------
+ function nand_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return not (and_reduce(l));
+ end function nand_reduce;
+
+ -------------------------------------------------------------------
+ -- or
+ -------------------------------------------------------------------
+ function or_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return or_reduce (to_StdULogicVector (l));
+ end function or_reduce;
+ -------------------------------------------------------------------
+ function or_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ variable result : STD_ULOGIC := '0';
+ begin
+ for i in l'reverse_range loop
+ result := (l(i) or result);
+ end loop;
+ return result;
+ end function or_reduce;
+
+ -------------------------------------------------------------------
+ -- nor
+ -------------------------------------------------------------------
+ function nor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return "not"(or_reduce(To_StdULogicVector(l)));
+ end function nor_reduce;
+ -------------------------------------------------------------------
+ function nor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return "not"(or_reduce(l));
+ end function nor_reduce;
+
+ -------------------------------------------------------------------
+ -- xor
+ -------------------------------------------------------------------
+ function xor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return xor_reduce (to_StdULogicVector (l));
+ end function xor_reduce;
+ -------------------------------------------------------------------
+ function xor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ variable result : STD_ULOGIC := '0';
+ begin
+ for i in l'reverse_range loop
+ result := (l(i) xor result);
+ end loop;
+ return result;
+ end function xor_reduce;
+
+ -------------------------------------------------------------------
+ -- xnor
+ -------------------------------------------------------------------
+ function xnor_reduce (l : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return "not"(xor_reduce(To_StdULogicVector(l)));
+ end function xnor_reduce;
+ -------------------------------------------------------------------
+ function xnor_reduce (l : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ begin
+ return "not"(xor_reduce(l));
+ end function xnor_reduce;
+ -- %%% End "remove the following functions"
+
+
+ -- The following functions are implicity in 1076-2006
+ -- truth table for "?=" function
+ constant match_logic_table : stdlogic_table := (
+ -----------------------------------------------------
+ -- U X 0 1 Z W L H - | |
+ -----------------------------------------------------
+ ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '1'), -- | U |
+ ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | X |
+ ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'), -- | 0 |
+ ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'), -- | 1 |
+ ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | Z |
+ ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '1'), -- | W |
+ ('U', 'X', '1', '0', 'X', 'X', '1', '0', '1'), -- | L |
+ ('U', 'X', '0', '1', 'X', 'X', '0', '1', '1'), -- | H |
+ ('1', '1', '1', '1', '1', '1', '1', '1', '1') -- | - |
+ );
+
+ constant no_match_logic_table : stdlogic_table := (
+ -----------------------------------------------------
+ -- U X 0 1 Z W L H - | |
+ -----------------------------------------------------
+ ('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', '0'), -- | U |
+ ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | X |
+ ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'), -- | 0 |
+ ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'), -- | 1 |
+ ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | Z |
+ ('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', '0'), -- | W |
+ ('U', 'X', '0', '1', 'X', 'X', '0', '1', '0'), -- | L |
+ ('U', 'X', '1', '0', 'X', 'X', '1', '0', '0'), -- | H |
+ ('0', '0', '0', '0', '0', '0', '0', '0', '0') -- | - |
+ );
+
+ -------------------------------------------------------------------
+ -- ?= functions, Similar to "std_match", but returns "std_ulogic".
+ -------------------------------------------------------------------
+ -- %%% FUNCTION "?=" ( l, r : std_ulogic ) RETURN std_ulogic IS
+ function \?=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ begin
+ return match_logic_table (l, r);
+ end function \?=\;
+ -- %%% END FUNCTION "?=";
+ -------------------------------------------------------------------
+ -- %%% FUNCTION "?=" ( l, r : std_logic_vector ) RETURN std_ulogic IS
+ function \?=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ alias lv : STD_LOGIC_VECTOR(1 to l'length) is l;
+ alias rv : STD_LOGIC_VECTOR(1 to r'length) is r;
+ variable result, result1 : STD_ULOGIC; -- result
+ begin
+ -- Logically identical to an "=" operator.
+ if ((l'length < 1) or (r'length < 1)) then
+ report "STD_LOGIC_1164.""?="": null detected, returning X"
+ severity warning;
+ return 'X';
+ end if;
+ if lv'length /= rv'length then
+ report "STD_LOGIC_1164.""?="": L'LENGTH /= R'LENGTH, returning X"
+ severity warning;
+ return 'X';
+ else
+ result := '1';
+ for i in lv'low to lv'high loop
+ result1 := match_logic_table(lv(i), rv(i));
+ if result1 = 'U' then
+ return 'U';
+ elsif result1 = 'X' or result = 'X' then
+ result := 'X';
+ else
+ result := result and result1;
+ end if;
+ end loop;
+ return result;
+ end if;
+ end function \?=\;
+ -- %%% END FUNCTION "?=";
+ -------------------------------------------------------------------
+ -- %%% FUNCTION "?=" ( l, r : std_ulogic_vector ) RETURN std_ulogic IS
+ function \?=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ alias lv : STD_ULOGIC_VECTOR(1 to l'length) is l;
+ alias rv : STD_ULOGIC_VECTOR(1 to r'length) is r;
+ variable result, result1 : STD_ULOGIC;
+ begin
+ if ((l'length < 1) or (r'length < 1)) then
+ report "STD_LOGIC_1164.""?="": null detected, returning X"
+ severity warning;
+ return 'X';
+ end if;
+ if lv'length /= rv'length then
+ report "STD_LOGIC_1164.""?="": L'LENGTH /= R'LENGTH, returning X"
+ severity warning;
+ return 'X';
+ else
+ result := '1';
+ for i in lv'low to lv'high loop
+ result1 := match_logic_table(lv(i), rv(i));
+ if result1 = 'U' then
+ return 'U';
+ elsif result1 = 'X' or result = 'X' then
+ result := 'X';
+ else
+ result := result and result1;
+ end if;
+ end loop;
+ return result;
+ end if;
+ end function \?=\;
+ -- %%% END FUNCTION "?=";
+ -- %%% FUNCTION "?/=" ( l, r : std_ulogic ) RETURN std_ulogic is
+ function \?/=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ begin
+ return no_match_logic_table (l, r);
+ end function \?/=\;
+ -- %%% END FUNCTION "?/=";
+ -- %%% FUNCTION "?/=" ( l, r : std_logic_vector ) RETURN std_ulogic is
+ function \?/=\ (l, r : STD_LOGIC_VECTOR) return STD_ULOGIC is
+ alias lv : STD_LOGIC_VECTOR(1 to l'length) is l;
+ alias rv : STD_LOGIC_VECTOR(1 to r'length) is r;
+ variable result, result1 : STD_ULOGIC; -- result
+ begin
+ if ((l'length < 1) or (r'length < 1)) then
+ report "STD_LOGIC_1164.""?/="": null detected, returning X"
+ severity warning;
+ return 'X';
+ end if;
+ if lv'length /= rv'length then
+ report "STD_LOGIC_1164.""?/="": L'LENGTH /= R'LENGTH, returning X"
+ severity warning;
+ return 'X';
+ else
+ result := '0';
+ for i in lv'low to lv'high loop
+ result1 := no_match_logic_table(lv(i), rv(i));
+ if result1 = 'U' then
+ return 'U';
+ elsif result1 = 'X' or result = 'X' then
+ result := 'X';
+ else
+ result := result or result1;
+ end if;
+ end loop;
+ return result;
+ end if;
+ end function \?/=\;
+ -- %%% END FUNCTION "?/=";
+ -- %%% FUNCTION "?/=" ( l, r : std_ulogic_vector ) RETURN std_ulogic is
+ function \?/=\ (l, r : STD_ULOGIC_VECTOR) return STD_ULOGIC is
+ alias lv : STD_ULOGIC_VECTOR(1 to l'length) is l;
+ alias rv : STD_ULOGIC_VECTOR(1 to r'length) is r;
+ variable result, result1 : STD_ULOGIC;
+ begin
+ if ((l'length < 1) or (r'length < 1)) then
+ report "STD_LOGIC_1164.""?/="": null detected, returning X"
+ severity warning;
+ return 'X';
+ end if;
+ if lv'length /= rv'length then
+ report "STD_LOGIC_1164.""?/="": L'LENGTH /= R'LENGTH, returning X"
+ severity warning;
+ return 'X';
+ else
+ result := '0';
+ for i in lv'low to lv'high loop
+ result1 := no_match_logic_table(lv(i), rv(i));
+ if result1 = 'U' then
+ return 'U';
+ elsif result1 = 'X' or result = 'X' then
+ result := 'X';
+ else
+ result := result or result1;
+ end if;
+ end loop;
+ return result;
+ end if;
+ end function \?/=\;
+ -- %%% END FUNCTION "?/=";
+ -- %%% FUNCTION "?>" ( l, r : std_ulogic ) RETURN std_ulogic is
+ function \?>\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ variable lx, rx : STD_ULOGIC;
+ begin
+ if (l = '-') or (r = '-') then
+ report "STD_LOGIC_1164.""?>"": '-' found in compare string"
+ severity error;
+ return 'X';
+ else
+ lx := to_x01 (l);
+ rx := to_x01 (r);
+ if lx = 'X' or rx = 'X' then
+ return 'X';
+ elsif lx > rx then
+ return '1';
+ else
+ return '0';
+ end if;
+ end if;
+ end function \?>\;
+ -- %%% END FUNCTION "?>";
+
+ -- %%% FUNCTION "?>=" ( l, r : std_ulogic ) RETURN std_ulogic is
+ function \?>=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ variable lx, rx : STD_ULOGIC;
+ begin
+ if (l = '-') or (r = '-') then
+ report "STD_LOGIC_1164.""?>="": '-' found in compare string"
+ severity error;
+ return 'X';
+ else
+ lx := to_x01 (l);
+ rx := to_x01 (r);
+ if lx = 'X' or rx = 'X' then
+ return 'X';
+ elsif lx >= rx then
+ return '1';
+ else
+ return '0';
+ end if;
+ end if;
+ end function \?>=\;
+ -- %%% END FUNCTION "?/>=";
+
+ -- %%% FUNCTION "?<" ( l, r : std_ulogic ) RETURN std_ulogic is
+ function \?<\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ variable lx, rx : STD_ULOGIC;
+ begin
+ if (l = '-') or (r = '-') then
+ report "STD_LOGIC_1164.""?<"": '-' found in compare string"
+ severity error;
+ return 'X';
+ else
+ lx := to_x01 (l);
+ rx := to_x01 (r);
+ if lx = 'X' or rx = 'X' then
+ return 'X';
+ elsif lx < rx then
+ return '1';
+ else
+ return '0';
+ end if;
+ end if;
+ end function \?<\;
+ -- %%% END FUNCTION "?/<";
+
+ -- %%% FUNCTION "?<=" ( l, r : std_ulogic ) RETURN std_ulogic is
+ function \?<=\ (l, r : STD_ULOGIC) return STD_ULOGIC is
+ variable lx, rx : STD_ULOGIC;
+ begin
+ if (l = '-') or (r = '-') then
+ report "STD_LOGIC_1164.""?<="": '-' found in compare string"
+ severity error;
+ return 'X';
+ else
+ lx := to_x01 (l);
+ rx := to_x01 (r);
+ if lx = 'X' or rx = 'X' then
+ return 'X';
+ elsif lx <= rx then
+ return '1';
+ else
+ return '0';
+ end if;
+ end if;
+ end function \?<=\;
+ -- %%% END FUNCTION "?/<=";
+
+ -- "??" operator, converts a std_ulogic to a boolean.
+-- %%% FUNCTION "??"
+ function \??\ (S : STD_ULOGIC) return BOOLEAN is
+ begin
+ return S = '1' or S = 'H';
+ end function \??\;
+-- %%% END FUNCTION "??";
+
+ -- rtl_synthesis off
+ -----------------------------------------------------------------------------
+ -- This section copied from "std_logic_textio"
+ -----------------------------------------------------------------------------
+ -- Type and constant definitions used to map STD_ULOGIC values
+ -- into/from character values.
+ type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', error);
+ type char_indexed_by_MVL9 is array (STD_ULOGIC) of CHARACTER;
+ type MVL9_indexed_by_char is array (CHARACTER) of STD_ULOGIC;
+ type MVL9plus_indexed_by_char is array (CHARACTER) of MVL9plus;
+ constant MVL9_to_char : char_indexed_by_MVL9 := "UX01ZWLH-";
+ constant char_to_MVL9 : MVL9_indexed_by_char :=
+ ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
+ 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
+ constant char_to_MVL9plus : MVL9plus_indexed_by_char :=
+ ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
+ 'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => error);
+
+ constant NBSP : CHARACTER := CHARACTER'val(160); -- space character
+ constant NUS : STRING(2 to 1) := (others => ' '); -- null STRING
+
+ -- purpose: Skips white space
+ procedure skip_whitespace (
+ L : inout LINE) is
+ variable readOk : BOOLEAN;
+ variable c : CHARACTER;
+ begin
+ while L /= null and L.all'length /= 0 loop
+ if (L.all(1) = ' ' or L.all(1) = NBSP or L.all(1) = HT) then
+ read (l, c, readOk);
+ else
+ exit;
+ end if;
+ end loop;
+ end procedure skip_whitespace;
+
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC;
+ GOOD : out BOOLEAN) is
+ variable c : CHARACTER;
+ variable readOk : BOOLEAN;
+ begin
+ VALUE := 'U'; -- initialize to a "U"
+ Skip_whitespace (L);
+ read (l, c, readOk);
+ if not readOk then
+ good := false;
+ else
+ if char_to_MVL9plus(c) = error then
+ good := false;
+ else
+ VALUE := char_to_MVL9(c);
+ good := true;
+ end if;
+ end if;
+ end procedure READ;
+
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
+ GOOD : out BOOLEAN) is
+ variable m : STD_ULOGIC;
+ variable c : CHARACTER;
+ variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1);
+ variable readOk : BOOLEAN;
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ begin
+ VALUE := (VALUE'range => 'U'); -- initialize to a "U"
+ Skip_whitespace (L);
+ if VALUE'length > 0 then
+ read (l, c, readOk);
+ i := 0;
+ good := false;
+ while i < VALUE'length loop
+ if not readOk then -- Bail out if there was a bad read
+ return;
+ elsif c = '_' then
+ if i = 0 then -- Begins with an "_"
+ return;
+ elsif lastu then -- "__" detected
+ return;
+ else
+ lastu := true;
+ end if;
+ elsif (char_to_MVL9plus(c) = error) then -- Illegal character
+ return;
+ else
+ mv(i) := char_to_MVL9(c);
+ i := i + 1;
+ if i > mv'high then -- reading done
+ good := true;
+ VALUE := mv;
+ return;
+ end if;
+ lastu := false;
+ end if;
+ read(L, c, readOk);
+ end loop;
+ else
+ good := true; -- read into a null array
+ end if;
+ end procedure READ;
+
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC) is
+ variable c : CHARACTER;
+ variable readOk : BOOLEAN;
+ begin
+ VALUE := 'U'; -- initialize to a "U"
+ Skip_whitespace (L);
+ read (l, c, readOk);
+ if not readOk then
+ report "STD_LOGIC_1164.READ(STD_ULOGIC) "
+ & "End of string encountered"
+ severity error;
+ return;
+ elsif char_to_MVL9plus(c) = error then
+ report
+ "STD_LOGIC_1164.READ(STD_ULOGIC) Error: Character '" &
+ c & "' read, expected STD_ULOGIC literal."
+ severity error;
+ else
+ VALUE := char_to_MVL9(c);
+ end if;
+ end procedure READ;
+
+ procedure READ (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
+ variable m : STD_ULOGIC;
+ variable c : CHARACTER;
+ variable readOk : BOOLEAN;
+ variable mv : STD_ULOGIC_VECTOR(0 to VALUE'length-1);
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ begin
+ VALUE := (VALUE'range => 'U'); -- initialize to a "U"
+ Skip_whitespace (L);
+ if VALUE'length > 0 then -- non Null input string
+ read (l, c, readOk);
+ i := 0;
+ while i < VALUE'length loop
+ if readOk = false then -- Bail out if there was a bad read
+ report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
+ & "End of string encountered"
+ severity error;
+ return;
+ elsif c = '_' then
+ if i = 0 then
+ report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
+ & "String begins with an ""_""" severity error;
+ return;
+ elsif lastu then
+ report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
+ & "Two underscores detected in input string ""__"""
+ severity error;
+ return;
+ else
+ lastu := true;
+ end if;
+ elsif c = ' ' or c = NBSP or c = HT then -- reading done.
+ report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
+ & "Short read, Space encounted in input string"
+ severity error;
+ return;
+ elsif char_to_MVL9plus(c) = error then
+ report "STD_LOGIC_1164.READ(STD_ULOGIC_VECTOR) "
+ & "Error: Character '" &
+ c & "' read, expected STD_ULOGIC literal."
+ severity error;
+ return;
+ else
+ mv(i) := char_to_MVL9(c);
+ i := i + 1;
+ if i > mv'high then
+ VALUE := mv;
+ return;
+ end if;
+ lastu := false;
+ end if;
+ read(L, c, readOk);
+ end loop;
+ end if;
+ end procedure READ;
+
+ procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
+ begin
+ write(l, MVL9_to_char(VALUE), justified, field);
+ end procedure WRITE;
+
+ procedure WRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
+ variable s : STRING(1 to VALUE'length);
+ variable m : STD_ULOGIC_VECTOR(1 to VALUE'length) := VALUE;
+ begin
+ for i in 1 to VALUE'length loop
+ s(i) := MVL9_to_char(m(i));
+ end loop;
+ write(l, s, justified, field);
+ end procedure WRITE;
+
+ -- Read and Write procedures for STD_LOGIC_VECTOR
+
+ procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR;
+ GOOD : out BOOLEAN) is
+ variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
+ begin
+ READ (L => L, VALUE => ivalue, GOOD => GOOD);
+ VALUE := to_stdlogicvector (ivalue);
+ end procedure READ;
+
+ procedure READ (L : inout LINE; VALUE : out STD_LOGIC_VECTOR) is
+ variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
+ begin
+ READ (L => L, VALUE => ivalue);
+ VALUE := to_stdlogicvector (ivalue);
+ end procedure READ;
+
+ procedure WRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
+ variable s : STRING(1 to VALUE'length);
+ variable m : STD_LOGIC_VECTOR(1 to VALUE'length) := VALUE;
+ begin
+ for i in 1 to VALUE'length loop
+ s(i) := MVL9_to_char(m(i));
+ end loop;
+ write(L, s, justified, field);
+ end procedure WRITE;
+
+ -----------------------------------------------------------------------
+ -- Alias for bread and bwrite are provided with call out the read and
+ -- write functions.
+ -----------------------------------------------------------------------
+
+ -- Hex Read and Write procedures for STD_ULOGIC_VECTOR.
+ -- Modified from the original to be more forgiving.
+
+ procedure Char2QuadBits (C : CHARACTER;
+ RESULT : out STD_ULOGIC_VECTOR(3 downto 0);
+ GOOD : out BOOLEAN;
+ ISSUE_ERROR : in BOOLEAN) is
+ begin
+ case c is
+ when '0' => result := x"0"; good := true;
+ when '1' => result := x"1"; good := true;
+ when '2' => result := x"2"; good := true;
+ when '3' => result := x"3"; good := true;
+ when '4' => result := x"4"; good := true;
+ when '5' => result := x"5"; good := true;
+ when '6' => result := x"6"; good := true;
+ when '7' => result := x"7"; good := true;
+ when '8' => result := x"8"; good := true;
+ when '9' => result := x"9"; good := true;
+ when 'A' | 'a' => result := x"A"; good := true;
+ when 'B' | 'b' => result := x"B"; good := true;
+ when 'C' | 'c' => result := x"C"; good := true;
+ when 'D' | 'd' => result := x"D"; good := true;
+ when 'E' | 'e' => result := x"E"; good := true;
+ when 'F' | 'f' => result := x"F"; good := true;
+ when 'Z' => result := "ZZZZ"; good := true;
+ when 'X' => result := "XXXX"; good := true;
+ when others =>
+ assert not ISSUE_ERROR
+ report
+ "STD_LOGIC_1164.HREAD Read a '" & c &
+ "', expected a Hex character (0-F)."
+ severity error;
+ good := false;
+ end case;
+ end procedure Char2QuadBits;
+
+ procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
+ GOOD : out BOOLEAN) is
+ variable ok : BOOLEAN;
+ variable c : CHARACTER;
+ constant ne : INTEGER := (VALUE'length+3)/4;
+ constant pad : INTEGER := ne*4 - VALUE'length;
+ variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ begin
+ VALUE := (VALUE'range => 'U'); -- initialize to a "U"
+ Skip_whitespace (L);
+ if VALUE'length > 0 then
+ read (l, c, ok);
+ i := 0;
+ while i < ne loop
+ -- Bail out if there was a bad read
+ if not ok then
+ good := false;
+ return;
+ elsif c = '_' then
+ if i = 0 then
+ good := false; -- Begins with an "_"
+ return;
+ elsif lastu then
+ good := false; -- "__" detected
+ return;
+ else
+ lastu := true;
+ end if;
+ else
+ Char2QuadBits(c, sv(4*i to 4*i+3), ok, false);
+ if not ok then
+ good := false;
+ return;
+ end if;
+ i := i + 1;
+ lastu := false;
+ end if;
+ if i < ne then
+ read(L, c, ok);
+ end if;
+ end loop;
+ if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
+ good := false; -- vector was truncated.
+ else
+ good := true;
+ VALUE := sv (pad to sv'high);
+ end if;
+ else
+ good := true; -- Null input string, skips whitespace
+ end if;
+ end procedure HREAD;
+
+ procedure HREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
+ variable ok : BOOLEAN;
+ variable c : CHARACTER;
+ constant ne : INTEGER := (VALUE'length+3)/4;
+ constant pad : INTEGER := ne*4 - VALUE'length;
+ variable sv : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ begin
+ VALUE := (VALUE'range => 'U'); -- initialize to a "U"
+ Skip_whitespace (L);
+ if VALUE'length > 0 then -- non Null input string
+ read (l, c, ok);
+ i := 0;
+ while i < ne loop
+ -- Bail out if there was a bad read
+ if not ok then
+ report "STD_LOGIC_1164.HREAD "
+ & "End of string encountered"
+ severity error;
+ return;
+ end if;
+ if c = '_' then
+ if i = 0 then
+ report "STD_LOGIC_1164.HREAD "
+ & "String begins with an ""_""" severity error;
+ return;
+ elsif lastu then
+ report "STD_LOGIC_1164.HREAD "
+ & "Two underscores detected in input string ""__"""
+ severity error;
+ return;
+ else
+ lastu := true;
+ end if;
+ else
+ Char2QuadBits(c, sv(4*i to 4*i+3), ok, true);
+ if not ok then
+ return;
+ end if;
+ i := i + 1;
+ lastu := false;
+ end if;
+ if i < ne then
+ read(L, c, ok);
+ end if;
+ end loop;
+ if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
+ report "STD_LOGIC_1164.HREAD Vector truncated"
+ severity error;
+ else
+ VALUE := sv (pad to sv'high);
+ end if;
+ end if;
+ end procedure HREAD;
+
+ procedure HWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
+ begin
+ write (L, to_hstring (VALUE), JUSTIFIED, FIELD);
+ end procedure HWRITE;
+
+
+ -- Octal Read and Write procedures for STD_ULOGIC_VECTOR.
+ -- Modified from the original to be more forgiving.
+
+ procedure Char2TriBits (C : CHARACTER;
+ RESULT : out STD_ULOGIC_VECTOR(2 downto 0);
+ GOOD : out BOOLEAN;
+ ISSUE_ERROR : in BOOLEAN) is
+ begin
+ case c is
+ when '0' => result := o"0"; good := true;
+ when '1' => result := o"1"; good := true;
+ when '2' => result := o"2"; good := true;
+ when '3' => result := o"3"; good := true;
+ when '4' => result := o"4"; good := true;
+ when '5' => result := o"5"; good := true;
+ when '6' => result := o"6"; good := true;
+ when '7' => result := o"7"; good := true;
+ when 'Z' => result := "ZZZ"; good := true;
+ when 'X' => result := "XXX"; good := true;
+ when others =>
+ assert not ISSUE_ERROR
+ report
+ "STD_LOGIC_1164.OREAD Error: Read a '" & c &
+ "', expected an Octal character (0-7)."
+ severity error;
+ good := false;
+ end case;
+ end procedure Char2TriBits;
+
+ procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR;
+ GOOD : out BOOLEAN) is
+ variable ok : BOOLEAN;
+ variable c : CHARACTER;
+ constant ne : INTEGER := (VALUE'length+2)/3;
+ constant pad : INTEGER := ne*3 - VALUE'length;
+ variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ begin
+ VALUE := (VALUE'range => 'U'); -- initialize to a "U"
+ Skip_whitespace (L);
+ if VALUE'length > 0 then
+ read (l, c, ok);
+ i := 0;
+ while i < ne loop
+ -- Bail out if there was a bad read
+ if not ok then
+ good := false;
+ return;
+ elsif c = '_' then
+ if i = 0 then
+ good := false; -- Begins with an "_"
+ return;
+ elsif lastu then
+ good := false; -- "__" detected
+ return;
+ else
+ lastu := true;
+ end if;
+ else
+ Char2TriBits(c, sv(3*i to 3*i+2), ok, false);
+ if not ok then
+ good := false;
+ return;
+ end if;
+ i := i + 1;
+ lastu := false;
+ end if;
+ if i < ne then
+ read(L, c, ok);
+ end if;
+ end loop;
+ if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
+ good := false; -- vector was truncated.
+ else
+ good := true;
+ VALUE := sv (pad to sv'high);
+ end if;
+ else
+ good := true; -- read into a null array
+ end if;
+ end procedure OREAD;
+
+ procedure OREAD (L : inout LINE; VALUE : out STD_ULOGIC_VECTOR) is
+ variable c : CHARACTER;
+ variable ok : BOOLEAN;
+ constant ne : INTEGER := (VALUE'length+2)/3;
+ constant pad : INTEGER := ne*3 - VALUE'length;
+ variable sv : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
+ variable i : INTEGER;
+ variable lastu : BOOLEAN := false; -- last character was an "_"
+ begin
+ VALUE := (VALUE'range => 'U'); -- initialize to a "U"
+ Skip_whitespace (L);
+ if VALUE'length > 0 then
+ read (l, c, ok);
+ i := 0;
+ while i < ne loop
+ -- Bail out if there was a bad read
+ if not ok then
+ report "STD_LOGIC_1164.OREAD "
+ & "End of string encountered"
+ severity error;
+ return;
+ elsif c = '_' then
+ if i = 0 then
+ report "STD_LOGIC_1164.OREAD "
+ & "String begins with an ""_""" severity error;
+ return;
+ elsif lastu then
+ report "STD_LOGIC_1164.OREAD "
+ & "Two underscores detected in input string ""__"""
+ severity error;
+ return;
+ else
+ lastu := true;
+ end if;
+ else
+ Char2TriBits(c, sv(3*i to 3*i+2), ok, true);
+ if not ok then
+ return;
+ end if;
+ i := i + 1;
+ lastu := false;
+ end if;
+ if i < ne then
+ read(L, c, ok);
+ end if;
+ end loop;
+ if or_reduce (sv (0 to pad-1)) = '1' then -- %%% replace with "or"
+ report "STD_LOGIC_1164.OREAD Vector truncated"
+ severity error;
+ else
+ VALUE := sv (pad to sv'high);
+ end if;
+ end if;
+ end procedure OREAD;
+
+ procedure OWRITE (L : inout LINE; VALUE : in STD_ULOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
+ begin
+ write (L, to_ostring(VALUE), JUSTIFIED, FIELD);
+ end procedure OWRITE;
+
+ -- Hex Read and Write procedures for STD_LOGIC_VECTOR
+
+ procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR;
+ GOOD : out BOOLEAN) is
+ variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
+ begin
+ HREAD (L => L, VALUE => ivalue, GOOD => GOOD);
+ VALUE := to_stdlogicvector (ivalue);
+ end procedure HREAD;
+
+ procedure HREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR) is
+ variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
+ begin
+ HREAD (L => L, VALUE => ivalue);
+ VALUE := to_stdlogicvector (ivalue);
+ end procedure HREAD;
+
+ procedure HWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
+ begin
+ write (L, to_hstring(VALUE), JUSTIFIED, FIELD);
+ end procedure HWRITE;
+
+ -- Octal Read and Write procedures for STD_LOGIC_VECTOR
+
+ procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR;
+ GOOD : out BOOLEAN) is
+ variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
+ begin
+ OREAD (L => L, VALUE => ivalue, GOOD => GOOD);
+ VALUE := to_stdlogicvector (ivalue);
+ end procedure OREAD;
+
+ procedure OREAD (L : inout LINE; VALUE : out STD_LOGIC_VECTOR) is
+ variable ivalue : STD_ULOGIC_VECTOR (VALUE'range);
+ begin
+ OREAD (L => L, VALUE => ivalue);
+ VALUE := to_stdlogicvector (ivalue);
+ end procedure OREAD;
+
+ procedure OWRITE (L : inout LINE; VALUE : in STD_LOGIC_VECTOR;
+ JUSTIFIED : in SIDE := right; FIELD : in WIDTH := 0) is
+ begin
+ write (L, to_ostring(VALUE), JUSTIFIED, FIELD);
+ end procedure OWRITE;
+
+ -----------------------------------------------------------------------------
+ -- New string functions for vhdl-200x fast track
+ -----------------------------------------------------------------------------
+ function to_string (value : STD_ULOGIC) return STRING is
+ variable result : STRING (1 to 1);
+ begin
+ result (1) := MVL9_to_char (value);
+ return result;
+ end function to_string;
+ -------------------------------------------------------------------
+ -- TO_STRING (an alias called "to_bstring" is provide)
+ -------------------------------------------------------------------
+ function to_string (value : STD_ULOGIC_VECTOR) return STRING is
+ alias ivalue : STD_ULOGIC_VECTOR(1 to value'length) is value;
+ variable result : STRING(1 to value'length);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ for i in ivalue'range loop
+ result(i) := MVL9_to_char(iValue(i));
+ end loop;
+ return result;
+ end if;
+ end function to_string;
+
+ -------------------------------------------------------------------
+ -- TO_HSTRING
+ -------------------------------------------------------------------
+ function to_hstring (value : STD_ULOGIC_VECTOR) return STRING is
+ constant ne : INTEGER := (value'length+3)/4;
+ variable pad : STD_ULOGIC_VECTOR(0 to (ne*4 - value'length) - 1);
+ variable ivalue : STD_ULOGIC_VECTOR(0 to ne*4 - 1);
+ variable result : STRING(1 to ne);
+ variable quad : STD_ULOGIC_VECTOR(0 to 3);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value (value'left) = 'Z' then
+ pad := (others => 'Z');
+ else
+ pad := (others => '0');
+ end if;
+ ivalue := pad & value;
+ for i in 0 to ne-1 loop
+ quad := To_X01Z(ivalue(4*i to 4*i+3));
+ case quad is
+ when x"0" => result(i+1) := '0';
+ when x"1" => result(i+1) := '1';
+ when x"2" => result(i+1) := '2';
+ when x"3" => result(i+1) := '3';
+ when x"4" => result(i+1) := '4';
+ when x"5" => result(i+1) := '5';
+ when x"6" => result(i+1) := '6';
+ when x"7" => result(i+1) := '7';
+ when x"8" => result(i+1) := '8';
+ when x"9" => result(i+1) := '9';
+ when x"A" => result(i+1) := 'A';
+ when x"B" => result(i+1) := 'B';
+ when x"C" => result(i+1) := 'C';
+ when x"D" => result(i+1) := 'D';
+ when x"E" => result(i+1) := 'E';
+ when x"F" => result(i+1) := 'F';
+ when "ZZZZ" => result(i+1) := 'Z';
+ when others => result(i+1) := 'X';
+ end case;
+ end loop;
+ return result;
+ end if;
+ end function to_hstring;
+
+ -------------------------------------------------------------------
+ -- TO_OSTRING
+ -------------------------------------------------------------------
+ function to_ostring (value : STD_ULOGIC_VECTOR) return STRING is
+ constant ne : INTEGER := (value'length+2)/3;
+ variable pad : STD_ULOGIC_VECTOR(0 to (ne*3 - value'length) - 1);
+ variable ivalue : STD_ULOGIC_VECTOR(0 to ne*3 - 1);
+ variable result : STRING(1 to ne);
+ variable tri : STD_ULOGIC_VECTOR(0 to 2);
+ begin
+ if value'length < 1 then
+ return NUS;
+ else
+ if value (value'left) = 'Z' then
+ pad := (others => 'Z');
+ else
+ pad := (others => '0');
+ end if;
+ ivalue := pad & value;
+ for i in 0 to ne-1 loop
+ tri := To_X01Z(ivalue(3*i to 3*i+2));
+ case tri is
+ when o"0" => result(i+1) := '0';
+ when o"1" => result(i+1) := '1';
+ when o"2" => result(i+1) := '2';
+ when o"3" => result(i+1) := '3';
+ when o"4" => result(i+1) := '4';
+ when o"5" => result(i+1) := '5';
+ when o"6" => result(i+1) := '6';
+ when o"7" => result(i+1) := '7';
+ when "ZZZ" => result(i+1) := 'Z';
+ when others => result(i+1) := 'X';
+ end case;
+ end loop;
+ return result;
+ end if;
+ end function to_ostring;
+
+ function to_string (value : STD_LOGIC_VECTOR) return STRING is
+ begin
+ return to_string (to_stdulogicvector (value));
+ end function to_string;
+
+ function to_hstring (value : STD_LOGIC_VECTOR) return STRING is
+ begin
+ return to_hstring (to_stdulogicvector (value));
+ end function to_hstring;
+
+ function to_ostring (value : STD_LOGIC_VECTOR) return STRING is
+ begin
+ return to_ostring (to_stdulogicvector (value));
+ end function to_ostring;
+
+ -- rtl_synthesis on
+ function maximum (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin -- function maximum
+ if L > R then return L;
+ else return R;
+ end if;
+ end function maximum;
+
+ -- std_logic_vector output
+ function minimum (L, R : STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
+ begin -- function minimum
+ if L > R then return R;
+ else return L;
+ end if;
+ end function minimum;
+
+ function maximum (L, R : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ begin -- function maximum
+ if L > R then return L;
+ else return R;
+ end if;
+ end function maximum;
+
+ -- std_logic_vector output
+ function minimum (L, R : STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
+ begin -- function minimum
+ if L > R then return R;
+ else return L;
+ end if;
+ end function minimum;
+
+ function maximum (L, R : STD_ULOGIC) return STD_ULOGIC is
+ begin -- function maximum
+ if L > R then return L;
+ else return R;
+ end if;
+ end function maximum;
+
+ -- std_logic_vector output
+ function minimum (L, R : STD_ULOGIC) return STD_ULOGIC is
+ begin -- function minimum
+ if L > R then return R;
+ else return L;
+ end if;
+ end function minimum;
+end package body std_logic_1164_additions;
Index: vhld_tb/trunk/Doc/VHDLtbusers.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: vhld_tb/trunk/Doc/VHDLtbusers.odt
===================================================================
--- vhld_tb/trunk/Doc/VHDLtbusers.odt (nonexistent)
+++ vhld_tb/trunk/Doc/VHDLtbusers.odt (revision 14)
vhld_tb/trunk/Doc/VHDLtbusers.odt
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: vhld_tb/trunk/Doc/VHDLtbusers.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: vhld_tb/trunk/Doc/VHDLtbusers.pdf
===================================================================
--- vhld_tb/trunk/Doc/VHDLtbusers.pdf (nonexistent)
+++ vhld_tb/trunk/Doc/VHDLtbusers.pdf (revision 14)
vhld_tb/trunk/Doc/VHDLtbusers.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: vhld_tb/trunk/examples/example1/vhdl/example_dut_tb_bhv.vhd
===================================================================
--- vhld_tb/trunk/examples/example1/vhdl/example_dut_tb_bhv.vhd (nonexistent)
+++ vhld_tb/trunk/examples/example1/vhdl/example_dut_tb_bhv.vhd (revision 14)
@@ -0,0 +1,543 @@
+-- this file generated from template by ttb_gen
+
+architecture bhv of example_dut_tb is
+
+
+
+ signal tb_clk : std_logic;
+
+-------------------------------------------------------------------------
+-- Component defintion
+
+-------------------------------------------------------------------------------
+-- USER Component instantiations
+--for all: Arbitor use entity tb_objects.arbitor(bhv);
+
+
+ begin
+
+-------------------------------------------------------------------------------
+-- clock driver process
+-- the main clock generator
+clock_driver:
+ process
+ begin
+ tb_clk <= '0';
+ wait for 5 ns;
+ tb_clk <= '1';
+ wait for 5 ns;
+ end process clock_driver;
+
+
+ ex_clk_in <= tb_clk;
+
+ --------------------------------------------------------------------------
+ -- Read_file Process:
+ --
+ -- This process is the main process of the testbench. This process reads
+ -- the stumulus file, parses it, creates lists of records, then uses these
+ -- lists to exicute user instructions. There are two passes through the
+ -- script. Pass one reads in the stimulus text file, checks it, creates
+ -- lists of valid instructions, valid list of variables and finialy a list
+ -- of user instructions(the sequence). The second pass through the file,
+ -- records are drawn from the user instruction list, variables are converted
+ -- to integers and put through the elsif structure for exicution.
+ --------------------------------------------------------------------------
+ Read_file: process
+ variable current_line : text_line; -- The current input line
+ variable inst_list : inst_def_ptr; -- the instruction list
+ variable defined_vars : var_field_ptr; -- defined variables
+ variable inst_sequ : stim_line_ptr; -- the instruction sequence
+ variable file_list : file_def_ptr; -- pointer to the list of file names
+
+ variable instruction : text_field; -- instruction field
+ variable par1 : integer; -- paramiter 1
+ variable par2 : integer; -- paramiter 2
+ variable par3 : integer; -- paramiter 3
+ variable par4 : integer; -- paramiter 4
+ variable par5 : integer; -- paramiter 5
+ variable par6 : integer; -- paramiter 6
+ variable txt : stm_text_ptr;
+ variable nbase : base; -- the number base to use
+ variable len : integer; -- length of the instruction field
+ variable file_line : integer; -- Line number in the stimulus file
+ variable file_name : text_line; -- the file name the line came from
+ variable v_line : integer := 0; -- sequence number
+ variable stack : stack_register; -- Call stack
+ variable stack_ptr : integer := 0; -- call stack pointer
+ variable wh_stack : stack_register; -- while stack
+ variable wh_dpth : integer := 0; -- while depth
+ variable wh_ptr : integer := 0; -- while pointer
+ variable loop_num : integer := 0;
+ variable curr_loop_count : int_array := (others => 0);
+ variable term_loop_count : int_array := (others => 0);
+ variable loop_line : int_array := (others => 0);
+
+ variable messages : boolean := TRUE;
+ variable if_state : boolean := FALSE;
+ variable wh_state : boolean := FALSE;
+ variable wh_end : boolean := FALSE;
+ variable rand : std_logic_vector(31 downto 0);
+ variable rand_back : std_logic_vector(31 downto 0);
+
+ variable temp_int : integer;
+ variable temp_index : integer;
+ variable temp_str : text_field;
+ variable valid : integer;
+ variable v_temp_vec1 : std_logic_vector(31 downto 0);
+ variable v_temp_vec2 : std_logic_vector(31 downto 0);
+
+ variable v_read_data : std_logic_vector(31 downto 0);
+ --------------------------------------------------------------------------
+ -- Area for Procedures which may be usefull to more than one instruction.
+ -- By coding here commonly used code sections ...
+ -- you know the benifits.
+ ---------------------------------------------------------------------
+ -----------------------------------------------------------------
+ -- This procedure writes to the arbitor model access port
+-- procedure arb_write(add: in integer; .....
+-- end arb_write;
+
+
+ begin -- process Read_file
+
+ ex_reset_n <= '1';
+-- ex_clk_in <= '0';
+ stm_add <= (others => 'Z');
+ stm_dat <= (others => 'Z');
+ stm_rwn <= '1';
+ stm_req_n <= '1';
+
+ -----------------------------------------------------------------------
+ -- Stimulus file instruction definition
+ -- This is where the instructions used in the stimulus file are defined.
+ -- Syntax is
+ -- define_instruction(inst_def_ptr, instruction, paramiters)
+ -- inst_def_ptr: is a record pointer defined in tb_pkg_header
+ -- instruction: the text instruction name ie. "DEFINE_VAR"
+ -- paramiters: the number of fields or paramiters passed
+ --
+ -- Some basic instruction are created here, the user should create new
+ -- instructions below the standard ones.
+ ------------------------------------------------------------------------
+ define_instruction(inst_list, "DEFINE_VAR", 2); -- Define a Variable
+ define_instruction(inst_list, "EQU_VAR", 2);
+ define_instruction(inst_list, "ADD_VAR", 2);
+ define_instruction(inst_list, "SUB_VAR", 2);
+ define_instruction(inst_list, "CALL", 1);
+ define_instruction(inst_list, "RETURN_CALL", 0);
+ define_instruction(inst_list, "JUMP", 1);
+ define_instruction(inst_list, "LOOP", 1);
+ define_instruction(inst_list, "END_LOOP", 0);
+ define_instruction(inst_list, "IF", 3);
+ define_instruction(inst_list, "ELSE", 0);
+ define_instruction(inst_list, "ELSEIF", 3);
+ define_instruction(inst_list, "END_IF", 0);
+ define_instruction(inst_list, "WHILE", 3);
+ define_instruction(inst_list, "END_WHILE", 0);
+ define_instruction(inst_list, "MESSAGES_OFF", 0);
+ define_instruction(inst_list, "MESSAGES_ON", 0);
+ define_instruction(inst_list, "ABORT", 0); -- Error exit from sim
+ define_instruction(inst_list, "FINISH", 0); -- Normal exit from sim
+ define_instruction(inst_list, "INCLUDE", 1); -- Define a Variable
+
+ -- User defined instructions
+ define_instruction(inst_list, "RESET_SYS", 0);
+ define_instruction(inst_list, "READ_PINS", 1);
+ define_instruction(inst_list, "WRITE_DUT", 2);
+ define_instruction(inst_list, "VERIFY", 1);
+
+
+ ------------------------------------------------------------------------
+ -- Read, test, and load the stimulus file
+ read_instruction_file(stimulus_file, inst_list, defined_vars, inst_sequ,
+ file_list);
+
+------------------------------------------------------------------------
+-- Using the Instruction record list, get the instruction and implement
+-- it as per the statements in the elsif tree.
+ while(v_line < inst_sequ.num_of_lines) loop
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, file_list, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+
+--------------------------------------------------------------------------
+ if(instruction(1 to len) = "DEFINE_VAR") then
+ null; -- This instruction was implemented while reading the file
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "INCLUDE") then
+ null; -- This instruction was implemented while reading the file
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "ABORT") then
+ assert (false)
+ report "The test has aborted due to an error!!"
+ severity failure;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "FINISH") then
+ assert (false)
+ report "Test Finished with NO errors!!"
+ severity failure;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "EQU_VAR") then
+ update_variable(defined_vars, par1, par2, valid);
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "ADD_VAR") then
+ index_variable(defined_vars, par1, temp_int, valid);
+ if(valid /= 0) then
+ temp_int := temp_int + par2;
+ update_variable(defined_vars, par1, temp_int, valid);
+ else
+ assert (false)
+ report "ADD_VAR Error: Not a valid Variable??"
+ severity failure;
+ end if;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "SUB_VAR") then
+ index_variable(defined_vars, par1, temp_int, valid);
+ if(valid /= 0) then
+ temp_int := temp_int - par2;
+ update_variable(defined_vars, par1, temp_int, valid);
+ else
+ assert (false)
+ report "SUB_VAR Error: Not a valid Variable??"
+ severity failure;
+ end if;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "CALL") then
+ if(stack_ptr >= 7) then
+ assert (false)
+ report "Call Error: Stack over run, calls to deeply nested!!"
+ severity failure;
+ end if;
+ stack(stack_ptr) := v_line;
+ stack_ptr := stack_ptr + 1;
+ v_line := par1 - 1;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "RETURN_CALL") then
+ if(stack_ptr <= 0) then
+ assert (false)
+ report "Call Error: Stack under run??"
+ severity failure;
+ end if;
+ stack_ptr := stack_ptr - 1;
+ v_line := stack(stack_ptr);
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "JUMP") then
+ v_line := par1 - 1;
+ wh_state := false;
+ wh_stack := (others => 0);
+ wh_dpth := 0;
+ wh_ptr := 0;
+ stack := (others => 0);
+ stack_ptr := 0;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "LOOP") then
+ loop_num := loop_num + 1;
+ loop_line(loop_num) := v_line;
+ curr_loop_count(loop_num) := 0;
+ term_loop_count(loop_num) := par1;
+ assert (messages)
+ report LF & "Executing LOOP Command" &
+ LF & " Nested Loop:" & HT & integer'image(loop_num) &
+ LF & " Loop Length:" & HT & integer'image(par1)
+ severity note;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_LOOP") then
+ curr_loop_count(loop_num) := curr_loop_count(loop_num) + 1;
+ if (curr_loop_count(loop_num) = term_loop_count(loop_num)) then
+ loop_num := loop_num - 1;
+ else
+ v_line := loop_line(loop_num);
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "IF") then
+ if_state := false;
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: IF instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(if_state = false) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "ELSE" and
+ instruction(1 to len) /= "ELSEIF" and
+ instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "ELSEIF") then
+ if(if_state = true) then -- if the if_state is true then skip to the end
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+
+ else
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: ELSEIF instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(if_state = false) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "ELSE" and
+ instruction(1 to len) /= "ELSEIF" and
+ instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: ELSEIF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "ELSE") then
+ if(if_state = true) then -- if the if_state is true then skip the else
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_IF") then
+ null; -- instruction is a place holder for finding the end of IF.
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "WHILE") then
+ wh_state := false;
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: WHILE instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(wh_state = true) then
+ wh_stack(wh_ptr) := v_line;
+ wh_ptr := wh_ptr + 1;
+ else
+ wh_end := false;
+ while(wh_end /= true) loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: WHILE instruction unable to find terminating" &
+ LF & " END_WHILE statement."
+ severity failure;
+ end if;
+
+ -- if is a while need to escape it
+ if(instruction(1 to len) = "WHILE") then
+ wh_dpth := wh_dpth + 1;
+ -- if is the end_while we are looking for
+ elsif(instruction(1 to len) = "END_WHILE") then
+ if(wh_dpth = 0) then
+ wh_end := true;
+ else
+ wh_dpth := wh_dpth - 1;
+ end if;
+ end if;
+ end loop;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_WHILE") then
+ if(wh_ptr > 0) then
+ v_line := wh_stack(wh_ptr - 1) - 1;
+ wh_ptr := wh_ptr - 1;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "MESSAGES_OFF") then
+ messages := TRUE;
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "MESSAGES_ON") then
+ messages := FALSE;
+
+
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- USER Istruction area. Add all user instructions below this
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "RESET_SYS") then
+ wait until tb_clk'event and tb_clk = '1';
+ EX_RESET_N <= '0';
+ wait until tb_clk'event and tb_clk = '1';
+ wait until tb_clk'event and tb_clk = '1';
+ EX_RESET_N <= '1';
+ wait for 0 ns;
+
+--------------------------------------------------------------------------------
+-- READ_PINS
+-- read one of the two output interfaces on the dut, put value in read_data
+-- par1 0 read port1
+-- 1 read port2
+ elsif (instruction(1 to len) = "READ_PINS") then
+ if(par1 = 0) then
+ v_read_data := EX_DATA1;
+ elsif(par1 = 1) then
+ v_read_data := EX_DATA2;
+ else
+ assert (false)
+ report LF & "Out of range message" & LF
+ severity error;
+ end if;
+
+--------------------------------------------------------------------------------
+-- VERIFY
+-- par1 Data to compare
+ elsif (instruction(1 to len) = "VERIFY") then
+ v_temp_vec1 := std_logic_vector(conv_unsigned(par1, 32));
+ -- if (sim_halt = '1') then
+ assert (v_temp_vec1 = v_read_data)
+ report "VERIFY instruction found missmatch!" & LF &
+ "Expected data = " & to_hstring(v_temp_vec1) & LF &
+ "Read data = " & to_hstring(v_read_data) & LF &
+ "Found on line " & (integer'image(file_line)) & " in file " & file_name
+ severity failure;
+
+ -- else
+ -- assert (v_temp_vec1 = v_read_data)
+ -- report "VERIFY instruction found missmatch!" & LF &
+ -- "Expected data = " & to_hstring(v_temp_vec1) & LF &
+ -- "Read data = " & to_hstring(v_read_data) & LF &
+ -- "Found on line " & (integer'image(file_line)) & " in file " & file_name
+ -- severity error;
+ -- end if;
+
+--------------------------------------------------------------------------------
+-- PCI_WRITE
+-- par1 address
+-- par2 data
+-- This instruction I use for accessing models. which is the interface
+-- on the example dut. I use that interface as a stimulus access port.
+ elsif (instruction(1 to len) = "WRITE_DUT") then
+ stm_add <= std_logic_vector(conv_unsigned(par1,32));
+ stm_dat <= std_logic_vector(conv_unsigned(par2,32));
+ stm_req_n <= '0';
+ stm_rwn <= '0';
+ wait until stm_ack_n'event and stm_ack_n = '0';
+ stm_req_n <= '1';
+ wait until stm_ack_n'event and stm_ack_n = '1';
+ stm_add <= (others => 'Z');
+ stm_dat <= (others => 'Z');
+ stm_rwn <= '1';
+ wait for 0 ns;
+
+
+--------------------------------------------------------------------------------
+-- USER Istruction area. Add all user instructions above this
+--------------------------------------------------------------------------------
+ --------------------------------------------------------------------------
+ -- catch those little mistakes
+ else
+ assert (false)
+ report LF & "ERROR: Seems the command " & instruction(1 to len) & " was defined" & LF &
+ "but not found in the elsif chain, please check the spelling."
+ severity failure;
+ end if; -- else if structure end
+ txt_print_wvar(defined_vars, txt, hex);
+ end loop; -- Main Loop end
+
+ assert (false)
+ report LF & "The end of the simulation! It was not terminated as expected." & LF
+ severity failure;
+
+ end process Read_file;
+
+
+end bhv;
+
Index: vhld_tb/trunk/examples/example1/vhdl/example_dut_tb_ent.vhd
===================================================================
--- vhld_tb/trunk/examples/example1/vhdl/example_dut_tb_ent.vhd (nonexistent)
+++ vhld_tb/trunk/examples/example1/vhdl/example_dut_tb_ent.vhd (revision 14)
@@ -0,0 +1,27 @@
+-- ttb_gen generated file
+library IEEE;
+library ieee_proposed;
+library work;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use ieee_proposed.STD_LOGIC_1164_additions.all;
+use std.textio.all;
+use work.tb_pkg.all; -- test bench package
+
+
+entity example_dut_tb is
+ generic (
+ stimulus_file: in string
+ );
+ port (
+ ex_reset_n : buffer std_logic;
+ ex_clk_in : buffer std_logic;
+ ex_data1 : in std_logic_vector(31 downto 0);
+ ex_data2 : in std_logic_vector(31 downto 0);
+ stm_add : buffer std_logic_vector(31 downto 0);
+ stm_dat : inout std_logic_vector(31 downto 0);
+ stm_rwn : buffer std_logic;
+ stm_req_n : buffer std_logic;
+ stm_ack_n : in std_logic
+ );
+end example_dut_tb;
Index: vhld_tb/trunk/examples/example1/vhdl/example_dut_bhv.vhd
===================================================================
--- vhld_tb/trunk/examples/example1/vhdl/example_dut_bhv.vhd (nonexistent)
+++ vhld_tb/trunk/examples/example1/vhdl/example_dut_bhv.vhd (revision 14)
@@ -0,0 +1,202 @@
+
+architecture bhv of example_dut is
+
+ -----------------------------------------------------------------------------
+ -- driven by STIM_access
+ signal stim_addr: std_logic_vector(31 downto 0);
+ signal stim_write_dat: std_logic_vector(31 downto 0);
+ signal rd_req: std_logic := '0';
+ signal wr_req: std_logic := '0';
+ -----------------------------------------------------------------------------
+ -- driven by REG_access
+ signal stim_read_dat: std_logic_vector(31 downto 0);
+ signal req_ack: std_logic := '0';
+
+ -- the addressable register set
+ signal ctl_reg: std_logic_vector(31 downto 0);
+ signal seed_reg: std_logic_vector(31 downto 0) := "00010001000111000011000010000100";
+ signal config_reg: std_logic_vector(31 downto 0);
+ signal errors_reg: std_logic_vector(31 downto 0);
+ signal sample_edge: std_logic := '1';
+ signal drive_edge: std_logic := '0';
+ signal access0_word: std_logic_vector(31 downto 0);
+ signal access1_word: std_logic_vector(31 downto 0);
+ signal action_trig: std_logic := '0';
+ signal clear_trig: std_logic := '0';
+
+ --- Driven by Drive_out
+ signal clock_enable: std_logic := '0';
+
+begin
+
+------------------------------------------------
+-- Example process to drive outputs.
+output_drive:
+ process(EX_RESET_N, ctl_reg, access0_word, access1_word)
+ begin
+ if(EX_RESET_N = '0') then
+ EX_DATA1 <= (others => 'Z');
+ EX_DATA2 <= (others => 'Z');
+ elsif(access0_word'event) then
+ EX_DATA1 <= access0_word;
+ elsif(access1_word'event) then
+ EX_DATA2 <= access1_word;
+ end if;
+end process output_drive;
+
+
+
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+-- STIM Reg Access process
+REG_access:
+ process
+
+ variable v_temp_int: integer;
+ variable v_reload: integer := 0;
+ variable v_tmp_int: integer;
+
+ begin
+ if(EX_RESET_N'event and EX_RESET_N = '0') then
+ v_reload := 0;
+ -- standard registers
+ stim_read_dat <= (others => '0');
+ req_ack <= '0';
+ ctl_reg <= (others => '0');
+ config_reg <= (others => '0');
+ errors_reg <= (others => '0');
+
+ -- application registers
+ access0_word <= (others => 'Z');
+ access1_word <= (others => 'Z');
+ action_trig <= '0';
+
+ ---------------------------------------------------------
+
+ -- if is a write access
+ elsif(wr_req' event and wr_req = '1') then
+ -- create index 0 to 63
+ v_temp_int := conv_integer(unsigned(stim_addr(5 downto 0)));
+ -- create first level of addressing
+ case stim_addr(31 downto 12) is
+ -- first level decode
+ when "00000000000000000000" =>
+ -- create register access level of addressing
+ -- seconde level of decode
+ case stim_addr(11 downto 0) is
+ when "000000000000" =>
+ ctl_reg <= stim_write_dat;
+ when "000000000001" =>
+ config_reg <= stim_write_dat;
+ when "000000000010" =>
+ assert(false)
+ report ">>>> ERROR: The errors register is read only!!" & LF
+ severity note;
+-- errors_reg <= stim_write_dat;
+ when "000000000011" =>
+ seed_reg <= stim_write_dat;
+
+ when "000000000100" =>
+ access0_word <= stim_write_dat;
+ action_trig <= '1';
+ when "000000000101" =>
+ access1_word <= stim_write_dat;
+
+ when others =>
+ assert(false)
+ report "This area of object address is not valid" & LF
+ severity note;
+ end case;
+
+ when others =>
+ assert(false)
+ report "This area of object address is not valid" & LF
+ severity note;
+ end case;
+ -- acknowlage the request
+ req_ack <= '1';
+ wait until wr_req'event and wr_req = '0';
+ req_ack <= '0';
+
+ -- if is a read
+ elsif (rd_req' event and rd_req = '1') then
+ -- create first level of addressing
+ case stim_addr(31 downto 12) is
+ -- first level decode
+ when "00000000000000000000" =>
+ -- create register access level of addressing
+ -- seconde level of decode
+ case stim_addr(11 downto 0) is
+ when "000000000010" =>
+ stim_read_dat <= errors_reg;
+ errors_reg <= (others => '0');
+ when others =>
+ assert(false)
+ report "Read Location access ERROR: Arb model: No action taken!" & LF
+ severity note;
+ end case;
+ when others =>
+ assert(false)
+ report "Read Location access ERROR: Arb model: No action taken!" & LF
+ severity note;
+ end case;
+ -- acknowlage the request
+ req_ack <= '1';
+ wait until rd_req'event and rd_req = '0';
+ req_ack <= '0';
+
+ end if;
+ -- clear the trigger signal
+ if(clear_trig'event) then
+ action_trig <= '0';
+ end if;
+
+ wait on rd_req, wr_req, EX_RESET_N, clear_trig;
+ end process REG_access;
+
+-------------------------------------------------------------------------------
+-- STIM Access port processes
+--
+STIM_access:
+ process
+ begin
+ if(EX_RESET_N' event) then
+ STM_DAT <= (others => 'Z');
+ STM_ACK_N <= '1';
+ -- if read cycle
+ elsif(STM_REQ_N' event and STM_REQ_N = '0' and STM_RWN = '1') then
+ stim_addr <= STM_ADD;
+ rd_req <= '1';
+ wait until req_ack' event and req_ack = '1';
+ STM_DAT <= stim_read_dat;
+ rd_req <= '0';
+ wait for 1 ps;
+ STM_ACK_N <= '0';
+ wait until STM_REQ_N' event and STM_REQ_N = '1';
+ wait for 1 ps;
+ STM_DAT <= (others => 'Z');
+ STM_ACK_N <= '1';
+
+ -- if Write
+ elsif(STM_REQ_N' event and STM_REQ_N = '0' and STM_RWN = '0') then
+ STM_DAT <= (others => 'Z');
+ wait for 1 ps;
+ stim_addr <= STM_ADD;
+ stim_write_dat <= STM_DAT;
+
+ wr_req <= '1';
+ wait until req_ack' event and req_ack = '1';
+ wait for 1 ps;
+ wr_req <= '0';
+ wait for 1 ps;
+ STM_ACK_N <= '0';
+ wait until STM_REQ_N' event and STM_REQ_N = '1';
+ wait for 1 ps;
+ STM_ACK_N <= '1';
+ end if;
+
+ wait on STM_REQ_N, EX_RESET_N;
+ end process STIM_access;
+
+end bhv;
Index: vhld_tb/trunk/examples/example1/vhdl/example_dut_ttb_ent.vhd
===================================================================
--- vhld_tb/trunk/examples/example1/vhdl/example_dut_ttb_ent.vhd (nonexistent)
+++ vhld_tb/trunk/examples/example1/vhdl/example_dut_ttb_ent.vhd (revision 14)
@@ -0,0 +1,11 @@
+
+library IEEE;
+--library dut_lib;
+use IEEE.STD_LOGIC_1164.all;
+--use dut_lib.all;
+
+entity example_dut_ttb is
+ generic (
+ stimulus_file: string := "stm/stimulus_file.stm"
+ );
+end example_dut_ttb;
Index: vhld_tb/trunk/examples/example1/vhdl/example_dut_ttb_str.vhd
===================================================================
--- vhld_tb/trunk/examples/example1/vhdl/example_dut_ttb_str.vhd (nonexistent)
+++ vhld_tb/trunk/examples/example1/vhdl/example_dut_ttb_str.vhd (revision 14)
@@ -0,0 +1,79 @@
+-- structure file generated by ttb_gen
+architecture struct of example_dut_ttb is
+
+component example_dut
+ port (
+ ex_reset_n : in std_logic;
+ ex_clk_in : in std_logic;
+ ex_data1 : out std_logic_vector(31 downto 0);
+ ex_data2 : out std_logic_vector(31 downto 0);
+ stm_add : in std_logic_vector(31 downto 0);
+ stm_dat : inout std_logic_vector(31 downto 0);
+ stm_rwn : in std_logic;
+ stm_req_n : in std_logic;
+ stm_ack_n : out std_logic
+ );
+end component;
+
+component example_dut_tb
+ generic (
+ stimulus_file: in string
+ );
+ port (
+ ex_reset_n : buffer std_logic;
+ ex_clk_in : buffer std_logic;
+ ex_data1 : in std_logic_vector(31 downto 0);
+ ex_data2 : in std_logic_vector(31 downto 0);
+ stm_add : buffer std_logic_vector(31 downto 0);
+ stm_dat : inout std_logic_vector(31 downto 0);
+ stm_rwn : buffer std_logic;
+ stm_req_n : buffer std_logic;
+ stm_ack_n : in std_logic
+ );
+end component;
+
+--for all: example_dut use entity dut_lib.example_dut(str);
+--for all: example_dut_tb use entity work.example_dut_tb(bhv);
+
+ signal temp_ex_reset_n : std_logic;
+ signal temp_ex_clk_in : std_logic;
+ signal temp_ex_data1 : std_logic_vector(31 downto 0);
+ signal temp_ex_data2 : std_logic_vector(31 downto 0);
+ signal temp_stm_add : std_logic_vector(31 downto 0);
+ signal temp_stm_dat : std_logic_vector(31 downto 0);
+ signal temp_stm_rwn : std_logic;
+ signal temp_stm_req_n : std_logic;
+ signal temp_stm_ack_n : std_logic;
+
+begin
+
+dut: example_dut
+ port map(
+ ex_reset_n => temp_ex_reset_n,
+ ex_clk_in => temp_ex_clk_in,
+ ex_data1 => temp_ex_data1,
+ ex_data2 => temp_ex_data2,
+ stm_add => temp_stm_add,
+ stm_dat => temp_stm_dat,
+ stm_rwn => temp_stm_rwn,
+ stm_req_n => temp_stm_req_n,
+ stm_ack_n => temp_stm_ack_n
+ );
+
+tb: example_dut_tb
+ generic map(
+ stimulus_file => stimulus_file
+ )
+ port map(
+ ex_reset_n => temp_ex_reset_n,
+ ex_clk_in => temp_ex_clk_in,
+ ex_data1 => temp_ex_data1,
+ ex_data2 => temp_ex_data2,
+ stm_add => temp_stm_add,
+ stm_dat => temp_stm_dat,
+ stm_rwn => temp_stm_rwn,
+ stm_req_n => temp_stm_req_n,
+ stm_ack_n => temp_stm_ack_n
+ );
+
+end struct;
Index: vhld_tb/trunk/examples/example1/vhdl/example_dut_ent.vhd
===================================================================
--- vhld_tb/trunk/examples/example1/vhdl/example_dut_ent.vhd (nonexistent)
+++ vhld_tb/trunk/examples/example1/vhdl/example_dut_ent.vhd (revision 14)
@@ -0,0 +1,21 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use std.textio.all;
+
+entity example_dut is
+ port(
+ EX_RESET_N : in std_logic;
+ EX_CLK_IN : in std_logic;
+ -- interface pins
+ EX_DATA1 : out std_logic_vector(31 downto 0);
+ EX_DATA2 : out std_logic_vector(31 downto 0);
+ -- env access port
+ STM_ADD : in std_logic_vector(31 downto 0);
+ STM_DAT : inout std_logic_vector(31 downto 0);
+ STM_RWN : in std_logic;
+ STM_REQ_N : in std_logic;
+ STM_ACK_N : out std_logic
+ );
+end example_dut;
Index: vhld_tb/trunk/examples/example1/stm/stimulus_file.stm
===================================================================
--- vhld_tb/trunk/examples/example1/stm/stimulus_file.stm (nonexistent)
+++ vhld_tb/trunk/examples/example1/stm/stimulus_file.stm (revision 14)
@@ -0,0 +1,26 @@
+-- example stimulus file
+
+
+DEFINE_VAR DATA 0
+DEFINE_VAR ADDR1 4
+DEFINE_VAR ADDR2 5
+
+
+RESET_SYS
+
+LOOP 10
+ WRITE_DUT $ADDR1 $DATA
+ READ_PINS 0
+ VERIFY $DATA
+ ADD_VAR DATA 1
+
+ WRITE_DUT $ADDR2 $DATA
+ READ_PINS 1
+ VERIFY $DATA
+ ADD_VAR DATA 1
+
+END_LOOP
+
+
+
+FINISH
\ No newline at end of file
Index: vhld_tb/trunk/examples/example1/build_tb.bat
===================================================================
--- vhld_tb/trunk/examples/example1/build_tb.bat (nonexistent)
+++ vhld_tb/trunk/examples/example1/build_tb.bat (revision 14)
@@ -0,0 +1,5 @@
+
+vcom vhdl/example_dut_ent.vhd vhdl/example_dut_bhv.vhd
+
+vcom vhdl/example_dut_tb_ent.vhd vhdl/example_dut_tb_bhv.vhd
+vcom vhdl/example_dut_ttb_ent.vhd vhdl/example_dut_ttb_str.vhd
Index: vhld_tb/trunk/ttb_gen/ttb_gen_plus.tcl
===================================================================
--- vhld_tb/trunk/ttb_gen/ttb_gen_plus.tcl (nonexistent)
+++ vhld_tb/trunk/ttb_gen/ttb_gen_plus.tcl (revision 14)
@@ -0,0 +1,907 @@
+#! /usr/bin/env wish
+##-------------------------------------------------------------------------------
+##-- Copyright 2007 Ken Campbell
+##-- All Rights Reserved
+##
+## 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 2 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, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##-------------------------------------------------------------------------------
+##-- $Author: sckoarn $
+##--
+##-- $Date: 2007-09-02 04:01:43 $
+##--
+##-- $Name: not supported by cvs2svn $
+##--
+##-- $Id: ttb_gen_plus.tcl,v 1.1 2007-09-02 04:01:43 sckoarn Exp $
+##--
+##-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/ttb_gen/ttb_gen_plus.tcl,v $
+##--
+##-- Description :
+##-- This application takes a text file containing the definition of a VHDL
+## entity, parses that entity and generates the VHDL Test Bench starting
+## file set. It is a rewrite of the previous ttb_gen_gui to include
+## view of the file.
+##--
+##------------------------------------------------------------------------------
+
+## package requires
+package require Iwidgets 4.0
+
+## set the current version info
+set version "v1.0"
+## put up a title on the main window boarder
+wm title . "TTB Gen Plus $version"
+
+## the location of the template by default
+set template "../source/template_tb_bhv.vhd"
+
+set use_list 0
+
+## Working Directory or vhdl directory
+set workd [frame .wdf]
+set ent_dir [iwidgets::entryfield $workd.cen1 -labeltext "Working Directory"]
+button $workd.br0 -text "Browse" -command {fill_list}
+pack $workd.br0 -side right
+pack $ent_dir -fill x
+pack $workd -fill x -pady 6
+
+## Output directory
+set tlist [frame .lstf]
+set odir [iwidgets::entryfield $tlist.ent1 -labeltext "Output Directory"]
+set lbut [button $tlist.br1 -text "Browse" -command {browsed_from_set $odir $odir}]
+pack $lbut -side right
+pack $odir -fill x
+pack $tlist -fill x
+
+## Template location
+set tdirf [frame .tmpf]
+set tdir [iwidgets::entryfield $tdirf.ent2 -width 60 -labeltext "Template Location"]
+set tbut [button $tdirf.br2 -text "Browse" -command {browse_set_entry $tdir}]
+pack $tbut -side right
+pack $tdir -fill x
+pack $tdirf -fill x -pady 6
+$tdir delete 0 end
+$tdir insert end $template
+$tdir configure -state readonly
+
+## type spec
+set tsf [frame .tsfr]
+set load_but [button $tsf.bt1 -text "Generate" -command ttb_gen]
+set mo_sel [iwidgets::optionmenu $tsf.mode -labeltext "Mode"]
+##$mo_sel insert end Work Recurse List
+$mo_sel insert end "No bhv" "bhv"
+set p_view [iwidgets::feedback $tsf.fb1 -labeltext "Generation Status" -barheight 10]
+set statsVar ""
+##set stat_txt [label $tsf.lb1 -textvariable statsVar]
+set stat_txt [label .lb1 -textvariable statsVar]
+
+pack $load_but -side left
+pack $mo_sel -side left
+pack $p_view -side left
+pack $tsf
+pack $stat_txt -fill x
+
+## create paned window
+set win [iwidgets::panedwindow .pw -width 200 -height 300]
+$win add top -margin 4 -minimum 100
+$win add middle -margin 4 -minimum 100
+$win configure -orient vertical
+$win fraction 80 20
+$win paneconfigure 1 -minimum 60
+## create two locations for objects
+set wtop [$win childsite 0]
+set wbot [$win childsite 1]
+pack $win -fill both -expand yes
+## create two object boxes
+set list_win [iwidgets::selectionbox $wtop.sb -margin 2 -itemscommand load_ent_file \
+ -itemslabel "VHDL Files" -selectionlabel "Selected VHDL File"]
+set view_win [iwidgets::scrolledtext $wbot.rts -borderwidth 2 -wrap none]
+pack $list_win -fill both -expand yes
+pack $view_win -fill both -expand yes
+
+## some tags for the view window
+##$view_win tag configure highlite -background #a0b7ce
+$view_win tag configure highlite -background grey80
+
+###########################################################################
+## some debug and help procs
+## Message Error, terminate
+proc msg_error { msg } {
+ tk_messageBox -message $msg -type ok
+ exit
+}
+###########################################################################
+## Message, continue
+proc dbg_msg { msg } {
+ tk_messageBox -message $msg -type ok
+}
+#########################################################################
+## browse and get directory
+## Using extfileselectiondialog get a directory and update the
+## field passed to it
+proc browsed_from_set { src dest } {
+ set wdir [$src get]
+ if {$wdir == ""} {
+ iwidgets::extfileselectiondialog .dsb -modality application -fileson false
+ } else {
+ iwidgets::extfileselectiondialog .dsb -modality application -fileson false \
+ -directory $wdir
+ }
+
+ if {[.dsb activate]} {
+ set dchoice [.dsb get]
+ $dest configure -state normal
+ $dest delete 0 end
+ $dest insert 0 "$dchoice"
+ $dest configure -state readonly
+ }
+ destroy .dsb
+}
+#########################################################################
+## browse and get file name
+## Using extfileselectiondialog get a directory and update the
+## field passed to it
+proc browse_set_entry { dest } {
+iwidgets::extfileselectiondialog .dsb -modality application
+
+ if {[.dsb activate]} {
+ set dchoice [.dsb get]
+ $dest configure -state normal
+ $dest delete 0 end
+ $dest insert 0 "$dchoice"
+ $dest configure -state readonly
+ }
+ destroy .dsb
+}
+##########################################################################
+## proc pars_pindef
+proc pars_pindef { pin } {
+ set pdirection ""
+# dbg_msg $pin
+ set spin [split $pin ":"]
+ set pname_str [lindex $spin 0]
+ set pname [lindex $pname_str 0]
+# dbg_msg "Pin name is $pname"
+ set pdirection_str [lindex $spin 1]
+# dbg_msg $pdirection_str
+ ## parce out the direction, supporting only 3
+ set direction [string first "in " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "in"
+ }
+ set direction [string first "out " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "out"
+ }
+ set direction [string first "inout " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "inout"
+ }
+ if {$pdirection == ""} {
+ dbg_msg "Unsuported Pin direction found. \n Suported are IN OUT and INOUT."
+ }
+# dbg_msg "Pin direction is $pdirection"
+ ## now parce out the type
+ ## to overcome the std_logic_vector( # to #); vs (# to #); syntax
+ ## check and see if there is a vector spec in this pin with space after
+ ## the first bracket
+ set vect [string first "( " $pdirection_str]
+ if {$vect < 0} {
+ set ptype1 [lindex $pdirection_str 1]
+ set ptype2 [lindex $pdirection_str 2]
+ set ptype3 [lindex $pdirection_str 3]
+ set ptype "$ptype1 $ptype2 $ptype3"
+ } else {
+ set ptype1 [lindex $pdirection_str 1]
+ set ptype2 [lindex $pdirection_str 2]
+ set ptype3 [lindex $pdirection_str 3]
+ set ptype4 [lindex $pdirection_str 4]
+ set ptype "$ptype1 $ptype2 $ptype3 $ptype4"
+ }
+ ##puts $ptype
+
+ set last_pin [string first \; $ptype]
+ if {$last_pin >= 0} {
+ set is_vector [string first ( $ptype]
+ ## if there is a vector def
+ if {$is_vector >= 0} {
+ set temp_v [string first )) $ptype]
+ if {$temp_v >= 0} {
+ set s_e [expr $last_pin - 2]
+ set ptype [string range $ptype 0 $s_e]
+ } else {
+ set s_e [expr $last_pin - 1]
+ set ptype [string range $ptype 0 $s_e]
+ }
+ } else {
+ set temp_v [string first ) $ptype]
+ ## found a ); in the last pin def
+ if {$temp_v >= 0} {
+ set s_e [expr $last_pin - 2]
+ set ptype [string range $ptype 0 $s_e]
+ } else {
+ set s_e [expr $last_pin - 1]
+ set ptype [string range $ptype 0 $s_e]
+ }
+ }
+ }
+ set ptype [string trim $ptype]
+# dbg_msg "The type is $ptype"
+ lappend pdef $pname $pdirection $ptype
+ return $pdef
+}
+## end pars_pindef
+
+##--------------------------------------------------------------------------------
+## Write header to file passed
+proc write_header { handle } {
+ global version
+ ##global scan_date
+ set raw_date [clock scan now]
+ set scan_date [clock format $raw_date -format "%d %b %Y %T"]
+
+ ## so CVS will not modify selections, they have to be chopped up
+ set auth "-- \$Auth"
+ append auth "or: \$"
+ set cvs_date "-- \$dat"
+ append cvs_date "e: \$"
+ set cvs_name "-- \$Nam"
+ append cvs_name "e: \$"
+ set cvs_id "-- \$I"
+ append cvs_id "d: \$"
+ set cvs_source "-- \$Sour"
+ append cvs_source "ce: \$"
+ set cvs_log "-- \$Lo"
+ append cvs_log "g: \$"
+
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "-- Copyright -----------------------------------"
+ puts $handle "-- All Rights Reserved"
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "$auth"
+ puts $handle "--"
+ puts $handle "$cvs_date"
+ puts $handle "--"
+ puts $handle "$cvs_name"
+ puts $handle "--"
+ puts $handle "$cvs_id"
+ puts $handle "--"
+ puts $handle "$cvs_source"
+ puts $handle "--"
+ puts $handle "-- Description :"
+ puts $handle "-- This file was generated by TTB Gen Plus $version"
+ puts $handle "-- on $scan_date"
+ puts $handle "------------------------------------------------------------------------------"
+ puts $handle "-- This software contains concepts confidential to ----------------"
+ puts $handle "-- ---------. and is only made available within the terms of a written"
+ puts $handle "-- agreement."
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "-- Revision History:"
+ puts $handle "$cvs_log"
+ puts $handle "--"
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle ""
+ }
+
+##########################################################################
+## write Library and use statements
+proc write_lib_statements { handle } {
+ puts $handle "library IEEE;"
+ puts $handle "library ieee_proposed;"
+ puts $handle "library tb_pkg;"
+ puts $handle "--possible users libs;"
+ puts $handle "use IEEE.STD_LOGIC_1164.all;"
+ puts $handle "use IEEE.STD_LOGIC_ARITH.all;"
+ puts $handle "use ieee_proposed.STD_LOGIC_1164_additions.all;"
+ puts $handle "use std.textio.all;"
+ puts $handle "use tb_pkg.tb_pkg.all;"
+ puts $handle "--possible users use statement;"
+ puts $handle ""
+}
+
+#####################################################################
+## A directory has been selected now fill the list win with VHDL files
+proc fill_list {} {
+ global ent_dir odir
+ global tlist_ent use_list list_win ts_ent statsVar
+ global view_win mo_sel
+
+ ## get the user selection
+ browsed_from_set $ent_dir $ent_dir
+ ## as a default make output dir = input dir
+ set tmp_dir [$ent_dir get]
+ $odir delete 0 end
+ $odir insert end $tmp_dir
+ $odir configure -state readonly
+
+ ## clear the list window and selection
+ $list_win clear items
+ $list_win clear selection
+ $view_win clear
+ ## get the working directory
+ set dir [$ent_dir get]
+ ## get the list of VHDL files in working directory
+ set ftype ".vhd*"
+ set file_lst ""
+ set file_lst [glob -directory $dir *$ftype]
+
+##puts $file_lst
+
+ ## for each of the files in the file_lst
+ foreach l $file_lst {
+ ## creat string that is just the file name: no path
+ set testt $l
+ set nstart [string last "/" $l]
+ incr nstart
+ set name_str [string range $l $nstart end]
+ ## insert item on list
+ $list_win insert items 1 $name_str
+ }
+}
+
+######################################################################
+## load the vhdl file that has just been selected from list_win
+proc load_ent_file {} {
+ global ent_dir list_win view_win statsVar
+
+ ## update selection with selected item
+ $list_win selectitem
+ set sel_dx [$list_win curselection]
+ if {$sel_dx == ""} {
+ return
+ }
+ ## recover the selected item
+ set ln [$list_win get]
+ ## Get the working directory
+ #puts $ln
+ set lp [$ent_dir get]
+ ## append the file name
+ append lp "/" $ln
+ ## if the file does not exist return
+ set fexist [file exist $lp]
+ if {$fexist == 0} {
+ return
+ }
+ set ent_file [open $lp r]
+ ## clear the view_win
+ $view_win clear
+ set file_list {}
+ ## load file to memory
+ while {![eof $ent_file]} {
+ ## Get a line
+ set rline [gets $ent_file]
+ lappend file_list $rline
+ }
+ ## put file in text window and highlite the entity part
+ set ent_found 0
+ set in_ent 0
+ set statsVar ""
+ foreach l $file_list {
+ if {$in_ent == 0} {
+ set ent_def [string first entity $l]
+ set ent_is [string first is $l]
+ if {$ent_def >= 0 && $ent_is >= 0} {
+ set ent_name [lindex $l 1]
+ set statsVar "Entity $ent_name found"
+ set ent_found 1
+ set in_ent 1
+ $view_win insert end "$l\n" highlite
+ } else {
+ $view_win insert end "$l\n"
+ }
+ } else {
+ set ent_def [string first "end $ent_name" $l]
+ if {$ent_def >= 0} {
+ set end_name [lindex $l 1]
+ set end_found 1
+ set in_ent 0
+ $view_win insert end "$l\n" highlite
+ } elseif {[string first "end entity $ent_name" $l] >= 0} {
+ set end_name [lindex $l 1]
+ set end_found 1
+ set in_ent 0
+ $view_win insert end "$l\n" highlite
+ } else {
+ $view_win insert end "$l\n" highlite
+ }
+ }
+ }
+ if {$ent_found == 0} {
+ set statsVar "No Entity found!!"
+ }
+
+ ##$view_win import $lp
+ ##$view_win yview moveto 1
+ ##puts $lp
+}
+
+#########################################################################
+proc ttb_gen {} {
+ global mo_sel template ent_dir list_win odir p_view tdir
+
+ set template [$tdir get]
+
+ $p_view configure -steps 7
+ $p_view reset
+ ## recover the selected item
+ set ln [$list_win get]
+ ## Get the working directory
+ #puts $ln
+ set lp [$ent_dir get]
+ ## append the file name
+ append lp "/" $ln
+
+ set path_text $lp
+ set destin_text [$odir get]
+ set infile [open $path_text r]
+ set file_list list
+
+ set tmpcnt 0
+
+##################################################################
+## Read in the file and strip comments as we do
+ while {![eof $infile]} {
+ ## Get a line
+ set rline [gets $infile]
+ ## get rid of white space
+ set rline [string trim $rline]
+ ## Find comment if there
+ set cindex [string first -- $rline]
+ ## if a comment was found at the start of the line
+ if {$cindex == 0 || $rline == ""} {
+ set rline [string range $rline 0 [expr $cindex - 1]]
+ ##dbg_msg $rline
+ if {[llength $rline] > 0} {
+ lappend file_list [string tolower $rline]
+ }
+ ## else was not found so put line in list
+ } else {
+ lappend file_list [string tolower $rline]
+ }
+ incr tmpcnt
+ }
+ $p_view step
+ ## collect the library statements
+ foreach l $file_list {
+ set libpos [string first library $l]
+ if {$libpos >= 0} {
+ lappend libs_list $l
+ }
+ }
+ ## collect the use statements
+ foreach l $file_list {
+ set usepos [string first use $l]
+ if {$usepos >= 0} {
+ lappend use_list $l
+ }
+ }
+ ## check for the entity def
+ set ent_found 0
+ foreach l $file_list {
+ set ent_def [string first entity $l]
+ if {$ent_def >= 0} {
+ set ent_name [lindex $l 1]
+ break
+ }
+ }
+ ## if no ent die
+ if {$ent_def < 0} {
+ dbg_msg "An entity definition was not found in the file provided."
+ ## exit
+ }
+ $p_view step
+ ## check for end entity
+ foreach l $file_list {
+ lappend ent_list $l
+ set end_def [string first end $l]
+ if {$end_def >= 0} {
+ set end_ent [string first "end $ent_name" $l]
+ if {$end_ent >= 0} {
+ break
+ }
+ set end_ent [string first "end entity $ent_name" $l]
+ if {$end_ent >= 0} {
+ break
+ }
+ }
+ }
+ ## if no end die
+ if {$end_def < 0} {
+ dbg_msg "no end statement found for this entity"
+ ## exit
+ }
+
+ set port_found 0
+ ####################################################################
+ ## a few checks have been done, and non-relevant stuff stripped off.
+ ## now create an arrry of just the pin names and related info
+ foreach l $ent_list {
+ ## look for the port statement
+ if {$port_found == 0} {
+ set pfound [string first port $l]
+ ## found one now check if there is a pin def in the same line
+ if {$pfound >= 0} {
+ set port_found 1
+ set efound [string first : $l]
+ if {$efound >= 0} {
+ set line_test [split $l "("]
+ if {[llength $line_test] > 1} {
+ lappend port_list [lindex $line_test 1]
+ }
+ }
+ }
+ } else {
+ set efound [string first : $l]
+ if {$efound >= 0} {
+ lappend port_list $l
+ }
+ }
+ }
+ #dbg_msg $port_list
+ ## Change the port list into a pin info list
+ foreach l $port_list {
+ lappend split_pin [pars_pindef $l]
+ }
+ # dbg_msg $split_pin
+ ## calculate the longest pin name in characters
+ set name_length 0
+ foreach l $split_pin {
+ set temp_length [string length [lindex $l 0]]
+ if {$temp_length > $name_length} {
+ set name_length $temp_length
+ }
+ }
+ #dbg_msg $name_length
+ ## Make the name length one bigger
+ incr name_length
+
+ $p_view step
+#########################################################################
+## Generate the test bench entity.
+ ## Create the file name
+ set file_type "_tb_ent.vhd"
+ set ent_file_name $destin_text
+ append ent_file_name "/" $ent_name $file_type
+ # dbg_msg $ent_file_name
+ ## Create the tb entity name
+ set tb_ent_name $ent_name
+ set tb_sufix "_tb"
+ append tb_ent_name $tb_sufix
+
+ ## open and write the header
+ set ent_file [open $ent_file_name w+]
+ write_header $ent_file
+
+ ## write out Library and use statements
+ write_lib_statements $ent_file
+
+ puts $ent_file "entity $tb_ent_name is"
+ puts $ent_file " generic ("
+ puts $ent_file " stimulus_file: in string"
+ puts $ent_file " )\;"
+ puts $ent_file " port ("
+
+ ##-----------------------------------------
+ # for each pin in the list output the TB ent pin
+ set plist_size [llength $split_pin]
+ #dbg_msg $plist_size
+ set i 1
+ foreach l $split_pin {
+ set pdirection [lindex $l 1]
+ # puts $pdirection
+ ## switch on the source pin direction
+ switch -exact $pdirection {
+ "in" {set tb_ptype "buffer"}
+ "out" {set tb_ptype "in"}
+ "inout" {set tb_ptype "inout"}
+ default {
+ msg_error "Should have not got here .. pin direction in entity creation!!"
+ }
+ }
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" $tb_ptype]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ent_file $new_pname
+ incr i
+ }
+
+ puts $ent_file " )\;"
+ puts $ent_file "end $tb_ent_name;"
+ close $ent_file
+
+ $p_view step
+##################################################################
+## Generate the top level test bench entity
+ ## Create the file name
+ set file_type "_ttb_ent.vhd"
+ set ent_file_name $destin_text
+ append ent_file_name "/" $ent_name $file_type
+ # dbg_msg $ent_file_name
+ ## Create the tb entity name
+ set ttb_ent_name $ent_name
+ set ttb_sufix "_ttb"
+ append ttb_ent_name $ttb_sufix
+
+ ## open and write the header
+ set ttb_ent_file [open $ent_file_name w+]
+ write_header $ttb_ent_file
+
+ puts $ttb_ent_file "library IEEE;"
+ puts $ttb_ent_file "library dut_lib;"
+ puts $ttb_ent_file "use IEEE.STD_LOGIC_1164.all;"
+ puts $ttb_ent_file "use dut_lib.all;"
+ puts $ttb_ent_file ""
+ puts $ttb_ent_file "entity $ttb_ent_name is"
+ puts $ttb_ent_file " generic ("
+ puts $ttb_ent_file " stimulus_file: string := \"stm/stimulus_file.stm\""
+ puts $ttb_ent_file " )\;"
+ puts $ttb_ent_file "end $ttb_ent_name\;"
+
+ close $ttb_ent_file
+
+ $p_view step
+#################################################################
+## Generate the top level structure
+ ## Create the file name
+ set file_type "_ttb_str.vhd"
+ set str_file_name $destin_text
+ append str_file_name "/" $ent_name $file_type
+ # dbg_msg $ent_file_name
+ ## Create the tb entity name
+ set ttb_ent_name $ent_name
+ set ttb_sufix "_ttb"
+ append ttb_ent_name $ttb_sufix
+
+ ## open and write the header
+ set ttb_str_file [open $str_file_name w+]
+ write_header $ttb_str_file
+
+ puts $ttb_str_file ""
+ puts $ttb_str_file "architecture struct of $ttb_ent_name is"
+ puts $ttb_str_file ""
+ puts $ttb_str_file "component $ent_name"
+ puts $ttb_str_file " port ("
+ ## put out the dut component def
+ ###################################################
+ # for each pin in the list output the TB ent pin
+ set i 1
+ foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" [lindex $l 1]]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+ }
+ puts $ttb_str_file " )\;"
+ puts $ttb_str_file "end component\;"
+
+ puts $ttb_str_file ""
+ puts $ttb_str_file "component $tb_ent_name"
+ puts $ttb_str_file " generic ("
+ puts $ttb_str_file " stimulus_file: in string"
+ puts $ttb_str_file " )\;"
+ puts $ttb_str_file " port ("
+ ## put out the tb component def
+ ####################################################
+ # for each pin in the list output the TB ent pin
+ set i 1
+ foreach l $split_pin {
+ set pdirection [lindex $l 1]
+# dbg_msg $pdirection
+ ## switch on the source pin direction
+ switch -exact $pdirection {
+ "in" {set tb_ptype "buffer"}
+ "out" {set tb_ptype "in"}
+ "inout" {set tb_ptype "inout"}
+ default {
+ msg_error "Should have not got here .. pin direction in entity creation!!"
+ }
+ }
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" $tb_ptype]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+ }
+ puts $ttb_str_file " )\;"
+ puts $ttb_str_file "end component\;"
+ puts $ttb_str_file ""
+
+ puts $ttb_str_file "for all: $ent_name use entity dut_lib.$ent_name\(str)\;"
+ puts $ttb_str_file "for all: $tb_ent_name use entity work.$tb_ent_name\(bhv)\;"
+
+ puts $ttb_str_file ""
+ #####################################################
+ # for each pin in the list output the TB ent pin
+ # generate a signal name
+ foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " signal temp_%-${name_length}s" [lindex $l 0]]
+ append new_pname ": " [lindex $l 2] ";"
+ puts $ttb_str_file $new_pname
+ }
+
+ puts $ttb_str_file ""
+ puts $ttb_str_file "begin"
+ puts $ttb_str_file ""
+ puts $ttb_str_file "dut: $ent_name"
+ puts $ttb_str_file " port map("
+ ##-----------------------------------------
+ # for each pin in the list output the TB ent pin
+ # Generate port map for DUT
+ set i 1
+ foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ if {$i != $plist_size} {
+ append new_pname "=> temp_" [lindex $l 0] ","
+ } else {
+ append new_pname "=> temp_" [lindex $l 0]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+ }
+
+ puts $ttb_str_file " )\;"
+ puts $ttb_str_file ""
+ puts $ttb_str_file "tb: $tb_ent_name"
+ puts $ttb_str_file " generic map("
+ puts $ttb_str_file " stimulus_file => stimulus_file"
+ puts $ttb_str_file " )"
+ puts $ttb_str_file " port map("
+ ##-----------------------------------------
+ # for each pin in the list output the TB ent pin
+ # Generate port map for DUT
+ set i 1
+ foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ if {$i != $plist_size} {
+ append new_pname "=> temp_" [lindex $l 0] ","
+ } else {
+ append new_pname "=> temp_" [lindex $l 0]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+ }
+
+ puts $ttb_str_file " )\;"
+ puts $ttb_str_file ""
+ puts $ttb_str_file "end struct\;"
+ close $ttb_str_file
+
+ ######################################################################
+ ## Now generate the bhv file from template
+
+ if {[$mo_sel get] == "bhv"} {
+
+ $p_view step
+ set infile [open "$template" r]
+
+ while {![eof $infile]} {
+ ## Get a line
+ set rline [gets $infile]
+ lappend temp_file_list $rline
+ }
+ close $infile
+
+ ## strip off the header
+ set end_header 0
+ foreach l $temp_file_list {
+ set comment [string first -- $l]
+ if {$comment < 0} {
+ set end_header 1
+ }
+ ## if we found the end of the header
+ if {$end_header == 1} {
+ lappend template_list $l
+ }
+ }
+
+ ## split the file into two peices, to the point of input initialization
+ set i 1
+ foreach l $template_list {
+ ## check for parsing point
+ set mid_point [string first parse_tb1 $l]
+ if {$mid_point >= 0} {
+ break
+ }
+
+ if {$i > 2} {
+ lappend top_half $l
+ }
+ incr i
+ }
+
+ set found 0
+ foreach l $template_list {
+ if {$found == 1} {
+ lappend bottom_half $l
+ }
+ ## check for parsing point
+ set mid_point [string first parse_tb1 $l]
+ if {$mid_point >= 0} {
+ set found 1
+ }
+ }
+
+ ## Create the file name
+ set file_type "_tb_bhv.vhd"
+ set bhv_file_name $destin_text
+ append bhv_file_name "/" $ent_name $file_type
+ # dbg_msg $ent_file_name
+
+ ## open and write the header
+ set bhv_file [open $bhv_file_name w+]
+ write_header $bhv_file
+
+ puts $bhv_file ""
+ puts $bhv_file "architecture bhv of $tb_ent_name is"
+ puts $bhv_file ""
+ foreach l $top_half {
+ puts $bhv_file $l
+ }
+
+ puts $bhv_file ""
+ ## now generate and write out input initialization
+ foreach l $split_pin {
+ set temp_def [lindex $l 1]
+ set input_def [string first in $temp_def]
+ if {$input_def >= 0} {
+ set vector [string first vector $l]
+ set init_def [format " %-${name_length}s" [lindex $l 0]]
+ if {$vector >= 0} {
+ append init_def "<= (others => '0')\;"
+ } else {
+ append init_def "<= '0'\;"
+ }
+ puts $bhv_file $init_def
+ }
+ }
+ puts $bhv_file ""
+ ## now write out the bottem half and termination
+ foreach l $bottom_half {
+ puts $bhv_file $l
+ }
+
+ close $bhv_file
+ }
+ ## put out a terminating message for the user
+ dbg_msg "Test bench files were generated in directory:\n $destin_text"
+ $p_view step
+}
+## enable pop up console for debug
+bind . {catch {console show}}
+
+##-------------------------------------------------------------------------------
+##-- Revision History:
+##-- $Log: not supported by cvs2svn $
+##--
+##--
+##----------------------------------------------------------------------------
Index: vhld_tb/trunk/ttb_gen/ttb_gen_gui.tcl
===================================================================
--- vhld_tb/trunk/ttb_gen/ttb_gen_gui.tcl (nonexistent)
+++ vhld_tb/trunk/ttb_gen/ttb_gen_gui.tcl (revision 14)
@@ -0,0 +1,754 @@
+##-------------------------------------------------------------------------------
+##-- Copyright 2007 Ken Campbell
+##-- All Rights Reserved
+##
+## 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 2 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, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##-------------------------------------------------------------------------------
+##-- $Author: sckoarn $
+##--
+##-- $Date: 2007-04-06 04:06:49 $
+##--
+##-- $Name: not supported by cvs2svn $
+##--
+##-- $Id: ttb_gen_gui.tcl,v 1.1.1.1 2007-04-06 04:06:49 sckoarn Exp $
+##--
+##-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/ttb_gen/ttb_gen_gui.tcl,v $
+##--
+##-- Description :
+##-- This application takes a text file containing the definition of a VHDL
+## entity, parses that entity and generates the VHDL Test Bench starting
+## file set. ( This was the first application written by the author
+## in the tcl\tk language, forgive the style.)
+##--
+##------------------------------------------------------------------------------
+## set the current version info
+set ttbgen_version "v1.0"
+## get the time and date from the system
+set raw_date [clock scan now]
+set scan_date [clock format $raw_date -format "%d %b %Y %T"]
+## title and version info for window
+set msg_txt [label .l1 -text "Test Bench Generation Tool $ttbgen_version"];
+pack $msg_txt
+
+## destination spec frame
+set g [frame .dest]
+label $g.lab -text "Destination Directory: " -anchor e
+entry $g.ent -width 20
+pack $g.lab -side left
+pack $g.ent -side left -expand yes -fill x
+
+## source spec frame with browser
+set f [frame .sour]
+label $f.lab -text "Select Generation Source: " -anchor e
+entry $f.ent -width 20
+button $f.but -text "Browse ..." -command "fileDialog $f $f.ent $g.ent"
+pack $f.lab -side left
+pack $f.ent -side left -expand yes -fill x
+pack $f.but -side left
+pack $f -fill x -padx 1c -pady 3
+## pack destination frame
+pack $g -fill x -padx 1c -pady 3
+## check button for optional bhv generation
+checkbutton .b1 -text "Generate the bhv file?" -variable bhv
+pack .b1
+## create and place the buttons frame
+frame .buttons
+pack .buttons -side bottom -fill x -pady 2m
+button .buttons.exit -text "Exit" -command exit
+button .buttons.help -text "Help" -command "show_help $msg_txt"
+button .buttons.gene -text "Generate" -command "ttb_gen $f.ent $g.ent"
+pack .buttons.gene -side left -expand 1
+pack .buttons.help -side left -expand 1
+pack .buttons.exit -side left -expand 1
+
+
+###########################################################################
+## some debug and help procs
+## Message Error, terminate
+proc msg_error { msg } {
+ tk_messageBox -message $msg -type ok
+ exit
+}
+###########################################################################
+## Message, continue
+proc dbg_msg { msg } {
+ tk_messageBox -message $msg -type ok
+}
+##-----------------------------------------------------------------------
+## Help display proc. It changes the Lable at the top of the window to
+## have the following text
+proc show_help { h } {
+ $h configure -justify left -text "Test Bench Generation Help \n \n \
+ 1) Use Browse to select a source entity VHDL file \n \
+ 2) Provide the path to the destination directory \n \
+ 3) Check Generate bhv, if behave file should be generated \n \
+ 4) Hit the Generate button"
+}
+
+##---------------------------------------------------------------
+## File dialog handler
+proc fileDialog {f ent des} {
+ # Type names Extension
+ #
+ #---------------------------------------------------------
+ set types {
+ {"VHDL Code" {.vhd .vhdl} }
+ {"Text files" {.txt} }
+ {"Tcl Scripts" {.tcl} TEXT}
+ {"All files" *}
+ }
+
+ set file [tk_getOpenFile -filetypes $types -parent $f]
+
+ if {[string compare $file ""]} {
+ $ent delete 0 end
+ $ent insert 0 $file
+ $ent xview end
+
+ set des_directory [string last / $file]
+ $des delete 0 end
+ $des insert 0 [string range $file 0 $des_directory]
+ $des xview end
+ }
+}
+
+##-----------------------------------------------------------------------
+## proc pars_pindef
+proc pars_pindef { pin } {
+ set pdirection ""
+# dbg_msg $pin
+ set spin [split $pin ":"]
+ set pname_str [lindex $spin 0]
+ set pname [lindex $pname_str 0]
+# dbg_msg "Pin name is $pname"
+ set pdirection_str [lindex $spin 1]
+# dbg_msg $pdirection_str
+ ## parce out the direction, supporting only 3
+ set direction [string first "in " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "in"
+ }
+ set direction [string first "out " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "out"
+ }
+ set direction [string first "inout " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "inout"
+ }
+ if {$pdirection == ""} {
+ msg_error "Unsuported Pin direction found. \n Suported are IN OUT and INOUT."
+ }
+# dbg_msg "Pin direction is $pdirection"
+ ## now parce out the type
+ ## to overcome the std_logic_vector( # to #); vs (# to #); syntax
+ ## check and see if there is a vector spec in this pin with space after
+ ## the first bracket
+ set vect [string first "( " $pdirection_str]
+ if {$vect < 0} {
+ set ptype1 [lindex $pdirection_str 1]
+ set ptype2 [lindex $pdirection_str 2]
+ set ptype3 [lindex $pdirection_str 3]
+ set ptype "$ptype1 $ptype2 $ptype3"
+ } else {
+ set ptype1 [lindex $pdirection_str 1]
+ set ptype2 [lindex $pdirection_str 2]
+ set ptype3 [lindex $pdirection_str 3]
+ set ptype4 [lindex $pdirection_str 4]
+ set ptype "$ptype1 $ptype2 $ptype3 $ptype4"
+ }
+ ##puts $ptype
+
+ set last_pin [string first \; $ptype]
+ if {$last_pin >= 0} {
+ set is_vector [string first ( $ptype]
+ ## if there is a vector def
+ if {$is_vector >= 0} {
+ set temp_v [string first )) $ptype]
+
+ if {$temp_v >= 0} {
+ set s_e [expr $last_pin - 2]
+ set ptype [string range $ptype 0 $s_e]
+ } else {
+ set s_e [expr $last_pin - 1]
+ set ptype [string range $ptype 0 $s_e]
+ }
+ } else {
+ set temp_v [string first ) $ptype]
+ ## found a ); in the last pin def
+ if {$temp_v >= 0} {
+ set s_e [expr $last_pin - 2]
+ set ptype [string range $ptype 0 $s_e]
+ } else {
+ set s_e [expr $last_pin - 1]
+ set ptype [string range $ptype 0 $s_e]
+ }
+ }
+ }
+ set ptype [string trim $ptype]
+# dbg_msg "The type is $ptype"
+ lappend pdef $pname $pdirection $ptype
+ return $pdef
+}
+
+##--------------------------------------------------------------------------------
+## Write header to file passed
+proc write_header { handle } {
+ global ttbgen_version
+ global scan_date
+
+ ## so CVS will not modify selections, they have to be chopped up
+ set auth "-- \$Auth"
+ append auth "or: \$"
+ set cvs_date "-- \$dat"
+ append cvs_date "e: \$"
+ set cvs_name "-- \$Nam"
+ append cvs_name "e: \$"
+ set cvs_id "-- \$I"
+ append cvs_id "d: \$"
+ set cvs_source "-- \$Sour"
+ append cvs_source "ce: \$"
+ set cvs_log "-- \$Lo"
+ append cvs_log "g: \$"
+
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "-- Copyright 2007 xxxx"
+ puts $handle "-- All Rights Reserved"
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "$auth"
+ puts $handle "--"
+ puts $handle "$cvs_date"
+ puts $handle "--"
+ puts $handle "$cvs_name"
+ puts $handle "--"
+ puts $handle "$cvs_id"
+ puts $handle "--"
+ puts $handle "$cvs_source"
+ puts $handle "--"
+ puts $handle "-- Description :"
+ puts $handle "-- This file was generated by ttb_gen2_gui $ttbgen_version"
+ puts $handle "-- on $scan_date"
+ puts $handle "------------------------------------------------------------------------------"
+# puts $handle "-- This software contains concepts confidential to ------------------"
+# puts $handle "-- -----------. and is only made available within the terms of a written"
+# puts $handle "-- agreement."
+# puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "-- Revision History:"
+ puts $handle "$cvs_log"
+ puts $handle "--"
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle ""
+}
+
+##-------------------------------------------------------------------------
+## write Library and use statements
+proc write_lib_statements { handle } {
+puts $handle "library IEEE;"
+puts $handle "library ieee_proposed;"
+puts $handle "--library modelsim_lib;"
+puts $handle "use IEEE.STD_LOGIC_1164.all;"
+puts $handle "use IEEE.STD_LOGIC_ARITH.all;"
+puts $handle "use ieee_proposed.STD_LOGIC_1164_additions.all;"
+puts $handle "use std.textio.all;"
+puts $handle "--use modelsim_lib.util.all;"
+puts $handle ""
+}
+
+
+#########################################################################
+##
+## START of main program
+##
+#########################################################################
+proc ttb_gen { source destin } {
+
+global bhv
+
+set path_text [$source get]
+set destin_text [$destin get]
+
+set infile [open "$path_text" r]
+set file_list list
+
+##########################################
+## Path needs to be set up for the some usage cases
+## set the path to the template behave file
+set template "template_tb_bhv.vhd"
+#set template "\\\\Gs1\\public\\fpga_projects\\verification_docs\\html\\vhdltb\\template2_tb_bhv.vhd"
+
+set tmpcnt 0
+
+## -------------------------------------------------------------
+## Read in the file and strip comments as we do
+while {![eof $infile]} {
+ ## Get a line
+ set rline [gets $infile]
+ ## get rid of white space
+ set rline [string trim $rline]
+ ## Find comment if there
+ set cindex [string first -- $rline]
+ ## if a comment was found at the start of the line
+ if {$cindex == 0 || $rline == ""} {
+ set rline [string range $rline 0 [expr $cindex - 1]]
+ ##dbg_msg $rline
+ if {[llength $rline] > 0} {
+ lappend file_list [string tolower $rline]
+ }
+ ## else was not found so put line in list
+ } else {
+ lappend file_list [string tolower $rline]
+ # if {$tmpcnt > 490} {
+ # dbg_msg "$rline $tmpcnt"
+ # }
+ }
+ incr tmpcnt
+}
+
+## collect the library statements
+foreach l $file_list {
+ set libpos [string first library $l]
+ if {$libpos >= 0} {
+ lappend libs_list $l
+ }
+}
+
+## collect the use statements
+foreach l $file_list {
+ set usepos [string first use $l]
+ if {$usepos >= 0} {
+ lappend use_list $l
+ }
+}
+## check for the entity def
+set ent_found 0
+foreach l $file_list {
+ set ent_def [string first entity $l]
+ if {$ent_def >= 0} {
+## set ent_found 1
+ set ent_name [lindex $l 1]
+ break
+ }
+}
+## if no ent die
+if {$ent_def < 0} {
+ msg_error "An entity definition was not found in the file provided."
+## exit
+}
+
+## check for end entity
+foreach l $file_list {
+ lappend ent_list $l
+ set end_def [string first end $l]
+ if {$end_def >= 0} {
+ set end_ent [string first "end $ent_name" $l]
+ if {$end_ent >= 0} {
+ break
+ }
+ set end_ent [string first "end entity $ent_name" $l]
+ if {$end_ent >= 0} {
+ break
+ }
+ }
+}
+## if no end die
+if {$end_def < 0} {
+ msg_error "no end statement found for this entity"
+## exit
+}
+
+set port_found 0
+#######----------------------------------------------------------------
+## a few checks have been done, and non-relevant stuff stripped off.
+## now create an arrry of just the pin names and related info
+foreach l $ent_list {
+ ## look for the port statement
+ if {$port_found == 0} {
+ set pfound [string first port $l]
+ ## found one now check if there is a pin def in the same line
+ if {$pfound >= 0} {
+ set port_found 1
+ set efound [string first : $l]
+ if {$efound >= 0} {
+ set line_test [split $l "("]
+ if {[llength $line_test] > 1} {
+ lappend port_list [lindex $line_test 1]
+ }
+ }
+ }
+ } else {
+ set efound [string first : $l]
+ if {$efound >= 0} {
+ lappend port_list $l
+ }
+ }
+}
+#dbg_msg $port_list
+## Change the port list into a pin info list
+foreach l $port_list {
+ lappend split_pin [pars_pindef $l]
+}
+# dbg_msg $split_pin
+
+## calculate the longest pin name in characters
+set name_length 0
+foreach l $split_pin {
+ set temp_length [string length [lindex $l 0]]
+ if {$temp_length > $name_length} {
+ set name_length $temp_length
+ }
+}
+#dbg_msg $name_length
+## Make the name length one bigger
+incr name_length
+
+#########################################################################
+## Generate the test bench entity.
+
+## Create the file name
+set file_type "_tb_ent.vhd"
+set ent_file_name $destin_text
+append ent_file_name "/" $ent_name $file_type
+# dbg_msg $ent_file_name
+## Create the tb entity name
+set tb_ent_name $ent_name
+set tb_sufix "_tb"
+append tb_ent_name $tb_sufix
+
+## open and write the header
+set ent_file [open $ent_file_name w+]
+write_header $ent_file
+
+## write out Library and use statements
+write_lib_statements $ent_file
+
+puts $ent_file "entity $tb_ent_name is"
+puts $ent_file " generic ("
+puts $ent_file " stimulus_file: in string"
+puts $ent_file " )\;"
+puts $ent_file " port ("
+
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+set plist_size [llength $split_pin]
+#dbg_msg $plist_size
+set i 1
+foreach l $split_pin {
+ set pdirection [lindex $l 1]
+# puts $pdirection
+ ## switch on the source pin direction
+ switch -exact $pdirection {
+ "in" {set tb_ptype "buffer"}
+ "out" {set tb_ptype "in"}
+ "inout" {set tb_ptype "inout"}
+ default {
+ msg_error "Should have not got here .. pin direction in entity creation!!"
+ }
+ }
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" $tb_ptype]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ent_file $new_pname
+ incr i
+}
+
+puts $ent_file " )\;"
+puts $ent_file "end $tb_ent_name;"
+
+close $ent_file
+
+##################################################################
+## Generate the top level test bench entity
+## Create the file name
+set file_type "_ttb_ent.vhd"
+set ent_file_name $destin_text
+append ent_file_name "/" $ent_name $file_type
+# dbg_msg $ent_file_name
+## Create the tb entity name
+set ttb_ent_name $ent_name
+set ttb_sufix "_ttb"
+append ttb_ent_name $ttb_sufix
+
+## open and write the header
+set ttb_ent_file [open $ent_file_name w+]
+write_header $ttb_ent_file
+
+puts $ttb_ent_file "library IEEE;"
+puts $ttb_ent_file "library dut_lib;"
+puts $ttb_ent_file "use IEEE.STD_LOGIC_1164.all;"
+puts $ttb_ent_file "use dut_lib.all;"
+puts $ttb_ent_file ""
+puts $ttb_ent_file "entity $ttb_ent_name is"
+puts $ttb_ent_file " generic ("
+puts $ttb_ent_file " stimulus_file: string := \"stm/stimulus_file.stm\""
+puts $ttb_ent_file " )\;"
+puts $ttb_ent_file "end $ttb_ent_name\;"
+
+close $ttb_ent_file
+
+#################################################################
+## Generate the top level structure
+## Create the file name
+set file_type "_ttb_str.vhd"
+set str_file_name $destin_text
+append str_file_name "/" $ent_name $file_type
+# dbg_msg $ent_file_name
+## Create the tb entity name
+set ttb_ent_name $ent_name
+set ttb_sufix "_ttb"
+append ttb_ent_name $ttb_sufix
+
+## open and write the header
+set ttb_str_file [open $str_file_name w+]
+write_header $ttb_str_file
+
+puts $ttb_str_file ""
+puts $ttb_str_file "architecture struct of $ttb_ent_name is"
+puts $ttb_str_file ""
+puts $ttb_str_file "component $ent_name"
+puts $ttb_str_file " port ("
+## put out the dut component def
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+set i 1
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" [lindex $l 1]]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+puts $ttb_str_file " )\;"
+puts $ttb_str_file "end component\;"
+
+puts $ttb_str_file ""
+puts $ttb_str_file "component $tb_ent_name"
+puts $ttb_str_file " generic ("
+puts $ttb_str_file " stimulus_file: in string"
+puts $ttb_str_file " )\;"
+puts $ttb_str_file " port ("
+## put out the tb component def
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+set i 1
+foreach l $split_pin {
+ set pdirection [lindex $l 1]
+# dbg_msg $pdirection
+ ## switch on the source pin direction
+ switch -exact $pdirection {
+ "in" {set tb_ptype "buffer"}
+ "out" {set tb_ptype "in"}
+ "inout" {set tb_ptype "inout"}
+ default {
+ msg_error "Should have not got here .. pin direction in entity creation!!"
+ }
+ }
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" $tb_ptype]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+puts $ttb_str_file " )\;"
+puts $ttb_str_file "end component\;"
+puts $ttb_str_file ""
+
+puts $ttb_str_file "for all: $ent_name use entity dut_lib.$ent_name\(str)\;"
+puts $ttb_str_file "for all: $tb_ent_name use entity work.$tb_ent_name\(bhv)\;"
+
+puts $ttb_str_file ""
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+# generate a signal name
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " signal temp_%-${name_length}s" [lindex $l 0]]
+ append new_pname ": " [lindex $l 2] ";"
+ puts $ttb_str_file $new_pname
+}
+
+puts $ttb_str_file ""
+puts $ttb_str_file "begin"
+puts $ttb_str_file ""
+puts $ttb_str_file "dut: $ent_name"
+puts $ttb_str_file " port map("
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+# Generate port map for DUT
+set i 1
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ if {$i != $plist_size} {
+ append new_pname "=> temp_" [lindex $l 0] ","
+ } else {
+ append new_pname "=> temp_" [lindex $l 0]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+
+puts $ttb_str_file " )\;"
+puts $ttb_str_file ""
+puts $ttb_str_file "tb: $tb_ent_name"
+puts $ttb_str_file " generic map("
+puts $ttb_str_file " stimulus_file => stimulus_file"
+puts $ttb_str_file " )"
+puts $ttb_str_file " port map("
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+# Generate port map for DUT
+set i 1
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ if {$i != $plist_size} {
+ append new_pname "=> temp_" [lindex $l 0] ","
+ } else {
+ append new_pname "=> temp_" [lindex $l 0]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+
+puts $ttb_str_file " )\;"
+puts $ttb_str_file ""
+puts $ttb_str_file "end struct\;"
+
+close $ttb_str_file
+
+######################################################################
+## Now generate the bhv file from template
+
+if {$bhv == 1} {
+
+ set infile [open "$template" r]
+
+ while {![eof $infile]} {
+ ## Get a line
+ set rline [gets $infile]
+ lappend temp_file_list $rline
+ }
+
+ close $infile
+
+ ## strip off the header
+ set end_header 0
+ foreach l $temp_file_list {
+ set comment [string first -- $l]
+ if {$comment < 0} {
+ set end_header 1
+ }
+ ## if we found the end of the header
+ if {$end_header == 1} {
+ lappend template_list $l
+ }
+ }
+
+ ## split the file into two peices, to the point of input initialization
+ set i 1
+ foreach l $template_list {
+ ## check for parsing point
+ set mid_point [string first parse_tb1 $l]
+ if {$mid_point >= 0} {
+ break
+ }
+
+ if {$i > 2} {
+ lappend top_half $l
+ }
+ incr i
+ }
+
+ set found 0
+ foreach l $template_list {
+ if {$found == 1} {
+ lappend bottom_half $l
+ }
+ ## check for parsing point
+ set mid_point [string first parse_tb1 $l]
+ if {$mid_point >= 0} {
+ set found 1
+ }
+ }
+
+ ## Create the file name
+ set file_type "_tb_bhv.vhd"
+ set bhv_file_name $destin_text
+ append bhv_file_name "/" $ent_name $file_type
+ # dbg_msg $ent_file_name
+
+ ## open and write the header
+ set bhv_file [open $bhv_file_name w+]
+ write_header $bhv_file
+
+ puts $bhv_file ""
+ puts $bhv_file "architecture bhv of $tb_ent_name is"
+ puts $bhv_file ""
+ foreach l $top_half {
+ puts $bhv_file $l
+ }
+
+ puts $bhv_file ""
+ ## now generate and write out input initialization
+ foreach l $split_pin {
+ set temp_def [lindex $l 1]
+ set input_def [string first in $temp_def]
+ if {$input_def >= 0} {
+ set vector [string first vector $l]
+ set init_def [format " %-${name_length}s" [lindex $l 0]]
+ if {$vector >= 0} {
+ append init_def "<= (others => '0')\;"
+ } else {
+ append init_def "<= '0'\;"
+ }
+ puts $bhv_file $init_def
+ }
+ }
+ puts $bhv_file ""
+ ## now write out the bottem half and termination
+ foreach l $bottom_half {
+ puts $bhv_file $l
+ }
+
+ close $bhv_file
+ }
+ ## put out a terminating message for the user
+ dbg_msg "Test bench files were generated in directory:\n $destin_text"
+
+}
+
+bind . {catch {console show}}
+
+##-------------------------------------------------------------------------------
+##-- Revision History:
+##-- $Log: not supported by cvs2svn $
+##--
+##----------------------------------------------------------------------------
+
Index: vhld_tb/trunk/GNU_GPL.txt
===================================================================
--- vhld_tb/trunk/GNU_GPL.txt (nonexistent)
+++ vhld_tb/trunk/GNU_GPL.txt (revision 14)
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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 2 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
Index: vhld_tb/trunk
===================================================================
--- vhld_tb/trunk (nonexistent)
+++ vhld_tb/trunk (revision 14)
vhld_tb/trunk
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: vhld_tb/web_uploads
===================================================================
--- vhld_tb/web_uploads (nonexistent)
+++ vhld_tb/web_uploads (revision 14)
vhld_tb/web_uploads
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: vhld_tb/branches
===================================================================
--- vhld_tb/branches (nonexistent)
+++ vhld_tb/branches (revision 14)
vhld_tb/branches
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##
Index: vhld_tb/tags/rel_001/source/template_tb_bhv.vhd
===================================================================
--- vhld_tb/tags/rel_001/source/template_tb_bhv.vhd (nonexistent)
+++ vhld_tb/tags/rel_001/source/template_tb_bhv.vhd (revision 14)
@@ -0,0 +1,494 @@
+-------------------------------------------------------------------------------
+-- Copyright 2007 Ken Campbell
+-------------------------------------------------------------------------------
+-- $Author: sckoarn $
+--
+-- $Date: 2007-04-06 04:06:48 $
+--
+-- $Name: not supported by cvs2svn $
+--
+-- $Id: template_tb_bhv.vhd,v 1.1.1.1 2007-04-06 04:06:48 sckoarn Exp $
+--
+-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/template_tb_bhv.vhd,v $
+--
+-- Description : The the testbench package template behave file.
+-- Initial GNU release.
+--
+------------------------------------------------------------------------------
+--This file is part of The VHDL Test Bench.
+--
+-- The VHDL Test Bench 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 2 of the License, or
+-- (at your option) any later version.
+--
+-- Foobar 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 The VHDL Test Bench; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-------------------------------------------------------------------------------
+-- Revision History:
+-- $Log: not supported by cvs2svn $
+--
+-------------------------------------------------------------------------------
+
+architecture bhv of tb_Top is
+
+
+ signal tb_clk : std_logic;
+
+-------------------------------------------------------------------------
+-- Component defintion
+
+-------------------------------------------------------------------------------
+-- USER Component instantiations
+--for all: Arbitor use entity tb_objects.arbitor(bhv);
+
+
+ begin
+
+-------------------------------------------------------------------------------
+-- clock driver process
+-- the main clock generator
+clock_driver:
+ process
+ begin
+ tb_clk <= '0';
+ wait for 5 ns;
+ tb_clk <= '1';
+ wait for 5 ns;
+ end process clock_driver;
+
+ --------------------------------------------------------------------------
+ -- Read_file Process:
+ --
+ -- This process is the main process of the testbench. This process reads
+ -- the stumulus file, parses it, creates lists of records, then uses these
+ -- lists to exicute user instructions. There are two passes through the
+ -- script. Pass one reads in the stimulus text file, checks it, creates
+ -- lists of valid instructions, valid list of variables and finialy a list
+ -- of user instructions(the sequence). The second pass through the file,
+ -- records are drawn from the user instruction list, variables are converted
+ -- to integers and put through the elsif structure for exicution.
+ --------------------------------------------------------------------------
+ Read_file: process
+ variable current_line : text_line; -- The current input line
+ variable inst_list : inst_def_ptr; -- the instruction list
+ variable defined_vars : var_field_ptr; -- defined variables
+ variable inst_sequ : stim_line_ptr; -- the instruction sequence
+
+ variable instruction : text_field; -- instruction field
+ variable par1 : integer; -- paramiter 1
+ variable par2 : integer; -- paramiter 2
+ variable par3 : integer; -- paramiter 3
+ variable par4 : integer; -- paramiter 4
+ variable par5 : integer; -- paramiter 5
+ variable par6 : integer; -- paramiter 6
+ variable txt : stm_text_ptr;
+ variable nbase : base; -- the number base to use
+ variable len : integer; -- length of the instruction field
+ variable file_line : integer; -- Line number in the stimulus file
+ variable file_name : text_line; -- the file name the line came from
+ variable v_line : integer := 0; -- sequence number
+ variable stack : stack_register; -- Call stack
+ variable stack_ptr : integer := 0; -- call stack pointer
+ variable wh_stack : stack_register; -- while stack
+ variable wh_dpth : integer := 0; -- while depth
+ variable wh_ptr : integer := 0; -- while pointer
+ variable loop_num : integer := 0;
+ variable curr_loop_count : int_array := (others => 0);
+ variable term_loop_count : int_array := (others => 0);
+ variable loop_line : int_array := (others => 0);
+
+ variable messages : boolean := TRUE;
+ variable if_state : boolean := FALSE;
+ variable wh_state : boolean := FALSE;
+ variable wh_end : boolean := FALSE;
+ variable rand : std_logic_vector(31 downto 0);
+ variable rand_back : std_logic_vector(31 downto 0);
+
+ variable temp_int : integer;
+ variable temp_index : integer;
+ variable temp_str : text_field;
+ variable valid : integer;
+ variable v_temp_vec1 : std_logic_vector(31 downto 0);
+ variable v_temp_vec2 : std_logic_vector(31 downto 0);
+
+ --------------------------------------------------------------------------
+ -- Area for Procedures which may be usefull to more than one instruction.
+ -- By coding here commonly used code sections ...
+ -- you know the benifits.
+ ---------------------------------------------------------------------
+ -----------------------------------------------------------------
+ -- This procedure writes to the arbitor model access port
+-- procedure arb_write(add: in integer; .....
+-- end arb_write;
+
+
+ begin -- process Read_file
+-- parse_tb1 start input initialization
+ -----------------------------------------------------------------------
+ -- Stimulus file instruction definition
+ -- This is where the instructions used in the stimulus file are defined.
+ -- Syntax is
+ -- define_instruction(inst_def_ptr, instruction, paramiters)
+ -- inst_def_ptr: is a record pointer defined in tb_pkg_header
+ -- instruction: the text instruction name ie. "DEFINE_VAR"
+ -- paramiters: the number of fields or paramiters passed
+ --
+ -- Some basic instruction are created here, the user should create new
+ -- instructions below the standard ones.
+ ------------------------------------------------------------------------
+ define_instruction(inst_list, "DEFINE_VAR", 2); -- Define a Variable
+ define_instruction(inst_list, "EQU_VAR", 2);
+ define_instruction(inst_list, "ADD_VAR", 2);
+ define_instruction(inst_list, "SUB_VAR", 2);
+ define_instruction(inst_list, "CALL", 1);
+ define_instruction(inst_list, "RETURN_CALL", 0);
+ define_instruction(inst_list, "JUMP", 1);
+ define_instruction(inst_list, "LOOP", 1);
+ define_instruction(inst_list, "END_LOOP", 0);
+ define_instruction(inst_list, "IF", 3);
+ define_instruction(inst_list, "ELSE", 0);
+ define_instruction(inst_list, "END_IF", 0);
+ define_instruction(inst_list, "WHILE", 3);
+ define_instruction(inst_list, "END_WHILE", 0);
+ define_instruction(inst_list, "MESSAGES_OFF", 0);
+ define_instruction(inst_list, "MESSAGES_ON", 0);
+ define_instruction(inst_list, "ABORT", 0); -- Error exit from sim
+ define_instruction(inst_list, "FINISH", 0); -- Normal exit from sim
+ define_instruction(inst_list, "INCLUDE", 1); -- Define a Variable
+
+ -- User defined instructions
+
+ ------------------------------------------------------------------------
+ -- Read, test, and load the stimulus file
+ read_instruction_file(stimulus_file, inst_list, defined_vars, inst_sequ);
+
+------------------------------------------------------------------------
+-- Using the Instruction record list, get the instruction and implement
+-- it as per the statements in the elsif tree.
+ while(v_line < inst_sequ.num_of_lines) loop
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+
+--------------------------------------------------------------------------
+ if(instruction(1 to len) = "DEFINE_VAR") then
+ null; -- This instruction was implemented while reading the file
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "INCLUDE") then
+ null; -- This instruction was implemented while reading the file
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "ABORT") then
+ assert (false)
+ report "The test has aborted due to an error!!"
+ severity failure;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "FINISH") then
+ assert (false)
+ report "Test Finished with NO errors!!"
+ severity failure;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "EQU_VAR") then
+ update_variable(defined_vars, par1, par2, valid);
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "ADD_VAR") then
+ index_variable(defined_vars, par1, temp_int, valid);
+ if(valid /= 0) then
+ temp_int := temp_int + par2;
+ update_variable(defined_vars, par1, temp_int, valid);
+ else
+ assert (false)
+ report "ADD_VAR Error: Not a valid Variable??"
+ severity failure;
+ end if;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "SUB_VAR") then
+ index_variable(defined_vars, par1, temp_int, valid);
+ if(valid /= 0) then
+ temp_int := temp_int - par2;
+ update_variable(defined_vars, par1, temp_int, valid);
+ else
+ assert (false)
+ report "SUB_VAR Error: Not a valid Variable??"
+ severity failure;
+ end if;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "CALL") then
+ if(stack_ptr >= 7) then
+ assert (false)
+ report "Call Error: Stack over run, calls to deeply nested!!"
+ severity failure;
+ end if;
+ stack(stack_ptr) := v_line;
+ stack_ptr := stack_ptr + 1;
+ v_line := par1 - 1;
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "RETURN_CALL") then
+ if(stack_ptr <= 0) then
+ assert (false)
+ report "Call Error: Stack under run??"
+ severity failure;
+ end if;
+ stack_ptr := stack_ptr - 1;
+ v_line := stack(stack_ptr);
+
+--------------------------------------------------------------------------
+ elsif(instruction(1 to len) = "JUMP") then
+ v_line := par1 - 1;
+ wh_state := false;
+ wh_stack := (others => 0);
+ wh_dpth := 0;
+ wh_ptr := 0;
+ stack := (others => 0);
+ stack_ptr := 0;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "LOOP") then
+ loop_num := loop_num + 1;
+ loop_line(loop_num) := v_line;
+ curr_loop_count(loop_num) := 0;
+ term_loop_count(loop_num) := par1;
+ assert (messages)
+ report LF & "Executing LOOP Command" &
+ LF & " Nested Loop:" & HT & integer'image(loop_num) &
+ LF & " Loop Length:" & HT & integer'image(par1)
+ severity note;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_LOOP") then
+ curr_loop_count(loop_num) := curr_loop_count(loop_num) + 1;
+ if (curr_loop_count(loop_num) = term_loop_count(loop_num)) then
+ loop_num := loop_num - 1;
+ else
+ v_line := loop_line(loop_num);
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "IF") then
+ if_state := false;
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: IF instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(if_state = false) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "ELSE" and
+ instruction(1 to len) /= "ELSEIF" and
+ instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "ELSEIF") then
+ if(if_state = true) then -- if the if_state is true then skip to the end
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+
+ else
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: ELSEIF instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(if_state = false) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "ELSE" and
+ instruction(1 to len) /= "ELSEIF" and
+ instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: ELSEIF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "ELSE") then
+ if(if_state = true) then -- if the if_state is true then skip the else
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ while(instruction(1 to len) /= "END_IF") loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: IF instruction unable to find terminating" &
+ LF & " ELSE, ELSEIF or END_IF statement."
+ severity failure;
+ end if;
+ end loop;
+ v_line := v_line - 1; -- re-align so it will be operated on.
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_IF") then
+ null; -- instruction is a place holder for finding the end of IF.
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "WHILE") then
+ wh_state := false;
+ case par2 is
+ when 0 => if(par1 = par3) then if_state := true; end if;
+ when 1 => if(par1 > par3) then if_state := true; end if;
+ when 2 => if(par1 < par3) then if_state := true; end if;
+ when 3 => if(par1 /= par3) then if_state := true; end if;
+ when 4 => if(par1 >= par3) then if_state := true; end if;
+ when 5 => if(par1 <= par3) then if_state := true; end if;
+ when others =>
+ assert (false)
+ report LF & "ERROR: WHILE instruction got an unexpected value" &
+ LF & " in parameter 2!" & LF &
+ "Found on line " & (ew_to_str(file_line,dec)) & " in file " & file_name
+ severity failure;
+ end case;
+
+ if(wh_state = true) then
+ wh_stack(wh_ptr) := v_line;
+ wh_ptr := wh_ptr + 1;
+ else
+ wh_end := false;
+ while(wh_end /= true) loop
+ if(v_line < inst_sequ.num_of_lines) then
+ v_line := v_line + 1;
+ access_inst_sequ(inst_sequ, defined_vars, v_line, instruction,
+ par1, par2, par3, par4, par5, par6, txt, len, file_name, file_line);
+ else
+ assert (false)
+ report LF & "ERROR: WHILE instruction unable to find terminating" &
+ LF & " END_WHILE statement."
+ severity failure;
+ end if;
+
+ -- if is a while need to escape it
+ if(instruction(1 to len) = "WHILE") then
+ wh_dpth := wh_dpth + 1;
+ -- if is the end_while we are looking for
+ elsif(instruction(1 to len) = "END_WHILE") then
+ if(wh_dpth = 0) then
+ wh_end := true;
+ else
+ wh_dpth := wh_dpth - 1;
+ end if;
+ end if;
+ end loop;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "END_WHILE") then
+ if(wh_ptr > 0) then
+ v_line := wh_stack(wh_ptr - 1) - 1;
+ wh_ptr := wh_ptr - 1;
+ end if;
+
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "MESSAGES_OFF") then
+ messages := TRUE;
+--------------------------------------------------------------------------------
+ elsif (instruction(1 to len) = "MESSAGES_ON") then
+ messages := FALSE;
+
+
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- USER Istruction area. Add all user instructions below this
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- elsif (instruction(1 to len) = "RESET_SYS") then
+
+
+--------------------------------------------------------------------------------
+-- USER Istruction area. Add all user instructions above this
+--------------------------------------------------------------------------------
+ --------------------------------------------------------------------------
+ -- catch those little mistakes
+ else
+ assert (messages)
+ report LF & "ERROR: Seems the command stated in the stm file was not found" & LF &
+ "but is valid, please check the spelling of the instruction in the elsif chain."
+ severity failure;
+ end if; -- else if structure end
+ end loop; -- Main Loop end
+
+ assert (false)
+ report LF & "The end of the simulation! It was not terminated as expected." & LF
+ severity failure;
+
+ end process Read_file;
+
+
+end bhv;
Index: vhld_tb/tags/rel_001/source/tb_pkg_body.vhd
===================================================================
--- vhld_tb/tags/rel_001/source/tb_pkg_body.vhd (nonexistent)
+++ vhld_tb/tags/rel_001/source/tb_pkg_body.vhd (revision 14)
@@ -0,0 +1,1605 @@
+-------------------------------------------------------------------------------
+-- Copyright 2007 Ken Campbell
+-------------------------------------------------------------------------------
+-- $Author: sckoarn $
+--
+-- $Date: 2007-04-06 04:06:48 $
+--
+-- $Name: not supported by cvs2svn $
+--
+-- $Id: tb_pkg_body.vhd,v 1.1.1.1 2007-04-06 04:06:48 sckoarn Exp $
+--
+-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/tb_pkg_body.vhd,v $
+--
+-- Description : The the testbench package body file.
+-- Initial GNU release.
+--
+------------------------------------------------------------------------------
+--This file is part of The VHDL Test Bench.
+--
+-- The VHDL Test Bench 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 2 of the License, or
+-- (at your option) any later version.
+--
+-- Foobar 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 The VHDL Test Bench; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-------------------------------------------------------------------------------
+-- Revision History:
+-- $Log: not supported by cvs2svn $
+--
+-------------------------------------------------------------------------------
+
+package body tb_pkg is
+
+-------------------------------------------------------------------------------
+-- FUNCTION Defs
+-------------------------------------------------------------------------------
+-- is_digit
+ function is_digit(constant c: in character) return boolean is
+ variable rtn : boolean;
+ begin
+ if (c >= '0' and c <= '9') then
+ rtn := true;
+ else
+ rtn := false;
+ end if;
+ return rtn;
+ end is_digit;
+--------------------------------------
+-- is_space
+ function is_space(constant c: in character) return boolean is
+ variable rtn : boolean;
+ begin
+ if(c = ' ' or c = ht) then
+ rtn := true;
+ else
+ rtn := false;
+ end if;
+ return rtn;
+ end is_space;
+---------------------------------------------------------------
+function ew_to_slv(value : in integer;
+ length : in integer) return std_logic_vector is
+ variable result : std_logic_vector((length - 1) downto 0);
+ variable temp : natural;
+ variable power : natural;
+
+ begin
+ assert(length > 1)
+ report LF & "Error: ew_to_slv, Bit length must be greater than 1 to form a vector! "
+ severity failure;
+ temp := value;
+ for i in (length - 1) downto 0 loop
+ power := 2**i;
+ if(temp > ((2**i) - 1)) then
+ result(i) := '1';
+ temp := temp - ((2**i) - 1);
+ else
+ result(i) := '0';
+ end if;
+ end loop;
+
+ return result;
+ end ew_to_slv;
+------------------------------------------------------------------------------
+-- to_char
+ function ew_to_char(int: integer) return character is
+ variable c: character;
+ begin
+ c := nul;
+ case int is
+ when 0 => c := '0';
+ when 1 => c := '1';
+ when 2 => c := '2';
+ when 3 => c := '3';
+ when 4 => c := '4';
+ when 5 => c := '5';
+ when 6 => c := '6';
+ when 7 => c := '7';
+ when 8 => c := '8';
+ when 9 => c := '9';
+ when 10 => c := 'A';
+ when 11 => c := 'B';
+ when 12 => c := 'C';
+ when 13 => c := 'D';
+ when 14 => c := 'E';
+ when 15 => c := 'F';
+ when others =>
+ assert(false)
+ report LF & "Error: ew_to_char was given a non Number didgit."
+ severity failure;
+ end case;
+
+ return c;
+ end ew_to_char;
+
+-------------------------------------------------------------------------------
+-- to_string function integer
+ function to_str(int: integer) return string is
+ begin
+ return ew_to_str(int,dec) ;
+ end to_str ;
+
+-------------------------------------------------------------------------------
+-- ew_str_cat
+ function ew_str_cat(s1: stm_text;
+ s2: text_field) return stm_text is
+
+ variable i: integer;
+ variable j: integer;
+ variable sc: stm_text;
+
+ begin
+ sc := s1;
+ i := 1;
+ while(sc(i) /= nul) loop
+ i := i + 1;
+ end loop;
+ j := 1;
+ while(s2(j) /= nul) loop
+ sc(i) := s2(j);
+ i := i + 1;
+ j := j + 1;
+ end loop;
+
+ return sc;
+ end ew_str_cat;
+
+-------------------------------------------------------------------------------
+-- fld_len field length
+-- inputs : string of type text_field
+-- return : integer number of non 'nul' chars
+function fld_len(s : in text_field) return integer is
+ variable i: integer := 1;
+ begin
+ while(s(i) /= nul) loop
+ i := i + 1;
+ end loop;
+ return (i - 1);
+ end fld_len;
+------------------------------------------------------------------------------
+-- c2int convert character to integer
+function c2int(c: in character) return integer is
+ variable i: integer;
+begin
+ i := -1;
+ case c is
+ when '0' => i := 0;
+ when '1' => i := 1;
+ when '2' => i := 2;
+ when '3' => i := 3;
+ when '4' => i := 4;
+ when '5' => i := 5;
+ when '6' => i := 6;
+ when '7' => i := 7;
+ when '8' => i := 8;
+ when '9' => i := 9;
+ when others =>
+ assert(false)
+ report LF & "Error: c2int was given a non Number didgit."
+ severity failure;
+ end case;
+ return i;
+end c2int;
+-------------------------------------------------------------------------------
+-- str2integer Convert a string to integer number.
+-- inputs : string
+-- output : int value
+function str2integer(str: in string) return integer is
+ variable l: integer;
+ variable j: integer := 1;
+ variable rtn: integer := 0;
+begin
+ l := fld_len(str);
+
+ for i in l downto 1 loop
+ rtn := rtn + (c2int(str(j)) *(10**(i - 1)));
+ j := j + 1;
+ end loop;
+
+ return rtn;
+end str2integer;
+-------------------------------------------------------------------------------
+-- hex2integer convert hex Stimulus field to integer
+-- inputs : string of type text_field containing only Hex numbers
+-- return : integer value
+function hex2integer(hex_number: in text_field;
+ file_name: in text_line;
+ line: in integer) return integer is
+ variable len: integer;
+ variable temp_field: text_field;
+ variable temp_int: integer;
+ variable power: integer;
+ variable int_number: integer;
+ begin
+ len := fld_len(hex_number);
+ power := 0;
+ temp_int := 0;
+ for i in len downto 1 loop
+ case hex_number(i) is
+ when '0' =>
+ int_number := 0;
+ when '1' =>
+ int_number := 1;
+ when '2' =>
+ int_number := 2;
+ when '3' =>
+ int_number := 3;
+ when '4' =>
+ int_number := 4;
+ when '5' =>
+ int_number := 5;
+ when '6' =>
+ int_number := 6;
+ when '7' =>
+ int_number := 7;
+ when '8' =>
+ int_number := 8;
+ when '9' =>
+ int_number := 9;
+ when 'a' | 'A'=>
+ int_number := 10;
+ when 'b' | 'B'=>
+ int_number := 11;
+ when 'c' | 'C'=>
+ int_number := 12;
+ when 'd' | 'D'=>
+ int_number := 13;
+ when 'e' | 'E'=>
+ int_number := 14;
+ when 'f' | 'F'=>
+ int_number := 15;
+ when others =>
+ assert(false)
+ report LF & "Error: hex2integer found non Hex didgit on line "
+ & (integer'image(line)) & " of file " & file_name
+ severity failure;
+ end case;
+
+ temp_int := temp_int + (int_number *(16 ** power));
+ power := power + 1;
+ end loop;
+
+ return temp_int;
+ end hex2integer;
+-------------------------------------------------------------------------------
+-- convert character to 4 bit vector
+-- input character
+-- output std_logic_vector 4 bits
+function c2std_vec(c: in character) return std_logic_vector is
+begin
+ case c is
+ when '0' => return "0000";
+ when '1' => return "0001";
+ when '2' => return "0010";
+ when '3' => return "0011";
+ when '4' => return "0100";
+ when '5' => return "0101";
+ when '6' => return "0110";
+ when '7' => return "0111";
+ when '8' => return "1000";
+ when '9' => return "1001";
+ when 'a' | 'A' => return "1010";
+ when 'b' | 'B' => return "1011";
+ when 'c' | 'C' => return "1100";
+ when 'd' | 'D' => return "1101";
+ when 'e' | 'E' => return "1110";
+ when 'f' | 'F' => return "1111";
+ when others =>
+ assert(false)
+ report LF & "Error: c2std_vec found non Hex didgit on file line "
+ severity failure;
+ return "XXXX";
+ end case;
+end c2std_vec;
+-------------------------------------------------------------------------------
+-- std_vec2c convert 4 bit std_vector to a character
+-- input std_logic_vector 4 bits
+-- output character
+function std_vec2c(vec: in std_logic_vector(3 downto 0)) return character is
+begin
+ case vec is
+ when "0000" => return '0';
+ when "0001" => return '1';
+ when "0010" => return '2';
+ when "0011" => return '3';
+ when "0100" => return '4';
+ when "0101" => return '5';
+ when "0110" => return '6';
+ when "0111" => return '7';
+ when "1000" => return '8';
+ when "1001" => return '9';
+ when "1010" => return 'A';
+ when "1011" => return 'B';
+ when "1100" => return 'C';
+ when "1101" => return 'D';
+ when "1110" => return 'E';
+ when "1111" => return 'F';
+ when others =>
+ assert(false)
+ report LF & "Error: std_vec2c found non-binary didgit in vec "
+ severity failure;
+ return 'X';
+ end case;
+end std_vec2c;
+-------------------------------------------------------------------------------
+-- bin2integer convert bin Stimulus field to integer
+-- inputs : string of type text_field containing only binary numbers
+-- return : integer value
+function bin2integer(bin_number: in text_field;
+ file_name: in text_line;
+ line: in integer) return integer is
+ variable len: integer;
+ variable temp_field: text_field;
+ variable temp_int: integer;
+ variable power: integer;
+ variable int_number: integer;
+ begin
+ len := fld_len(bin_number);
+ power := 0;
+ temp_int := 0;
+ for i in len downto 1 loop
+ case bin_number(i) is
+ when '0' =>
+ int_number := 0;
+ when '1' =>
+ int_number := 1;
+ when others =>
+ assert(false)
+ report LF & "Error: bin2integer found non Binary didgit on line "
+ & (integer'image(line)) & " of file " & file_name
+ severity failure;
+ end case;
+
+ temp_int := temp_int + (int_number *(2 ** power));
+ power := power + 1;
+ end loop;
+
+ return temp_int;
+ end bin2integer;
+-------------------------------------------------------------------------------
+-- stim_to_integer convert Stimulus field to integer
+-- inputs : string of type text_field "stimulus format of number"
+-- return : integer value
+function stim_to_integer(field: in text_field;
+ file_name: in text_line;
+ line: in integer) return integer is
+ variable len: integer;
+ variable text: text_field;
+ variable value: integer := 1;
+ variable temp_str : string(1 to 48);
+ begin
+ len := fld_len(field);
+
+ case field(1) is
+ when 'x' | 'h' =>
+ value := 2;
+ while(field(value) /= nul) loop
+ temp_str(value - 1) := field(value);
+ value := value + 1;
+ end loop;
+ value := hex2integer(temp_str,file_name,line);
+ when 'b' =>
+ value := 2;
+ while(field(value) /= nul) loop
+ temp_str(value - 1) := field(value);
+ value := value + 1;
+ end loop;
+ value := bin2integer(temp_str,file_name,line);
+ when others =>
+-- value := from_string(field(1 to len));
+ value := str2integer(field);
+ end case;
+ return value;
+ end stim_to_integer;
+
+-------------------------------------------------------------------------------
+-- to_str function with base parameter
+-- Convert integer to number base
+ function ew_to_str(int: integer; b: base) return text_field is
+
+ variable temp : text_field ;
+ variable temp1 : text_field ;
+ variable radix : integer := 0;
+ variable num : integer := 0;
+ variable power : integer := 1;
+ variable len : integer := 1;
+ variable pre : string(1 to 2);
+ variable i : integer;
+ variable j : integer;
+ variable vec : std_logic_vector(31 downto 0);
+
+ begin
+
+ num := int;
+ temp := (others => nul);
+ case b is
+ when bin =>
+ radix := 2; -- depending on what
+ pre := "0b";
+ when oct =>
+ radix := 8; -- base the number is
+ pre := "0o";
+ when hex =>
+ radix := 16; -- to be displayed as
+ pre := "0x";
+ when dec =>
+ radix := 10; -- choose a radix range
+ pre := (others => nul);
+ end case ;
+ -- Now jump through Hoops because of sign
+ if(num < 0 and b = hex) then
+ vec := std_logic_vector(conv_unsigned(int, 32));
+ temp(1) := std_vec2c(vec(31 downto 28));
+ temp(2) := std_vec2c(vec(27 downto 24));
+ temp(3) := std_vec2c(vec(23 downto 20));
+ temp(4) := std_vec2c(vec(19 downto 16));
+ temp(5) := std_vec2c(vec(15 downto 12));
+ temp(6) := std_vec2c(vec(11 downto 8));
+ temp(7) := std_vec2c(vec(7 downto 4));
+ temp(8) := std_vec2c(vec(3 downto 0));
+ else
+ while num >= radix loop -- determine how many
+ len := len + 1; -- characters required
+ num := num / radix; -- to represent the
+ end loop ; -- number.
+ for i in len downto 1 loop -- convert the number to
+ temp(i) := ew_to_char(int/power mod radix); -- a string starting
+ power := power * radix; -- with the right hand
+ end loop ; -- side.
+ end if;
+ -- add prefix if is one
+ if(pre(1) /= nul) then
+ temp1 := temp;
+ i := 1;
+ j := 3;
+ temp(1 to 2) := pre;
+ while(temp1(i) /= nul) loop
+ temp(j) := temp1(i);
+ i := i + 1;
+ j := j + 1;
+ end loop;
+ end if;
+
+ return temp;
+
+ end ew_to_str ;
+
+-------------------------------------------------------------------------------
+-- Procedure to print instruction records to stdout *for debug*
+ procedure print_inst(variable inst : in stim_line_ptr) is
+ variable l: text_line;
+ variable l_i: integer := 1;
+ variable j: integer := 1;
+ begin
+ while (inst.instruction(j) /= nul) loop
+ l(l_i) := inst.instruction(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field one
+ if(inst.inst_field_1(1) /= nul) then
+ while (inst.inst_field_1(j) /= nul) loop
+ l(l_i) := inst.inst_field_1(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field two
+ if(inst.inst_field_2(1) /= nul) then
+ while (inst.inst_field_2(j) /= nul) loop
+ l(l_i) := inst.inst_field_2(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field three
+ if(inst.inst_field_3(1) /= nul) then
+ while (inst.inst_field_3(j) /= nul) loop
+ l(l_i) := inst.inst_field_3(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ l(l_i) := ' ';
+ l_i := l_i + 1;
+ j := 1;
+ -- field four
+ if(inst.inst_field_4(1) /= nul) then
+ while (inst.inst_field_4(j) /= nul) loop
+ l(l_i) := inst.inst_field_4(j);
+ j := j +1;
+ l_i := l_i + 1;
+ end loop;
+ end if;
+ end if;
+ end if;
+ end if;
+ print(l);
+
+ print(" Sequence Number: " & to_str(inst.line_number) &
+ " File Line Number: " & to_str(inst.file_line));
+ if(inst.num_of_lines > 0) then
+ print(" Number of Lines: " & to_str(inst.num_of_lines));
+ end if;
+ end print_inst;
+
+--------------------------------------------------------------------------------
+-- access_variable
+-- inputs:
+-- Text field containing variable
+-- outputs:
+-- value $VAR returns Value of VAR
+-- value VAR returns index of VAR
+--
+-- valid is 1 if valid 0 if not
+ procedure access_variable(variable var_list : in var_field_ptr;
+ variable var : in text_field;
+ variable value : out integer;
+ variable valid : out integer) is
+ variable l : integer;
+ variable l_2 : integer;
+ variable var_ptr : var_field_ptr;
+ variable temp_field : text_field;
+ variable ptr : integer := 0; -- 0 is index, 1 is pointer
+ begin
+ l := fld_len(var);
+ valid := 0;
+ -- if the variable is a special
+ if(var(1) = '=') then
+ value := 0;
+ valid := 1;
+ elsif(var(1 to 2) = ">=") then
+ value := 4;
+ valid := 1;
+ elsif(var(1 to 2) = "<=") then
+ value := 5;
+ valid := 1;
+ elsif(var(1) = '>') then
+ value := 1;
+ valid := 1;
+ elsif(var(1) = '<') then
+ value := 2;
+ valid := 1;
+ elsif(var(1 to 2) = "!=") then
+ value := 3;
+ valid := 1;
+
+ else
+ if(var(1) = '$') then
+ ptr := 1; -- this is a pointer
+ for i in 2 to l loop
+ temp_field(i-1) := var(i);
+ end loop;
+ else
+ temp_field := var;
+ end if;
+
+ var_ptr := var_list;
+ while(var_ptr.next_rec /= null) loop
+ -- if we have a match
+ if(temp_field = var_ptr.var_name) then
+ if(ptr = 1) then
+ value := var_ptr.var_value;
+ valid := 1;
+ else
+ value := var_ptr.var_index;
+ valid := 1;
+ end if;
+ exit;
+ end if;
+ var_ptr := var_ptr.next_rec;
+ end loop;
+
+ -- if we have a match and was the last record
+ if(var_ptr.next_rec = null and temp_field = var_ptr.var_name) then
+ if(ptr = 1) then
+ value := var_ptr.var_value;
+ valid := 1;
+ else
+ value := var_ptr.var_index;
+ valid := 1;
+ end if;
+ end if;
+ end if;
+ end access_variable;
+--------------------------------------------------------------------------------
+-- index_variable
+-- inputs:
+-- index: the index of the variable being accessed
+-- outputs:
+-- Variable Value
+-- valid is 1 if valid 0 if not
+ procedure index_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : out integer;
+ variable valid : out integer) is
+ variable ptr: var_field_ptr;
+ begin
+ ptr := var_list;
+ valid := 0;
+ while(ptr.next_rec /= null) loop
+ if(ptr.var_index = index) then
+ value := ptr.var_value;
+ valid := 1;
+ exit;
+ end if;
+ ptr := ptr.next_rec;
+ end loop;
+ if(ptr.var_index = index) then
+ value := ptr.var_value;
+ valid := 1;
+ end if;
+ end index_variable;
+
+--------------------------------------------------------------------------------
+-- update_variable
+-- inputs:
+-- index: the index of the variable being updated
+-- outputs:
+-- valid is 1 if valid 0 if not
+ procedure update_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : in integer;
+ variable valid : out integer) is
+ variable ptr: var_field_ptr;
+ begin
+ ptr := var_list;
+ valid := 0;
+ while(ptr.next_rec /= null) loop
+ if(ptr.var_index = index) then
+ ptr.var_value := value;
+ valid := 1;
+ exit;
+ end if;
+ ptr := ptr.next_rec;
+ end loop;
+ -- check the current one
+ if(ptr.var_index = index) then
+ ptr.var_value := value;
+ valid := 1;
+ end if;
+ end update_variable;
+
+-------------------------------------------------------------------------------
+-- Read a line from a file
+-- inputs : file of type text
+-- outputs : The line of type text_line
+ procedure file_read_line(file file_name: text;
+ variable file_line: out text_line
+ ) is
+ variable index: integer; -- index into string
+ variable rline: line;
+
+ begin
+
+ index := 1; -- set index to begin of string
+ file_line := (others => nul);
+ if(not endfile(file_name)) then
+ readline(file_name,rline);
+
+ while(rline'right /= (index - 1) and rline'length /= 0) loop
+ file_line(index) := rline(index);
+ index := index + 1;
+ end loop;
+ end if;
+ end file_read_line;
+
+ ------------------------------------------------------------------------------
+ -- procedure to break a line down in to text fields
+ procedure tokenize_line(variable text_line: in text_line;
+ variable token1: out text_field;
+ variable token2: out text_field;
+ variable token3: out text_field;
+ variable token4: out text_field;
+ variable token5: out text_field;
+ variable token6: out text_field;
+ variable token7: out text_field;
+ variable txt_ptr: out stm_text_ptr;
+ variable valid: out integer) is
+ variable token_index: integer := 0;
+ variable current_token: text_field;
+ variable token_number: integer := 0;
+ variable c: string(1 to 2);
+ variable comment_found: integer := 0;
+ variable txt_found: integer := 0;
+ variable j: integer;
+
+ begin
+ -- null outputs
+ token1 := (others => nul);
+ token2 := (others => nul);
+ token3 := (others => nul);
+ token4 := (others => nul);
+ token5 := (others => nul);
+ token6 := (others => nul);
+ token7 := (others => nul);
+ txt_ptr := null;
+ valid := 0;
+ txt_found := 0;
+ j := 1;
+
+ -- loop for max number of char
+ for i in 1 to text_line'high loop
+ -- collect for comment test ** assumed no line will be max 256
+ c(1) := text_line(i);
+ c(2) := text_line(i + 1); -- or this line will blow up
+ if(c = "--") then
+ comment_found := 1;
+ exit;
+ end if;
+ -- if is begin text char '"'
+ if(c(1) = '"') then --" <-- this double quote is just to fix highlighting.
+ txt_found := 1;
+ txt_ptr := new stm_text;
+ next;
+ end if;
+
+ -- if we have found a txt string
+ if (txt_found = 1 and text_line(i) /= nul) then
+ -- if string too long, prevent tool hang, truncate and notify
+ if(j > c_stm_text_len) then
+ print("tokenize_line: truncated txt line, it was larger than c_stm_text_len");
+ exit;
+ end if;
+ txt_ptr(j) := text_line(i);
+ j := j + 1;
+ -- if is a character store in the right token
+ elsif(is_space(text_line(i)) = false and text_line(i) /= nul) then
+ token_index := token_index + 1;
+ current_token(token_index) := text_line(i);
+ -- else is a space, deal with pointers
+ elsif(is_space(text_line(i + 1)) = false and text_line(i + 1) /= nul) then
+ case token_number is
+ when 0 =>
+ if(token_index /= 0) then
+ token1 := current_token;
+ current_token := (others => nul);
+ token_number := 1;
+ valid := 1;
+ token_index := 0;
+ end if;
+ when 1 =>
+ token2 := current_token;
+ current_token := (others => nul);
+ token_number := 2;
+ valid := 2;
+ token_index := 0;
+ when 2 =>
+ token3 := current_token;
+ current_token := (others => nul);
+ token_number := 3;
+ valid := 3;
+ token_index := 0;
+ when 3 =>
+ token4 := current_token;
+ current_token := (others => nul);
+ token_number := 4;
+ valid := 4;
+ token_index := 0;
+ when 4 =>
+ token5 := current_token;
+ current_token := (others => nul);
+ token_number := 5;
+ valid := 5;
+ token_index := 0;
+ when 5 =>
+ token6 := current_token;
+ current_token := (others => nul);
+ token_number := 6;
+ valid := 6;
+ token_index := 0;
+ when 6 =>
+ token7 := current_token;
+ current_token := (others => nul);
+ token_number := 7;
+ valid := 7;
+ token_index := 0;
+ when 7 =>
+ when others =>
+ null;
+ end case;
+ end if;
+ -- break from loop if is null
+ if(text_line(i) = nul) then
+ if(token_index /= 0) then
+ case token_number is
+ when 0 =>
+ token1 := current_token;
+ valid := 1;
+ when 1 =>
+ token2 := current_token;
+ valid := 2;
+ when 2 =>
+ token3 := current_token;
+ valid := 3;
+ when 3 =>
+ token4 := current_token;
+ valid := 4;
+ when 4 =>
+ token5 := current_token;
+ valid := 5;
+ when 5 =>
+ token6 := current_token;
+ valid := 6;
+ when 6 =>
+ token7 := current_token;
+ valid := 7;
+ when others =>
+ null;
+ end case;
+ end if;
+ exit;
+ end if;
+ end loop;
+ -- did we find a comment and there is a token
+ if(comment_found = 1) then
+ if(token_index /= 0) then
+ case token_number is
+ when 0 =>
+ token1 := current_token;
+ valid := 1;
+ when 1 =>
+ token2 := current_token;
+ valid := 2;
+ when 2 =>
+ token3 := current_token;
+ valid := 3;
+ when 3 =>
+ token4 := current_token;
+ valid := 4;
+ when 4 =>
+ token5 := current_token;
+ valid := 5;
+ when 5 =>
+ token6 := current_token;
+ valid := 6;
+ when 6 =>
+ token7 := current_token;
+ valid := 7;
+ when others =>
+ null;
+ end case;
+ end if;
+ end if;
+ end tokenize_line;
+-------------------------------------------------------------------------------
+-- Add a new instruction to the instruction list
+-- inputs :
+-- outputs :
+ procedure define_instruction(variable inst_set: inout inst_def_ptr;
+ constant inst: in string;
+ constant args: in integer) is
+ variable v_inst_ptr: inst_def_ptr;
+ variable v_prev_ptr: inst_def_ptr;
+ variable v_new_ptr: inst_def_ptr;
+ variable v_temp_inst: inst_def_ptr;
+ variable v_length: integer;
+ variable v_list_size: integer;
+ variable v_dup_error: boolean;
+
+ begin
+ assert(inst'high <= max_field_len)
+ report LF & "Error: Creation of Instruction of length greater than Max_field_len attemped!!" &
+ LF & "This Max is currently set to " & (integer'image(max_field_len))
+ severity failure;
+ -- get to the last element and test is not exsiting
+ v_temp_inst := inst_set;
+ v_inst_ptr := inst_set;
+ -- zero the size
+ v_list_size := 0;
+ while(v_inst_ptr /= null) loop
+ -- if there is a chance of a duplicate command
+ if(v_inst_ptr.instruction_l = inst'high) then
+ v_dup_error := true;
+ for i in 1 to inst'high loop
+ if(v_inst_ptr.instruction(i) /= inst(i)) then
+ v_dup_error := false;
+ end if;
+ end loop;
+ -- if we find a duplicate, die
+ assert(v_dup_error = false)
+ report LF & "Error: Duplicate instruction definition attempted!"
+ severity failure;
+ end if;
+ v_prev_ptr := v_inst_ptr; -- store for pointer updates
+ v_inst_ptr := v_inst_ptr.next_rec;
+ v_list_size := v_list_size + 1;
+ end loop;
+
+ -- add the new instruction
+ v_new_ptr := new inst_def;
+ -- if this is the first command return new pointer
+ if(v_list_size = 0) then
+ v_temp_inst := v_new_ptr;
+ -- else write new pointer to next_rec
+ else
+ v_prev_ptr.next_rec := v_new_ptr;
+ end if;
+ v_new_ptr.instruction_l := inst'high;
+ v_new_ptr.params := args;
+ -- copy the instruction text into field
+ for i in 1 to v_new_ptr.instruction_l loop
+ v_new_ptr.instruction(i) := inst(i);
+ end loop;
+ -- return the pointer
+ inst_set := v_temp_inst;
+
+ end define_instruction;
+
+--------------------------------------------------------------------------------
+-- Check for valid instruction in the list of instructions
+procedure check_valid_inst(variable inst : in text_field;
+ variable inst_set : in inst_def_ptr;
+ variable token_num: in integer;
+ variable line_num : in integer;
+ variable name : in text_line) is
+ variable l : integer := 0;
+ variable seti: inst_def_ptr;
+ variable match: integer := 0;
+ variable ilv: integer := 0; -- inline variable
+ begin
+ -- create useable pointer
+ seti := inst_set;
+ -- count up the characters in inst
+ l := fld_len(inst);
+ -- if this is a referance variable -- handle in add variable Proc
+ if(inst(l) = ':') then
+ match := 1;
+ ilv := 1;
+ else
+ -- process list till null next
+ while (seti.next_rec /= null) loop
+ if(seti.instruction_l = l) then
+ match := 1;
+ for j in 1 to l loop
+ if(seti.instruction(j) /= inst(j)) then
+ match := 0;
+ end if;
+ end loop;
+ end if;
+ if(match = 0) then
+ seti := seti.next_rec;
+ else
+ exit;
+ end if;
+ end loop;
+ -- check current one
+ if(seti.instruction_l = l and match = 0) then
+ match := 1;
+ for j in 1 to l loop
+ if(seti.instruction(j) /= inst(j)) then
+ match := 0;
+ end if;
+ end loop;
+ end if;
+ end if;
+
+ -- if we had a match, check the number of paramiters
+ if(match = 1 and ilv = 0) then
+ assert(seti.params = (token_num - 1))
+ report LF & "Error: Undefined Instruction was found, incorrect number of fields passed!" & LF &
+ "This is found on line " & (integer'image(line_num)) & " in file " & name & LF
+ severity failure;
+ end if;
+
+ -- if we find a duplicate, die
+ assert(match = 1)
+ report LF & "Error: Undefined Instruction on line " & (integer'image(line_num)) &
+ " found in input file " & name & LF
+ severity failure;
+ end check_valid_inst;
+
+--------------------------------------------------------------------------------
+-- add_variable
+-- This procedure adds a variable to the variable list. This is localy
+-- available at this time.
+procedure add_variable(variable var_list : inout var_field_ptr;
+ variable p1 : in text_field; -- should be var name
+ variable p2 : in text_field; -- should be value
+ variable token_num : in integer;
+ variable sequ_num : in integer;
+ variable line_num : in integer;
+ variable name : in text_line;
+ variable length : in integer) is
+
+ variable temp_var: var_field_ptr;
+ variable current_ptr: var_field_ptr;
+ variable index: integer := 1;
+
+ begin
+ -- if this is NOT the first one
+ if(var_list /= null) then
+ current_ptr := var_list;
+ index := index + 1;
+ if(p1(length) /= ':') then -- is not an inline variable
+ while(current_ptr.next_rec /= null) loop
+ -- if we have defined the current before then die
+ assert(current_ptr.var_name /= p1)
+ report LF & "Error: Attemping to add a duplicate Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ current_ptr := current_ptr.next_rec;
+ index := index + 1;
+ end loop;
+ -- if we have defined the current before then die. This checks the last one
+ assert(current_ptr.var_name /= p1)
+ report LF & "Error: Attemping to add a duplicate Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ temp_var := new var_field;
+ temp_var.var_name := p1; -- direct write of text_field
+ temp_var.var_value := stim_to_integer(p2,name,line_num); -- convert text_field to integer
+ temp_var.var_index := index;
+ current_ptr.next_rec := temp_var;
+ else
+ while(current_ptr.next_rec /= null) loop
+ -- if we have defined the current before then die
+ assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
+ report LF & "Error: Attemping to add a duplicate Inline Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ current_ptr := current_ptr.next_rec;
+ index := index + 1;
+ end loop;
+ -- if we have defined the current before then die. This checks the last one
+ assert(current_ptr.var_name(1 to (length - 1)) /= p1(1 to (length - 1)))
+ report LF & "Error: Attemping to add a duplicate Inline Variable definition "
+ & " on line " & (integer'image(line_num)) & " of file " & name
+ severity failure;
+
+ temp_var := new var_field;
+ temp_var.var_name(1 to (length - 1)) := p1(1 to (length - 1));
+ temp_var.var_value := sequ_num;
+ temp_var.var_index := index;
+ current_ptr.next_rec := temp_var;
+ end if;
+ -- this is the first one
+ else
+ if(p1(length) /= ':') then -- is not an inline variable
+ temp_var := new var_field;
+ temp_var.var_name := p1; -- direct write of text_field
+ temp_var.var_index := index;
+ temp_var.var_value := stim_to_integer(p2,name,line_num); -- convert text_field to integer
+ var_list := temp_var;
+ else
+ temp_var := new var_field;
+ temp_var.var_name(1 to (length - 1)) := p1(1 to (length - 1));
+ temp_var.var_value := sequ_num;
+ temp_var.var_index := index;
+ var_list := temp_var;
+ end if;
+ end if;
+ end add_variable;
+--------------------------------------------------------------------------------
+-- add_instruction
+-- This is the procedure that adds the instruction to the linked list of
+-- instructions. Also Variable addition are called and or handled.
+-- the instruction sequence Link list.
+-- inputs:
+-- stim_line_ptr is the pointer to the instruction List
+-- inst is the instruction token
+-- p1 paramitor one, corrisponds to field one of stimulus
+-- p2 paramitor one, corrisponds to field two of stimulus
+-- p3 paramitor one, corrisponds to field three of stimulus
+-- p4 paramitor one, corrisponds to field four of stimulus
+-- p5 paramitor one, corrisponds to field three of stimulus
+-- p6 paramitor one, corrisponds to field four of stimulus
+-- str_ptr pointer to string for print instruction
+-- token_num the number of tokens, including instruction
+-- sequ_num is the stimulus file line referance ie program line number
+-- line_num Line number in the text file
+-- outputs:
+-- none. Error will terminate sim
+ procedure add_instruction(variable inst_list : inout stim_line_ptr;
+ variable var_list : inout var_field_ptr;
+ variable inst : in text_field;
+ variable p1 : in text_field;
+ variable p2 : in text_field;
+ variable p3 : in text_field;
+ variable p4 : in text_field;
+ variable p5 : in text_field;
+ variable p6 : in text_field;
+ variable str_ptr : in stm_text_ptr;
+ variable token_num : in integer;
+ variable sequ_num : inout integer;
+ variable line_num : in integer;
+ variable file_name : in text_line) is
+-- variable temp_string: string;
+ variable temp_stim_line: stim_line_ptr;
+ variable temp_current: stim_line_ptr;
+ variable valid: integer;
+ variable l: integer;
+ begin
+ valid := 1;
+ l := fld_len(inst);
+ temp_current := inst_list;
+ -- take care of special cases
+ if(inst(1 to l) = "DEFINE_VAR") then
+ l := fld_len(p1);
+ -- Add the variable to the Variable pool, not considered an instruction
+ add_variable(var_list,p1,p2,token_num,sequ_num,line_num,file_name,l);
+ elsif(inst(l) = ':') then
+ add_variable(var_list,inst,p1,token_num,sequ_num,line_num,file_name,l);
+ valid := 0;
+ end if;
+
+ if(valid = 1) then
+ -- prepare the new record
+ temp_stim_line := new stim_line;
+ temp_stim_line.instruction := inst;
+ temp_stim_line.inst_field_1 := p1;
+ temp_stim_line.inst_field_2 := p2;
+ temp_stim_line.inst_field_3 := p3;
+ temp_stim_line.inst_field_4 := p4;
+ temp_stim_line.inst_field_5 := p5;
+ temp_stim_line.inst_field_6 := p6;
+ temp_stim_line.txt := str_ptr;
+ temp_stim_line.line_number := sequ_num;
+ temp_stim_line.file_name := file_name;
+ temp_stim_line.file_line := line_num;
+
+ -- if is not the first instruction
+ if(inst_list /= null) then
+ while(temp_current.next_rec /= null) loop
+ temp_current := temp_current.next_rec;
+ end loop;
+ temp_current.next_rec := temp_stim_line;
+ inst_list.num_of_lines := inst_list.num_of_lines + 1;
+ -- other wise is first instruction to be added
+ else
+ inst_list := temp_stim_line;
+ inst_list.num_of_lines := 1;
+ end if;
+ sequ_num := sequ_num + 1;
+-- print_inst(temp_stim_line); -- for debug
+ end if;
+
+ end add_instruction;
+--------------------------------------------------------------------------------
+-- The read include file procedure
+-- This is the main procedure for reading, parcing, checking and returning
+-- the instruction sequence Link list.
+ procedure read_include_file(variable name: text_line;
+ variable sequ_numb: inout integer;
+ variable inst_set: inout inst_def_ptr;
+ variable var_list: inout var_field_ptr;
+ variable inst_sequ: inout stim_line_ptr;
+ variable status: inout integer) is
+ variable l: text_line; -- the line
+ variable l_num: integer; -- line number file
+ variable sequ_line: integer; -- line number program
+ variable t1: text_field;
+ variable t2: text_field;
+ variable t3: text_field;
+ variable t4: text_field;
+ variable t5: text_field;
+ variable t6: text_field;
+ variable t7: text_field;
+ variable t_txt: stm_text_ptr;
+ variable valid: integer;
+ variable v_inst_ptr: inst_def_ptr;
+ variable v_var_prt: var_field_ptr;
+ variable v_sequ_ptr: stim_line_ptr;
+ variable v_len: integer;
+ variable v_stat: file_open_status;
+
+ begin
+ sequ_line := sequ_numb;
+
+ file_open(v_stat, include_file, name, read_mode);
+ if(v_stat /= open_ok) then
+ print("Error: Unable to open include file " & name);
+ status := 1;
+ return;
+ end if;
+ l_num := 1; -- initialize line number
+
+ v_inst_ptr := inst_set;
+ v_var_prt := var_list;
+ v_sequ_ptr := inst_sequ;
+
+ -- while not the end of file read it
+ while(not endfile(include_file)) loop
+ file_read_line(include_file,l);
+ -- tokenize the line
+ tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
+ v_len := fld_len(t1);
+ if(t1(1 to v_len) = "INCLUDE") then
+ print("Nested INCLUDE statement found: " & t2);
+ assert(false)
+ report LF & "Error: Nested INCLUDE statements are not supported at this time."
+ severity failure;
+
+ -- if there was valid tokens
+ elsif(valid /= 0) then
+ check_valid_inst(t1, v_inst_ptr, valid, l_num, name);
+ add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,sequ_line,l_num,name);
+ end if;
+ l_num := l_num + 1;
+ end loop; -- end loop read file
+ file_close(include_file);
+ sequ_numb := sequ_line;
+ inst_set := v_inst_ptr;
+ var_list := v_var_prt;
+ inst_sequ := v_sequ_ptr;
+ end read_include_file;
+
+--------------------------------------------------------------------------------
+-- The read instruction file procedure
+-- This is the main procedure for reading, parcing, checking and returning
+-- the instruction sequence Link list.
+ procedure read_instruction_file(constant file_name: string;
+ variable inst_set: inout inst_def_ptr;
+ variable var_list: inout var_field_ptr;
+ variable inst_sequ: inout stim_line_ptr) is
+ variable l: text_line; -- the line
+ variable l_num: integer; -- line number file
+ variable sequ_line: integer; -- line number program
+ variable t1: text_field;
+ variable t2: text_field;
+ variable t3: text_field;
+ variable t4: text_field;
+ variable t5: text_field;
+ variable t6: text_field;
+ variable t7: text_field;
+ variable t_txt: stm_text_ptr;
+ variable valid: integer;
+ variable v_ostat: integer;
+ variable v_inst_ptr: inst_def_ptr;
+ variable v_var_prt: var_field_ptr;
+ variable v_sequ_ptr: stim_line_ptr;
+ variable v_len: integer;
+ variable v_stat: file_open_status;
+ variable v_name: text_line;
+ variable v_iname: text_line;
+
+ begin
+ -- open the stimulus_file and check
+ file_open(v_stat, stimulus, file_name, read_mode);
+ assert(v_stat = open_ok)
+ report LF & "Error: Unable to open stimulus_file " & file_name
+ severity failure;
+ -- copy file name to type text_line
+ for i in 1 to file_name'high loop
+ v_name(i) := file_name(i);
+ end loop;
+
+ l_num := 1;
+ sequ_line := 1;
+ v_ostat := 0;
+
+ v_inst_ptr := inst_set;
+ v_var_prt := var_list;
+ v_sequ_ptr := inst_sequ;
+
+ -- while not the end of file read it
+ while(not endfile(stimulus)) loop
+ file_read_line(stimulus,l);
+ -- tokenize the line
+ tokenize_line(l,t1,t2,t3,t4,t5,t6,t7,t_txt,valid);
+ v_len := fld_len(t1);
+ -- if there is an INCLUDE instruction
+ if(t1(1 to v_len) = "INCLUDE") then
+ if(valid = 2) then
+ v_iname := (others => nul);
+ for i in 1 to max_field_len loop
+ v_iname(i) := t2(i);
+ end loop;
+ else
+ v_iname := (others => nul);
+ for i in 1 to c_stm_text_len loop
+ v_iname(i) := t_txt(i);
+ end loop;
+ end if;
+ print("INCLUDE found: Loading file " & v_iname);
+ read_include_file(v_iname,sequ_line,v_inst_ptr,v_var_prt,v_sequ_ptr,v_ostat);
+ -- if include file not found
+ if(v_ostat = 1) then
+ exit;
+ end if;
+ -- if there was valid tokens
+ elsif(valid /= 0) then
+ check_valid_inst(t1, v_inst_ptr, valid, l_num, v_name);
+ add_instruction(v_sequ_ptr,v_var_prt,t1,t2,t3,t4,t5,t6,t7,t_txt,valid,sequ_line,l_num,v_name);
+ end if;
+ l_num := l_num + 1;
+ end loop; -- end loop read file
+
+ file_close(stimulus); -- close the file when done
+
+ assert(v_ostat = 0)
+ report LF & "Include file not found! Test Terminated" & LF
+ severity failure;
+
+ inst_set := v_inst_ptr;
+ var_list := v_var_prt;
+ inst_sequ := v_sequ_ptr;
+ end read_instruction_file;
+
+------------------------------------------------------------------------------
+-- access_inst_sequ
+-- This procedure accesses the instruction sequence and returns the parameters
+-- as the exsist related to the variables state.
+ procedure access_inst_sequ(variable inst_sequ : in stim_line_ptr;
+ variable var_list : in var_field_ptr;
+ variable sequ_num : in integer;
+ variable inst : out text_field;
+ variable p1 : out integer;
+ variable p2 : out integer;
+ variable p3 : out integer;
+ variable p4 : out integer;
+ variable p5 : out integer;
+ variable p6 : out integer;
+ variable txt : out stm_text_ptr;
+ variable inst_len : out integer;
+ variable fname : out text_line;
+ variable file_line : out integer
+ ) is
+ variable temp_text_field: text_field;
+ variable temp_var: text_field;
+ variable inst_ptr: stim_line_ptr;
+ variable valid: integer;
+ variable line: integer; -- value of the file_line
+ variable file_name: text_line;
+ begin
+-- inst_ptr := inst_sequ;
+-- while(inst_ptr.next_rec /= null) loop
+-- print_inst(inst_ptr);
+-- inst_ptr := inst_ptr.next_rec;
+-- end loop;
+ -- get to the instruction indicated by sequ_num
+ inst_ptr := inst_sequ;
+ while(inst_ptr.next_rec /= null) loop
+ if(inst_ptr.line_number = sequ_num) then
+ exit;
+ else
+ inst_ptr := inst_ptr.next_rec;
+ end if;
+ end loop;
+ -- output the instruction and its length
+ inst := inst_ptr.instruction;
+ inst_len := fld_len(inst_ptr.instruction);
+ file_line := inst_ptr.file_line;
+ line := inst_ptr.file_line;
+ file_name := inst_ptr.file_name;
+ fname := inst_ptr.file_name;
+ txt := inst_ptr.txt;
+ -- load parameter one
+ temp_text_field := inst_ptr.inst_field_1;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p1 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p1 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p1,valid);
+ assert(valid = 1)
+ report LF & "Error: First variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter two
+ temp_text_field := inst_ptr.inst_field_2;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p2 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p2 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p2,valid);
+ assert(valid = 1)
+ report LF & "Error: Second variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter three
+ temp_text_field := inst_ptr.inst_field_3;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p3 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p3 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p3,valid);
+ assert(valid = 1)
+ report LF & "Error: Third variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter four
+ temp_text_field := inst_ptr.inst_field_4;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p4 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p4 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p4,valid);
+ assert(valid = 1)
+ report LF & "Error: Forth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter five
+ temp_text_field := inst_ptr.inst_field_5;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p5 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p5 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p5,valid);
+ assert(valid = 1)
+ report LF & "Error: Fifth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ -- load parameter six
+ temp_text_field := inst_ptr.inst_field_6;
+ if(temp_text_field(1) /= nul) then
+ -- if this is a numaric field convert to integer
+ if(temp_text_field(1) = 'x' or temp_text_field(1) = 'h' or
+ temp_text_field(1) = 'b') then
+ p6 := stim_to_integer(temp_text_field,file_name,line);
+ elsif(is_digit(temp_text_field(1)) = true) then
+ p6 := stim_to_integer(temp_text_field,file_name,line);
+ else -- else is a variable, get the value or halt incase of error
+ access_variable(var_list,temp_text_field,p6,valid);
+ assert(valid = 1)
+ report LF & "Error: Sixth variable on stimulus line " & (integer'image(line))
+ & " is not valid!!" & LF & "In file " & file_name
+ severity failure;
+ end if;
+ end if;
+ end access_inst_sequ;
+
+-------------------------------------------------------------------------
+-- dump inst_sequ
+-- This procedure dumps to the simulation window the current instruction
+-- sequence. The whole thing will be dumped, which could be big.
+-- ** intended for testbench development debug **
+ procedure dump_inst_sequ(variable inst_sequ : in stim_line_ptr) is
+ variable v_sequ : stim_line_ptr;
+ begin
+ v_sequ := inst_sequ;
+ while(v_sequ.next_rec /= null) loop
+ print("-----------------------------------------------------------------");
+ print("Instruction is " & v_sequ.instruction & " Par1: " & v_sequ.inst_field_1 &
+ " Par2: " & v_sequ.inst_field_2 & " Par3: " & v_sequ.inst_field_3 &
+ " Par4: " & v_sequ.inst_field_4);
+ print("Line Number: " & to_str(v_sequ.line_number) & " File Line Number: " & to_str(v_sequ.file_line) &
+ " File Name: " & v_sequ.file_name);
+
+ v_sequ := v_sequ.next_rec;
+ end loop;
+ -- get the last one
+ print("-----------------------------------------------------------------");
+ print("Instruction is " & v_sequ.instruction & " Par1: " & v_sequ.inst_field_1 &
+ " Par2: " & v_sequ.inst_field_2 & " Par3: " & v_sequ.inst_field_3 &
+ " Par4: " & v_sequ.inst_field_4);
+ print("Line Number: " & to_str(v_sequ.line_number) & " File Line Number: " & to_str(v_sequ.file_line) &
+ " File Name: " & v_sequ.file_name);
+ end dump_inst_sequ;
+
+-------------------------------------------------------------------------------
+-- Procedure to print messages to stdout
+ procedure print(s: in string) is
+ variable l: line;
+ begin
+ write(l, s);
+ writeline(output,l);
+ end print;
+
+-------------------------------------------------------------------------------
+-- procedure to print to the stdout the txt pointer
+ procedure txt_print(variable ptr: in stm_text_ptr) is
+ variable txt_str : stm_text;
+ begin
+
+ if (ptr /= null) then
+ txt_str := (others => nul);
+ for i in 1 to 128 loop
+ if (ptr(i) = nul) then
+ exit;
+ end if;
+ txt_str(i) := ptr(i);
+ end loop;
+ print(txt_str);
+ end if;
+ end txt_print;
+
+-------------------------------------------------------------------------------
+-- procedure to print to the stdout the txt pointer, and
+-- sub any variables found
+ procedure txt_print_wvar(variable var_list : in var_field_ptr;
+ variable ptr : in stm_text_ptr;
+ constant b : in base) is
+
+ variable i: integer;
+ variable j: integer;
+ variable k: integer;
+ variable txt_str: stm_text;
+ variable tmp_str: stm_text;
+ variable v1: integer;
+ variable valid: integer;
+ variable tmp_field: text_field;
+ variable tmp_i: integer;
+
+ begin
+ if(ptr /= null) then
+ i := 1;
+ j := 1;
+ txt_str := (others => nul);
+ while(i <= 128 and j <= 128) loop
+ if(ptr(i) /= '$') then
+ txt_str(j) := ptr(i);
+ i := i + 1;
+ j := j + 1;
+ else
+ tmp_field := (others => nul);
+ tmp_i := 1;
+ tmp_field(tmp_i) := ptr(i);
+ i := i + 1;
+ tmp_i := tmp_i + 1;
+ -- parse to the next space
+ while(ptr(i) /= ' ' and ptr(i) /= nul) loop
+ tmp_field(tmp_i) := ptr(i);
+ i := i + 1;
+ tmp_i := tmp_i + 1;
+ end loop;
+ access_variable(var_list,tmp_field,v1,valid);
+ assert(valid = 1)
+ report LF & "Invalid Variable found in stm_text_ptr: ignoring."
+ severity warning;
+
+ if(valid = 1) then
+
+ txt_str := ew_str_cat(txt_str, ew_to_str(v1, b));
+ k := 1;
+ while(txt_str(k) /= nul) loop
+ k := k + 1;
+ end loop;
+ j := k;
+ end if;
+ end if;
+ end loop;
+ -- print the created string
+ print(txt_str);
+ end if;
+ end txt_print_wvar;
+
+end tb_pkg;
+
Index: vhld_tb/tags/rel_001/source/tb_pkg_header.vhd
===================================================================
--- vhld_tb/tags/rel_001/source/tb_pkg_header.vhd (nonexistent)
+++ vhld_tb/tags/rel_001/source/tb_pkg_header.vhd (revision 14)
@@ -0,0 +1,219 @@
+-------------------------------------------------------------------------------
+-- Copyright 2007 Ken Campbell
+-------------------------------------------------------------------------------
+-- $Author: sckoarn $
+--
+-- $Date: 2007-04-06 04:06:48 $
+--
+-- $Name: not supported by cvs2svn $
+--
+-- $Id: tb_pkg_header.vhd,v 1.1.1.1 2007-04-06 04:06:48 sckoarn Exp $
+--
+-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/source/tb_pkg_header.vhd,v $
+--
+-- Description : The the testbench package header file.
+-- Initial GNU release.
+--
+------------------------------------------------------------------------------
+--This file is part of The VHDL Test Bench.
+--
+-- The VHDL Test Bench 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 2 of the License, or
+-- (at your option) any later version.
+--
+-- Foobar 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 The VHDL Test Bench; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+-------------------------------------------------------------------------------
+-- Revision History:
+-- $Log: not supported by cvs2svn $
+--
+-------------------------------------------------------------------------------
+library IEEE;
+
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.STD_LOGIC_ARITH.all;
+use std.textio.all;
+library ieee_proposed;
+use ieee_proposed.STD_LOGIC_1164_additions.all;
+
+package ew_tb_pkg2 is
+
+ -- Constants
+ constant max_str_len : integer := 256;
+ constant max_field_len : integer := 48;
+ constant c_stm_text_len : integer := 128;
+ -- file handles
+ file stimulus : text; -- file main file
+ file include_file : text; -- file declaration for includes
+
+ -- Type Def's
+ type base is (bin, oct, hex, dec);
+-- subtype stack_element is integer range 0 to 8192;
+ type stack_register is array(7 downto 0) of integer;
+ type state_register is array(7 downto 0) of boolean;
+ type int_array is array(1 to 16) of integer;
+
+ subtype text_line is string(1 to max_str_len);
+ subtype text_field is string(1 to max_field_len);
+ subtype stm_text is string(1 to c_stm_text_len);
+ type stm_text_ptr is access stm_text;
+ -- define the stimulus line record and access
+ type stim_line;
+ type stim_line_ptr is access stim_line; -- Pointer to stim_line record
+ type stim_line is record
+ instruction: text_field;
+ inst_field_1: text_field;
+ inst_field_2: text_field;
+ inst_field_3: text_field;
+ inst_field_4: text_field;
+ inst_field_5: text_field;
+ inst_field_6: text_field;
+ txt: stm_text_ptr;
+ line_number: integer; -- sequence line
+ num_of_lines: integer; -- total number of lines
+ file_line: integer; -- file line number
+ file_name: text_line;
+ next_rec: stim_line_ptr;
+ end record;
+ -- define the variables field and pointer
+ type var_field;
+ type var_field_ptr is access var_field; -- pointer to var_field
+ type var_field is record
+ var_name: text_field;
+ var_index: integer;
+ var_value: integer;
+ next_rec: var_field_ptr;
+ end record;
+ -- define the instruction structure
+ type inst_def;
+ type inst_def_ptr is access inst_def;
+ type inst_def is record
+ instruction: text_field;
+ instruction_l: integer;
+ params: integer;
+ next_rec: inst_def_ptr;
+ end record;
+
+---*****************************************************************************
+ -- Function Declaration
+-- function str_len(variable line: text_line) return text_field;
+-- function fld_len(s : in text_field) integer;
+ function ew_to_slv(value : in integer;
+ length : in integer) return std_logic_vector;
+
+ function c2std_vec(c: in character) return std_logic_vector;
+
+--------------------------------------------------------------------------------
+ -- Procedure declarations
+--------------------------------------------------------------------------
+-- define_instruction
+-- inputs file_name the file to be read from
+--
+-- output file_line a line of text from the file
+ procedure define_instruction(variable inst_set: inout inst_def_ptr;
+ constant inst: in string;
+ constant args: in integer);
+
+--------------------------------------------------------------------------------
+-- index_variable
+-- inputs:
+-- index: the index of the variable being accessed
+-- outputs:
+-- Variable Value
+-- valid is 1 if valid 0 if not
+ procedure index_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : out integer;
+ variable valid : out integer);
+
+--------------------------------------------------------------------------------
+-- update_variable
+-- inputs:
+-- index: the index of the variable being accessed
+-- outputs:
+-- Variable Value
+-- valid is 1 if valid 0 if not
+ procedure update_variable(variable var_list : in var_field_ptr;
+ variable index : in integer;
+ variable value : in integer;
+ variable valid : out integer);
+
+-------------------------------------------------------------------------------
+-- read_instruction_file
+-- This procedure reads the instruction file, name passed throught file_name.
+-- Pointers to records are passed in and out. A table of variables is created
+-- with variable name and value (converted to integer). The instructions are
+-- parsesed into the inst_sequ list. Instructions are validated against the
+-- inst_set which must have been set up prior to loading the instruction file.
+ procedure read_instruction_file(constant file_name: string;
+ variable inst_set: inout inst_def_ptr;
+ variable var_list: inout var_field_ptr;
+ variable inst_sequ: inout stim_line_ptr);
+
+------------------------------------------------------------------------------
+-- access_inst_sequ
+-- This procedure retreeves an instruction from the sequence of instructions.
+-- Based on the line number you pass to it, it returns the instruction with
+-- any variables substituted as integers.
+ procedure access_inst_sequ(variable inst_sequ : in stim_line_ptr;
+ variable var_list : in var_field_ptr;
+ variable sequ_num : in integer;
+ variable inst : out text_field;
+ variable p1 : out integer;
+ variable p2 : out integer;
+ variable p3 : out integer;
+ variable p4 : out integer;
+ variable p5 : out integer;
+ variable p6 : out integer;
+ variable txt : out stm_text_ptr;
+ variable inst_len : out integer;
+ variable fname : out text_line;
+ variable file_line : out integer
+ );
+------------------------------------------------------------------------
+-- tokenize_line
+-- This procedure takes a type text_line in and returns up to 6
+-- tokens and the count in integer valid, as well if text string
+-- is found the pointer to that is returned.
+ procedure tokenize_line(variable text_line: in text_line;
+ variable token1: out text_field;
+ variable token2: out text_field;
+ variable token3: out text_field;
+ variable token4: out text_field;
+ variable token5: out text_field;
+ variable token6: out text_field;
+ variable token7: out text_field;
+ variable txt_ptr: out stm_text_ptr;
+ variable valid: out integer);
+-------------------------------------------------------------------------
+-- string convertion
+ function ew_to_str(int: integer; b: base) return text_field;
+ function to_str(int: integer) return string;
+
+-------------------------------------------------------------------------
+-- Procedre print
+-- print to stdout string
+ procedure print(s: in string);
+-------------------------------------------------------------------------
+-- Procedure print stim txt
+ procedure txt_print(variable ptr: in stm_text_ptr);
+-------------------------------------------------------------------------
+-- Procedure print stim txt sub variables found
+ procedure txt_print_wvar(variable var_list : in var_field_ptr;
+ variable ptr : in stm_text_ptr;
+ constant b : in base);
+-------------------------------------------------------------------------
+-- dump inst_sequ
+-- This procedure dumps to the simulation window the current instruction
+-- sequence. The whole thing will be dumped, which could be big.
+-- ** intended for testbench development debug**
+ procedure dump_inst_sequ(variable inst_sequ : in stim_line_ptr);
+
+end ew_tb_pkg2;
Index: vhld_tb/tags/rel_001/ttb_gen/ttb_gen_gui.tcl
===================================================================
--- vhld_tb/tags/rel_001/ttb_gen/ttb_gen_gui.tcl (nonexistent)
+++ vhld_tb/tags/rel_001/ttb_gen/ttb_gen_gui.tcl (revision 14)
@@ -0,0 +1,754 @@
+##-------------------------------------------------------------------------------
+##-- Copyright 2007 Ken Campbell
+##-- All Rights Reserved
+##
+## 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 2 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, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##-------------------------------------------------------------------------------
+##-- $Author: sckoarn $
+##--
+##-- $Date: 2007-04-06 04:06:49 $
+##--
+##-- $Name: not supported by cvs2svn $
+##--
+##-- $Id: ttb_gen_gui.tcl,v 1.1.1.1 2007-04-06 04:06:49 sckoarn Exp $
+##--
+##-- $Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/vhld_tb/ttb_gen/ttb_gen_gui.tcl,v $
+##--
+##-- Description :
+##-- This application takes a text file containing the definition of a VHDL
+## entity, parses that entity and generates the VHDL Test Bench starting
+## file set. ( This was the first application written by the author
+## in the tcl\tk language, forgive the style.)
+##--
+##------------------------------------------------------------------------------
+## set the current version info
+set ttbgen_version "v1.0"
+## get the time and date from the system
+set raw_date [clock scan now]
+set scan_date [clock format $raw_date -format "%d %b %Y %T"]
+## title and version info for window
+set msg_txt [label .l1 -text "Test Bench Generation Tool $ttbgen_version"];
+pack $msg_txt
+
+## destination spec frame
+set g [frame .dest]
+label $g.lab -text "Destination Directory: " -anchor e
+entry $g.ent -width 20
+pack $g.lab -side left
+pack $g.ent -side left -expand yes -fill x
+
+## source spec frame with browser
+set f [frame .sour]
+label $f.lab -text "Select Generation Source: " -anchor e
+entry $f.ent -width 20
+button $f.but -text "Browse ..." -command "fileDialog $f $f.ent $g.ent"
+pack $f.lab -side left
+pack $f.ent -side left -expand yes -fill x
+pack $f.but -side left
+pack $f -fill x -padx 1c -pady 3
+## pack destination frame
+pack $g -fill x -padx 1c -pady 3
+## check button for optional bhv generation
+checkbutton .b1 -text "Generate the bhv file?" -variable bhv
+pack .b1
+## create and place the buttons frame
+frame .buttons
+pack .buttons -side bottom -fill x -pady 2m
+button .buttons.exit -text "Exit" -command exit
+button .buttons.help -text "Help" -command "show_help $msg_txt"
+button .buttons.gene -text "Generate" -command "ttb_gen $f.ent $g.ent"
+pack .buttons.gene -side left -expand 1
+pack .buttons.help -side left -expand 1
+pack .buttons.exit -side left -expand 1
+
+
+###########################################################################
+## some debug and help procs
+## Message Error, terminate
+proc msg_error { msg } {
+ tk_messageBox -message $msg -type ok
+ exit
+}
+###########################################################################
+## Message, continue
+proc dbg_msg { msg } {
+ tk_messageBox -message $msg -type ok
+}
+##-----------------------------------------------------------------------
+## Help display proc. It changes the Lable at the top of the window to
+## have the following text
+proc show_help { h } {
+ $h configure -justify left -text "Test Bench Generation Help \n \n \
+ 1) Use Browse to select a source entity VHDL file \n \
+ 2) Provide the path to the destination directory \n \
+ 3) Check Generate bhv, if behave file should be generated \n \
+ 4) Hit the Generate button"
+}
+
+##---------------------------------------------------------------
+## File dialog handler
+proc fileDialog {f ent des} {
+ # Type names Extension
+ #
+ #---------------------------------------------------------
+ set types {
+ {"VHDL Code" {.vhd .vhdl} }
+ {"Text files" {.txt} }
+ {"Tcl Scripts" {.tcl} TEXT}
+ {"All files" *}
+ }
+
+ set file [tk_getOpenFile -filetypes $types -parent $f]
+
+ if {[string compare $file ""]} {
+ $ent delete 0 end
+ $ent insert 0 $file
+ $ent xview end
+
+ set des_directory [string last / $file]
+ $des delete 0 end
+ $des insert 0 [string range $file 0 $des_directory]
+ $des xview end
+ }
+}
+
+##-----------------------------------------------------------------------
+## proc pars_pindef
+proc pars_pindef { pin } {
+ set pdirection ""
+# dbg_msg $pin
+ set spin [split $pin ":"]
+ set pname_str [lindex $spin 0]
+ set pname [lindex $pname_str 0]
+# dbg_msg "Pin name is $pname"
+ set pdirection_str [lindex $spin 1]
+# dbg_msg $pdirection_str
+ ## parce out the direction, supporting only 3
+ set direction [string first "in " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "in"
+ }
+ set direction [string first "out " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "out"
+ }
+ set direction [string first "inout " $pdirection_str]
+ if {$direction >= 0} {
+ set pdirection "inout"
+ }
+ if {$pdirection == ""} {
+ msg_error "Unsuported Pin direction found. \n Suported are IN OUT and INOUT."
+ }
+# dbg_msg "Pin direction is $pdirection"
+ ## now parce out the type
+ ## to overcome the std_logic_vector( # to #); vs (# to #); syntax
+ ## check and see if there is a vector spec in this pin with space after
+ ## the first bracket
+ set vect [string first "( " $pdirection_str]
+ if {$vect < 0} {
+ set ptype1 [lindex $pdirection_str 1]
+ set ptype2 [lindex $pdirection_str 2]
+ set ptype3 [lindex $pdirection_str 3]
+ set ptype "$ptype1 $ptype2 $ptype3"
+ } else {
+ set ptype1 [lindex $pdirection_str 1]
+ set ptype2 [lindex $pdirection_str 2]
+ set ptype3 [lindex $pdirection_str 3]
+ set ptype4 [lindex $pdirection_str 4]
+ set ptype "$ptype1 $ptype2 $ptype3 $ptype4"
+ }
+ ##puts $ptype
+
+ set last_pin [string first \; $ptype]
+ if {$last_pin >= 0} {
+ set is_vector [string first ( $ptype]
+ ## if there is a vector def
+ if {$is_vector >= 0} {
+ set temp_v [string first )) $ptype]
+
+ if {$temp_v >= 0} {
+ set s_e [expr $last_pin - 2]
+ set ptype [string range $ptype 0 $s_e]
+ } else {
+ set s_e [expr $last_pin - 1]
+ set ptype [string range $ptype 0 $s_e]
+ }
+ } else {
+ set temp_v [string first ) $ptype]
+ ## found a ); in the last pin def
+ if {$temp_v >= 0} {
+ set s_e [expr $last_pin - 2]
+ set ptype [string range $ptype 0 $s_e]
+ } else {
+ set s_e [expr $last_pin - 1]
+ set ptype [string range $ptype 0 $s_e]
+ }
+ }
+ }
+ set ptype [string trim $ptype]
+# dbg_msg "The type is $ptype"
+ lappend pdef $pname $pdirection $ptype
+ return $pdef
+}
+
+##--------------------------------------------------------------------------------
+## Write header to file passed
+proc write_header { handle } {
+ global ttbgen_version
+ global scan_date
+
+ ## so CVS will not modify selections, they have to be chopped up
+ set auth "-- \$Auth"
+ append auth "or: \$"
+ set cvs_date "-- \$dat"
+ append cvs_date "e: \$"
+ set cvs_name "-- \$Nam"
+ append cvs_name "e: \$"
+ set cvs_id "-- \$I"
+ append cvs_id "d: \$"
+ set cvs_source "-- \$Sour"
+ append cvs_source "ce: \$"
+ set cvs_log "-- \$Lo"
+ append cvs_log "g: \$"
+
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "-- Copyright 2007 xxxx"
+ puts $handle "-- All Rights Reserved"
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "$auth"
+ puts $handle "--"
+ puts $handle "$cvs_date"
+ puts $handle "--"
+ puts $handle "$cvs_name"
+ puts $handle "--"
+ puts $handle "$cvs_id"
+ puts $handle "--"
+ puts $handle "$cvs_source"
+ puts $handle "--"
+ puts $handle "-- Description :"
+ puts $handle "-- This file was generated by ttb_gen2_gui $ttbgen_version"
+ puts $handle "-- on $scan_date"
+ puts $handle "------------------------------------------------------------------------------"
+# puts $handle "-- This software contains concepts confidential to ------------------"
+# puts $handle "-- -----------. and is only made available within the terms of a written"
+# puts $handle "-- agreement."
+# puts $handle "-------------------------------------------------------------------------------"
+ puts $handle "-- Revision History:"
+ puts $handle "$cvs_log"
+ puts $handle "--"
+ puts $handle "-------------------------------------------------------------------------------"
+ puts $handle ""
+}
+
+##-------------------------------------------------------------------------
+## write Library and use statements
+proc write_lib_statements { handle } {
+puts $handle "library IEEE;"
+puts $handle "library ieee_proposed;"
+puts $handle "--library modelsim_lib;"
+puts $handle "use IEEE.STD_LOGIC_1164.all;"
+puts $handle "use IEEE.STD_LOGIC_ARITH.all;"
+puts $handle "use ieee_proposed.STD_LOGIC_1164_additions.all;"
+puts $handle "use std.textio.all;"
+puts $handle "--use modelsim_lib.util.all;"
+puts $handle ""
+}
+
+
+#########################################################################
+##
+## START of main program
+##
+#########################################################################
+proc ttb_gen { source destin } {
+
+global bhv
+
+set path_text [$source get]
+set destin_text [$destin get]
+
+set infile [open "$path_text" r]
+set file_list list
+
+##########################################
+## Path needs to be set up for the some usage cases
+## set the path to the template behave file
+set template "template_tb_bhv.vhd"
+#set template "\\\\Gs1\\public\\fpga_projects\\verification_docs\\html\\vhdltb\\template2_tb_bhv.vhd"
+
+set tmpcnt 0
+
+## -------------------------------------------------------------
+## Read in the file and strip comments as we do
+while {![eof $infile]} {
+ ## Get a line
+ set rline [gets $infile]
+ ## get rid of white space
+ set rline [string trim $rline]
+ ## Find comment if there
+ set cindex [string first -- $rline]
+ ## if a comment was found at the start of the line
+ if {$cindex == 0 || $rline == ""} {
+ set rline [string range $rline 0 [expr $cindex - 1]]
+ ##dbg_msg $rline
+ if {[llength $rline] > 0} {
+ lappend file_list [string tolower $rline]
+ }
+ ## else was not found so put line in list
+ } else {
+ lappend file_list [string tolower $rline]
+ # if {$tmpcnt > 490} {
+ # dbg_msg "$rline $tmpcnt"
+ # }
+ }
+ incr tmpcnt
+}
+
+## collect the library statements
+foreach l $file_list {
+ set libpos [string first library $l]
+ if {$libpos >= 0} {
+ lappend libs_list $l
+ }
+}
+
+## collect the use statements
+foreach l $file_list {
+ set usepos [string first use $l]
+ if {$usepos >= 0} {
+ lappend use_list $l
+ }
+}
+## check for the entity def
+set ent_found 0
+foreach l $file_list {
+ set ent_def [string first entity $l]
+ if {$ent_def >= 0} {
+## set ent_found 1
+ set ent_name [lindex $l 1]
+ break
+ }
+}
+## if no ent die
+if {$ent_def < 0} {
+ msg_error "An entity definition was not found in the file provided."
+## exit
+}
+
+## check for end entity
+foreach l $file_list {
+ lappend ent_list $l
+ set end_def [string first end $l]
+ if {$end_def >= 0} {
+ set end_ent [string first "end $ent_name" $l]
+ if {$end_ent >= 0} {
+ break
+ }
+ set end_ent [string first "end entity $ent_name" $l]
+ if {$end_ent >= 0} {
+ break
+ }
+ }
+}
+## if no end die
+if {$end_def < 0} {
+ msg_error "no end statement found for this entity"
+## exit
+}
+
+set port_found 0
+#######----------------------------------------------------------------
+## a few checks have been done, and non-relevant stuff stripped off.
+## now create an arrry of just the pin names and related info
+foreach l $ent_list {
+ ## look for the port statement
+ if {$port_found == 0} {
+ set pfound [string first port $l]
+ ## found one now check if there is a pin def in the same line
+ if {$pfound >= 0} {
+ set port_found 1
+ set efound [string first : $l]
+ if {$efound >= 0} {
+ set line_test [split $l "("]
+ if {[llength $line_test] > 1} {
+ lappend port_list [lindex $line_test 1]
+ }
+ }
+ }
+ } else {
+ set efound [string first : $l]
+ if {$efound >= 0} {
+ lappend port_list $l
+ }
+ }
+}
+#dbg_msg $port_list
+## Change the port list into a pin info list
+foreach l $port_list {
+ lappend split_pin [pars_pindef $l]
+}
+# dbg_msg $split_pin
+
+## calculate the longest pin name in characters
+set name_length 0
+foreach l $split_pin {
+ set temp_length [string length [lindex $l 0]]
+ if {$temp_length > $name_length} {
+ set name_length $temp_length
+ }
+}
+#dbg_msg $name_length
+## Make the name length one bigger
+incr name_length
+
+#########################################################################
+## Generate the test bench entity.
+
+## Create the file name
+set file_type "_tb_ent.vhd"
+set ent_file_name $destin_text
+append ent_file_name "/" $ent_name $file_type
+# dbg_msg $ent_file_name
+## Create the tb entity name
+set tb_ent_name $ent_name
+set tb_sufix "_tb"
+append tb_ent_name $tb_sufix
+
+## open and write the header
+set ent_file [open $ent_file_name w+]
+write_header $ent_file
+
+## write out Library and use statements
+write_lib_statements $ent_file
+
+puts $ent_file "entity $tb_ent_name is"
+puts $ent_file " generic ("
+puts $ent_file " stimulus_file: in string"
+puts $ent_file " )\;"
+puts $ent_file " port ("
+
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+set plist_size [llength $split_pin]
+#dbg_msg $plist_size
+set i 1
+foreach l $split_pin {
+ set pdirection [lindex $l 1]
+# puts $pdirection
+ ## switch on the source pin direction
+ switch -exact $pdirection {
+ "in" {set tb_ptype "buffer"}
+ "out" {set tb_ptype "in"}
+ "inout" {set tb_ptype "inout"}
+ default {
+ msg_error "Should have not got here .. pin direction in entity creation!!"
+ }
+ }
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" $tb_ptype]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ent_file $new_pname
+ incr i
+}
+
+puts $ent_file " )\;"
+puts $ent_file "end $tb_ent_name;"
+
+close $ent_file
+
+##################################################################
+## Generate the top level test bench entity
+## Create the file name
+set file_type "_ttb_ent.vhd"
+set ent_file_name $destin_text
+append ent_file_name "/" $ent_name $file_type
+# dbg_msg $ent_file_name
+## Create the tb entity name
+set ttb_ent_name $ent_name
+set ttb_sufix "_ttb"
+append ttb_ent_name $ttb_sufix
+
+## open and write the header
+set ttb_ent_file [open $ent_file_name w+]
+write_header $ttb_ent_file
+
+puts $ttb_ent_file "library IEEE;"
+puts $ttb_ent_file "library dut_lib;"
+puts $ttb_ent_file "use IEEE.STD_LOGIC_1164.all;"
+puts $ttb_ent_file "use dut_lib.all;"
+puts $ttb_ent_file ""
+puts $ttb_ent_file "entity $ttb_ent_name is"
+puts $ttb_ent_file " generic ("
+puts $ttb_ent_file " stimulus_file: string := \"stm/stimulus_file.stm\""
+puts $ttb_ent_file " )\;"
+puts $ttb_ent_file "end $ttb_ent_name\;"
+
+close $ttb_ent_file
+
+#################################################################
+## Generate the top level structure
+## Create the file name
+set file_type "_ttb_str.vhd"
+set str_file_name $destin_text
+append str_file_name "/" $ent_name $file_type
+# dbg_msg $ent_file_name
+## Create the tb entity name
+set ttb_ent_name $ent_name
+set ttb_sufix "_ttb"
+append ttb_ent_name $ttb_sufix
+
+## open and write the header
+set ttb_str_file [open $str_file_name w+]
+write_header $ttb_str_file
+
+puts $ttb_str_file ""
+puts $ttb_str_file "architecture struct of $ttb_ent_name is"
+puts $ttb_str_file ""
+puts $ttb_str_file "component $ent_name"
+puts $ttb_str_file " port ("
+## put out the dut component def
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+set i 1
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" [lindex $l 1]]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+puts $ttb_str_file " )\;"
+puts $ttb_str_file "end component\;"
+
+puts $ttb_str_file ""
+puts $ttb_str_file "component $tb_ent_name"
+puts $ttb_str_file " generic ("
+puts $ttb_str_file " stimulus_file: in string"
+puts $ttb_str_file " )\;"
+puts $ttb_str_file " port ("
+## put out the tb component def
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+set i 1
+foreach l $split_pin {
+ set pdirection [lindex $l 1]
+# dbg_msg $pdirection
+ ## switch on the source pin direction
+ switch -exact $pdirection {
+ "in" {set tb_ptype "buffer"}
+ "out" {set tb_ptype "in"}
+ "inout" {set tb_ptype "inout"}
+ default {
+ msg_error "Should have not got here .. pin direction in entity creation!!"
+ }
+ }
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ set new_ptype [format ": %-8s" $tb_ptype]
+ if {$i != $plist_size} {
+ append new_pname $new_ptype [lindex $l 2] ";"
+ } else {
+ append new_pname $new_ptype [lindex $l 2]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+puts $ttb_str_file " )\;"
+puts $ttb_str_file "end component\;"
+puts $ttb_str_file ""
+
+puts $ttb_str_file "for all: $ent_name use entity dut_lib.$ent_name\(str)\;"
+puts $ttb_str_file "for all: $tb_ent_name use entity work.$tb_ent_name\(bhv)\;"
+
+puts $ttb_str_file ""
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+# generate a signal name
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " signal temp_%-${name_length}s" [lindex $l 0]]
+ append new_pname ": " [lindex $l 2] ";"
+ puts $ttb_str_file $new_pname
+}
+
+puts $ttb_str_file ""
+puts $ttb_str_file "begin"
+puts $ttb_str_file ""
+puts $ttb_str_file "dut: $ent_name"
+puts $ttb_str_file " port map("
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+# Generate port map for DUT
+set i 1
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ if {$i != $plist_size} {
+ append new_pname "=> temp_" [lindex $l 0] ","
+ } else {
+ append new_pname "=> temp_" [lindex $l 0]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+
+puts $ttb_str_file " )\;"
+puts $ttb_str_file ""
+puts $ttb_str_file "tb: $tb_ent_name"
+puts $ttb_str_file " generic map("
+puts $ttb_str_file " stimulus_file => stimulus_file"
+puts $ttb_str_file " )"
+puts $ttb_str_file " port map("
+##-----------------------------------------
+# for each pin in the list output the TB ent pin
+# Generate port map for DUT
+set i 1
+foreach l $split_pin {
+ ## creat some formats for appending
+ set new_pname [format " %-${name_length}s" [lindex $l 0]]
+ if {$i != $plist_size} {
+ append new_pname "=> temp_" [lindex $l 0] ","
+ } else {
+ append new_pname "=> temp_" [lindex $l 0]
+ }
+ puts $ttb_str_file $new_pname
+ incr i
+}
+
+puts $ttb_str_file " )\;"
+puts $ttb_str_file ""
+puts $ttb_str_file "end struct\;"
+
+close $ttb_str_file
+
+######################################################################
+## Now generate the bhv file from template
+
+if {$bhv == 1} {
+
+ set infile [open "$template" r]
+
+ while {![eof $infile]} {
+ ## Get a line
+ set rline [gets $infile]
+ lappend temp_file_list $rline
+ }
+
+ close $infile
+
+ ## strip off the header
+ set end_header 0
+ foreach l $temp_file_list {
+ set comment [string first -- $l]
+ if {$comment < 0} {
+ set end_header 1
+ }
+ ## if we found the end of the header
+ if {$end_header == 1} {
+ lappend template_list $l
+ }
+ }
+
+ ## split the file into two peices, to the point of input initialization
+ set i 1
+ foreach l $template_list {
+ ## check for parsing point
+ set mid_point [string first parse_tb1 $l]
+ if {$mid_point >= 0} {
+ break
+ }
+
+ if {$i > 2} {
+ lappend top_half $l
+ }
+ incr i
+ }
+
+ set found 0
+ foreach l $template_list {
+ if {$found == 1} {
+ lappend bottom_half $l
+ }
+ ## check for parsing point
+ set mid_point [string first parse_tb1 $l]
+ if {$mid_point >= 0} {
+ set found 1
+ }
+ }
+
+ ## Create the file name
+ set file_type "_tb_bhv.vhd"
+ set bhv_file_name $destin_text
+ append bhv_file_name "/" $ent_name $file_type
+ # dbg_msg $ent_file_name
+
+ ## open and write the header
+ set bhv_file [open $bhv_file_name w+]
+ write_header $bhv_file
+
+ puts $bhv_file ""
+ puts $bhv_file "architecture bhv of $tb_ent_name is"
+ puts $bhv_file ""
+ foreach l $top_half {
+ puts $bhv_file $l
+ }
+
+ puts $bhv_file ""
+ ## now generate and write out input initialization
+ foreach l $split_pin {
+ set temp_def [lindex $l 1]
+ set input_def [string first in $temp_def]
+ if {$input_def >= 0} {
+ set vector [string first vector $l]
+ set init_def [format " %-${name_length}s" [lindex $l 0]]
+ if {$vector >= 0} {
+ append init_def "<= (others => '0')\;"
+ } else {
+ append init_def "<= '0'\;"
+ }
+ puts $bhv_file $init_def
+ }
+ }
+ puts $bhv_file ""
+ ## now write out the bottem half and termination
+ foreach l $bottom_half {
+ puts $bhv_file $l
+ }
+
+ close $bhv_file
+ }
+ ## put out a terminating message for the user
+ dbg_msg "Test bench files were generated in directory:\n $destin_text"
+
+}
+
+bind . {catch {console show}}
+
+##-------------------------------------------------------------------------------
+##-- Revision History:
+##-- $Log: not supported by cvs2svn $
+##--
+##----------------------------------------------------------------------------
+
Index: vhld_tb/tags/rel_001/Doc/VHDLtbusers.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: vhld_tb/tags/rel_001/Doc/VHDLtbusers.odt
===================================================================
--- vhld_tb/tags/rel_001/Doc/VHDLtbusers.odt (nonexistent)
+++ vhld_tb/tags/rel_001/Doc/VHDLtbusers.odt (revision 14)
vhld_tb/tags/rel_001/Doc/VHDLtbusers.odt
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: vhld_tb/tags/rel_001/GNU_GPL.txt
===================================================================
--- vhld_tb/tags/rel_001/GNU_GPL.txt (nonexistent)
+++ vhld_tb/tags/rel_001/GNU_GPL.txt (revision 14)
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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 2 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
Index: vhld_tb/tags
===================================================================
--- vhld_tb/tags (nonexistent)
+++ vhld_tb/tags (revision 14)
vhld_tb/tags
Property changes :
Added: svn:mergeinfo
## -0,0 +0,0 ##