From: Sam Moore Date: Fri, 11 Apr 2014 04:53:55 +0000 (+0800) Subject: Add Makefile, change original tester to be the vfpu X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fvfpu.git;a=commitdiff_plain;h=ecbc325cc08fb2731d1fc820a87979b75b4306bc Add Makefile, change original tester to be the vfpu --- diff --git a/.gitignore b/.gitignore index 365a631..b7bbba4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ *.test *.out *.err +*.cf diff --git a/src/COPYRIGHT.jop b/src/COPYRIGHT.jop new file mode 100644 index 0000000..6b82061 --- /dev/null +++ b/src/COPYRIGHT.jop @@ -0,0 +1,25 @@ +-- Author: Jidan Al-eryani +-- E-mail: jidan@gmx.net +-- +-- Copyright (C) 2006 +-- +-- This source file may be used and distributed without +-- restriction provided that this copyright statement is not +-- removed from the file and that any derivative work contains +-- the original copyright notice and the associated disclaimer. +-- +-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY +-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..71fe9e2 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,24 @@ +#Makefile for a VHDL FPU based on https://github.com/jop-devel/jop +GHDL = ghdl +GHDL_FLAGS = --std=93c --ieee=synopsys -fexplicit +OBJ = fpupack.o pre_norm_addsub.o addsub_28.o post_norm_addsub.o pre_norm_mul.o mul_24.o serial_mul.o post_norm_mul.o pre_norm_div.o serial_div.o post_norm_div.o pre_norm_sqrt.o sqrt.o post_norm_sqrt.o comppack.o fpu.o txt_util.o + +RM = rm -f + +BIN = ../bin/vfpu + +$(BIN) : $(OBJ) main + mv main $(BIN) + +% : %.o + $(GHDL) -e $(GHDL_FLAGS) $@ + + +%.o : %.vhd + $(GHDL) -a $(GHDL_FLAGS) $< + +clean : + rm -f $(OBJ) + rm -f main.o + rm -f *~ + rm -f $(BIN) diff --git a/src/main.vhd b/src/main.vhd new file mode 100644 index 0000000..99596ee --- /dev/null +++ b/src/main.vhd @@ -0,0 +1,147 @@ +-- Simulates the fpu by reading signals from stdin and writing results to stdout +-- See COPYRIGHT.jop for the original copyright notice. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.math_real.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_misc.all; +use std.textio.all; +use work.txt_util.all; + + -- fpu operations (fpu_op_i): + -- ======================== + -- 000 = add, + -- 001 = substract, + -- 010 = multiply, + -- 011 = divide, + -- 100 = square root + -- 101 = unused + -- 110 = unused + -- 111 = unused + + -- Rounding Mode: + -- ============== + -- 00 = round to nearest even(default), + -- 01 = round to zero, + -- 10 = round up, + -- 11 = round down + + +entity main is +end main; + +architecture rtl of main is + +component fpu + port ( + clk_i : in std_logic; + opa_i : in std_logic_vector(31 downto 0); + opb_i : in std_logic_vector(31 downto 0); + fpu_op_i : in std_logic_vector(2 downto 0); + rmode_i : in std_logic_vector(1 downto 0); + output_o : out std_logic_vector(31 downto 0); + ine_o : out std_logic; + overflow_o : out std_logic; + underflow_o : out std_logic; + div_zero_o : out std_logic; + inf_o : out std_logic; + zero_o : out std_logic; + qnan_o : out std_logic; + snan_o : out std_logic; + start_i : in std_logic; + ready_o : out std_logic + ); +end component; + + +signal clk_i : std_logic:= '1'; +signal opa_i, opb_i : std_logic_vector(31 downto 0) := (others => '0'); +signal fpu_op_i : std_logic_vector(2 downto 0) := (others => '0'); +signal rmode_i : std_logic_vector(1 downto 0) := (others => '0'); +signal output_o : std_logic_vector(31 downto 0) := (others => '0'); +signal start_i, ready_o : std_logic := '0'; +signal ine_o, overflow_o, underflow_o, div_zero_o, inf_o, zero_o, qnan_o, snan_o: std_logic := '0'; + + + +signal slv_out : std_logic_vector(31 downto 0); + +constant CLK_PERIOD :time := 10 ns; -- period of clk period + + +begin + + -- instantiate fpu + i_fpu: fpu port map ( + clk_i => clk_i, + opa_i => opa_i, + opb_i => opb_i, + fpu_op_i => fpu_op_i, + rmode_i => rmode_i, + output_o => output_o, + ine_o => ine_o, + overflow_o => overflow_o, + underflow_o => underflow_o, + div_zero_o => div_zero_o, + inf_o => inf_o, + zero_o => zero_o, + qnan_o => qnan_o, + snan_o => snan_o, + start_i => start_i, + ready_o => ready_o); + + + --------------------------------------------------------------------------- + -- toggle clock + --------------------------------------------------------------------------- + clk_i <= not(clk_i) after 5 ns; + + + mainloop : process + --The operands and results are in Hex format. + file input_file: TEXT open read_mode is "STD_INPUT"; + + variable file_line: line; + variable str_in: string(8 downto 1); + variable str_fpu_op: string(3 downto 1); + variable str_rmode: string(2 downto 1); + + + + begin + -- Read ops from input_file + start_i <= '0'; + while not endfile(input_file) loop + + wait for CLK_PERIOD; + start_i <= '1'; + + str_read(input,str_in); + opa_i <= strhex_to_slv(str_in); + + str_read(input,str_in); + opb_i <= strhex_to_slv(str_in); + + str_read(input_file,str_fpu_op); + fpu_op_i <= to_std_logic_vector(str_fpu_op); + + str_read(input_file,str_rmode); + rmode_i <= to_std_logic_vector(str_rmode); + + str_read(input_file,str_in); + slv_out <= strhex_to_slv(str_in); + + wait for CLK_PERIOD; + start_i <= '0'; + wait until ready_o='1'; + + + print(hstr(output_o)); + + end loop; + wait; + end process mainloop; + +end rtl; diff --git a/src/test_bench/fpu_wave.do b/src/test_bench/fpu_wave.do deleted file mode 100644 index 51181b0..0000000 --- a/src/test_bench/fpu_wave.do +++ /dev/null @@ -1,34 +0,0 @@ -onerror {resume} -quietly WaveActivateNextPane {} 0 -add wave -noupdate -format Logic /tb_fpu/clk_i -add wave -noupdate -format Literal /tb_fpu/opa_i -add wave -noupdate -format Literal /tb_fpu/opb_i -add wave -noupdate -format Literal /tb_fpu/fpu_op_i -add wave -noupdate -format Literal /tb_fpu/rmode_i -add wave -noupdate -format Literal /tb_fpu/output_o -add wave -noupdate -format Logic /tb_fpu/start_i -add wave -noupdate -format Logic /tb_fpu/ready_o -add wave -noupdate -format Logic /tb_fpu/ine_o -add wave -noupdate -format Logic /tb_fpu/overflow_o -add wave -noupdate -format Logic /tb_fpu/underflow_o -add wave -noupdate -format Logic /tb_fpu/div_zero_o -add wave -noupdate -format Logic /tb_fpu/inf_o -add wave -noupdate -format Logic /tb_fpu/zero_o -add wave -noupdate -format Logic /tb_fpu/qnan_o -add wave -noupdate -format Logic /tb_fpu/snan_o -TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 1} {16182 ns} 0} -configure wave -namecolwidth 255 -configure wave -valuecolwidth 317 -configure wave -justifyvalue left -configure wave -signalnamewidth 0 -configure wave -snapdistance 10 -configure wave -datasetprefix 0 -configure wave -rowmargin 4 -configure wave -childrowmargin 2 -configure wave -gridoffset 0 -configure wave -gridperiod 1 -configure wave -griddelta 40 -configure wave -timeline 0 -update -WaveRestoreZoom {0 ns} {544 ns} diff --git a/src/test_bench/fpusim.bat b/src/test_bench/fpusim.bat deleted file mode 100644 index f77b287..0000000 --- a/src/test_bench/fpusim.bat +++ /dev/null @@ -1,29 +0,0 @@ -set REL= ..\ - -vlib work - -vcom %REL%fpupack.vhd -vcom %REL%pre_norm_addsub.vhd -vcom %REL%addsub_28.vhd -vcom %REL%post_norm_addsub.vhd -vcom %REL%pre_norm_mul.vhd -vcom %REL%mul_24.vhd -vcom %REL%serial_mul.vhd -vcom %REL%post_norm_mul.vhd -vcom %REL%pre_norm_div.vhd -vcom %REL%serial_div.vhd -vcom %REL%post_norm_div.vhd -vcom %REL%pre_norm_sqrt.vhd -vcom %REL%sqrt.vhd -vcom %REL%post_norm_sqrt.vhd -vcom %REL%comppack.vhd -vcom %REL%fpu.vhd - -vcom txt_util.vhd -vcom tb_fpu.vhd - -pause Start simulation? - -vsim -do fpu_wave.do tb_fpu - - diff --git a/src/test_bench/maketest.bat b/src/test_bench/maketest.bat deleted file mode 100644 index 6500bb2..0000000 --- a/src/test_bench/maketest.bat +++ /dev/null @@ -1,23 +0,0 @@ -timesoftfloat -nearesteven float32_add > testcases.txt -timesoftfloat -nearesteven float32_sub >> testcases.txt -timesoftfloat -nearesteven float32_mul >> testcases.txt -timesoftfloat -nearesteven float32_div >> testcases.txt -timesoftfloat -nearesteven float32_sqrt >> testcases.txt - -timesoftfloat -tozero float32_add >> testcases.txt -timesoftfloat -tozero float32_sub >> testcases.txt -timesoftfloat -tozero float32_mul >> testcases.txt -timesoftfloat -tozero float32_div >> testcases.txt -timesoftfloat -tozero float32_sqrt >> testcases.txt - -timesoftfloat -up float32_add >> testcases.txt -timesoftfloat -up float32_sub >> testcases.txt -timesoftfloat -up float32_mul >> testcases.txt -timesoftfloat -up float32_div >> testcases.txt -timesoftfloat -up float32_sqrt >> testcases.txt - -timesoftfloat -down float32_add >> testcases.txt -timesoftfloat -down float32_sub >> testcases.txt -timesoftfloat -down float32_mul >> testcases.txt -timesoftfloat -down float32_div >> testcases.txt -timesoftfloat -down float32_sqrt >> testcases.txt \ No newline at end of file diff --git a/src/test_bench/readme.txt b/src/test_bench/readme.txt deleted file mode 100644 index 2511475..0000000 --- a/src/test_bench/readme.txt +++ /dev/null @@ -1,9 +0,0 @@ -To test the FPU core, do the following: - -1) Build timesoftfloat.exe for your specific platform(read instructions in folder SoftFloat for howto do that). - Before you do that, try the already included file. - -2) Create the testcases by running maketest.bat in folder test_bench. Default value is 100000 cases for each - arithmetic operation and for each rounding mode. This comes up to 2 million test cases. - -3) run fpusim.bat to simulate and test the FPU core using modelsim. \ No newline at end of file diff --git a/src/test_bench/tb_fpu.vhd b/src/test_bench/tb_fpu.vhd deleted file mode 100644 index 9a9f78f..0000000 --- a/src/test_bench/tb_fpu.vhd +++ /dev/null @@ -1,259 +0,0 @@ -------------------------------------------------------------------------------- --- --- Project: --- --- Description: test bench for the FPU core -------------------------------------------------------------------------------- --- --- 100101011010011100100 --- 110000111011100100000 --- 100000111011000101101 --- 100010111100101111001 --- 110000111011101101001 --- 010000001011101001010 --- 110100111001001100001 --- 110111010000001100111 --- 110110111110001011101 --- 101110110010111101000 --- 100000010111000000000 --- --- Author: Jidan Al-eryani --- E-mail: jidan@gmx.net --- --- Copyright (C) 2006 --- --- This source file may be used and distributed without --- restriction provided that this copyright statement is not --- removed from the file and that any derivative work contains --- the original copyright notice and the associated disclaimer. --- --- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY --- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES --- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE --- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR --- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT --- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; -use ieee.math_real.all; -use ieee.std_logic_arith.all; -use ieee.std_logic_misc.all; -use std.textio.all; -use work.txt_util.all; - - -- fpu operations (fpu_op_i): - -- ======================== - -- 000 = add, - -- 001 = substract, - -- 010 = multiply, - -- 011 = divide, - -- 100 = square root - -- 101 = unused - -- 110 = unused - -- 111 = unused - - -- Rounding Mode: - -- ============== - -- 00 = round to nearest even(default), - -- 01 = round to zero, - -- 10 = round up, - -- 11 = round down - - -entity tb_fpu is -end tb_fpu; - -architecture rtl of tb_fpu is - -component fpu - port ( - clk_i : in std_logic; - opa_i : in std_logic_vector(31 downto 0); - opb_i : in std_logic_vector(31 downto 0); - fpu_op_i : in std_logic_vector(2 downto 0); - rmode_i : in std_logic_vector(1 downto 0); - output_o : out std_logic_vector(31 downto 0); - ine_o : out std_logic; - overflow_o : out std_logic; - underflow_o : out std_logic; - div_zero_o : out std_logic; - inf_o : out std_logic; - zero_o : out std_logic; - qnan_o : out std_logic; - snan_o : out std_logic; - start_i : in std_logic; - ready_o : out std_logic - ); -end component; - - -signal clk_i : std_logic:= '1'; -signal opa_i, opb_i : std_logic_vector(31 downto 0); -signal fpu_op_i : std_logic_vector(2 downto 0); -signal rmode_i : std_logic_vector(1 downto 0); -signal output_o : std_logic_vector(31 downto 0); -signal start_i, ready_o : std_logic ; -signal ine_o, overflow_o, underflow_o, div_zero_o, inf_o, zero_o, qnan_o, snan_o: std_logic; - - - -signal slv_out : std_logic_vector(31 downto 0); - -constant CLK_PERIOD :time := 10 ns; -- period of clk period - - -begin - - -- instantiate fpu - i_fpu: fpu port map ( - clk_i => clk_i, - opa_i => opa_i, - opb_i => opb_i, - fpu_op_i => fpu_op_i, - rmode_i => rmode_i, - output_o => output_o, - ine_o => ine_o, - overflow_o => overflow_o, - underflow_o => underflow_o, - div_zero_o => div_zero_o, - inf_o => inf_o, - zero_o => zero_o, - qnan_o => qnan_o, - snan_o => snan_o, - start_i => start_i, - ready_o => ready_o); - - - --------------------------------------------------------------------------- - -- toggle clock - --------------------------------------------------------------------------- - clk_i <= not(clk_i) after 5 ns; - - - verify : process - --The operands and results are in Hex format. The test vectors must be placed in a strict order for the verfication to work. - file testcases_file: TEXT open read_mode is "testcases.txt"; --Name of the file containing the test cases. - - variable file_line: line; - variable str_in: string(8 downto 1); - variable str_fpu_op: string(3 downto 1); - variable str_rmode: string(2 downto 1); - begin - - - --------------------------------------------------------------------------------------------------------------------------------------------------- - ---------------------------------------------------SoftFloat test vectors (10000 test cases for each operation) -------------------------------------------------------------------- - start_i <= '0'; - while not endfile(testcases_file) loop - - wait for CLK_PERIOD; start_i <= '1'; - - str_read(testcases_file,str_in); - opa_i <= strhex_to_slv(str_in); - - str_read(testcases_file,str_in); - opb_i <= strhex_to_slv(str_in); - - str_read(testcases_file,str_fpu_op); - fpu_op_i <= to_std_logic_vector(str_fpu_op); - - str_read(testcases_file,str_rmode); - rmode_i <= to_std_logic_vector(str_rmode); - - str_read(testcases_file,str_in); - slv_out <= strhex_to_slv(str_in); - - wait for CLK_PERIOD; start_i <= '0'; wait until ready_o='1'; - - assert output_o = slv_out - report "Error!!!" - severity failure; - str_read(testcases_file,str_in); - - end loop; - - -------- Boundary values----- - - start_i <= '0'; - -- seeeeeeeefffffffffffffffffffffff - --infinity - wait for CLK_PERIOD; start_i <= '1'; - opa_i <= "01111111011111111111111111111111"; - opb_i <= "01111111011111111111111111111111"; - fpu_op_i <= "000"; - rmode_i <= "00"; - wait for CLK_PERIOD; start_i <= '0'; wait until ready_o='1'; - assert output_o="01111111100000000000000000000000" - report "Error!!!" - severity failure; - - -- seeeeeeeefffffffffffffffffffffff - -- 1 x1.001 - 1x1.000 = 0x0.001 - wait for CLK_PERIOD; start_i <= '1'; - opa_i <= "00000000100100000000000000000000"; - opb_i <= "10000000100000000000000000000000"; - fpu_op_i <= "000"; - rmode_i <= "00"; - wait for CLK_PERIOD; start_i <= '0'; wait until ready_o='1'; - assert output_o="00000000000100000000000000000000" - report "Error!!!" - severity failure; - - -- seeeeeeeefffffffffffffffffffffff - -- 10 x 1.0001 - 10 x 1.0000 = - wait for CLK_PERIOD; start_i <= '1'; - opa_i <= "00000001000010000000000000000000"; - opb_i <= "10000001000000000000000000000000"; - fpu_op_i <= "000"; - rmode_i <= "00"; - wait for CLK_PERIOD; start_i <= '0'; wait until ready_o='1'; - assert output_o="00000000000100000000000000000000" - report "Error!!!" - severity failure; - - - -- seeeeeeeefffffffffffffffffffffff - -- -0 -0 = -0 - wait for CLK_PERIOD; start_i <= '1'; - opa_i <= "10000000000000000000000000000000"; - opb_i <= "10000000000000000000000000000000"; - fpu_op_i <= "000"; - rmode_i <= "00"; - wait for CLK_PERIOD; start_i <= '0'; wait until ready_o='1'; - assert output_o="10000000000000000000000000000000" - report "Error!!!" - severity failure; - - -- seeeeeeeefffffffffffffffffffffff - -- 0 + x = x - wait for CLK_PERIOD; start_i <= '1'; - opa_i <= "00000000000000000000000000000000"; - opb_i <= "01000010001000001000000000100000"; - fpu_op_i <= "000"; - rmode_i <= "00"; - wait for CLK_PERIOD; start_i <= '0'; wait until ready_o='1'; - assert output_o="01000010001000001000000000100000" - report "Error!!!" - severity failure; - - - ---------------------------------------------------------------------------------------------------------------------------------------------------- - assert false - report "Success!!!.......Yahoooooooooooooo" - severity failure; - - wait; - - end process verify; - -end rtl; \ No newline at end of file diff --git a/src/test_bench/timesoftfloat.exe b/src/test_bench/timesoftfloat.exe deleted file mode 100644 index 1f747bf..0000000 Binary files a/src/test_bench/timesoftfloat.exe and /dev/null differ diff --git a/src/test_bench/txt_util.vhd b/src/test_bench/txt_util.vhd deleted file mode 100644 index 3ccc65d..0000000 --- a/src/test_bench/txt_util.vhd +++ /dev/null @@ -1,614 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use std.textio.all; - - -package txt_util is - - -- prints a message to the screen - procedure print(text: string); - - -- prints the message when active - -- useful for debug switches - procedure print(active: boolean; text: string); - - -- converts std_logic into a character - function chr(sl: std_logic) return character; - - -- converts std_logic into a string (1 to 1) - function str(sl: std_logic) return string; - - -- converts std_logic_vector into a string (binary base) - function str(slv: std_logic_vector) return string; - - -- converts boolean into a string - function str(b: boolean) return string; - - -- converts an integer into a single character - -- (can also be used for hex conversion and other bases) - function chr(int: integer) return character; - - -- converts integer into string using specified base - function str(int: integer; base: integer) return string; - - -- converts integer to string, using base 10 - function str(int: integer) return string; - - -- convert std_logic_vector into a string in hex format - function hstr(slv: std_logic_vector) return string; - - - -- functions to manipulate strings - ----------------------------------- - - -- convert a character to upper case - function to_upper(c: character) return character; - - -- convert a character to lower case - function to_lower(c: character) return character; - - -- convert a string to upper case - function to_upper(s: string) return string; - - -- convert a string to lower case - function to_lower(s: string) return string; - - - - -- functions to convert strings into other formats - -------------------------------------------------- - - -- converts a character into std_logic - function to_std_logic(c: character) return std_logic; - - -- converts a string into std_logic_vector - function to_std_logic_vector(s: string) return std_logic_vector; - - -- convert Hex string to 32-bit into std_logic_vector - function strhex_to_slv(s : string) return std_logic_vector; - - - - -- file I/O - ----------- - - -- read variable length string from input file - procedure str_read(file in_file: TEXT; - res_string: out string); - - -- print string to a file and start new line - procedure print(file out_file: TEXT; - new_string: in string); - - -- print character to a file and start new line - procedure print(file out_file: TEXT; - char: in character); - -end txt_util; - - - - -package body txt_util is - - - - - -- prints text to the screen - - procedure print(text: string) is - variable msg_line: line; - begin - write(msg_line, text); - writeline(output, msg_line); - end print; - - - - - -- prints text to the screen when active - - procedure print(active: boolean; text: string) is - begin - if active then - print(text); - end if; - end print; - - - -- converts std_logic into a character - - function chr(sl: std_logic) return character is - variable c: character; - begin - case sl is - when 'U' => c:= 'U'; - when 'X' => c:= 'X'; - when '0' => c:= '0'; - when '1' => c:= '1'; - when 'Z' => c:= 'Z'; - when 'W' => c:= 'W'; - when 'L' => c:= 'L'; - when 'H' => c:= 'H'; - when '-' => c:= '-'; - end case; - return c; - end chr; - - - - -- converts std_logic into a string (1 to 1) - - function str(sl: std_logic) return string is - variable s: string(1 to 1); - begin - s(1) := chr(sl); - return s; - end str; - - - - -- converts std_logic_vector into a string (binary base) - -- (this also takes care of the fact that the range of - -- a string is natural while a std_logic_vector may - -- have an integer range) - - function str(slv: std_logic_vector) return string is - variable result : string (1 to slv'length); - variable r : integer; - begin - r := 1; - for i in slv'range loop - result(r) := chr(slv(i)); - r := r + 1; - end loop; - return result; - end str; - - - function str(b: boolean) return string is - - begin - if b then - return "true"; - else - return "false"; - end if; - end str; - - - -- converts an integer into a character - -- for 0 to 9 the obvious mapping is used, higher - -- values are mapped to the characters A-Z - -- (this is usefull for systems with base > 10) - -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) - - function chr(int: integer) return character is - variable c: character; - begin - 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 16 => c := 'G'; - when 17 => c := 'H'; - when 18 => c := 'I'; - when 19 => c := 'J'; - when 20 => c := 'K'; - when 21 => c := 'L'; - when 22 => c := 'M'; - when 23 => c := 'N'; - when 24 => c := 'O'; - when 25 => c := 'P'; - when 26 => c := 'Q'; - when 27 => c := 'R'; - when 28 => c := 'S'; - when 29 => c := 'T'; - when 30 => c := 'U'; - when 31 => c := 'V'; - when 32 => c := 'W'; - when 33 => c := 'X'; - when 34 => c := 'Y'; - when 35 => c := 'Z'; - when others => c := '?'; - end case; - return c; - end chr; - - - - -- convert integer to string using specified base - -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) - - function str(int: integer; base: integer) return string is - - variable temp: string(1 to 10); - variable num: integer; - variable abs_int: integer; - variable len: integer := 1; - variable power: integer := 1; - - begin - - -- bug fix for negative numbers - abs_int := abs(int); - - num := abs_int; - - while num >= base loop -- Determine how many - len := len + 1; -- characters required - num := num / base; -- to represent the - end loop ; -- number. - - for i in len downto 1 loop -- Convert the number to - temp(i) := chr(abs_int/power mod base); -- a string starting - power := power * base; -- with the right hand - end loop ; -- side. - - -- return result and add sign if required - if int < 0 then - return '-'& temp(1 to len); - else - return temp(1 to len); - end if; - - end str; - - - -- convert integer to string, using base 10 - function str(int: integer) return string is - - begin - - return str(int, 10) ; - - end str; - - - - -- converts a std_logic_vector into a hex string. - function hstr(slv: std_logic_vector) return string is - variable hexlen: integer; - variable longslv : std_logic_vector(67 downto 0) := (others => '0'); - variable hex : string(1 to 16); - variable fourbit : std_logic_vector(3 downto 0); - begin - hexlen := (slv'left+1)/4; - if (slv'left+1) mod 4 /= 0 then - hexlen := hexlen + 1; - end if; - longslv(slv'left downto 0) := slv; - for i in (hexlen -1) downto 0 loop - fourbit := longslv(((i*4)+3) downto (i*4)); - case fourbit is - when "0000" => hex(hexlen -I) := '0'; - when "0001" => hex(hexlen -I) := '1'; - when "0010" => hex(hexlen -I) := '2'; - when "0011" => hex(hexlen -I) := '3'; - when "0100" => hex(hexlen -I) := '4'; - when "0101" => hex(hexlen -I) := '5'; - when "0110" => hex(hexlen -I) := '6'; - when "0111" => hex(hexlen -I) := '7'; - when "1000" => hex(hexlen -I) := '8'; - when "1001" => hex(hexlen -I) := '9'; - when "1010" => hex(hexlen -I) := 'A'; - when "1011" => hex(hexlen -I) := 'B'; - when "1100" => hex(hexlen -I) := 'C'; - when "1101" => hex(hexlen -I) := 'D'; - when "1110" => hex(hexlen -I) := 'E'; - when "1111" => hex(hexlen -I) := 'F'; - when "ZZZZ" => hex(hexlen -I) := 'z'; - when "UUUU" => hex(hexlen -I) := 'u'; - when "XXXX" => hex(hexlen -I) := 'x'; - when others => hex(hexlen -I) := '?'; - end case; - end loop; - return hex(1 to hexlen); - end hstr; - - - - -- functions to manipulate strings - ----------------------------------- - - - -- convert a character to upper case - - function to_upper(c: character) return character is - - variable u: character; - - begin - - case c is - when 'a' => u := 'A'; - when 'b' => u := 'B'; - when 'c' => u := 'C'; - when 'd' => u := 'D'; - when 'e' => u := 'E'; - when 'f' => u := 'F'; - when 'g' => u := 'G'; - when 'h' => u := 'H'; - when 'i' => u := 'I'; - when 'j' => u := 'J'; - when 'k' => u := 'K'; - when 'l' => u := 'L'; - when 'm' => u := 'M'; - when 'n' => u := 'N'; - when 'o' => u := 'O'; - when 'p' => u := 'P'; - when 'q' => u := 'Q'; - when 'r' => u := 'R'; - when 's' => u := 'S'; - when 't' => u := 'T'; - when 'u' => u := 'U'; - when 'v' => u := 'V'; - when 'w' => u := 'W'; - when 'x' => u := 'X'; - when 'y' => u := 'Y'; - when 'z' => u := 'Z'; - when others => u := c; - end case; - - return u; - - end to_upper; - - - -- convert a character to lower case - - function to_lower(c: character) return character is - - variable l: character; - - begin - - case c is - when 'A' => l := 'a'; - when 'B' => l := 'b'; - when 'C' => l := 'c'; - when 'D' => l := 'd'; - when 'E' => l := 'e'; - when 'F' => l := 'f'; - when 'G' => l := 'g'; - when 'H' => l := 'h'; - when 'I' => l := 'i'; - when 'J' => l := 'j'; - when 'K' => l := 'k'; - when 'L' => l := 'l'; - when 'M' => l := 'm'; - when 'N' => l := 'n'; - when 'O' => l := 'o'; - when 'P' => l := 'p'; - when 'Q' => l := 'q'; - when 'R' => l := 'r'; - when 'S' => l := 's'; - when 'T' => l := 't'; - when 'U' => l := 'u'; - when 'V' => l := 'v'; - when 'W' => l := 'w'; - when 'X' => l := 'x'; - when 'Y' => l := 'y'; - when 'Z' => l := 'z'; - when others => l := c; - end case; - - return l; - - end to_lower; - - - - -- convert a string to upper case - - function to_upper(s: string) return string is - - variable uppercase: string (s'range); - - begin - - for i in s'range loop - uppercase(i):= to_upper(s(i)); - end loop; - return uppercase; - - end to_upper; - - - - -- convert a string to lower case - - function to_lower(s: string) return string is - - variable lowercase: string (s'range); - - begin - - for i in s'range loop - lowercase(i):= to_lower(s(i)); - end loop; - return lowercase; - - end to_lower; - - - --- functions to convert strings into other types - - --- converts a character into a std_logic - -function to_std_logic(c: character) return std_logic is - variable sl: std_logic; - begin - case c is - when 'U' => - sl := 'U'; - when 'X' => - sl := 'X'; - when '0' => - sl := '0'; - when '1' => - sl := '1'; - when 'Z' => - sl := 'Z'; - when 'W' => - sl := 'W'; - when 'L' => - sl := 'L'; - when 'H' => - sl := 'H'; - when '-' => - sl := '-'; - when others => - sl := 'X'; - end case; - return sl; - end to_std_logic; - - --- converts a string into std_logic_vector - -function to_std_logic_vector(s: string) return std_logic_vector is - variable slv: std_logic_vector(s'high-s'low downto 0); - variable k: integer; -begin - k := s'high-s'low; - for i in s'range loop - slv(k) := to_std_logic(s(i)); - k := k - 1; - end loop; - return slv; -end to_std_logic_vector; - - --- convert Hex string to 32-bit SLV - function strhex_to_slv(s : string) return std_logic_vector is - variable int : string(1 to s'length) := s; - variable ptr : integer range 0 to 32 := 0; - variable slv: std_logic_vector(31 downto 0) := (others=>'0'); - begin - for i in int'reverse_range loop - case int(i) is - when '0' => slv(ptr+3 downto ptr) := "0000"; ptr := ptr+4; - when '1' => slv(ptr+3 downto ptr) := "0001"; ptr := ptr+4; - when '2' => slv(ptr+3 downto ptr) := "0010"; ptr := ptr+4; - when '3' => slv(ptr+3 downto ptr) := "0011"; ptr := ptr+4; - when '4' => slv(ptr+3 downto ptr) := "0100"; ptr := ptr+4; - when '5' => slv(ptr+3 downto ptr) := "0101"; ptr := ptr+4; - when '6' => slv(ptr+3 downto ptr) := "0110"; ptr := ptr+4; - when '7' => slv(ptr+3 downto ptr) := "0111"; ptr := ptr+4; - when '8' => slv(ptr+3 downto ptr) := "1000"; ptr := ptr+4; - when '9' => slv(ptr+3 downto ptr) := "1001"; ptr := ptr+4; - when 'a'|'A' => slv(ptr+3 downto ptr) := "1010"; ptr := ptr+4; - when 'b'|'B' => slv(ptr+3 downto ptr) := "1011"; ptr := ptr+4; - when 'c'|'C' => slv(ptr+3 downto ptr) := "1100"; ptr := ptr+4; - when 'd'|'D' => slv(ptr+3 downto ptr) := "1101"; ptr := ptr+4; - when 'e'|'E' => slv(ptr+3 downto ptr) := "1110"; ptr := ptr+4; - when 'f'|'F' => slv(ptr+3 downto ptr) := "1111"; ptr := ptr+4; - when others => null; - end case; - end loop; - return slv; - end strhex_to_slv; ----------------- --- file I/O -- ----------------- - - - --- read variable length string from input file - -procedure str_read(file in_file: TEXT; - res_string: out string) is - - variable l: line; - variable c: character; - variable is_string: boolean; - - begin - - readline(in_file, l); - -- clear the contents of the result string - for i in res_string'range loop - res_string(i) := ' '; - end loop; - -- read all characters of the line, up to the length - -- of the results string - for i in res_string'range loop - read(l, c, is_string); - res_string(i) := c; - if not is_string then -- found end of line - exit; - end if; - end loop; - -end str_read; - - --- print string to a file -procedure print(file out_file: TEXT; - new_string: in string) is - - variable l: line; - - begin - - write(l, new_string); - writeline(out_file, l); - -end print; - - --- print character to a file and start new line -procedure print(file out_file: TEXT; - char: in character) is - - variable l: line; - - begin - - write(l, char); - writeline(out_file, l); - -end print; - - - --- appends contents of a string to a file until line feed occurs --- (LF is considered to be the end of the string) - -procedure str_write(file out_file: TEXT; - new_string: in string) is - begin - - for i in new_string'range loop - print(out_file, new_string(i)); - if new_string(i) = LF then -- end of string - exit; - end if; - end loop; - -end str_write; - - - - -end txt_util; - - - - diff --git a/src/txt_util.vhd b/src/txt_util.vhd new file mode 100644 index 0000000..3ccc65d --- /dev/null +++ b/src/txt_util.vhd @@ -0,0 +1,614 @@ +library ieee; +use ieee.std_logic_1164.all; +use std.textio.all; + + +package txt_util is + + -- prints a message to the screen + procedure print(text: string); + + -- prints the message when active + -- useful for debug switches + procedure print(active: boolean; text: string); + + -- converts std_logic into a character + function chr(sl: std_logic) return character; + + -- converts std_logic into a string (1 to 1) + function str(sl: std_logic) return string; + + -- converts std_logic_vector into a string (binary base) + function str(slv: std_logic_vector) return string; + + -- converts boolean into a string + function str(b: boolean) return string; + + -- converts an integer into a single character + -- (can also be used for hex conversion and other bases) + function chr(int: integer) return character; + + -- converts integer into string using specified base + function str(int: integer; base: integer) return string; + + -- converts integer to string, using base 10 + function str(int: integer) return string; + + -- convert std_logic_vector into a string in hex format + function hstr(slv: std_logic_vector) return string; + + + -- functions to manipulate strings + ----------------------------------- + + -- convert a character to upper case + function to_upper(c: character) return character; + + -- convert a character to lower case + function to_lower(c: character) return character; + + -- convert a string to upper case + function to_upper(s: string) return string; + + -- convert a string to lower case + function to_lower(s: string) return string; + + + + -- functions to convert strings into other formats + -------------------------------------------------- + + -- converts a character into std_logic + function to_std_logic(c: character) return std_logic; + + -- converts a string into std_logic_vector + function to_std_logic_vector(s: string) return std_logic_vector; + + -- convert Hex string to 32-bit into std_logic_vector + function strhex_to_slv(s : string) return std_logic_vector; + + + + -- file I/O + ----------- + + -- read variable length string from input file + procedure str_read(file in_file: TEXT; + res_string: out string); + + -- print string to a file and start new line + procedure print(file out_file: TEXT; + new_string: in string); + + -- print character to a file and start new line + procedure print(file out_file: TEXT; + char: in character); + +end txt_util; + + + + +package body txt_util is + + + + + -- prints text to the screen + + procedure print(text: string) is + variable msg_line: line; + begin + write(msg_line, text); + writeline(output, msg_line); + end print; + + + + + -- prints text to the screen when active + + procedure print(active: boolean; text: string) is + begin + if active then + print(text); + end if; + end print; + + + -- converts std_logic into a character + + function chr(sl: std_logic) return character is + variable c: character; + begin + case sl is + when 'U' => c:= 'U'; + when 'X' => c:= 'X'; + when '0' => c:= '0'; + when '1' => c:= '1'; + when 'Z' => c:= 'Z'; + when 'W' => c:= 'W'; + when 'L' => c:= 'L'; + when 'H' => c:= 'H'; + when '-' => c:= '-'; + end case; + return c; + end chr; + + + + -- converts std_logic into a string (1 to 1) + + function str(sl: std_logic) return string is + variable s: string(1 to 1); + begin + s(1) := chr(sl); + return s; + end str; + + + + -- converts std_logic_vector into a string (binary base) + -- (this also takes care of the fact that the range of + -- a string is natural while a std_logic_vector may + -- have an integer range) + + function str(slv: std_logic_vector) return string is + variable result : string (1 to slv'length); + variable r : integer; + begin + r := 1; + for i in slv'range loop + result(r) := chr(slv(i)); + r := r + 1; + end loop; + return result; + end str; + + + function str(b: boolean) return string is + + begin + if b then + return "true"; + else + return "false"; + end if; + end str; + + + -- converts an integer into a character + -- for 0 to 9 the obvious mapping is used, higher + -- values are mapped to the characters A-Z + -- (this is usefull for systems with base > 10) + -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) + + function chr(int: integer) return character is + variable c: character; + begin + 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 16 => c := 'G'; + when 17 => c := 'H'; + when 18 => c := 'I'; + when 19 => c := 'J'; + when 20 => c := 'K'; + when 21 => c := 'L'; + when 22 => c := 'M'; + when 23 => c := 'N'; + when 24 => c := 'O'; + when 25 => c := 'P'; + when 26 => c := 'Q'; + when 27 => c := 'R'; + when 28 => c := 'S'; + when 29 => c := 'T'; + when 30 => c := 'U'; + when 31 => c := 'V'; + when 32 => c := 'W'; + when 33 => c := 'X'; + when 34 => c := 'Y'; + when 35 => c := 'Z'; + when others => c := '?'; + end case; + return c; + end chr; + + + + -- convert integer to string using specified base + -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) + + function str(int: integer; base: integer) return string is + + variable temp: string(1 to 10); + variable num: integer; + variable abs_int: integer; + variable len: integer := 1; + variable power: integer := 1; + + begin + + -- bug fix for negative numbers + abs_int := abs(int); + + num := abs_int; + + while num >= base loop -- Determine how many + len := len + 1; -- characters required + num := num / base; -- to represent the + end loop ; -- number. + + for i in len downto 1 loop -- Convert the number to + temp(i) := chr(abs_int/power mod base); -- a string starting + power := power * base; -- with the right hand + end loop ; -- side. + + -- return result and add sign if required + if int < 0 then + return '-'& temp(1 to len); + else + return temp(1 to len); + end if; + + end str; + + + -- convert integer to string, using base 10 + function str(int: integer) return string is + + begin + + return str(int, 10) ; + + end str; + + + + -- converts a std_logic_vector into a hex string. + function hstr(slv: std_logic_vector) return string is + variable hexlen: integer; + variable longslv : std_logic_vector(67 downto 0) := (others => '0'); + variable hex : string(1 to 16); + variable fourbit : std_logic_vector(3 downto 0); + begin + hexlen := (slv'left+1)/4; + if (slv'left+1) mod 4 /= 0 then + hexlen := hexlen + 1; + end if; + longslv(slv'left downto 0) := slv; + for i in (hexlen -1) downto 0 loop + fourbit := longslv(((i*4)+3) downto (i*4)); + case fourbit is + when "0000" => hex(hexlen -I) := '0'; + when "0001" => hex(hexlen -I) := '1'; + when "0010" => hex(hexlen -I) := '2'; + when "0011" => hex(hexlen -I) := '3'; + when "0100" => hex(hexlen -I) := '4'; + when "0101" => hex(hexlen -I) := '5'; + when "0110" => hex(hexlen -I) := '6'; + when "0111" => hex(hexlen -I) := '7'; + when "1000" => hex(hexlen -I) := '8'; + when "1001" => hex(hexlen -I) := '9'; + when "1010" => hex(hexlen -I) := 'A'; + when "1011" => hex(hexlen -I) := 'B'; + when "1100" => hex(hexlen -I) := 'C'; + when "1101" => hex(hexlen -I) := 'D'; + when "1110" => hex(hexlen -I) := 'E'; + when "1111" => hex(hexlen -I) := 'F'; + when "ZZZZ" => hex(hexlen -I) := 'z'; + when "UUUU" => hex(hexlen -I) := 'u'; + when "XXXX" => hex(hexlen -I) := 'x'; + when others => hex(hexlen -I) := '?'; + end case; + end loop; + return hex(1 to hexlen); + end hstr; + + + + -- functions to manipulate strings + ----------------------------------- + + + -- convert a character to upper case + + function to_upper(c: character) return character is + + variable u: character; + + begin + + case c is + when 'a' => u := 'A'; + when 'b' => u := 'B'; + when 'c' => u := 'C'; + when 'd' => u := 'D'; + when 'e' => u := 'E'; + when 'f' => u := 'F'; + when 'g' => u := 'G'; + when 'h' => u := 'H'; + when 'i' => u := 'I'; + when 'j' => u := 'J'; + when 'k' => u := 'K'; + when 'l' => u := 'L'; + when 'm' => u := 'M'; + when 'n' => u := 'N'; + when 'o' => u := 'O'; + when 'p' => u := 'P'; + when 'q' => u := 'Q'; + when 'r' => u := 'R'; + when 's' => u := 'S'; + when 't' => u := 'T'; + when 'u' => u := 'U'; + when 'v' => u := 'V'; + when 'w' => u := 'W'; + when 'x' => u := 'X'; + when 'y' => u := 'Y'; + when 'z' => u := 'Z'; + when others => u := c; + end case; + + return u; + + end to_upper; + + + -- convert a character to lower case + + function to_lower(c: character) return character is + + variable l: character; + + begin + + case c is + when 'A' => l := 'a'; + when 'B' => l := 'b'; + when 'C' => l := 'c'; + when 'D' => l := 'd'; + when 'E' => l := 'e'; + when 'F' => l := 'f'; + when 'G' => l := 'g'; + when 'H' => l := 'h'; + when 'I' => l := 'i'; + when 'J' => l := 'j'; + when 'K' => l := 'k'; + when 'L' => l := 'l'; + when 'M' => l := 'm'; + when 'N' => l := 'n'; + when 'O' => l := 'o'; + when 'P' => l := 'p'; + when 'Q' => l := 'q'; + when 'R' => l := 'r'; + when 'S' => l := 's'; + when 'T' => l := 't'; + when 'U' => l := 'u'; + when 'V' => l := 'v'; + when 'W' => l := 'w'; + when 'X' => l := 'x'; + when 'Y' => l := 'y'; + when 'Z' => l := 'z'; + when others => l := c; + end case; + + return l; + + end to_lower; + + + + -- convert a string to upper case + + function to_upper(s: string) return string is + + variable uppercase: string (s'range); + + begin + + for i in s'range loop + uppercase(i):= to_upper(s(i)); + end loop; + return uppercase; + + end to_upper; + + + + -- convert a string to lower case + + function to_lower(s: string) return string is + + variable lowercase: string (s'range); + + begin + + for i in s'range loop + lowercase(i):= to_lower(s(i)); + end loop; + return lowercase; + + end to_lower; + + + +-- functions to convert strings into other types + + +-- converts a character into a std_logic + +function to_std_logic(c: character) return std_logic is + variable sl: std_logic; + begin + case c is + when 'U' => + sl := 'U'; + when 'X' => + sl := 'X'; + when '0' => + sl := '0'; + when '1' => + sl := '1'; + when 'Z' => + sl := 'Z'; + when 'W' => + sl := 'W'; + when 'L' => + sl := 'L'; + when 'H' => + sl := 'H'; + when '-' => + sl := '-'; + when others => + sl := 'X'; + end case; + return sl; + end to_std_logic; + + +-- converts a string into std_logic_vector + +function to_std_logic_vector(s: string) return std_logic_vector is + variable slv: std_logic_vector(s'high-s'low downto 0); + variable k: integer; +begin + k := s'high-s'low; + for i in s'range loop + slv(k) := to_std_logic(s(i)); + k := k - 1; + end loop; + return slv; +end to_std_logic_vector; + + +-- convert Hex string to 32-bit SLV + function strhex_to_slv(s : string) return std_logic_vector is + variable int : string(1 to s'length) := s; + variable ptr : integer range 0 to 32 := 0; + variable slv: std_logic_vector(31 downto 0) := (others=>'0'); + begin + for i in int'reverse_range loop + case int(i) is + when '0' => slv(ptr+3 downto ptr) := "0000"; ptr := ptr+4; + when '1' => slv(ptr+3 downto ptr) := "0001"; ptr := ptr+4; + when '2' => slv(ptr+3 downto ptr) := "0010"; ptr := ptr+4; + when '3' => slv(ptr+3 downto ptr) := "0011"; ptr := ptr+4; + when '4' => slv(ptr+3 downto ptr) := "0100"; ptr := ptr+4; + when '5' => slv(ptr+3 downto ptr) := "0101"; ptr := ptr+4; + when '6' => slv(ptr+3 downto ptr) := "0110"; ptr := ptr+4; + when '7' => slv(ptr+3 downto ptr) := "0111"; ptr := ptr+4; + when '8' => slv(ptr+3 downto ptr) := "1000"; ptr := ptr+4; + when '9' => slv(ptr+3 downto ptr) := "1001"; ptr := ptr+4; + when 'a'|'A' => slv(ptr+3 downto ptr) := "1010"; ptr := ptr+4; + when 'b'|'B' => slv(ptr+3 downto ptr) := "1011"; ptr := ptr+4; + when 'c'|'C' => slv(ptr+3 downto ptr) := "1100"; ptr := ptr+4; + when 'd'|'D' => slv(ptr+3 downto ptr) := "1101"; ptr := ptr+4; + when 'e'|'E' => slv(ptr+3 downto ptr) := "1110"; ptr := ptr+4; + when 'f'|'F' => slv(ptr+3 downto ptr) := "1111"; ptr := ptr+4; + when others => null; + end case; + end loop; + return slv; + end strhex_to_slv; +---------------- +-- file I/O -- +---------------- + + + +-- read variable length string from input file + +procedure str_read(file in_file: TEXT; + res_string: out string) is + + variable l: line; + variable c: character; + variable is_string: boolean; + + begin + + readline(in_file, l); + -- clear the contents of the result string + for i in res_string'range loop + res_string(i) := ' '; + end loop; + -- read all characters of the line, up to the length + -- of the results string + for i in res_string'range loop + read(l, c, is_string); + res_string(i) := c; + if not is_string then -- found end of line + exit; + end if; + end loop; + +end str_read; + + +-- print string to a file +procedure print(file out_file: TEXT; + new_string: in string) is + + variable l: line; + + begin + + write(l, new_string); + writeline(out_file, l); + +end print; + + +-- print character to a file and start new line +procedure print(file out_file: TEXT; + char: in character) is + + variable l: line; + + begin + + write(l, char); + writeline(out_file, l); + +end print; + + + +-- appends contents of a string to a file until line feed occurs +-- (LF is considered to be the end of the string) + +procedure str_write(file out_file: TEXT; + new_string: in string) is + begin + + for i in new_string'range loop + print(out_file, new_string(i)); + if new_string(i) = LF then -- end of string + exit; + end if; + end loop; + +end str_write; + + + + +end txt_util; + + + + diff --git a/src/vfpu b/src/vfpu new file mode 120000 index 0000000..218546c --- /dev/null +++ b/src/vfpu @@ -0,0 +1 @@ +../bin/vfpu \ No newline at end of file