diff --git a/sim/SimP.vhd b/sim/SimP.vhd new file mode 100644 index 0000000..29a5ae7 --- /dev/null +++ b/sim/SimP.vhd @@ -0,0 +1,86 @@ +library ieee; + use ieee.std_logic_1164.all; + --use ieee.numeric_std.all; + +library libvhdl; + use libvhdl.AssertP.all; + + + +package SimP is + + + procedure wait_cycles (signal clk : in std_logic; n : in natural); + + procedure spi_master (data_in : in std_logic_vector; data_out : out std_logic_vector; + signal sclk : inout std_logic; signal ste : out std_logic; + signal mosi : out std_logic; signal miso : in std_logic; + cpol : in natural range 0 to 1; period : in time); + + procedure spi_slave (data_in : in std_logic_vector; data_out : out std_logic_vector; + signal sclk : in std_logic; signal ste : in std_logic; + signal mosi : in std_logic; signal miso : out std_logic; + cpol : in natural range 0 to 1); + + +end package SimP; + + + +package body SimP is + + + -- wait for n rising egdes on clk + procedure wait_cycles (signal clk : in std_logic; n : in natural) is + begin + for i in 1 to n loop + wait until rising_edge(clk); + end loop; + end procedure wait_cycles; + + + procedure spi_master ( data_in : in std_logic_vector; data_out : out std_logic_vector; + signal sclk : inout std_logic; signal ste : out std_logic; + signal mosi : out std_logic; signal miso : in std_logic; + cpol : in natural range 0 to 1; period : in time) is + begin + assert_equal(data_in'length, data_out'length, "data_in & data_out must have same length!"); + sclk <= std_logic'val(cpol+2); + ste <= '0'; + mosi <= '1'; + wait for period; + for i in data_in'range loop + sclk <= not(sclk); + mosi <= data_in(i); + wait for period; + sclk <= not(sclk); + data_out(i) := miso; + wait for period; + end loop; + ste <= '1'; + mosi <= '1'; + wait for period; + end procedure spi_master; + + + procedure spi_slave ( data_in : in std_logic_vector; data_out : out std_logic_vector; + signal sclk : in std_logic; signal ste : in std_logic; + signal mosi : in std_logic; signal miso : out std_logic; + cpol : in natural range 0 to 1) is + variable v_cpol : std_logic := std_logic'val(cpol+2); + begin + assert_equal(data_in'length, data_out'length, "data_in & data_out must have same length!"); + miso <= 'Z'; + wait until ste = '0'; + for i in data_in'range loop + wait until sclk'event and sclk = not(v_cpol); + miso <= data_in(i); + wait until sclk'event and sclk = v_cpol; + data_out(i) := mosi; + end loop; + wait until ste = '1'; + miso <= 'Z'; + end procedure spi_slave; + + +end package body SimP; \ No newline at end of file diff --git a/test/Makefile b/test/Makefile index 1d85e7f..beb2ba6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,7 +2,7 @@ SIM_SRC = ../sim VHD_STD = 02 .PHONY: sim -sim: queuet stringt +sim: queuet stringt simt queuet : QueueT.vhd $(SIM_SRC)/QueueP.vhd $(SIM_SRC)/StringP.vhd $(SIM_SRC)/AssertP.vhd ghdl -a --std=$(VHD_STD) --work=libvhdl $(SIM_SRC)/StringP.vhd $(SIM_SRC)/AssertP.vhd $(SIM_SRC)/QueueP.vhd @@ -16,9 +16,16 @@ stringt : StringT.vhd $(SIM_SRC)/StringP.vhd $(SIM_SRC)/AssertP.vhd ghdl -e --std=$(VHD_STD) StringT ghdl -r --std=$(VHD_STD) StringT +simt : SimT.vhd $(SIM_SRC)/StringP.vhd $(SIM_SRC)/AssertP.vhd $(SIM_SRC)/SimP.vhd + ghdl -a --std=$(VHD_STD) --work=libvhdl $(SIM_SRC)/StringP.vhd $(SIM_SRC)/AssertP.vhd $(SIM_SRC)/SimP.vhd + ghdl -a --std=$(VHD_STD) SimT.vhd + ghdl -e --std=$(VHD_STD) SimT + ghdl -r --std=$(VHD_STD) SimT + .PHONY: clean clean: rm -f *.o rm -f *.cf rm -f queuet rm -f stringt + rm -f simt diff --git a/test/SimT.vhd b/test/SimT.vhd new file mode 100644 index 0000000..a30580d --- /dev/null +++ b/test/SimT.vhd @@ -0,0 +1,89 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library libvhdl; + use libvhdl.StringP.all; + use libvhdl.AssertP.all; + use libvhdl.SimP.all; + + + +entity SimT is +end entity SimT; + + + +architecture sim of SimT is + + + constant C_PERIOD : time := 5 ns; + + signal s_done : boolean := false; + + signal s_clk : std_logic := '0'; + + signal s_sclk : std_logic; + signal s_ste : std_logic; + signal s_mosi : std_logic; + signal s_miso : std_logic; + + +begin + + + s_clk <= not(s_clk) after C_PERIOD when not(s_done) else '0'; + + + SimTestP : process is + variable v_time : time; + begin + wait until s_clk = '1'; + v_time := now; + wait_cycles(s_clk, 10); + assert (now - v_time) = C_PERIOD * 20 + severity failure; + s_done <= true; + wait; + end process SimTestP; + + + SpiMasterP : process is + variable v_slave_data : std_logic_vector(7 downto 0); + begin + for i in 0 to 255 loop + spi_master (data_in => std_logic_vector(to_unsigned(i, 8)), + data_out => v_slave_data, + sclk => s_sclk, + ste => s_ste, + mosi => s_mosi, + miso => s_miso, + cpol => 1, + period => 1 us + ); + assert_equal(v_slave_data, std_logic_vector(to_unsigned(i, 8))); + end loop; + wait; + end process SpiMasterP; + + + SpiSlaveP : process is + variable v_master_data : std_logic_vector(7 downto 0); + begin + for i in 0 to 255 loop + spi_slave (data_in => std_logic_vector(to_unsigned(i, 8)), + data_out => v_master_data, + sclk => s_sclk, + ste => s_ste, + mosi => s_mosi, + miso => s_miso, + cpol => 1 + ); + assert_equal(v_master_data, std_logic_vector(to_unsigned(i, 8))); + end loop; + wait; + report "INFO: SimP tests finished successfully"; + end process SpiSlaveP; + + +end architecture sim;