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.

242 lines
7.2 KiB

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