Various projects using Raspberry Pi
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
5.9 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. entity RaspiFpgaCtrlE is
  5. port (
  6. --+ System if
  7. Rst_n_i : in std_logic;
  8. Clk_i : in std_logic;
  9. --+ local register if
  10. LocalWen_o : out std_logic;
  11. LocalRen_o : out std_logic;
  12. LocalAdress_o : out std_logic_vector(7 downto 0);
  13. LocalData_i : in std_logic_vector(7 downto 0);
  14. LocalData_o : out std_logic_vector(7 downto 0);
  15. LocalAck_i : in std_logic;
  16. LocalError_i : in std_logic;
  17. --+ EFB if
  18. EfbSpiIrq_i : in std_logic
  19. );
  20. end entity RaspiFpgaCtrlE;
  21. architecture rtl of RaspiFpgaCtrlE is
  22. --+ EFB SPI slave register addresses
  23. constant C_SPICR0 : std_logic_vector(7 downto 0) := x"54"; --* ctrl reg 0
  24. constant C_SPICR1 : std_logic_vector(7 downto 0) := x"55"; --* ctrl reg 1
  25. constant C_SPICR2 : std_logic_vector(7 downto 0) := x"56"; --* ctrl reg 2
  26. constant C_SPIBR : std_logic_vector(7 downto 0) := x"57"; --* clk pre-scale
  27. constant C_SPICSR : std_logic_vector(7 downto 0) := x"58"; --* master chip select
  28. constant C_SPITXDR : std_logic_vector(7 downto 0) := x"59"; --* transmit data
  29. constant C_SPIISR : std_logic_vector(7 downto 0) := x"5A"; --* status
  30. constant C_SPIRXDR : std_logic_vector(7 downto 0) := x"5B"; --* receive data
  31. constant C_SPIIRQ : std_logic_vector(7 downto 0) := x"5C"; --* interrupt request
  32. constant C_SPIIRQEN : std_logic_vector(7 downto 0) := x"5D"; --* interrupt request enable
  33. type t_cmdctrl_fsm is (IDLE, INIT_SET, INIT_ACK, TXDR_SET, TXDR_ACK, INT_WAIT,
  34. RXDR_SET, RXDR_ACK);
  35. signal s_cmdctrl_fsm : t_cmdctrl_fsm;
  36. type t_wb_master is record
  37. adr : std_logic_vector(7 downto 0);
  38. data : std_logic_vector(7 downto 0);
  39. end record t_wb_master;
  40. type t_wb_master_array is array (natural range <>) of t_wb_master;
  41. constant C_INIT : t_wb_master_array := ((C_SPICR1, x"80"),
  42. (C_SPICR2, x"00"),
  43. (C_SPIIRQEN, x"08"));
  44. signal s_init_cnt : natural range 0 to C_INIT'length;
  45. type t_byte_array is array (natural range <>) of std_logic_vector(7 downto 0);
  46. signal s_register : t_byte_array(0 to 127);
  47. signal s_register_we : std_logic;
  48. signal s_register_address : natural range s_register'range;
  49. type t_spi_frame is (NOP, HEADER, WRITE_DATA, READ_DATA);
  50. signal s_spi_frame : t_spi_frame;
  51. begin
  52. --+ FSM to write/request data from the wishbone master
  53. --+ Combinatoral outputs
  54. LocalWen_o <= '1' when s_cmdctrl_fsm = INIT_SET or s_cmdctrl_fsm = TXDR_SET else '0';
  55. LocalRen_o <= '1' when s_cmdctrl_fsm = RXDR_SET else '0';
  56. LocalAdress_o <= C_INIT(s_init_cnt).adr when s_cmdctrl_fsm = INIT_SET else
  57. C_SPITXDR when s_cmdctrl_fsm = TXDR_SET else
  58. C_SPIRXDR when s_cmdctrl_fsm = RXDR_SET else
  59. (others => '0');
  60. LocalData_o <= C_INIT(s_init_cnt).data when s_cmdctrl_fsm = INIT_SET else
  61. s_register(s_register_address) when s_cmdctrl_fsm = TXDR_SET and s_spi_frame = READ_DATA else
  62. x"FF";
  63. CmdCtrlP : process (Clk_i) is
  64. begin
  65. if (rising_edge(Clk_i)) then
  66. if (Rst_n_i = '0') then
  67. s_cmdctrl_fsm <= IDLE;
  68. else
  69. FsmC : case s_cmdctrl_fsm is
  70. when IDLE =>
  71. s_cmdctrl_fsm <= INIT_SET;
  72. when INIT_SET =>
  73. s_cmdctrl_fsm <= INIT_ACK;
  74. when INIT_ACK =>
  75. if (LocalAck_i = '1') then
  76. if (s_init_cnt = C_INIT'length) then
  77. s_cmdctrl_fsm <= TXDR_SET;
  78. else
  79. s_cmdctrl_fsm <= INIT_SET;
  80. end if;
  81. end if;
  82. when TXDR_SET =>
  83. s_cmdctrl_fsm <= TXDR_ACK;
  84. when TXDR_ACK =>
  85. if (LocalAck_i = '1') then
  86. s_cmdctrl_fsm <= INT_WAIT;
  87. end if;
  88. when INT_WAIT =>
  89. if (EfbSpiIrq_i = '1') then
  90. s_cmdctrl_fsm <= RXDR_SET;
  91. end if;
  92. when RXDR_SET =>
  93. s_cmdctrl_fsm <= RXDR_ACK;
  94. when RXDR_ACK =>
  95. if (LocalAck_i = '1') then
  96. s_cmdctrl_fsm <= TXDR_SET;
  97. end if;
  98. when others =>
  99. null;
  100. end case FsmC;
  101. end if;
  102. end if;
  103. end process CmdCtrlP;
  104. CmdRegisterP : process (Clk_i) is
  105. begin
  106. if (rising_edge(Clk_i)) then
  107. if (Rst_n_i = '0') then
  108. s_init_cnt <= 0;
  109. s_spi_frame <= NOP;
  110. s_register_address <= 0;
  111. else
  112. case s_cmdctrl_fsm is
  113. when IDLE =>
  114. s_init_cnt <= 0;
  115. s_spi_frame <= NOP;
  116. s_register_address <= 0;
  117. when INIT_SET =>
  118. s_init_cnt <= s_init_cnt + 1;
  119. when RXDR_ACK =>
  120. if (LocalAck_i = '1') then
  121. if (s_spi_frame = HEADER) then
  122. s_register_address <= to_integer(unsigned(LocalData_i(6 downto 0)));
  123. if (LocalData_i(7) = '0') then
  124. s_spi_frame <= READ_DATA;
  125. else
  126. s_spi_frame <= WRITE_DATA;
  127. end if;
  128. else
  129. if (LocalData_i = x"00") then
  130. s_spi_frame <= HEADER;
  131. end if;
  132. end if;
  133. end if;
  134. when others =>
  135. null;
  136. end case;
  137. end if;
  138. end if;
  139. end process CmdRegisterP;
  140. s_register_we <= LocalAck_i when s_cmdctrl_fsm = RXDR_ACK and s_spi_frame = WRITE_DATA else '0';
  141. RegisterFileP : process (Clk_i) is
  142. begin
  143. if (rising_edge(Clk_i)) then
  144. if (Rst_n_i = '0') then
  145. s_register <= (others => (others => '0'));
  146. else
  147. if (s_register_we = '1') then
  148. s_register(s_register_address) <= LocalData_i;
  149. end if;
  150. end if;
  151. end if;
  152. end process RegisterFileP;
  153. end architecture rtl;