axis_accumulator.v 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. `timescale 1 ns / 1 ps
  2. module axis_accumulator #
  3. (
  4. parameter integer S_AXIS_TDATA_WIDTH = 16,
  5. parameter integer M_AXIS_TDATA_WIDTH = 32,
  6. parameter integer CNTR_WIDTH = 16,
  7. parameter AXIS_TDATA_SIGNED = "FALSE",
  8. parameter CONTINUOUS = "FALSE"
  9. )
  10. (
  11. // System signals
  12. input wire aclk,
  13. input wire aresetn,
  14. input wire [CNTR_WIDTH-1:0] cfg_data,
  15. // Slave side
  16. output wire s_axis_tready,
  17. input wire [S_AXIS_TDATA_WIDTH-1:0] s_axis_tdata,
  18. input wire s_axis_tvalid,
  19. // Master side
  20. input wire m_axis_tready,
  21. output wire [M_AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
  22. output wire m_axis_tvalid
  23. );
  24. reg [M_AXIS_TDATA_WIDTH-1:0] int_tdata_reg, int_tdata_next;
  25. reg [M_AXIS_TDATA_WIDTH-1:0] int_accu_reg, int_accu_next;
  26. reg [CNTR_WIDTH-1:0] int_cntr_reg, int_cntr_next;
  27. reg int_tvalid_reg, int_tvalid_next;
  28. reg int_tready_reg, int_tready_next;
  29. wire [M_AXIS_TDATA_WIDTH-1:0] sum_accu_wire;
  30. wire int_comp_wire, int_tvalid_wire;
  31. always @(posedge aclk)
  32. begin
  33. if(~aresetn)
  34. begin
  35. int_tdata_reg <= {(M_AXIS_TDATA_WIDTH){1'b0}};
  36. int_tvalid_reg <= 1'b0;
  37. int_tready_reg <= 1'b0;
  38. int_accu_reg <= {(M_AXIS_TDATA_WIDTH){1'b0}};
  39. int_cntr_reg <= {(CNTR_WIDTH){1'b0}};
  40. end
  41. else
  42. begin
  43. int_tdata_reg <= int_tdata_next;
  44. int_tvalid_reg <= int_tvalid_next;
  45. int_tready_reg <= int_tready_next;
  46. int_accu_reg <= int_accu_next;
  47. int_cntr_reg <= int_cntr_next;
  48. end
  49. end
  50. assign int_comp_wire = int_cntr_reg < cfg_data;
  51. assign int_tvalid_wire = int_tready_reg & s_axis_tvalid;
  52. generate
  53. if(AXIS_TDATA_SIGNED == "TRUE")
  54. begin : SIGNED
  55. assign sum_accu_wire = $signed(int_accu_reg) + $signed(s_axis_tdata);
  56. end
  57. else
  58. begin : UNSIGNED
  59. assign sum_accu_wire = int_accu_reg + s_axis_tdata;
  60. end
  61. endgenerate
  62. generate
  63. if(CONTINUOUS == "TRUE")
  64. begin : CONTINUE
  65. always @*
  66. begin
  67. int_tdata_next = int_tdata_reg;
  68. int_tvalid_next = int_tvalid_reg;
  69. int_tready_next = int_tready_reg;
  70. int_accu_next = int_accu_reg;
  71. int_cntr_next = int_cntr_reg;
  72. if(~int_tready_reg & int_comp_wire)
  73. begin
  74. int_tready_next = 1'b1;
  75. end
  76. if(int_tvalid_wire & int_comp_wire)
  77. begin
  78. int_cntr_next = int_cntr_reg + 1'b1;
  79. int_accu_next = sum_accu_wire;
  80. end
  81. if(int_tvalid_wire & ~int_comp_wire)
  82. begin
  83. int_cntr_next = {(CNTR_WIDTH){1'b0}};
  84. int_accu_next = {(M_AXIS_TDATA_WIDTH){1'b0}};
  85. int_tdata_next = sum_accu_wire;
  86. int_tvalid_next = 1'b1;
  87. end
  88. if(m_axis_tready & int_tvalid_reg)
  89. begin
  90. int_tvalid_next = 1'b0;
  91. end
  92. end
  93. end
  94. else
  95. begin : STOP
  96. always @*
  97. begin
  98. int_tdata_next = int_tdata_reg;
  99. int_tvalid_next = int_tvalid_reg;
  100. int_tready_next = int_tready_reg;
  101. int_accu_next = int_accu_reg;
  102. int_cntr_next = int_cntr_reg;
  103. if(~int_tready_reg & int_comp_wire)
  104. begin
  105. int_tready_next = 1'b1;
  106. end
  107. if(int_tvalid_wire & int_comp_wire)
  108. begin
  109. int_cntr_next = int_cntr_reg + 1'b1;
  110. int_accu_next = sum_accu_wire;
  111. end
  112. if(int_tvalid_wire & ~int_comp_wire)
  113. begin
  114. int_tready_next = 1'b0;
  115. int_tdata_next = sum_accu_wire;
  116. int_tvalid_next = 1'b1;
  117. end
  118. if(m_axis_tready & int_tvalid_reg)
  119. begin
  120. int_tvalid_next = 1'b0;
  121. end
  122. end
  123. end
  124. endgenerate
  125. assign s_axis_tready = int_tready_reg;
  126. assign m_axis_tdata = int_tdata_reg;
  127. assign m_axis_tvalid = int_tvalid_reg;
  128. endmodule