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.

193 lines
5.7 KiB

  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. entity WishBoneSlaveE is
  5. generic (
  6. Formal : boolean := false;
  7. AddressWidth : natural := 32;
  8. DataWidth : natural := 32
  9. );
  10. port (
  11. --+ wishbone system if
  12. WbRst_i : in std_logic;
  13. WbClk_i : in std_logic;
  14. --+ wishbone inputs
  15. WbCyc_i : in std_logic;
  16. WbStb_i : in std_logic;
  17. WbWe_i : in std_logic;
  18. WbAdr_i : in std_logic_vector(AddressWidth-1 downto 0);
  19. WbDat_i : in std_logic_vector(DataWidth-1 downto 0);
  20. --+ wishbone outputs
  21. WbDat_o : out std_logic_vector(DataWidth-1 downto 0);
  22. WbAck_o : out std_logic;
  23. WbErr_o : out std_logic;
  24. --+ local register if
  25. LocalWen_o : out std_logic;
  26. LocalRen_o : out std_logic;
  27. LocalAdress_o : out std_logic_vector(AddressWidth-1 downto 0);
  28. LocalData_o : out std_logic_vector(DataWidth-1 downto 0);
  29. LocalData_i : in std_logic_vector(DataWidth-1 downto 0)
  30. );
  31. end entity WishBoneSlaveE;
  32. architecture rtl of WishBoneSlaveE is
  33. type t_wb_slave_fsm is (IDLE, ADDRESS, DATA);
  34. signal s_wb_slave_fsm : t_wb_slave_fsm;
  35. signal s_wb_active : boolean;
  36. begin
  37. WbSlaveControlP : process (WbClk_i) is
  38. begin
  39. if (rising_edge(WbClk_i)) then
  40. if (WbRst_i = '1') then
  41. s_wb_slave_fsm <= IDLE;
  42. else
  43. WbReadC : case s_wb_slave_fsm is
  44. when IDLE =>
  45. s_wb_slave_fsm <= ADDRESS;
  46. when ADDRESS =>
  47. if (s_wb_active and WbWe_i = '0') then
  48. s_wb_slave_fsm <= DATA;
  49. end if;
  50. when DATA =>
  51. s_wb_slave_fsm <= ADDRESS;
  52. when others =>
  53. s_wb_slave_fsm <= IDLE;
  54. end case;
  55. end if;
  56. end if;
  57. end process WbSlaveControlP;
  58. s_wb_active <= true when s_wb_slave_fsm /= IDLE and WbCyc_i = '1' and WbStb_i = '1' else false;
  59. --+ local register if outputs
  60. LocalWen_o <= WbWe_i when s_wb_slave_fsm = ADDRESS and s_wb_active else '0';
  61. LocalRen_o <= not(WbWe_i) when s_wb_slave_fsm = ADDRESS and s_wb_active else '0';
  62. LocalAdress_o <= WbAdr_i when s_wb_slave_fsm /= IDLE and s_wb_active else (others => '0');
  63. LocalData_o <= WbDat_i when s_wb_slave_fsm = ADDRESS and s_wb_active and WbWe_i = '1' else (others => '0');
  64. --+ wishbone if outputs
  65. WbDat_o <= LocalData_i when s_wb_slave_fsm = DATA and WbWe_i = '0' else (others => '0');
  66. WbAck_o <= '1' when (s_wb_slave_fsm = DATA and WbWe_i = '0') or (s_wb_slave_fsm = ADDRESS and s_wb_active and WbWe_i = '1') else '0';
  67. WbErr_o <= '1' when s_wb_slave_fsm = DATA and WbWe_i = '1' else '0';
  68. FormalG : if Formal generate
  69. -- Glue logic
  70. signal s_wb_data : std_logic_vector(DataWidth-1 downto 0);
  71. signal s_wb_address : std_logic_vector(AddressWidth-1 downto 0);
  72. begin
  73. SyncWbSignals : process is
  74. begin
  75. wait until rising_edge(WbClk_i);
  76. if (s_wb_slave_fsm = ADDRESS and WbCyc_i = '1' and WbStb_i = '1') then
  77. if (WbWe_i = '1') then
  78. s_wb_data <= WbDat_i;
  79. end if;
  80. s_wb_address <= WbAdr_i;
  81. end if;
  82. end process SyncWbSignals;
  83. default clock is rising_edge(WbClk_i);
  84. restrict {WbRst_i = '1'; WbRst_i = '0'[+]}[*1];
  85. assume always WbCyc_i = WbStb_i;
  86. assume always WbWe_i -> WbStb_i;
  87. assume always WbWe_i and WbAck_o -> next not WbWe_i;
  88. -- FSM state checks
  89. FSM_IDLE_TO_ADDRESS : assert always
  90. not WbRst_i and s_wb_slave_fsm = IDLE ->
  91. next s_wb_slave_fsm = ADDRESS abort WbRst_i;
  92. FSM_ADDRESS_TO_DATA : assert always
  93. not WbRst_i and s_wb_slave_fsm = ADDRESS and WbStb_i and WbCyc_i and not WbWe_i ->
  94. next s_wb_slave_fsm = DATA abort WbRst_i;
  95. FSM_ADDRESS_TO_ADDRESS : assert always
  96. not WbRst_i and s_wb_slave_fsm = ADDRESS and not (WbStb_i and WbCyc_i and not WbWe_i) ->
  97. next s_wb_slave_fsm = ADDRESS abort WbRst_i;
  98. FSM_DATA_TO_ADDRESS : assert always
  99. not WbRst_i and s_wb_slave_fsm = DATA ->
  100. next s_wb_slave_fsm = ADDRESS abort WbRst_i;
  101. -- Wishbone write cycle checks
  102. WB_WRITE_CYCLE_0 : assert always
  103. s_wb_slave_fsm = ADDRESS and WbStb_i and WbCyc_i and WbWe_i ->
  104. LocalWen_o and WbAck_o;
  105. WB_WRITE_CYCLE_1 : assert always
  106. LocalWen_o -> LocalAdress_o = WbAdr_i;
  107. WB_WRITE_CYCLE_2 : assert always
  108. LocalWen_o -> LocalData_o = WbDat_i;
  109. -- Wishbone read cycle checks
  110. WB_READ_CYCLE_0 : assert always
  111. s_wb_slave_fsm = ADDRESS and WbStb_i and WbCyc_i and not WbWe_i ->
  112. LocalRen_o and not WbAck_o;
  113. WB_READ_CYCLE_1 : assert always
  114. LocalRen_o -> LocalAdress_o = WbAdr_i;
  115. WB_READ_CYCLE_2 : assert always
  116. s_wb_slave_fsm = DATA and not WbWe_i ->
  117. WbAck_o and WbDat_o = LocalData_i;
  118. WB_READ_ERROR : assert always
  119. s_wb_slave_fsm = DATA and WbWe_i ->
  120. WbErr_o;
  121. WB_NEVER_ACK_AND_ERR : assert never
  122. WbAck_o and WbErr_o;
  123. WB_ERR : assert always
  124. WbErr_o ->
  125. (WbCyc_i and WbStb_i)
  126. report "PSL ERROR: WbErr invalid";
  127. LOCAL_WE : assert always
  128. LocalWen_o ->
  129. (WbCyc_i and WbStb_i and WbWe_i and not LocalRen_o) and
  130. (next not LocalWen_o)
  131. report "PSL ERROR: LocalWen invalid";
  132. LOCAL_RE : assert always
  133. LocalRen_o ->
  134. (WbCyc_i and WbStb_i and not WbWe_i and not LocalWen_o) and
  135. (next not LocalRen_o)
  136. report "PSL ERROR: LocalRen invalid";
  137. RESET : assert always
  138. WbRst_i -> next
  139. (to_integer(unsigned(WbDat_o)) = 0 and WbAck_o = '0' and WbErr_o = '0' and
  140. LocalWen_o = '0' and LocalRen_o = '0' and to_integer(unsigned(LocalAdress_o)) = 0 and to_integer(unsigned(LocalData_o)) = 0)
  141. report "PSL ERROR: Reset error";
  142. end generate FormalG;
  143. end architecture rtl;