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.

247 lines
7.7 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. --+ RNG if
  20. RngStart_o : out std_logic;
  21. RngWait_o : out std_logic_vector(7 downto 0);
  22. RngRun_o : out std_logic_vector(7 downto 0);
  23. RngDataValid_i : in std_logic;
  24. RngData_i : in std_logic_vector(7 downto 0)
  25. );
  26. end entity RaspiFpgaCtrlE;
  27. architecture rtl of RaspiFpgaCtrlE is
  28. --+ EFB SPI slave register addresses
  29. constant C_SPICR0 : std_logic_vector(7 downto 0) := x"54"; --* ctrl reg 0
  30. constant C_SPICR1 : std_logic_vector(7 downto 0) := x"55"; --* ctrl reg 1
  31. constant C_SPICR2 : std_logic_vector(7 downto 0) := x"56"; --* ctrl reg 2
  32. constant C_SPIBR : std_logic_vector(7 downto 0) := x"57"; --* clk pre-scale
  33. constant C_SPICSR : std_logic_vector(7 downto 0) := x"58"; --* master chip select
  34. constant C_SPITXDR : std_logic_vector(7 downto 0) := x"59"; --* transmit data
  35. constant C_SPIISR : std_logic_vector(7 downto 0) := x"5A"; --* status
  36. constant C_SPIRXDR : std_logic_vector(7 downto 0) := x"5B"; --* receive data
  37. constant C_SPIIRQ : std_logic_vector(7 downto 0) := x"5C"; --* interrupt request
  38. constant C_SPIIRQEN : std_logic_vector(7 downto 0) := x"5D"; --* interrupt request enable
  39. --+ Register file addresses
  40. constant C_REG_RNGSTATUS : natural := 0;
  41. constant C_REG_RNGWAIT : natural := 1;
  42. constant C_REG_RNGRUN : natural := 2;
  43. constant C_REG_RNGDATA : natural := 3;
  44. type t_cmdctrl_fsm is (IDLE, INIT_SET, INIT_ACK, TXDR_SET, TXDR_ACK, INT_WAIT,
  45. RXDR_SET, RXDR_ACK, INT_CLEAR_SET, INT_CLEAR_ACK);
  46. signal s_cmdctrl_fsm : t_cmdctrl_fsm;
  47. type t_wb_master is record
  48. adr : std_logic_vector(7 downto 0);
  49. data : std_logic_vector(7 downto 0);
  50. end record t_wb_master;
  51. type t_wb_master_array is array (natural range <>) of t_wb_master;
  52. constant C_INIT : t_wb_master_array := ((C_SPICR1, x"80"),
  53. (C_SPICR2, x"00"),
  54. (C_SPIIRQEN, x"08"));
  55. signal s_init_cnt : natural range 0 to C_INIT'length;
  56. type t_byte_array is array (natural range <>) of std_logic_vector(7 downto 0);
  57. signal s_register : t_byte_array(0 to 127);
  58. signal s_register_we : std_logic;
  59. signal s_register_address : natural range s_register'range;
  60. type t_spi_frame is (NOP, HEADER, WRITE_DATA, READ_DATA);
  61. signal s_spi_frame : t_spi_frame;
  62. begin
  63. --+ FSM to write/request data from the wishbone master
  64. --+ Combinatoral outputs
  65. LocalWen_o <= '1' when s_cmdctrl_fsm = INIT_SET or s_cmdctrl_fsm = TXDR_SET or s_cmdctrl_fsm = INT_CLEAR_SET else '0';
  66. LocalRen_o <= '1' when s_cmdctrl_fsm = RXDR_SET else '0';
  67. LocalAdress_o <= C_INIT(s_init_cnt).adr when s_cmdctrl_fsm = INIT_SET else
  68. C_SPITXDR when s_cmdctrl_fsm = TXDR_SET else
  69. C_SPIRXDR when s_cmdctrl_fsm = RXDR_SET else
  70. C_SPIIRQ when s_cmdctrl_fsm = INT_CLEAR_SET else
  71. (others => '0');
  72. LocalData_o <= C_INIT(s_init_cnt).data when s_cmdctrl_fsm = INIT_SET else
  73. s_register(s_register_address) when s_cmdctrl_fsm = TXDR_SET and s_spi_frame = READ_DATA else
  74. x"FF";
  75. --+ FSM to write/request data from the wishbone master
  76. --+ State logic/register
  77. CmdCtrlP : process (Clk_i) is
  78. begin
  79. if (rising_edge(Clk_i)) then
  80. if (Rst_n_i = '0') then
  81. s_cmdctrl_fsm <= IDLE;
  82. else
  83. FsmC : case s_cmdctrl_fsm is
  84. when IDLE =>
  85. s_cmdctrl_fsm <= INIT_SET;
  86. when INIT_SET =>
  87. s_cmdctrl_fsm <= INIT_ACK;
  88. when INIT_ACK =>
  89. if (LocalAck_i = '1') then
  90. if (s_init_cnt = C_INIT'length) then
  91. s_cmdctrl_fsm <= TXDR_SET;
  92. else
  93. s_cmdctrl_fsm <= INIT_SET;
  94. end if;
  95. end if;
  96. when TXDR_SET =>
  97. s_cmdctrl_fsm <= TXDR_ACK;
  98. when TXDR_ACK =>
  99. if (LocalAck_i = '1') then
  100. s_cmdctrl_fsm <= INT_WAIT;
  101. end if;
  102. when INT_WAIT =>
  103. if (EfbSpiIrq_i = '1') then
  104. s_cmdctrl_fsm <= RXDR_SET;
  105. end if;
  106. when RXDR_SET =>
  107. s_cmdctrl_fsm <= RXDR_ACK;
  108. when RXDR_ACK =>
  109. if (LocalAck_i = '1') then
  110. s_cmdctrl_fsm <= INT_CLEAR_SET;
  111. end if;
  112. when INT_CLEAR_SET =>
  113. s_cmdctrl_fsm <= INT_CLEAR_ACK;
  114. when INT_CLEAR_ACK =>
  115. if (LocalAck_i = '1') then
  116. s_cmdctrl_fsm <= TXDR_SET;
  117. end if;
  118. when others =>
  119. null;
  120. end case FsmC;
  121. end if;
  122. end if;
  123. end process CmdCtrlP;
  124. --+ FSM to write/request data from the wishbone master
  125. --+ Registered outputs
  126. CmdRegisterP : process (Clk_i) is
  127. begin
  128. if (rising_edge(Clk_i)) then
  129. if (Rst_n_i = '0') then
  130. s_init_cnt <= 0;
  131. s_spi_frame <= NOP;
  132. s_register_address <= 0;
  133. else
  134. case s_cmdctrl_fsm is
  135. when IDLE =>
  136. s_init_cnt <= 0;
  137. s_spi_frame <= NOP;
  138. s_register_address <= 0;
  139. when INIT_SET =>
  140. s_init_cnt <= s_init_cnt + 1;
  141. when RXDR_ACK =>
  142. if (LocalAck_i = '1') then
  143. if (s_spi_frame = HEADER) then
  144. s_register_address <= to_integer(unsigned(LocalData_i(6 downto 0)));
  145. if (LocalData_i(7) = '0') then
  146. s_spi_frame <= READ_DATA;
  147. else
  148. s_spi_frame <= WRITE_DATA;
  149. end if;
  150. else
  151. if (LocalData_i = x"00") then
  152. s_spi_frame <= HEADER;
  153. else
  154. s_spi_frame <= NOP;
  155. end if;
  156. end if;
  157. end if;
  158. when others =>
  159. null;
  160. end case;
  161. end if;
  162. end if;
  163. end process CmdRegisterP;
  164. --+ Register bank write enable
  165. s_register_we <= LocalAck_i when s_cmdctrl_fsm = RXDR_ACK and s_spi_frame = WRITE_DATA else '0';
  166. --+ Register bank 127x8
  167. RegisterFileP : process (Clk_i) is
  168. begin
  169. if (rising_edge(Clk_i)) then
  170. if (Rst_n_i = '0') then
  171. s_register <= (others => (others => '0'));
  172. s_register(C_REG_RNGWAIT) <= x"0F";
  173. s_register(C_REG_RNGRUN) <= x"0F";
  174. else
  175. s_register(C_REG_RNGSTATUS)(0) <= '0'; -- reset RNG start after each clock cycle
  176. if (s_register_we = '1') then
  177. s_register(s_register_address) <= LocalData_i;
  178. end if;
  179. -- register RNG data
  180. if (RngDataValid_i = '1') then
  181. s_register(C_REG_RNGSTATUS)(1) <= '1';
  182. s_register(C_REG_RNGDATA) <= RngData_i;
  183. end if;
  184. -- clear RNG done flag when RNG was started
  185. if (s_register(C_REG_RNGSTATUS)(0) = '1') then
  186. s_register(C_REG_RNGSTATUS)(1) <= '0';
  187. end if;
  188. end if;
  189. end if;
  190. end process RegisterFileP;
  191. --+ RNG control outputs
  192. RngStart_o <= s_register(C_REG_RNGSTATUS)(0);
  193. RngWait_o <= s_register(C_REG_RNGWAIT);
  194. RngRun_o <= s_register(C_REG_RNGRUN);
  195. end architecture rtl;