library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity spi_leds_and_enc_v1_0_spi_fsm is generic ( data_width : integer := 32; spi_clkdiv : integer := 10 ); port ( reset_in : in std_logic; clk_in : in std_logic; clk_en : in std_logic; spi_clk : out std_logic; spi_cs : out std_logic; spi_mosi : out std_logic; spi_miso : in std_logic; tx_data : in std_logic_vector(data_width-1 downto 0); rx_data : out std_logic_vector(data_width-1 downto 0); trasfer_rq : in std_logic; transfer_ready : out std_logic ); end spi_leds_and_enc_v1_0_spi_fsm; architecture arch_imp of spi_leds_and_enc_v1_0_spi_fsm is signal shift_reg : std_logic_vector(data_width-1 downto 0); signal data_cnt : natural range 0 to data_width; signal div_cnt : natural range 0 to spi_clkdiv-1; signal clk_phase : std_logic; signal in_progress : std_logic; begin process is begin wait until rising_edge (clk_in); if ( reset_in = '1' ) then shift_reg <= (others => '0'); rx_data <= (others => '0'); div_cnt <= spi_clkdiv-1; transfer_ready <= '0'; data_cnt <= 0; spi_clk <= '1'; spi_cs <= '1'; spi_mosi <= '0'; clk_phase <= '0'; in_progress <= '0'; elsif (clk_en = '1') then transfer_ready <= '0'; if (div_cnt /= 0) then div_cnt <= div_cnt - 1; elsif clk_phase = '1' then div_cnt <= spi_clkdiv-1; clk_phase <= '0'; spi_clk <= '1'; if in_progress = '1' then shift_reg(data_width-1) <= spi_miso; end if; else clk_phase <= '1'; div_cnt <= spi_clkdiv-1; spi_clk <= '0'; if (data_cnt = 0) then spi_cs <= '1'; if in_progress = '1' then spi_cs <= '1'; rx_data <= shift_reg; end if; transfer_ready <= in_progress; in_progress <= '0'; if (trasfer_rq = '1') then shift_reg <= tx_data; data_cnt <= data_width; spi_mosi <= '0'; end if; else in_progress <= '1'; spi_cs <= '0'; spi_mosi <= shift_reg(0); shift_reg <= '0' & shift_reg(data_width-1 downto 1); data_cnt <= data_cnt - 1; end if; end if; end if; end process; end arch_imp;