URL
https://opencores.org/ocsvn/uart16750/uart16750/trunk
Subversion Repositories uart16750
Compare Revisions
- This comparison shows the changes necessary to convert path
/uart16750/trunk/bench/vhdl
- from Rev 15 to Rev 17
- ↔ Reverse comparison
Rev 15 → Rev 17
/uart_transactor.vhd
0,0 → 1,211
-- UART transactor |
-- |
-- Author: Sebastian Witt |
-- Date: 03.02.2008 |
-- Version: 1.0 |
-- |
-- This code is free software; you can redistribute it and/or |
-- modify it under the terms of the GNU Lesser General Public |
-- License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- |
-- This code is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
-- Lesser General Public License for more details. |
-- |
-- You should have received a copy of the GNU Lesser General Public |
-- License along with this library; if not, write to the |
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
-- Boston, MA 02111-1307 USA |
-- |
|
LIBRARY IEEE; |
USE IEEE.std_logic_1164.all; |
|
use std.textio.all; |
use work.uart_package.all; |
use work.txt_util.all; |
|
entity uart_transactor is |
generic ( |
stim_file : string := "sim/uart_stim.dat"; -- Stimulus input file |
log_file : string := "sim/uart_log.txt" -- Log file |
); |
end uart_transactor; |
|
architecture tb of uart_transactor is |
file stimulus : TEXT open read_mode is stim_file; -- Open stimulus file for read |
file log : TEXT open write_mode is log_file; -- Open log file for write |
|
-- The DUT |
component uart_16750 is |
port ( |
CLK : in std_logic; -- Clock |
RST : in std_logic; -- Reset |
BAUDCE : in std_logic; -- Baudrate generator clock enable |
CS : in std_logic; -- Chip select |
WR : in std_logic; -- Write to UART |
RD : in std_logic; -- Read from UART |
A : in std_logic_vector(2 downto 0); -- Register select |
DIN : in std_logic_vector(7 downto 0); -- Data bus input |
DOUT : out std_logic_vector(7 downto 0); -- Data bus output |
DDIS : out std_logic; -- Driver disable |
INT : out std_logic; -- Interrupt output |
OUT1N : out std_logic; -- Output 1 |
OUT2N : out std_logic; -- Output 2 |
RCLK : in std_logic; -- Receiver clock (16x baudrate) |
BAUDOUTN : out std_logic; -- Baudrate generator output (16x baudrate) |
RTSN : out std_logic; -- RTS output |
DTRN : out std_logic; -- DTR output |
CTSN : in std_logic; -- CTS input |
DSRN : in std_logic; -- DSR input |
DCDN : in std_logic; -- DCD input |
RIN : in std_logic; -- RI input |
SIN : in std_logic; -- Receiver input |
SOUT : out std_logic -- Transmitter output |
); |
end component; |
component slib_clock_div is |
generic ( |
RATIO : integer := 18 -- Clock divider ratio |
); |
port ( |
CLK : in std_logic; -- Clock |
RST : in std_logic; -- Reset |
CE : in std_logic; -- Clock enable input |
Q : out std_logic -- New clock enable output |
); |
end component; |
|
|
-- DUT signals |
signal clk, rst : std_logic; |
signal uart_if : uart_interface; |
signal dout : std_logic_vector (7 downto 0); |
signal ddis, int : std_logic; |
signal baudce, rclk, baudoutn : std_logic; |
signal out1n, out2n, rtsn, dtrn, ctsn, dsrn, dcdn, rin, sin, sout : std_logic; |
|
constant cycle : time := 30 ns; |
|
begin |
-- Main clock |
CLOCK: process |
begin |
clk <= '0'; |
wait for cycle/2; |
clk <= '1'; |
wait for cycle/2; |
end process; |
|
-- Baudrate generator clock enable |
BGCE: slib_clock_div generic map (RATIO => 18) port map (clk, rst, '1', baudce); |
|
rclk <= baudoutn; |
|
-- Pull-up |
--uart_if.data <= (others => 'H'); |
|
-- UART interface bus tri-state buffer |
LPCBUF: process (ddis, dout) |
begin |
if (ddis = '0') then |
uart_if.data <= dout; |
else |
uart_if.data <= (others => 'Z'); |
end if; |
end process; |
|
DUT: uart_16750 port map ( CLK => CLK, |
RST => RST, |
BAUDCE => BAUDCE, |
CS => uart_if.cs, |
WR => uart_if.wr, |
RD => uart_if.rd, |
A => uart_if.a, |
DIN => uart_if.data, |
DOUT => dout, |
DDIS => ddis, |
INT => int, |
OUT1N => out1n, |
OUT2N => out2n, |
RCLK => rclk, |
BAUDOUTN=> baudoutn, |
RTSN => rtsn, |
DTRN => dtrn, |
CTSN => ctsn, |
DSRN => dsrn, |
DCDN => dcdn, |
RIN => rin, |
SIN => sin, |
SOUT => sout |
); |
|
-- Main transaction process |
TRANPROC: process |
variable s : string(1 to 100); |
variable address : std_logic_vector(2 downto 0); |
variable data : std_logic_vector(7 downto 0); |
variable data2 : std_logic_vector(7 downto 0); |
begin |
-- Default values |
rst <= '1'; |
ctsn <= '1'; |
dsrn <= '1'; |
dcdn <= '1'; |
rin <= '1'; |
sin <= '1'; |
uart_if.a <= (others => '0'); |
uart_if.data <= (others => 'Z'); |
uart_if.cs <= '0'; |
uart_if.rd <= '0'; |
uart_if.wr <= '0'; |
|
wait until falling_edge(clk); |
|
-- Get commands from stimulus file |
while not endfile(stimulus) loop |
str_read(stimulus, s); -- Read line into string |
|
if (s(1 to 4) = "#SET") then -- Set values |
-- Format: RSTN CTSN DSRN DCDN RIN |
rst <= to_std_logic(s(6)); |
--CTSN <= to_std_logic(s(8)); |
--DSRN <= to_std_logic(s(10)); |
--DCDN <= to_std_logic(s(12)); |
--RIN <= to_std_logic(s(14)); |
elsif (s(1 to 5) = "#WAIT") then -- Wait n cycles |
wait for integer'value(s(7 to 12))*cycle; |
elsif (s(1 to 3) = "#RD") then -- Read from UART and compare |
address := to_std_logic_vector(s(5 to 7)); |
data := to_std_logic_vector(s(9 to 16)); |
uart_read (uart_if, address, data2, log); |
if (not compare(data, data2)) then |
print (log, time'image(now) & ": " & "Failed: Expected 0x" & hstr(data) & " got 0x" & hstr(data2)); |
end if; |
elsif (s(1 to 3) = "#WR") then -- Write to LPC |
address := to_std_logic_vector(s(5 to 7)); |
data := to_std_logic_vector(s(9 to 16)); |
uart_write (uart_if, address, data, log); |
elsif (s(1 to 4) = "#LOG") then -- Write message to log |
print (log, time'image(now) & ": " & s(6 to 80)); |
elsif (s(1 to 4) = "#CUO") then -- Check UART outputs INT OUT1N OUT2N RTSN DTRN |
data2(4 downto 0) := to_std_logic_vector(s(6 to 10)); |
data(4 downto 0) := INT & OUT1N & OUT2N & RTSN & DTRN; |
if (not compare(data(3 downto 0), data2(3 downto 0))) then |
print (log, time'image(now) & ": " & "UART outputs failed: Expected " & |
str(data2(4 downto 0)) & " got " & str(data(4 downto 0))); |
else |
print (log, time'image(now) & ": " & "UART outputs: " & str(data(4 downto 0))); |
end if; |
else |
print ("Unknown command: " & s); |
end if; |
end loop; |
|
wait; |
end process; |
|
end tb; |
|
/uart_package.vhd
0,0 → 1,136
-- |
-- Package for UART testing |
-- |
-- Author: Sebastian Witt |
-- Version: 1.0 |
-- Date: 31.01.2008 |
-- |
-- This code is free software; you can redistribute it and/or |
-- modify it under the terms of the GNU Lesser General Public |
-- License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- |
-- This code is distributed in the hope that it will be useful, |
-- but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
-- Lesser General Public License for more details. |
-- |
-- You should have received a copy of the GNU Lesser General Public |
-- License along with this library; if not, write to the |
-- Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
-- Boston, MA 02111-1307 USA |
-- |
|
LIBRARY IEEE; |
USE IEEE.std_logic_1164.all; |
use std.textio.all; |
|
use work.txt_util.all; |
|
|
package uart_package is |
constant CYCLE : time := 30 ns; |
|
-- UART register addresses |
constant A_RBR : std_logic_vector(2 downto 0) := "000"; |
constant A_DLL : std_logic_vector(2 downto 0) := "000"; |
constant A_THR : std_logic_vector(2 downto 0) := "000"; |
constant A_DLM : std_logic_vector(2 downto 0) := "001"; |
constant A_IER : std_logic_vector(2 downto 0) := "001"; |
constant A_IIR : std_logic_vector(2 downto 0) := "010"; |
constant A_FCR : std_logic_vector(2 downto 0) := "010"; |
constant A_LCR : std_logic_vector(2 downto 0) := "011"; |
constant A_MCR : std_logic_vector(2 downto 0) := "100"; |
constant A_LSR : std_logic_vector(2 downto 0) := "101"; |
constant A_MSR : std_logic_vector(2 downto 0) := "110"; |
constant A_SCR : std_logic_vector(2 downto 0) := "111"; |
|
-- UART input interface |
type uart_interface is record |
CS : std_logic; |
WR : std_logic; |
RD : std_logic; |
A : std_logic_vector (2 downto 0); |
DATA : std_logic_vector (7 downto 0); |
end record; |
|
-- Write to UART |
procedure uart_write (signal ui : inout uart_interface; |
addr : in std_logic_vector (2 downto 0); |
data : in std_logic_vector (7 downto 0); |
file log : TEXT |
); |
|
-- Read from UART |
procedure uart_read (signal ui : inout uart_interface; |
addr : in std_logic_vector(2 downto 0); |
ret : out std_logic_vector(7 downto 0); |
file log : TEXT |
); |
|
-- Compare two std_logig_vectors (handles don't-care) |
function compare (d1 : std_logic_vector; d2 : std_logic_vector) return boolean; |
|
end uart_package; |
|
package body uart_package is |
-- Write to UART |
procedure uart_write (signal ui : inout uart_interface; |
addr : in std_logic_vector (2 downto 0); |
data : in std_logic_vector (7 downto 0); |
file log : TEXT |
) is |
begin |
print (log, "UART write: 0x" & hstr(addr) & " : 0x" & hstr(data)); |
wait for cycle; |
assert ui.DATA = "ZZZZZZZZ" report "Data bus not tri-state" severity warning; |
ui.A <= addr; |
ui.DATA <= data; |
ui.CS <= '1'; |
wait for cycle; |
ui.WR <= '1'; |
wait for cycle; |
ui.WR <= '0'; |
ui.CS <= '0'; |
ui.DATA <= (others => 'Z'); |
end uart_write; |
|
-- Read from UART |
procedure uart_read (signal ui : inout uart_interface; |
addr : in std_logic_vector(2 downto 0); |
ret : out std_logic_vector(7 downto 0); |
file log : TEXT |
) is |
variable data : std_logic_vector(7 downto 0); |
begin |
wait for cycle; |
assert ui.DATA = "ZZZZZZZZ" report "Data bus not tri-state" severity warning; |
ui.A <= addr; |
ui.CS <= '1'; |
wait for cycle; |
ui.RD <= '1'; |
wait for cycle; |
data := ui.DATA; |
wait for cycle; |
ui.RD <= '0'; |
ui.CS <= '0'; |
print (log, "UART read: 0x" & hstr(addr) & " : 0x" & hstr(data)); |
ret := data; |
end uart_read; |
|
-- Compare two std_logig_vectors (handles don't-care) |
function compare (d1 : std_logic_vector; d2 : std_logic_vector) return boolean is |
variable i : natural; |
begin |
for i in d1'range loop |
if (not (d1(i)='-' or d2(i)='-')) then |
if (d1(i)/=d2(i)) then |
return false; |
end if; |
end if; |
end loop; |
return true; |
end compare; |
|
end uart_package; |
|
/slib_testbench.vhd
0,0 → 1,202
-- Testbench for slib_clock_div |
LIBRARY IEEE; |
USE IEEE.std_logic_1164.all; |
USE IEEE.numeric_std.all; |
USE IEEE.std_logic_unsigned.all; |
|
entity tb_slib_clock_div is |
end tb_slib_clock_div; |
|
architecture tb of tb_slib_clock_div is |
component slib_clock_div is |
generic ( |
RATIO : integer := 16 -- Clock divider ratio |
); |
port ( |
CLK : in std_logic; -- Clock |
RST : in std_logic; -- Reset |
CE : in std_logic; -- Clock enable input |
Q : out std_logic -- New clock enable output |
); |
end component; |
|
-- Signals |
signal clk, rst, q : std_logic; |
constant cycle : time := 30 ns; |
begin |
-- Clock process |
process |
begin |
clk <= '0'; |
wait for cycle/2; |
clk <= '1'; |
wait for cycle/2; |
end process; |
|
DUT: slib_clock_div generic map ( |
RATIO => 16 |
) port map ( |
clk, rst, '1', q |
); |
|
-- Test process |
DUTPROC: process |
begin |
rst <= '1'; |
wait until falling_edge(CLK); wait for 3*cycle; |
rst <= '0'; |
|
wait for 500*cycle; |
end process; |
|
end tb; |
|
-- Testbench for slib_mv_filter |
LIBRARY IEEE; |
USE IEEE.std_logic_1164.all; |
USE IEEE.numeric_std.all; |
USE IEEE.std_logic_unsigned.all; |
|
entity tb_slib_mv_filter is |
end tb_slib_mv_filter; |
|
architecture tb of tb_slib_mv_filter is |
component slib_mv_filter is |
generic ( |
WIDTH : natural := 4; |
THRESHOLD : natural := 10 |
); |
port ( |
CLK : in std_logic; -- Clock |
RST : in std_logic; -- Reset |
SAMPLE : in std_logic; -- Clock enable for sample process |
CLEAR : in std_logic; -- Reset process |
D : in std_logic; -- Signal input |
Q : out std_logic -- Signal D was at least THRESHOLD samples high |
); |
end component; |
|
-- Signals |
signal clk, rst, sample, clear, d, q : std_logic; |
constant cycle : time := 30 ns; |
constant scycle : time := 3000 ns; |
begin |
-- Clock process |
process |
begin |
clk <= '0'; |
wait for cycle/2; |
clk <= '1'; |
wait for cycle/2; |
end process; |
-- Sample clock process |
process |
begin |
sample <= '0'; |
wait for scycle/2; |
sample <= '1'; |
wait for cycle; |
end process; |
|
DUT: slib_mv_filter generic map ( |
WIDTH => 4, |
THRESHOLD => 10 |
) port map ( |
clk, rst, sample, clear, d, q |
); |
|
-- Test process |
DUTPROC: process |
begin |
rst <= '1'; d <= '0'; clear <= '0'; |
wait until falling_edge(CLK); wait for 3*cycle; |
rst <= '0'; |
wait for 2*scycle; |
d <= '1'; |
wait for 4*scycle; |
d <= '0'; |
wait for 2*scycle; |
d <= '1'; |
wait for scycle; |
d <= '1'; |
wait for 5*scycle; |
clear <= '1'; |
wait for cycle; |
clear <= '0'; |
wait for 10*scycle; |
d <= '0'; |
|
|
wait for 500*scycle; |
end process; |
|
|
end tb; |
|
-- Testbench for slib_shift_reg |
LIBRARY IEEE; |
USE IEEE.std_logic_1164.all; |
USE IEEE.numeric_std.all; |
USE IEEE.std_logic_unsigned.all; |
|
entity tb_slib_shift_reg is |
end tb_slib_shift_reg; |
|
architecture tb of tb_slib_shift_reg is |
-- Serial shift register |
component slib_shift_reg is |
generic ( |
WIDTH : natural := 16 -- Register width |
); |
port ( |
CLK : in std_logic; -- Clock |
RST : in std_logic; -- Reset |
ENABLE : in std_logic; -- Enable shift operation |
LOAD : in std_logic; -- Load shift register |
DIR : in std_logic; -- Shift direction |
MSB_IN : in std_logic; -- MSB in |
LSB_IN : in std_logic; -- LSB in |
DIN : in std_logic_vector(WIDTH-1 downto 0); -- Load shift register input |
DOUT : out std_logic_vector(WIDTH-1 downto 0) -- Shift register output |
); |
end component; |
-- Signals |
signal clk, rst, enable, load, dir, msb_in, lsb_in : std_logic; |
signal din, dout : std_logic_vector(15 downto 0); |
constant cycle : time := 30 ns; |
begin |
-- Clock process |
process |
begin |
CLK <= '0'; |
wait for cycle/2; |
CLK <= '1'; |
wait for cycle/2; |
end process; |
|
DUT: slib_shift_reg port map ( |
clk, rst , enable, load, dir, |
msb_in, lsb_in, din, dout); |
|
-- Test process |
DUTPROC: process |
begin |
rst <= '1'; enable <= '0'; load <= '0'; dir <= '0'; msb_in <= '0'; |
lsb_in <= '0'; din <= x"abcd"; |
wait until rising_edge(CLK); wait for 3*cycle; |
rst <= '0'; |
wait for cycle; load <= '1'; wait for cycle; load <= '0'; |
wait for cycle; enable <= '1'; |
wait for 4*cycle; dir <= '1'; |
wait for 3*cycle; msb_in <= '1'; |
wait for 2*cycle; dir <= '0'; lsb_in <= '1'; |
wait for 10*cycle; rst <= '0'; wait for cycle; rst <= '1'; |
lsb_in <= '0'; |
|
din <= x"0001"; load <= '1'; wait for cycle; load <= '0'; |
|
wait for 500*cycle; |
end process; |
|
end tb; |
|
/txt_util.vhd
0,0 → 1,611
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 std_logic_vector to integer |
function to_integer (a: std_logic_vector) return integer; |
|
-- 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 std_logic_vector to integer |
|
function to_integer (a: std_logic_vector) return integer is |
variable y: integer := 0; |
begin |
y := 0; |
if (a'length < 32) then |
for i in a'length-1 downto 0 loop |
y := y * 2; |
if (a(i) = '1') or (a(i) = 'H') then |
y := y + 1; |
elsif (a(i) = 'U') or (a(i) = 'X') or (a(i) = 'Z') or |
(a(i) = 'W') or (a(i) = '-') then |
y := y + 0; |
end if; |
end loop; |
else |
assert false |
report "Function = to_integer." & |
"The std_logic_vector input to this function MUST be less than 32 bits." |
severity error; |
end if; |
return y; -- y returns 0 if std_logic_vector is > 31 bits |
end to_integer; |
|
|
|
|
---------------- |
-- 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); |
if not is_string then -- found end of line |
exit; |
end if; |
res_string(i) := c; |
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; |
|
|
|
|