---------------------------------------------------- --! @file --! @brief Simulation utilities ---------------------------------------------------- use std.textio.all; --! @brief Simulation utility package --! @detail provides type definitions for frequency and baudrate, procedures for --! frequency/baudrate calculations and RS232-transceiver procedures package SimUtils is -- ### Clocks ### --! @brief Frequency unit type (Hz, kHz, MHz, GHz) type frequency is range 1 to 1e9 units Hz; kHz = 1000 Hz; MHz = 1000 kHz; GHz = 1000 MHz; end units frequency; --! @brief calculate period from frequency --! @param f frequency --! @return time value with period function period ( f : frequency ) return time; --! @brief calculate half period from frequency --! @param f frequency --! @return time value with half period function halfperiod ( f : frequency ) return time; --! @brief clock generation module component ClockSource is generic ( freq : Frequency ); port ( clk : out bit; enable : in boolean ); end component; -- ### Rs232 Transmitter/Receiver ### --! @brief Baudrate unit type (Baud, kBaud, MBaud) type baudrate is range 2400 to 1e6 units Baud; kBaud = 1000 Baud; MBaud = 1000 kBaud; end units baudrate; --! @brief "Byte" type (8-Bit bit_vector) subtype byte is bit_vector(7 downto 0); --! @brief calculate duration of one symbol from baudrate --! @param b baudrate --! @return time value for symbol duration function symboltime( b : baudrate ) return time; --! @brief transmit RS232 byte --! @detail setup: 8 data bits, 1 stop bit, no parity --! @param b baudrate of transmission --! @param data data byte to send --! @param tx signal used for sending procedure sendRs232 ( b : in baudrate; data : in byte; signal tx : out bit ); --! @brief receive RS232 byte --! @detail setup: 8 data bits, 1 stop bit, no parity --! @param b baudrate expected for incoming transmission --! @param data target variable for received byte --! @param rx signal used for sampling procedure recvRs232 ( b : in baudrate; data : out byte; signal rx : in bit ); -- ### Text I/O ### procedure print_byte ( variable v : in byte ); end package SimUtils; package body SimUtils is -- Clocks function period ( f : frequency) return time is begin return 1.0/real(frequency'pos(f)) * 1 sec; end function period; function halfperiod ( f : frequency) return time is begin return 1.0/real(frequency'pos(f))/2.0 * 1 sec; end function halfperiod; -- RS232 function symboltime( b : baudrate ) return time is begin return 1.0/real(baudrate'pos(b)) * 1 sec; end function symboltime; procedure sendRs232 ( b : in baudrate; data : in byte; signal tx : out bit ) is variable t : time; variable l : line; begin t := symboltime(b); -- start bit tx <= '0'; wait for t; -- data bits for i in 0 to 7 loop tx <= data(i); wait for t; end loop; -- stop bit tx <= '1'; wait for t; end procedure sendRs232; procedure recvRs232 ( b : in baudrate; data : out byte; signal rx : in bit ) is variable t : time; begin t := symboltime(b); -- start bit if rx /= '1' then wait until rx = '1'; end if; wait until rx = '0'; wait for 1.5*t; -- data bits for i in 0 to 7 loop data(i) := rx; wait for t; end loop; -- stop bit assert rx = '1'; end procedure recvRs232; procedure print_byte ( variable v : in byte ) is variable l : line; begin write(l, v); writeline(output, l); end procedure print_byte; end package body SimUtils; -- ### ClockSource component ### use work.SimUtils.all; --! @brief clock generation module entity ClockSource is generic ( freq : Frequency --! clock frequency ); port ( clk : out bit; --! clock output enable : in boolean --! clock will stop forever when "False" ); end entity ClockSource; --! @brief clock generation module architecture architecture a of ClockSource is begin process begin if not enable then wait; end if; clk <= '1'; wait for halfperiod(freq); clk <= '0'; wait for halfperiod(freq); end process; end architecture a;