Library of reusable VHDL components
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.

258 lines
7.9 KiB

  1. -- Copyright (c) 2014 - 2022 by Torsten Meissner
  2. --
  3. -- Licensed under the Apache License, Version 2.0 (the "License");
  4. -- you may not use this file except in compliance with the License.
  5. -- You may obtain a copy of the License at
  6. --
  7. -- https://www.apache.org/licenses/LICENSE-2.0
  8. --
  9. -- Unless required by applicable law or agreed to in writing, software
  10. -- distributed under the License is distributed on an "AS IS" BASIS,
  11. -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. -- See the License for the specific language governing permissions and
  13. -- limitations under the License.
  14. library ieee;
  15. use ieee.std_logic_1164.all;
  16. use ieee.numeric_std.all;
  17. entity WishBoneMasterE is
  18. generic (
  19. Coverage : boolean := false;
  20. Formal : boolean := false;
  21. Simulation : boolean := false;
  22. AddressWidth : natural := 8;
  23. DataWidth : natural := 8
  24. );
  25. port (
  26. --+ wishbone system if
  27. WbRst_i : in std_logic;
  28. WbClk_i : in std_logic;
  29. --+ wishbone outputs
  30. WbCyc_o : out std_logic;
  31. WbStb_o : out std_logic;
  32. WbWe_o : out std_logic;
  33. WbAdr_o : out std_logic_vector(AddressWidth-1 downto 0);
  34. WbDat_o : out std_logic_vector(DataWidth-1 downto 0);
  35. --+ wishbone inputs
  36. WbDat_i : in std_logic_vector(DataWidth-1 downto 0);
  37. WbAck_i : in std_logic;
  38. WbErr_i : in std_logic;
  39. --+ local register if
  40. LocalWen_i : in std_logic;
  41. LocalRen_i : in std_logic;
  42. LocalAdress_i : in std_logic_vector(AddressWidth-1 downto 0);
  43. LocalData_i : in std_logic_vector(DataWidth-1 downto 0);
  44. LocalData_o : out std_logic_vector(DataWidth-1 downto 0);
  45. LocalAck_o : out std_logic;
  46. LocalError_o : out std_logic
  47. );
  48. end entity WishBoneMasterE;
  49. architecture rtl of WishBoneMasterE is
  50. type t_wb_master_fsm is (IDLE, ADDRESS, DATA);
  51. signal s_wb_master_fsm : t_wb_master_fsm;
  52. signal s_wb_wen : std_logic;
  53. begin
  54. --+ Wishbone master control state machine
  55. WbMasterStatesP : process (WbClk_i) is
  56. begin
  57. if (rising_edge(WbClk_i)) then
  58. if (WbRst_i = '1') then
  59. s_wb_master_fsm <= IDLE;
  60. else
  61. WbReadC : case s_wb_master_fsm is
  62. when IDLE =>
  63. if ((LocalWen_i xor LocalRen_i) = '1') then
  64. s_wb_master_fsm <= ADDRESS;
  65. end if;
  66. when ADDRESS =>
  67. if (WbAck_i = '1' or WbErr_i = '1') then
  68. s_wb_master_fsm <= IDLE;
  69. else
  70. s_wb_master_fsm <= DATA;
  71. end if;
  72. when DATA =>
  73. if (WbErr_i = '1' or WbAck_i = '1') then
  74. s_wb_master_fsm <= IDLE;
  75. end if;
  76. when others =>
  77. s_wb_master_fsm <= IDLE;
  78. end case;
  79. end if;
  80. end if;
  81. end process WbMasterStatesP;
  82. --+ combinatoral local register if outputs
  83. LocalData_o <= WbDat_i when s_wb_master_fsm = DATA else (others => '0');
  84. LocalError_o <= WbErr_i when s_wb_master_fsm /= IDLE else '0';
  85. LocalAck_o <= WbAck_i when (s_wb_master_fsm = ADDRESS or s_wb_master_fsm = DATA) and WbErr_i = '0' else '0';
  86. --+ combinatoral wishbone if outputs
  87. WbStb_o <= '1' when s_wb_master_fsm /= IDLE else '0';
  88. WbCyc_o <= '1' when s_wb_master_fsm /= IDLE else '0';
  89. WbWe_o <= s_wb_wen when s_wb_master_fsm /= IDLE else '0';
  90. --+ registered wishbone if outputs
  91. OutRegsP : process (WbClk_i) is
  92. begin
  93. if (rising_edge(WbClk_i)) then
  94. if (WbRst_i = '1') then
  95. WbAdr_o <= (others => '0');
  96. WbDat_o <= (others => '0');
  97. s_wb_wen <= '0';
  98. else
  99. if (s_wb_master_fsm = IDLE) then
  100. if ((LocalWen_i xor LocalRen_i) = '1') then
  101. WbAdr_o <= LocalAdress_i;
  102. s_wb_wen <= LocalWen_i;
  103. end if;
  104. if (LocalWen_i = '1') then
  105. WbDat_o <= LocalData_i;
  106. end if;
  107. end if;
  108. end if;
  109. end if;
  110. end process OutRegsP;
  111. default clock is rising_edge(WbClk_i);
  112. FormalG : if Formal generate
  113. -- Glue logic
  114. signal s_local_data : std_logic_vector(DataWidth-1 downto 0);
  115. signal s_local_address : std_logic_vector(AddressWidth-1 downto 0);
  116. begin
  117. process is
  118. begin
  119. wait until rising_edge(WbClk_i);
  120. if (s_wb_master_fsm = IDLE) then
  121. if (LocalWen_i = '1') then
  122. s_local_data <= LocalData_i;
  123. s_local_address <= LocalAdress_i;
  124. end if;
  125. if (LocalRen_i = '1') then
  126. s_local_address <= LocalAdress_i;
  127. end if;
  128. end if;
  129. end process;
  130. restrict {WbRst_i = '1'; WbRst_i = '0'[+]}[*1];
  131. RESET : assert always
  132. WbRst_i -> next
  133. WbCyc_o = '0' and WbStb_o = '0' and WbWe_o = '0' and
  134. to_integer(unsigned(WbAdr_o)) = 0 and to_integer(unsigned(WbDat_o)) = 0 and
  135. LocalAck_o = '0' and LocalError_o = '0' and to_integer(unsigned(LocalData_o)) = 0
  136. report "WB master: Reset error";
  137. WB_WRITE : assert always
  138. ((not WbCyc_o and not WbStb_o and LocalWen_i and not LocalRen_i) ->
  139. next (WbCyc_o and WbStb_o and WbWe_o)) abort WbRst_i
  140. report "WB master: Write error";
  141. WB_READ : assert always
  142. ((not WbCyc_o and not WbStb_o and LocalRen_i and not LocalWen_i) ->
  143. next (WbCyc_o and WbStb_o and not WbWe_o)) abort WbRst_i
  144. report "WB master: Read error";
  145. assert never LocalError_o and LocalAck_o;
  146. assert always WbStb_o = WbCyc_o;
  147. assert always
  148. not WbRst_i and WbCyc_o and not WbAck_i and not WbErr_i ->
  149. next (WbCyc_o until (WbAck_i or WbErr_i)) abort WbRst_i;
  150. assert always WbCyc_o and WbAck_i -> next not WbCyc_o;
  151. assert always WbWe_o and WbAck_i -> next not WbWe_o;
  152. assert always WbWe_o -> WbCyc_o;
  153. assert always WbWe_o -> WbDat_o = s_local_data abort WbRst_i;
  154. assert always WbWe_o -> WbAdr_o = s_local_address abort WbRst_i;
  155. assert always WbCyc_o and not WbWe_o -> WbAdr_o = s_local_address abort WbRst_i;
  156. end generate FormalG;
  157. CoverageG : if Coverage generate
  158. restrict {WbRst_i = '1'; WbRst_i = '0'[+]}[*1];
  159. COVER_LOCAL_WRITE : cover {s_wb_master_fsm = IDLE and LocalWen_i = '1' and
  160. LocalRen_i = '0' and WbRst_i = '0'}
  161. report "WB master: Local write";
  162. COVER_LOCAL_READ : cover {s_wb_master_fsm = IDLE and LocalRen_i = '1' and
  163. LocalWen_i = '0' and WbRst_i = '0'}
  164. report "WB master: Local read";
  165. COVER_LOCAL_WRITE_READ : cover {s_wb_master_fsm = IDLE and LocalWen_i = '1' and
  166. LocalRen_i = '1' and WbRst_i = '0'}
  167. report "WB master: Local write & read";
  168. end generate CoverageG;
  169. SimulationG : if Simulation generate
  170. -- assert directives
  171. RESET : assert always
  172. WbRst_i ->
  173. WbCyc_o = '0' and WbStb_o = '0' and WbWe_o = '0' and
  174. to_integer(unsigned(WbAdr_o)) = 0 and to_integer(unsigned(WbDat_o)) = 0 and
  175. LocalAck_o = '0' and LocalError_o = '0' and to_integer(unsigned(LocalData_o)) = 0
  176. report "WB master: Reset error";
  177. WB_WRITE : assert always
  178. ((not(WbCyc_o) and not(WbStb_o) and LocalWen_i and not (LocalRen_i)) ->
  179. next (WbCyc_o = '1' and WbStb_o = '1' and WbWe_o = '1')) abort WbRst_i
  180. report "WB master: Write error";
  181. WB_READ : assert always
  182. ((not(WbCyc_o) and not(WbStb_o) and LocalRen_i and not(LocalWen_i)) ->
  183. next (WbCyc_o = '1' and WbStb_o = '1' and WbWe_o = '0')) abort WbRst_i
  184. report "WB master: Read error";
  185. -- cover directives
  186. COVER_LOCAL_WRITE : cover {s_wb_master_fsm = IDLE and LocalWen_i = '1' and
  187. LocalRen_i = '0' and WbRst_i = '0'}
  188. report "WB master: Local write";
  189. COVER_LOCAL_READ : cover {s_wb_master_fsm = IDLE and LocalRen_i = '1' and
  190. LocalWen_i = '0' and WbRst_i = '0'}
  191. report "WB master: Local read";
  192. COVER_LOCAL_WRITE_READ : cover {s_wb_master_fsm = IDLE and LocalWen_i = '1' and
  193. LocalRen_i = '1' and WbRst_i = '0'}
  194. report "WB master: Local write & read";
  195. end generate SimulationG;
  196. end architecture rtl;