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.

422 lines
9.2 KiB

  1. -- Async reset synchronizer circuit inspired from
  2. -- Chris Cummings SNUG 2002 paper
  3. -- Synchronous Resets? Asynchronous Resets?
  4. -- I am so confused!
  5. -- How will I ever know which to use?
  6. library ieee ;
  7. use ieee.std_logic_1164.all;
  8. entity reset_sync is
  9. generic (
  10. POLARITY : std_logic := '0'
  11. );
  12. port (
  13. clk_i : in std_logic;
  14. rst_i : in std_logic;
  15. rst_o : out std_logic
  16. );
  17. end entity;
  18. architecture sim of reset_sync is
  19. signal s_rst_d : std_logic_vector(1 downto 0);
  20. begin
  21. process (clk_i, rst_i) is
  22. begin
  23. if (rst_i = POLARITY) then
  24. s_rst_d <= (others => POLARITY);
  25. elsif (rising_edge(clk_i)) then
  26. s_rst_d <= s_rst_d(0) & not POLARITY;
  27. end if;
  28. end process;
  29. rst_o <= s_rst_d(1);
  30. end architecture;
  31. -- Async reset synchronizer circuit inspired from
  32. -- Chris Cummings SNUG 2002 paper
  33. -- Synchronous Resets? Asynchronous Resets?
  34. -- I am so confused!
  35. -- How will I ever know which to use?
  36. library ieee ;
  37. use ieee.std_logic_1164.all;
  38. entity reset_sync_slv is
  39. generic (
  40. POLARITY : std_logic := '0'
  41. );
  42. port (
  43. clk_i : in std_logic;
  44. rst_i : in std_logic_vector;
  45. rst_o : out std_logic_vector
  46. );
  47. end entity;
  48. architecture sim of reset_sync_slv is
  49. begin
  50. GEN : for i in rst_i'range generate
  51. signal s_rst_d : std_logic_vector(1 downto 0);
  52. begin
  53. process (clk_i, rst_i(i)) is
  54. begin
  55. if (rst_i(i) = POLARITY) then
  56. s_rst_d <= (others => POLARITY);
  57. elsif (rising_edge(clk_i)) then
  58. s_rst_d <= s_rst_d(0) & not POLARITY;
  59. end if;
  60. end process;
  61. rst_o(i) <= s_rst_d(1);
  62. end generate;
  63. end architecture;
  64. library ieee;
  65. use ieee.std_logic_1164.all;
  66. use ieee.numeric_std.all;
  67. entity fifo is
  68. generic (
  69. DEPTH : positive := 16;
  70. WIDTH : positive := 16
  71. );
  72. port (
  73. rst_n_i : in std_logic;
  74. clk_i : in std_logic;
  75. -- write
  76. wen_i : in std_logic;
  77. din_i : in std_logic_vector(WIDTH-1 downto 0);
  78. full_o : out std_logic;
  79. werror_o : out std_logic;
  80. -- read
  81. ren_i : in std_logic;
  82. dout_o : out std_logic_vector(WIDTH-1 downto 0);
  83. empty_o : out std_logic;
  84. rerror_o : out std_logic
  85. );
  86. end entity fifo;
  87. architecture rtl of fifo is
  88. subtype t_fifo_pnt is natural range 0 to DEPTH-1;
  89. signal s_write_pnt : t_fifo_pnt;
  90. signal s_read_pnt : t_fifo_pnt;
  91. type t_fifo_mem is array (t_fifo_pnt'low to t_fifo_pnt'high) of std_logic_vector(din_i'range);
  92. signal s_fifo_mem : t_fifo_mem;
  93. signal s_almost_full : boolean;
  94. signal s_almost_empty : boolean;
  95. function incr_pnt (data : t_fifo_pnt) return t_fifo_pnt is
  96. begin
  97. if (data = t_fifo_mem'high) then
  98. return 0;
  99. end if;
  100. return data + 1;
  101. end function incr_pnt;
  102. begin
  103. s_almost_full <= (s_write_pnt = s_read_pnt - 1) or
  104. (s_write_pnt = t_fifo_mem'high and s_read_pnt = t_fifo_mem'low);
  105. s_almost_empty <= (s_read_pnt = s_write_pnt - 1) or
  106. (s_read_pnt = t_fifo_mem'high and s_write_pnt = t_fifo_mem'low);
  107. WriteP : process (rst_n_i, clk_i) is
  108. begin
  109. if (not rst_n_i) then
  110. s_write_pnt <= 0;
  111. werror_o <= '0';
  112. elsif (rising_edge(clk_i)) then
  113. werror_o <= Wen_i and Full_o;
  114. if (Wen_i = '1' and Full_o = '0') then
  115. s_fifo_mem(s_write_pnt) <= Din_i;
  116. s_write_pnt <= incr_pnt(s_write_pnt);
  117. end if;
  118. end if;
  119. end process WriteP;
  120. ReadP : process (rst_n_i, clk_i) is
  121. begin
  122. if (not rst_n_i) then
  123. s_read_pnt <= 0;
  124. rerror_o <= '0';
  125. elsif (rising_edge(clk_i)) then
  126. rerror_o <= Ren_i and Empty_o;
  127. if (Ren_i = '1' and Empty_o = '0') then
  128. Dout_o <= s_fifo_mem(s_read_pnt);
  129. s_read_pnt <= incr_pnt(s_read_pnt);
  130. end if;
  131. end if;
  132. end process ReadP;
  133. FlagsP : process (rst_n_i, clk_i) is
  134. begin
  135. if (rst_n_i = '0') then
  136. Full_o <= '0';
  137. Empty_o <= '1';
  138. elsif (rising_edge(clk_i)) then
  139. if (Wen_i = '1') then
  140. if (Ren_i = '0' and s_almost_full) then
  141. Full_o <= '1';
  142. end if;
  143. Empty_o <= '0';
  144. end if;
  145. if (Ren_i = '1') then
  146. if (Wen_i = '0' and s_almost_empty) then
  147. Empty_o <= '1';
  148. end if;
  149. Full_o <= '0';
  150. end if;
  151. end if;
  152. end process FlagsP;
  153. end architecture;
  154. -- Synchronous AXI stream FIFO based on generic fifo
  155. -- component. Configurable depth and width.
  156. library ieee ;
  157. use ieee.std_logic_1164.all;
  158. library gatemate;
  159. use gatemate.components.all;
  160. entity axis_fifo is
  161. generic (
  162. DEPTH : positive := 8;
  163. WIDTH : positive := 8
  164. );
  165. port (
  166. -- global
  167. rst_n_i : in std_logic;
  168. clk_i : in std_logic;
  169. -- axis in
  170. tdata_i : in std_logic_vector(WIDTH-1 downto 0);
  171. tvalid_i : in std_logic;
  172. tready_o : out std_logic;
  173. -- axis aout
  174. tdata_o : out std_logic_vector(WIDTH-1 downto 0);
  175. tvalid_o : out std_logic;
  176. tready_i : in std_logic
  177. );
  178. end entity;
  179. architecture rtl of axis_fifo is
  180. signal s_fifo_wen : std_logic;
  181. signal s_fifo_ren : std_logic;
  182. signal s_fifo_empty : std_logic;
  183. signal s_fifo_full : std_logic;
  184. signal s_fwft_empty : std_logic;
  185. signal s_ren : std_logic;
  186. begin
  187. fifo : entity work.fifo
  188. generic map (
  189. DEPTH => DEPTH,
  190. WIDTH => WIDTH
  191. )
  192. port map (
  193. rst_n_i => rst_n_i,
  194. clk_i => clk_i,
  195. -- write
  196. wen_i => s_fifo_wen,
  197. din_i => tdata_i,
  198. full_o => s_fifo_full,
  199. werror_o => open,
  200. -- read
  201. ren_i => s_fifo_ren,
  202. dout_o => tdata_o,
  203. empty_o => s_fifo_empty,
  204. rerror_o => open
  205. );
  206. -- FWFT logic
  207. process (clk_i, rst_n_i) is
  208. begin
  209. if (not rst_n_i) then
  210. s_fwft_empty <= '1';
  211. elsif (rising_edge(clk_i)) then
  212. if (s_fifo_ren) then
  213. s_fwft_empty <= '0';
  214. elsif (s_ren) then
  215. s_fwft_empty <= '1';
  216. end if;
  217. end if;
  218. end process;
  219. s_fifo_ren <= not s_fifo_empty and (s_fwft_empty or s_ren);
  220. -- AXIS logic
  221. s_fifo_wen <= tvalid_i and not s_fifo_full;
  222. s_ren <= tready_i and not s_fwft_empty;
  223. tready_o <= not s_fifo_full;
  224. tvalid_o <= not s_fwft_empty;
  225. end architecture;
  226. -- Synchronous AXI stream FIFO based on GateMate CC_FIFO_40K
  227. -- primitive
  228. library ieee ;
  229. use ieee.std_logic_1164.all;
  230. library gatemate;
  231. use gatemate.components.all;
  232. entity axis_fifo_gm is
  233. generic (
  234. WIDTH : positive := 8
  235. );
  236. port (
  237. -- global
  238. rst_n_i : in std_logic;
  239. clk_i : in std_logic;
  240. -- axis in
  241. tdata_i : in std_logic_vector(WIDTH-1 downto 0);
  242. tvalid_i : in std_logic;
  243. tready_o : out std_logic;
  244. -- axis aout
  245. tdata_o : out std_logic_vector(WIDTH-1 downto 0);
  246. tvalid_o : out std_logic;
  247. tready_i : in std_logic
  248. );
  249. end entity;
  250. architecture rtl of axis_fifo_gm is
  251. signal s_fifo_wen : std_logic;
  252. signal s_fifo_ren : std_logic;
  253. signal s_fifo_empty : std_logic;
  254. signal s_fifo_full : std_logic;
  255. signal s_fwft_empty : std_logic;
  256. signal s_ren : std_logic;
  257. signal s_fifo_a_en : std_logic;
  258. signal s_fifo_b_en : std_logic;
  259. signal s_fifo_b_we : std_logic;
  260. signal s_fifo_din : std_logic_vector(79 downto 0);
  261. signal s_fifo_dout : std_logic_vector(79 downto 0);
  262. begin
  263. -- CC_FIFO_40K instance (512x80)
  264. fifo : CC_FIFO_40K
  265. generic map (
  266. LOC => "UNPLACED",
  267. ALMOST_FULL_OFFSET => (others => '0'),
  268. ALMOST_EMPTY_OFFSET => (others => '0'),
  269. A_WIDTH => WIDTH, -- 1..80
  270. B_WIDTH => WIDTH, -- 1..80
  271. RAM_MODE => "SDP",
  272. FIFO_MODE => "SYNC",
  273. A_CLK_INV => '0',
  274. B_CLK_INV => '0',
  275. A_EN_INV => '0',
  276. B_EN_INV => '0',
  277. A_WE_INV => '0',
  278. B_WE_INV => '0',
  279. A_DO_REG => '0',
  280. B_DO_REG => '0',
  281. A_ECC_EN => '0',
  282. B_ECC_EN => '0'
  283. )
  284. port map(
  285. A_ECC_1B_ERR => open,
  286. B_ECC_1B_ERR => open,
  287. A_ECC_2B_ERR => open,
  288. B_ECC_2B_ERR => open,
  289. -- FIFO pop port
  290. A_DO => s_fifo_dout(39 downto 0),
  291. B_DO => s_fifo_dout(79 downto 40),
  292. A_CLK => clk_i,
  293. A_EN => s_fifo_a_en,
  294. -- FIFO push port
  295. A_DI => s_fifo_din(39 downto 0),
  296. B_DI => s_fifo_din(79 downto 40),
  297. A_BM => (others => '1'),
  298. B_BM => (others => '1'),
  299. B_CLK => clk_i,
  300. B_EN => s_fifo_b_en,
  301. B_WE => s_fifo_b_we,
  302. -- FIFO control
  303. F_RST_N => rst_n_i,
  304. F_ALMOST_FULL_OFFSET => (others => '0'),
  305. F_ALMOST_EMPTY_OFFSET => (others => '0'),
  306. -- FIFO status signals
  307. F_FULL => s_fifo_full,
  308. F_EMPTY => s_fifo_empty,
  309. F_ALMOST_FULL => open,
  310. F_ALMOST_EMPTY => open,
  311. F_RD_ERROR => open,
  312. F_WR_ERROR => open,
  313. F_RD_PTR => open,
  314. F_WR_PTR => open
  315. );
  316. s_fifo_b_en <= s_fifo_wen;
  317. s_fifo_b_we <= s_fifo_wen;
  318. s_fifo_a_en <= s_fifo_ren;
  319. -- FWFT logic
  320. process (clk_i, rst_n_i) is
  321. begin
  322. if (not rst_n_i) then
  323. s_fwft_empty <= '1';
  324. elsif (rising_edge(clk_i)) then
  325. if (s_fifo_ren) then
  326. s_fwft_empty <= '0';
  327. elsif (s_ren) then
  328. s_fwft_empty <= '1';
  329. end if;
  330. end if;
  331. end process;
  332. s_fifo_ren <= not s_fifo_empty and (s_fwft_empty or s_ren);
  333. -- AXIS logic
  334. s_fifo_wen <= tvalid_i and not s_fifo_full;
  335. s_ren <= tready_i and not s_fwft_empty;
  336. tready_o <= not s_fifo_full;
  337. s_fifo_din(tdata_i'range) <= tdata_i;
  338. tvalid_o <= not s_fwft_empty;
  339. tdata_o <= s_fifo_dout(tdata_o'range);
  340. end architecture;