trace_packet_tx.v 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. `timescale 1ns/1ps
  2. // 16-byte binary frame over UART.
  3. // Byte 0 : 0xA5
  4. // Byte 1 : 0x5A
  5. // Byte 2 : type (0x81 STATUS/PONG, 0x82 TRACE, 0x83 SUMMARY)
  6. // Byte 3..4 : sequence/count, big-endian
  7. // Byte 5..6 : event_id, big-endian
  8. // Byte 7..10 : timestamp/run_cycles, big-endian
  9. // Byte 11..14 : data/drop_count, big-endian
  10. // Byte 15 : CRC-8, polynomial 0x07, init 0x00, over bytes 2..14
  11. module trace_packet_tx #(
  12. parameter integer CLK_HZ = 25000000,
  13. parameter integer BAUD = 115200
  14. )(
  15. input wire clk,
  16. input wire reset_n,
  17. input wire send,
  18. input wire [7:0] pkt_type,
  19. input wire [15:0] seq,
  20. input wire [15:0] event_id,
  21. input wire [31:0] timestamp,
  22. input wire [31:0] data,
  23. output wire uart_tx_o,
  24. output reg busy,
  25. output reg done
  26. );
  27. reg [7:0] type_l;
  28. reg [15:0] seq_l;
  29. reg [15:0] event_l;
  30. reg [31:0] time_l;
  31. reg [31:0] data_l;
  32. reg [4:0] byte_index;
  33. reg [7:0] crc;
  34. reg uart_start;
  35. reg [7:0] uart_data;
  36. reg waiting_uart;
  37. wire uart_busy;
  38. wire uart_done;
  39. function [7:0] crc8_update;
  40. input [7:0] crc_in;
  41. input [7:0] data_in;
  42. integer i;
  43. reg [7:0] c;
  44. begin
  45. c = crc_in ^ data_in;
  46. for (i = 0; i < 8; i = i + 1) begin
  47. if (c[7])
  48. c = (c << 1) ^ 8'h07;
  49. else
  50. c = (c << 1);
  51. end
  52. crc8_update = c;
  53. end
  54. endfunction
  55. function [7:0] frame_byte;
  56. input [4:0] idx;
  57. begin
  58. case (idx)
  59. 5'd0: frame_byte = 8'hA5;
  60. 5'd1: frame_byte = 8'h5A;
  61. 5'd2: frame_byte = type_l;
  62. 5'd3: frame_byte = seq_l[15:8];
  63. 5'd4: frame_byte = seq_l[7:0];
  64. 5'd5: frame_byte = event_l[15:8];
  65. 5'd6: frame_byte = event_l[7:0];
  66. 5'd7: frame_byte = time_l[31:24];
  67. 5'd8: frame_byte = time_l[23:16];
  68. 5'd9: frame_byte = time_l[15:8];
  69. 5'd10: frame_byte = time_l[7:0];
  70. 5'd11: frame_byte = data_l[31:24];
  71. 5'd12: frame_byte = data_l[23:16];
  72. 5'd13: frame_byte = data_l[15:8];
  73. 5'd14: frame_byte = data_l[7:0];
  74. 5'd15: frame_byte = crc;
  75. default: frame_byte = 8'h00;
  76. endcase
  77. end
  78. endfunction
  79. uart_tx #(
  80. .CLK_HZ(CLK_HZ),
  81. .BAUD(BAUD)
  82. ) u_uart_tx (
  83. .clk(clk),
  84. .reset_n(reset_n),
  85. .start(uart_start),
  86. .data(uart_data),
  87. .tx(uart_tx_o),
  88. .busy(uart_busy),
  89. .done(uart_done)
  90. );
  91. always @(posedge clk or negedge reset_n) begin
  92. if (!reset_n) begin
  93. type_l <= 8'd0;
  94. seq_l <= 16'd0;
  95. event_l <= 16'd0;
  96. time_l <= 32'd0;
  97. data_l <= 32'd0;
  98. byte_index <= 5'd0;
  99. crc <= 8'd0;
  100. uart_start <= 1'b0;
  101. uart_data <= 8'd0;
  102. waiting_uart <= 1'b0;
  103. busy <= 1'b0;
  104. done <= 1'b0;
  105. end else begin
  106. uart_start <= 1'b0;
  107. done <= 1'b0;
  108. if (!busy) begin
  109. waiting_uart <= 1'b0;
  110. if (send) begin
  111. type_l <= pkt_type;
  112. seq_l <= seq;
  113. event_l <= event_id;
  114. time_l <= timestamp;
  115. data_l <= data;
  116. byte_index <= 5'd0;
  117. crc <= 8'h00;
  118. busy <= 1'b1;
  119. end
  120. end else begin
  121. if (!waiting_uart && !uart_busy) begin
  122. uart_data <= frame_byte(byte_index);
  123. uart_start <= 1'b1;
  124. waiting_uart <= 1'b1;
  125. end
  126. if (waiting_uart && uart_done) begin
  127. if ((byte_index >= 5'd2) && (byte_index <= 5'd14))
  128. crc <= crc8_update(crc, frame_byte(byte_index));
  129. waiting_uart <= 1'b0;
  130. if (byte_index == 5'd15) begin
  131. busy <= 1'b0;
  132. done <= 1'b1;
  133. end else begin
  134. byte_index <= byte_index + 1'b1;
  135. end
  136. end
  137. end
  138. end
  139. end
  140. endmodule