- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
-
-
-
- entity RaspiFpgaCtrlE is
- port (
- --+ System if
- Rst_n_i : in std_logic;
- Clk_i : in std_logic;
- --+ local register if
- LocalWen_o : out std_logic;
- LocalRen_o : out std_logic;
- LocalAdress_o : out std_logic_vector(7 downto 0);
- LocalData_i : in std_logic_vector(7 downto 0);
- LocalData_o : out std_logic_vector(7 downto 0);
- LocalAck_i : in std_logic;
- LocalError_i : in std_logic;
- --+ EFB if
- EfbSpiIrq_i : in std_logic
- );
- end entity RaspiFpgaCtrlE;
-
-
-
- architecture rtl of RaspiFpgaCtrlE is
-
-
- --+ EFB SPI slave register addresses
- constant C_SPICR0 : std_logic_vector(7 downto 0) := x"54"; --* ctrl reg 0
- constant C_SPICR1 : std_logic_vector(7 downto 0) := x"55"; --* ctrl reg 1
- constant C_SPICR2 : std_logic_vector(7 downto 0) := x"56"; --* ctrl reg 2
- constant C_SPIBR : std_logic_vector(7 downto 0) := x"57"; --* clk pre-scale
- constant C_SPICSR : std_logic_vector(7 downto 0) := x"58"; --* master chip select
- constant C_SPITXDR : std_logic_vector(7 downto 0) := x"59"; --* transmit data
- constant C_SPIISR : std_logic_vector(7 downto 0) := x"5A"; --* status
- constant C_SPIRXDR : std_logic_vector(7 downto 0) := x"5B"; --* receive data
- constant C_SPIIRQ : std_logic_vector(7 downto 0) := x"5C"; --* interrupt request
- constant C_SPIIRQEN : std_logic_vector(7 downto 0) := x"5D"; --* interrupt request enable
-
-
- type t_cmdctrl_fsm is (IDLE, INIT_SET, INIT_ACK, TXDR_SET, TXDR_ACK, INT_WAIT,
- RXDR_SET, RXDR_ACK);
-
- signal s_cmdctrl_fsm : t_cmdctrl_fsm;
-
- type t_wb_master is record
- adr : std_logic_vector(7 downto 0);
- data : std_logic_vector(7 downto 0);
- end record t_wb_master;
-
- type t_wb_master_array is array (natural range <>) of t_wb_master;
-
- constant C_INIT : t_wb_master_array := ((C_SPICR1, x"80"),
- (C_SPICR2, x"00"),
- (C_SPIIRQEN, x"08"));
-
- signal s_init_cnt : natural range 0 to C_INIT'length;
-
- type t_byte_array is array (natural range <>) of std_logic_vector(7 downto 0);
- signal s_register : t_byte_array(0 to 127);
-
- signal s_register_we : std_logic;
- signal s_register_address : natural range s_register'range;
-
- type t_spi_frame is (NOP, HEADER, WRITE_DATA, READ_DATA);
- signal s_spi_frame : t_spi_frame;
-
-
- begin
-
-
- --+ FSM to write/request data from the wishbone master
- --+ Combinatoral outputs
- LocalWen_o <= '1' when s_cmdctrl_fsm = INIT_SET or s_cmdctrl_fsm = TXDR_SET else '0';
- LocalRen_o <= '1' when s_cmdctrl_fsm = RXDR_SET else '0';
- LocalAdress_o <= C_INIT(s_init_cnt).adr when s_cmdctrl_fsm = INIT_SET else
- C_SPITXDR when s_cmdctrl_fsm = TXDR_SET else
- C_SPIRXDR when s_cmdctrl_fsm = RXDR_SET else
- (others => '0');
- LocalData_o <= C_INIT(s_init_cnt).data when s_cmdctrl_fsm = INIT_SET else
- s_register(s_register_address) when s_cmdctrl_fsm = TXDR_SET and s_spi_frame = READ_DATA else
- x"FF";
-
-
- CmdCtrlP : process (Clk_i) is
- begin
- if (rising_edge(Clk_i)) then
- if (Rst_n_i = '0') then
- s_cmdctrl_fsm <= IDLE;
- else
- FsmC : case s_cmdctrl_fsm is
-
- when IDLE =>
- s_cmdctrl_fsm <= INIT_SET;
-
- when INIT_SET =>
- s_cmdctrl_fsm <= INIT_ACK;
-
- when INIT_ACK =>
- if (LocalAck_i = '1') then
- if (s_init_cnt = C_INIT'length) then
- s_cmdctrl_fsm <= TXDR_SET;
- else
- s_cmdctrl_fsm <= INIT_SET;
- end if;
- end if;
-
- when TXDR_SET =>
- s_cmdctrl_fsm <= TXDR_ACK;
-
- when TXDR_ACK =>
- if (LocalAck_i = '1') then
- s_cmdctrl_fsm <= INT_WAIT;
- end if;
-
- when INT_WAIT =>
- if (EfbSpiIrq_i = '1') then
- s_cmdctrl_fsm <= RXDR_SET;
- end if;
-
- when RXDR_SET =>
- s_cmdctrl_fsm <= RXDR_ACK;
-
- when RXDR_ACK =>
- if (LocalAck_i = '1') then
- s_cmdctrl_fsm <= TXDR_SET;
- end if;
-
- when others =>
- null;
-
- end case FsmC;
- end if;
- end if;
- end process CmdCtrlP;
-
-
- CmdRegisterP : process (Clk_i) is
- begin
- if (rising_edge(Clk_i)) then
- if (Rst_n_i = '0') then
- s_init_cnt <= 0;
- s_spi_frame <= NOP;
- s_register_address <= 0;
- else
-
- case s_cmdctrl_fsm is
- when IDLE =>
- s_init_cnt <= 0;
- s_spi_frame <= NOP;
- s_register_address <= 0;
-
- when INIT_SET =>
- s_init_cnt <= s_init_cnt + 1;
-
- when RXDR_ACK =>
- if (LocalAck_i = '1') then
- if (s_spi_frame = HEADER) then
- s_register_address <= to_integer(unsigned(LocalData_i(6 downto 0)));
- if (LocalData_i(7) = '0') then
- s_spi_frame <= READ_DATA;
- else
- s_spi_frame <= WRITE_DATA;
- end if;
- else
- if (LocalData_i = x"00") then
- s_spi_frame <= HEADER;
- end if;
- end if;
- end if;
-
- when others =>
- null;
-
- end case;
-
- end if;
- end if;
- end process CmdRegisterP;
-
-
- s_register_we <= LocalAck_i when s_cmdctrl_fsm = RXDR_ACK and s_spi_frame = WRITE_DATA else '0';
-
-
- RegisterFileP : process (Clk_i) is
- begin
- if (rising_edge(Clk_i)) then
- if (Rst_n_i = '0') then
- s_register <= (others => (others => '0'));
- else
- if (s_register_we = '1') then
- s_register(s_register_address) <= LocalData_i;
- end if;
- end if;
- end if;
- end process RegisterFileP;
-
-
- end architecture rtl;
|