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.

209 lines
6.0 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 := true;
  7. Formal : boolean := true;
  8. AddressWidth : natural := 8;
  9. DataWidth : natural := 8
  10. );
  11. port (
  12. --+ wishbone system if
  13. WbRst_i : in std_logic;
  14. WbClk_i : in std_logic;
  15. --+ wishbone outputs
  16. WbCyc_o : out std_logic;
  17. WbStb_o : out std_logic;
  18. WbWe_o : out std_logic;
  19. WbAdr_o : out std_logic_vector(AddressWidth-1 downto 0);
  20. WbDat_o : out std_logic_vector(DataWidth-1 downto 0);
  21. --+ wishbone inputs
  22. WbDat_i : in std_logic_vector(DataWidth-1 downto 0);
  23. WbAck_i : in std_logic;
  24. WbErr_i : in std_logic;
  25. --+ local register if
  26. LocalWen_i : in std_logic;
  27. LocalRen_i : in std_logic;
  28. LocalAdress_i : in std_logic_vector(AddressWidth-1 downto 0);
  29. LocalData_i : in std_logic_vector(DataWidth-1 downto 0);
  30. LocalData_o : out std_logic_vector(DataWidth-1 downto 0);
  31. LocalAck_o : out std_logic;
  32. LocalError_o : out std_logic
  33. );
  34. end entity WishBoneMasterE;
  35. architecture rtl of WishBoneMasterE is
  36. type t_wb_master_fsm is (IDLE, ADDRESS, DATA);
  37. signal s_wb_master_fsm : t_wb_master_fsm;
  38. signal s_wb_wen : std_logic;
  39. begin
  40. --+ Wishbone master control state machine
  41. WbMasterStatesP : process (WbClk_i) is
  42. begin
  43. if (rising_edge(WbClk_i)) then
  44. if (WbRst_i = '1') then
  45. s_wb_master_fsm <= IDLE;
  46. else
  47. WbReadC : case s_wb_master_fsm is
  48. when IDLE =>
  49. if ((LocalWen_i xor LocalRen_i) = '1') then
  50. s_wb_master_fsm <= ADDRESS;
  51. end if;
  52. when ADDRESS =>
  53. if (WbAck_i = '1' or WbErr_i = '1') then
  54. s_wb_master_fsm <= IDLE;
  55. else
  56. s_wb_master_fsm <= DATA;
  57. end if;
  58. when DATA =>
  59. if (WbErr_i = '1' or WbAck_i = '1') then
  60. s_wb_master_fsm <= IDLE;
  61. end if;
  62. when others =>
  63. s_wb_master_fsm <= IDLE;
  64. end case;
  65. end if;
  66. end if;
  67. end process WbMasterStatesP;
  68. --+ combinatoral local register if outputs
  69. LocalData_o <= WbDat_i when s_wb_master_fsm = DATA else (others => '0');
  70. LocalError_o <= WbErr_i when s_wb_master_fsm /= IDLE else '0';
  71. LocalAck_o <= WbAck_i when (s_wb_master_fsm = ADDRESS or s_wb_master_fsm = DATA) and WbErr_i = '0' else '0';
  72. --+ combinatoral wishbone if outputs
  73. WbStb_o <= '1' when s_wb_master_fsm /= IDLE else '0';
  74. WbCyc_o <= '1' when s_wb_master_fsm /= IDLE else '0';
  75. WbWe_o <= s_wb_wen when s_wb_master_fsm /= IDLE else '0';
  76. --+ registered wishbone if outputs
  77. OutRegsP : process (WbClk_i) is
  78. begin
  79. if (rising_edge(WbClk_i)) then
  80. if (WbRst_i = '1') then
  81. WbAdr_o <= (others => '0');
  82. WbDat_o <= (others => '0');
  83. s_wb_wen <= '0';
  84. else
  85. if (s_wb_master_fsm = IDLE) then
  86. if ((LocalWen_i xor LocalRen_i) = '1') then
  87. WbAdr_o <= LocalAdress_i;
  88. s_wb_wen <= LocalWen_i;
  89. end if;
  90. if (LocalWen_i = '1') then
  91. WbDat_o <= LocalData_i;
  92. end if;
  93. end if;
  94. end if;
  95. end if;
  96. end process OutRegsP;
  97. FormalG : if Formal generate
  98. -- Glue logic
  99. signal s_local_data : std_logic_vector(DataWidth-1 downto 0);
  100. signal s_local_address : std_logic_vector(AddressWidth-1 downto 0);
  101. begin
  102. process is
  103. begin
  104. wait until rising_edge(WbClk_i);
  105. if (s_wb_master_fsm = IDLE) then
  106. if (LocalWen_i = '1') then
  107. s_local_data <= LocalData_i;
  108. s_local_address <= LocalAdress_i;
  109. end if;
  110. if (LocalRen_i = '1') then
  111. s_local_address <= LocalAdress_i;
  112. end if;
  113. end if;
  114. end process;
  115. default clock is rising_edge(WbClk_i);
  116. restrict {WbRst_i = '1'; WbRst_i = '0'[+]}[*1];
  117. RESET : assert always
  118. WbRst_i -> next
  119. WbCyc_o = '0' and WbStb_o = '0' and WbWe_o = '0' and
  120. to_integer(unsigned(WbAdr_o)) = 0 and to_integer(unsigned(WbDat_o)) = 0 and
  121. LocalAck_o = '0' and LocalError_o = '0' and to_integer(unsigned(LocalData_o)) = 0
  122. report "WB master: Reset error";
  123. WB_WRITE : assert always
  124. ((not WbCyc_o and not WbStb_o and LocalWen_i and not LocalRen_i) ->
  125. next (WbCyc_o and WbStb_o and WbWe_o)) abort WbRst_i
  126. report "WB master: Write error";
  127. WB_READ : assert always
  128. ((not WbCyc_o and not WbStb_o and LocalRen_i and not LocalWen_i) ->
  129. next (WbCyc_o and WbStb_o and not WbWe_o)) abort WbRst_i
  130. report "WB master: Read error";
  131. assert never LocalError_o and LocalAck_o;
  132. assert always WbStb_o = WbCyc_o;
  133. assert always
  134. not WbRst_i and WbCyc_o and not WbAck_i and not WbErr_i ->
  135. next (WbCyc_o until (WbAck_i or WbErr_i)) abort WbRst_i;
  136. assert always WbCyc_o and WbAck_i -> next not WbCyc_o;
  137. assert always WbWe_o and WbAck_i -> next not WbWe_o;
  138. assert always WbWe_o -> WbCyc_o;
  139. assert always WbWe_o -> WbDat_o = s_local_data abort WbRst_i;
  140. assert always WbWe_o -> WbAdr_o = s_local_address abort WbRst_i;
  141. assert always WbCyc_o and not WbWe_o -> WbAdr_o = s_local_address abort WbRst_i;
  142. end generate FormalG;
  143. CoverageG : if Coverage generate
  144. default clock is rising_edge(WbClk_i);
  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. test_cover : cover {s_wb_master_fsm = IDLE and LocalWen_i = '1'; s_wb_master_fsm = ADDRESS; s_wb_master_fsm = DATA};
  156. end generate CoverageG;
  157. end architecture rtl;