Generate ONLY the Verilog module code for the following specification. ## Problem Description Implement an asynchronous FIFO that transfers data from a write clock domain to an independent read clock domain. The FIFO depth is 8 entries and each entry is 16 bits wide. Data must be returned in first-in, first-out order. WRITE INTERFACE: - A write is accepted on a rising edge of `wr_clk` when both `wr_en` is high and `wr_full` is low. - On an accepted write, the value of `wr_data` is appended to the FIFO. - If `wr_en` is high while `wr_full` is high, no write is accepted and the FIFO contents must not change. READ INTERFACE: - A read is accepted on a rising edge of `rd_clk` when both `rd_en` is high and `rd_empty` is low. - On an accepted read, the oldest unread word must be removed from the FIFO. - `rd_data` must present the word returned by that accepted read immediately after the accepting edge. - If `rd_en` is high while `rd_empty` is high, no read is accepted and the FIFO contents must not change. - When no read is accepted on a given `rd_clk` edge, `rd_data` is don't-care and will not be checked. ORDERING: - The sequence of values observed on successful reads must exactly match the sequence of previously accepted writes. - Reads and writes may occur on unrelated clocks and in overlapping time windows, but the externally visible behaviour must still match a FIFO with 8-word storage capacity. FLAG BEHAVIOUR: - `wr_full` is observed in the write clock domain and must prevent any write that would cause the number of stored unread words to exceed 8. - `rd_empty` is observed in the read clock domain and must prevent any read when no unread words are available. - After a successful write that fills the final free entry, `wr_full` must be high immediately after that `wr_clk` edge. - After a successful read that removes the final unread word, `rd_empty` must be high immediately after that `rd_clk` edge. - After a successful read creates free space, `wr_full` may remain high for up to 2 additional rising edges of `wr_clk` before deasserting. - After a successful write makes data available to read, `rd_empty` may remain high for up to 2 additional rising edges of `rd_clk` before deasserting. - Aside from those bounded cross-domain visibility delays, the flags must reflect whether a write or read can safely be accepted in their local domains. RESET: - `wr_rst` and `rd_rst` are synchronous active-high resets for their respective clock domains. - The benchmark will only assert and deassert `wr_rst` and `rd_rst` together. - While reset is asserted, no writes or reads are accepted. - After reset has been observed in both domains, the FIFO must be empty. - After reset is released, `wr_full` must be low, `rd_empty` must be high, and no previously written data may remain available. ## Interface Specification Module Name: async_dual_clock_fifo Ports: - input 1 wr_clk // Write-domain clock - input 1 wr_rst // Synchronous active-high reset for the write domain - input 1 wr_en // Write request; sampled on rising edges of wr_clk - input 16 wr_data // Write-domain input data - output 1 wr_full // High when the FIFO cannot safely accept another write - input 1 rd_clk // Read-domain clock - input 1 rd_rst // Synchronous active-high reset for the read domain - input 1 rd_en // Read request; sampled on rising edges of rd_clk - output 16 rd_data // Data returned by an accepted read - output 1 rd_empty // High when no unread data is currently available to read ## Requirements - Generate ONLY the Verilog module code - Do NOT output any reasoning, analysis, scratchpad, or tags - Start directly with `module async_dual_clock_fifo` as the first line of your response - Do NOT include any testbenches - Do NOT include any explanations or comments outside the code - End with `endmodule` - Ensure the code is correct and synthesizable