axis_fifo.v 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. `timescale 1 ns / 1 ps
  2. module axis_fifo #
  3. (
  4. parameter integer S_AXIS_TDATA_WIDTH = 32,
  5. parameter integer M_AXIS_TDATA_WIDTH = 32,
  6. parameter integer WRITE_DEPTH = 512,
  7. parameter ALWAYS_READY = "FALSE",
  8. parameter ALWAYS_VALID = "FALSE"
  9. )
  10. (
  11. // System signals
  12. input wire aclk,
  13. input wire aresetn,
  14. // FIFO status
  15. output wire [15:0] write_count,
  16. output wire [15:0] read_count,
  17. // Slave side
  18. input wire [S_AXIS_TDATA_WIDTH-1:0] s_axis_tdata,
  19. input wire s_axis_tvalid,
  20. output wire s_axis_tready,
  21. // Master side
  22. output wire [M_AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
  23. output wire m_axis_tvalid,
  24. input wire m_axis_tready
  25. );
  26. localparam integer WRITE_COUNT_WIDTH = $clog2(WRITE_DEPTH) + 1;
  27. localparam integer READ_COUNT_WIDTH = $clog2(WRITE_DEPTH * S_AXIS_TDATA_WIDTH / M_AXIS_TDATA_WIDTH) + 1;
  28. wire [M_AXIS_TDATA_WIDTH-1:0] int_data_wire;
  29. wire int_empty_wire, int_full_wire;
  30. xpm_fifo_sync #(
  31. .WRITE_DATA_WIDTH(S_AXIS_TDATA_WIDTH),
  32. .FIFO_WRITE_DEPTH(WRITE_DEPTH),
  33. .READ_DATA_WIDTH(M_AXIS_TDATA_WIDTH),
  34. .READ_MODE("fwft"),
  35. .FIFO_READ_LATENCY(0),
  36. .FIFO_MEMORY_TYPE("block"),
  37. .USE_ADV_FEATURES("0404"),
  38. .WR_DATA_COUNT_WIDTH(WRITE_COUNT_WIDTH),
  39. .RD_DATA_COUNT_WIDTH(READ_COUNT_WIDTH)
  40. ) fifo_0 (
  41. .empty(int_empty_wire),
  42. .full(int_full_wire),
  43. .wr_data_count(write_count),
  44. .rd_data_count(read_count),
  45. .rst(~aresetn),
  46. .wr_clk(aclk),
  47. .wr_en(s_axis_tvalid),
  48. .din(s_axis_tdata),
  49. .rd_en(m_axis_tready),
  50. .dout(int_data_wire)
  51. );
  52. generate
  53. if(ALWAYS_READY == "TRUE")
  54. begin : READY_INPUT
  55. assign s_axis_tready = 1'b1;
  56. end
  57. else
  58. begin : BLOCKING_INPUT
  59. assign s_axis_tready = ~int_full_wire;
  60. end
  61. endgenerate
  62. generate
  63. if(ALWAYS_VALID == "TRUE")
  64. begin : VALID_OUTPUT
  65. assign m_axis_tdata = int_empty_wire ? {(M_AXIS_TDATA_WIDTH){1'b0}} : int_data_wire;
  66. assign m_axis_tvalid = 1'b1;
  67. end
  68. else
  69. begin : BLOCKING_OUTPUT
  70. assign m_axis_tdata = int_data_wire;
  71. assign m_axis_tvalid = ~int_empty_wire;
  72. end
  73. endgenerate
  74. endmodule