axis_ram_writer.v 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. `timescale 1 ns / 1 ps
  2. module axis_ram_writer #
  3. (
  4. parameter integer ADDR_WIDTH = 16,
  5. parameter integer AXI_ID_WIDTH = 6,
  6. parameter integer AXI_ADDR_WIDTH = 32,
  7. parameter integer AXI_DATA_WIDTH = 64,
  8. parameter integer AXIS_TDATA_WIDTH = 64,
  9. parameter integer FIFO_WRITE_DEPTH = 512
  10. )
  11. (
  12. // System signals
  13. input wire aclk,
  14. input wire aresetn,
  15. input wire [AXI_ADDR_WIDTH-1:0] min_addr,
  16. input wire [ADDR_WIDTH-1:0] cfg_data,
  17. output wire [ADDR_WIDTH-1:0] sts_data,
  18. // Master side
  19. output wire [AXI_ID_WIDTH-1:0] m_axi_awid, // AXI master: Write address ID
  20. output wire [3:0] m_axi_awlen, // AXI master: Write burst length
  21. output wire [2:0] m_axi_awsize, // AXI master: Write burst size
  22. output wire [1:0] m_axi_awburst, // AXI master: Write burst type
  23. output wire [3:0] m_axi_awcache, // AXI master: Write memory type
  24. output wire [AXI_ADDR_WIDTH-1:0] m_axi_awaddr, // AXI master: Write address
  25. output wire m_axi_awvalid, // AXI master: Write address valid
  26. input wire m_axi_awready, // AXI master: Write address ready
  27. output wire [AXI_ID_WIDTH-1:0] m_axi_wid, // AXI master: Write data ID
  28. output wire [AXI_DATA_WIDTH/8-1:0] m_axi_wstrb, // AXI master: Write strobes
  29. output wire m_axi_wlast, // AXI master: Write last
  30. output wire [AXI_DATA_WIDTH-1:0] m_axi_wdata, // AXI master: Write data
  31. output wire m_axi_wvalid, // AXI master: Write valid
  32. input wire m_axi_wready, // AXI master: Write ready
  33. input wire m_axi_bvalid, // AXI master: Write response valid
  34. output wire m_axi_bready, // AXI master: Write response ready
  35. // Slave side
  36. input wire [AXIS_TDATA_WIDTH-1:0] s_axis_tdata,
  37. input wire s_axis_tvalid,
  38. output wire s_axis_tready
  39. );
  40. localparam integer ADDR_SIZE = $clog2(AXI_DATA_WIDTH / 8);
  41. localparam integer COUNT_WIDTH = $clog2(FIFO_WRITE_DEPTH * AXIS_TDATA_WIDTH / AXI_DATA_WIDTH) + 1;
  42. reg int_awvalid_reg, int_wvalid_reg;
  43. reg [3:0] int_cntr_reg;
  44. reg [ADDR_WIDTH-1:0] int_addr_reg;
  45. wire int_full_wire, int_valid_wire;
  46. wire int_awvalid_wire, int_awready_wire;
  47. wire int_wlast_wire, int_wvalid_wire, int_wready_wire, int_rden_wire;
  48. wire [COUNT_WIDTH-1:0] int_count_wire;
  49. wire [AXI_DATA_WIDTH-1:0] int_wdata_wire;
  50. assign int_valid_wire = (int_count_wire > 15) & ~int_wvalid_reg;
  51. assign int_awvalid_wire = int_valid_wire | int_awvalid_reg;
  52. assign int_wvalid_wire = int_valid_wire | int_wvalid_reg;
  53. assign int_rden_wire = int_wvalid_wire & int_wready_wire;
  54. assign int_wlast_wire = &int_cntr_reg;
  55. xpm_fifo_sync #(
  56. .WRITE_DATA_WIDTH(AXIS_TDATA_WIDTH),
  57. .FIFO_WRITE_DEPTH(FIFO_WRITE_DEPTH),
  58. .READ_DATA_WIDTH(AXI_DATA_WIDTH),
  59. .READ_MODE("fwft"),
  60. .FIFO_READ_LATENCY(0),
  61. .FIFO_MEMORY_TYPE("block"),
  62. .USE_ADV_FEATURES("0400"),
  63. .RD_DATA_COUNT_WIDTH(COUNT_WIDTH)
  64. ) fifo_0 (
  65. .full(int_full_wire),
  66. .rd_data_count(int_count_wire),
  67. .rst(~aresetn),
  68. .wr_clk(aclk),
  69. .wr_en(s_axis_tvalid),
  70. .din(s_axis_tdata),
  71. .rd_en(int_rden_wire),
  72. .dout(int_wdata_wire)
  73. );
  74. always @(posedge aclk)
  75. begin
  76. if(~aresetn)
  77. begin
  78. int_awvalid_reg <= 1'b0;
  79. int_wvalid_reg <= 1'b0;
  80. int_cntr_reg <= 4'd0;
  81. int_addr_reg <= {(ADDR_WIDTH){1'b0}};
  82. end
  83. else
  84. begin
  85. if(int_valid_wire)
  86. begin
  87. int_awvalid_reg <= 1'b1;
  88. int_wvalid_reg <= 1'b1;
  89. end
  90. if(int_awvalid_wire & int_awready_wire)
  91. begin
  92. int_awvalid_reg <= 1'b0;
  93. int_addr_reg <= int_addr_reg < cfg_data ? int_addr_reg + 1'b1 : {(ADDR_WIDTH){1'b0}};
  94. end
  95. if(int_rden_wire)
  96. begin
  97. int_cntr_reg <= int_cntr_reg + 1'b1;
  98. end
  99. if(int_wready_wire & int_wlast_wire)
  100. begin
  101. int_wvalid_reg <= 1'b0;
  102. end
  103. end
  104. end
  105. output_buffer #(
  106. .DATA_WIDTH(AXI_ADDR_WIDTH)
  107. ) buf_0 (
  108. .aclk(aclk), .aresetn(aresetn),
  109. .in_data(min_addr + {int_addr_reg, 4'd0, {(ADDR_SIZE){1'b0}}}),
  110. .in_valid(int_awvalid_wire), .in_ready(int_awready_wire),
  111. .out_data(m_axi_awaddr),
  112. .out_valid(m_axi_awvalid), .out_ready(m_axi_awready)
  113. );
  114. output_buffer #(
  115. .DATA_WIDTH(AXI_DATA_WIDTH+1)
  116. ) buf_1 (
  117. .aclk(aclk), .aresetn(aresetn),
  118. .in_data({int_wlast_wire, int_wdata_wire}),
  119. .in_valid(int_wvalid_wire), .in_ready(int_wready_wire),
  120. .out_data({m_axi_wlast, m_axi_wdata}),
  121. .out_valid(m_axi_wvalid), .out_ready(m_axi_wready)
  122. );
  123. assign sts_data = int_addr_reg;
  124. assign m_axi_awid = {(AXI_ID_WIDTH){1'b0}};
  125. assign m_axi_awlen = 4'd15;
  126. assign m_axi_awsize = ADDR_SIZE;
  127. assign m_axi_awburst = 2'b01;
  128. assign m_axi_awcache = 4'b1111;
  129. assign m_axi_wid = {(AXI_ID_WIDTH){1'b0}};
  130. assign m_axi_wstrb = {(AXI_DATA_WIDTH/8){1'b1}};
  131. assign m_axi_bready = 1'b1;
  132. assign s_axis_tready = ~int_full_wire;
  133. endmodule