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 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/source/template_tb_bhv.vhd
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;
/trunk/source/tb_pkg_body.vhd
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;
 
/trunk/source/tb_pkg_header.vhd
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;
/trunk/ttb_gen/ttb_gen_gui.tcl
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 . <F12> {catch {console show}}
 
##-------------------------------------------------------------------------------
##-- Revision History:
##-- $Log: not supported by cvs2svn $
##--
##----------------------------------------------------------------------------
 
/trunk/Doc/VHDLtbusers.odt Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/Doc/VHDLtbusers.odt Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/GNU_GPL.txt =================================================================== --- trunk/GNU_GPL.txt (nonexistent) +++ trunk/GNU_GPL.txt (revision 2) @@ -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.

powered by: WebSVN 2.1.0

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