OpenCores
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/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 ##

powered by: WebSVN 2.1.0

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