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 SpiT is
|
|
end entity SpiT;
|
|
|
|
|
|
|
|
architecture sim of SpiT is
|
|
|
|
|
|
component SpiSlaveE is
|
|
generic (
|
|
G_DATA_WIDTH : positive := 8;
|
|
G_SPI_CPOL : natural range 0 to 1 := 0;
|
|
G_SPI_CPHA : natural range 0 to 1 := 0
|
|
);
|
|
port (
|
|
--+ system if
|
|
Reset_n_i : in std_logic;
|
|
Clk_i : in std_logic;
|
|
--+ SPI slave if
|
|
SpiSclk_i : in std_logic;
|
|
SpiSte_i : in std_logic;
|
|
SpiMosi_i : in std_logic;
|
|
SpiMiso_o : out std_logic;
|
|
--+ local VAI if
|
|
Data_i : in std_logic_vector(G_DATA_WIDTH-1 downto 0);
|
|
DataValid_i : in std_logic;
|
|
DataAccept_o : out std_logic;
|
|
Data_o : out std_logic_vector(G_DATA_WIDTH-1 downto 0);
|
|
DataValid_o : out std_logic;
|
|
DataAccept_i : in std_logic
|
|
);
|
|
end component SpiSlaveE;
|
|
|
|
|
|
constant C_PERIOD : time := 5 ns;
|
|
constant C_DATA_WIDTH : natural := 8;
|
|
|
|
signal s_done : boolean := false;
|
|
|
|
signal s_clk : std_logic := '0';
|
|
signal s_reset_n : std_logic := '0';
|
|
|
|
signal s_sclk : std_logic;
|
|
signal s_ste : std_logic;
|
|
signal s_mosi : std_logic;
|
|
signal s_miso : std_logic;
|
|
|
|
subtype t_spi_mode is natural range 0 to 3;
|
|
signal s_spi_mode : t_spi_mode;
|
|
|
|
|
|
begin
|
|
|
|
|
|
s_clk <= not(s_clk) after C_PERIOD when not(s_done) else '0';
|
|
s_reset_n <= '1' after 100 ns;
|
|
|
|
|
|
-- Unit test of spi master procedure, checks all combinations
|
|
-- of cpol & cpha against spi slave procedure
|
|
SpiMasterP : process is
|
|
variable v_slave_data : std_logic_vector(C_DATA_WIDTH-1 downto 0);
|
|
begin
|
|
s_sclk <= '1';
|
|
s_ste <= '1';
|
|
s_mosi <= '1';
|
|
s_spi_mode <= 0;
|
|
wait until s_reset_n = '1';
|
|
for mode in 0 to 3 loop
|
|
s_spi_mode <= mode;
|
|
for i in 0 to integer'(2**C_DATA_WIDTH-1) loop
|
|
spi_master (data_in => std_logic_vector(to_unsigned(i, C_DATA_WIDTH)),
|
|
data_out => v_slave_data,
|
|
sclk => s_sclk,
|
|
ste => s_ste,
|
|
mosi => s_mosi,
|
|
miso => s_miso,
|
|
cpol => mode / 2,
|
|
cpha => mode mod 2,
|
|
period => 1 us
|
|
);
|
|
assert_equal(v_slave_data, std_logic_vector(to_unsigned(i, C_DATA_WIDTH)));
|
|
end loop;
|
|
report "INFO: SPI mode " & integer'image(mode) & " test successfully";
|
|
end loop;
|
|
report "INFO: SpiSlaveE tests finished successfully";
|
|
s_done <= true;
|
|
wait;
|
|
end process SpiMasterP;
|
|
|
|
|
|
--+ spi ste demultiplexing
|
|
SpiSlavesG : for mode in t_spi_mode'low to t_spi_mode'high generate
|
|
|
|
|
|
subtype t_control_array is std_logic_vector(t_spi_mode'low to t_spi_mode'high);
|
|
signal s_spislave_ste : t_control_array;
|
|
|
|
type t_data_array is array (t_spi_mode'low to t_spi_mode'high) of std_logic_vector(C_DATA_WIDTH-1 downto 0);
|
|
|
|
signal s_din : t_data_array;
|
|
signal s_dout : t_data_array;
|
|
signal s_dout_valid : t_control_array;
|
|
signal s_dout_accept : t_control_array;
|
|
|
|
|
|
begin
|
|
|
|
|
|
s_din(mode) <= std_logic_vector(unsigned(s_dout(mode)) + 1);
|
|
|
|
s_spislave_ste(mode) <= s_ste when s_spi_mode = mode else '1';
|
|
|
|
i0_SpiSlaveE : SpiSlaveE
|
|
generic map (
|
|
G_DATA_WIDTH => 8,
|
|
G_SPI_CPOL => mode / 2,
|
|
G_SPI_CPHA => mode mod 2
|
|
)
|
|
port map (
|
|
--+ system if
|
|
Reset_n_i => s_reset_n,
|
|
Clk_i => s_clk,
|
|
--+ SPI slave if
|
|
SpiSclk_i => s_sclk,
|
|
SpiSte_i => s_spislave_ste(mode),
|
|
SpiMosi_i => s_mosi,
|
|
SpiMiso_o => s_miso,
|
|
--+ local VAI if
|
|
Data_i => s_din(mode),
|
|
DataValid_i => s_dout_valid(mode),
|
|
DataAccept_o => s_dout_accept(mode),
|
|
Data_o => s_dout(mode),
|
|
DataValid_o => s_dout_valid(mode),
|
|
DataAccept_i => s_dout_accept(mode)
|
|
);
|
|
|
|
|
|
end generate SpiSlavesG;
|
|
|
|
|
|
end architecture sim;
|