axis_misc_reader.v 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. `timescale 1 ns / 1 ps
  2. module axis_misc_reader #
  3. (
  4. parameter integer S_AXIS_TDATA_WIDTH = 40,
  5. parameter integer M_AXIS_TDATA_WIDTH = 32,
  6. parameter integer MISC_WIDTH = 8
  7. )
  8. (
  9. // System signals
  10. input wire aclk,
  11. input wire aresetn,
  12. output wire [MISC_WIDTH-1:0] misc_data,
  13. // Slave side
  14. output wire s_axis_tready,
  15. input wire [S_AXIS_TDATA_WIDTH-1:0] s_axis_tdata,
  16. input wire s_axis_tvalid,
  17. // Master side
  18. input wire m_axis_tready,
  19. output wire [M_AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
  20. output wire m_axis_tvalid
  21. );
  22. reg int_enbl_reg;
  23. reg [MISC_WIDTH-1:0] int_misc_reg;
  24. reg [39:0] pulse_counter;
  25. reg key_latch;
  26. reg [53:0] uart_buffer;
  27. reg [7:0] uart_pos;
  28. reg [5:0] uart_prescaler;
  29. reg [39:0] reflect_buffer;
  30. reg [7:0] reflect_pos;
  31. always @(posedge aclk)
  32. begin
  33. if(~aresetn)
  34. begin
  35. int_enbl_reg <= 1'b0;
  36. pulse_counter <= 40'd0;
  37. key_latch <= 1'b0;
  38. uart_pos <= 8'd0;
  39. uart_buffer <= 54'd0;
  40. uart_prescaler <= 6'd0;
  41. reflect_pos <= 8'd0;
  42. end
  43. else
  44. begin
  45. int_enbl_reg <= 1'b1;
  46. if(s_axis_tvalid & s_axis_tready)
  47. begin
  48. int_misc_reg[MISC_WIDTH-1:3] <= s_axis_tdata[S_AXIS_TDATA_WIDTH-1:S_AXIS_TDATA_WIDTH-MISC_WIDTH+3];
  49. int_misc_reg[0] <= uart_buffer[uart_pos];
  50. int_misc_reg[1] <= reflect_buffer[reflect_pos];
  51. int_misc_reg[2] <= reflect_pos != 0;
  52. // fast metadata reflect
  53. if(s_axis_tdata[S_AXIS_TDATA_WIDTH-1] & (~key_latch))
  54. begin
  55. // every pulse
  56. reflect_pos <= 8'd0;
  57. reflect_buffer <= pulse_counter;
  58. // increment pulse counter
  59. pulse_counter <= pulse_counter + 1'b1;
  60. end
  61. else
  62. begin
  63. reflect_pos <= reflect_pos < 39 ? reflect_pos + 1'b1 : reflect_pos;
  64. end
  65. if(s_axis_tdata[S_AXIS_TDATA_WIDTH-1] & (~key_latch) & (pulse_counter[3:0] == 4'h0))
  66. begin
  67. // beginning of every 16th pulse
  68. // copy data to uart buffer
  69. uart_buffer[0] <= 1'b0; // start bit
  70. uart_buffer[7:1] <= pulse_counter[10:4];
  71. uart_buffer[8] <= 1'b1; // protocol signalization - first byte
  72. uart_buffer[9] <= 1'b1; // stop bit
  73. uart_buffer[10] <= 1'b1; // pad bit
  74. uart_buffer[11] <= 1'b0; // start bit
  75. uart_buffer[18:12] <= pulse_counter[17:11];
  76. uart_buffer[20] <= 1'b1; // stop bit
  77. uart_buffer[21] <= 1'b1; // pad bit
  78. uart_buffer[22] <= 1'b0; // start bit
  79. uart_buffer[29:23] <= pulse_counter[24:18];
  80. uart_buffer[31] <= 1'b1; // stop bit
  81. uart_buffer[32] <= 1'b1; // pad bit
  82. uart_buffer[33] <= 1'b0; // start bit
  83. uart_buffer[40:34] <= pulse_counter[32:25];
  84. uart_buffer[42] <= 1'b1; // stop bit
  85. uart_buffer[43] <= 1'b1; // pad bit
  86. uart_buffer[44] <= 1'b0; // start bit
  87. uart_buffer[51:45] <= pulse_counter[39:33];
  88. uart_buffer[53] <= 1'b1; // stop bit
  89. // reset uart transmitter position
  90. uart_pos <= 8'd0;
  91. uart_prescaler <= 6'd0;
  92. end
  93. else
  94. begin
  95. // not the beginning of pulse - advance UART.
  96. // This will truncate the transmission if the next pulse is received too early;
  97. // the caller is responsible to sanitize this.
  98. if(uart_prescaler == 62)
  99. begin
  100. uart_pos <= uart_pos < 53 ? uart_pos + 1'b1 : uart_pos; // transmit stop bit forever after the end of the transmission
  101. end
  102. uart_prescaler <= uart_prescaler < 62 ? uart_prescaler + 1'b1 : 6'd0;
  103. end
  104. key_latch <= s_axis_tdata[S_AXIS_TDATA_WIDTH-1];
  105. end
  106. end
  107. end
  108. assign s_axis_tready = int_enbl_reg & m_axis_tready;
  109. assign misc_data = int_misc_reg;
  110. assign m_axis_tdata = s_axis_tdata[M_AXIS_TDATA_WIDTH-1:0];
  111. assign m_axis_tvalid = int_enbl_reg & s_axis_tvalid;
  112. endmodule