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.

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