| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- `timescale 1ns/1ps
- // 16-byte binary frame over UART.
- // Byte 0 : 0xA5
- // Byte 1 : 0x5A
- // Byte 2 : type (0x81 STATUS/PONG, 0x82 TRACE, 0x83 SUMMARY)
- // Byte 3..4 : sequence/count, big-endian
- // Byte 5..6 : event_id, big-endian
- // Byte 7..10 : timestamp/run_cycles, big-endian
- // Byte 11..14 : data/drop_count, big-endian
- // Byte 15 : CRC-8, polynomial 0x07, init 0x00, over bytes 2..14
- module trace_packet_tx #(
- parameter integer CLK_HZ = 25000000,
- parameter integer BAUD = 115200
- )(
- input wire clk,
- input wire reset_n,
- input wire send,
- input wire [7:0] pkt_type,
- input wire [15:0] seq,
- input wire [15:0] event_id,
- input wire [31:0] timestamp,
- input wire [31:0] data,
- output wire uart_tx_o,
- output reg busy,
- output reg done
- );
- reg [7:0] type_l;
- reg [15:0] seq_l;
- reg [15:0] event_l;
- reg [31:0] time_l;
- reg [31:0] data_l;
- reg [4:0] byte_index;
- reg [7:0] crc;
- reg uart_start;
- reg [7:0] uart_data;
- reg waiting_uart;
- wire uart_busy;
- wire uart_done;
- function [7:0] crc8_update;
- input [7:0] crc_in;
- input [7:0] data_in;
- integer i;
- reg [7:0] c;
- begin
- c = crc_in ^ data_in;
- for (i = 0; i < 8; i = i + 1) begin
- if (c[7])
- c = (c << 1) ^ 8'h07;
- else
- c = (c << 1);
- end
- crc8_update = c;
- end
- endfunction
- function [7:0] frame_byte;
- input [4:0] idx;
- begin
- case (idx)
- 5'd0: frame_byte = 8'hA5;
- 5'd1: frame_byte = 8'h5A;
- 5'd2: frame_byte = type_l;
- 5'd3: frame_byte = seq_l[15:8];
- 5'd4: frame_byte = seq_l[7:0];
- 5'd5: frame_byte = event_l[15:8];
- 5'd6: frame_byte = event_l[7:0];
- 5'd7: frame_byte = time_l[31:24];
- 5'd8: frame_byte = time_l[23:16];
- 5'd9: frame_byte = time_l[15:8];
- 5'd10: frame_byte = time_l[7:0];
- 5'd11: frame_byte = data_l[31:24];
- 5'd12: frame_byte = data_l[23:16];
- 5'd13: frame_byte = data_l[15:8];
- 5'd14: frame_byte = data_l[7:0];
- 5'd15: frame_byte = crc;
- default: frame_byte = 8'h00;
- endcase
- end
- endfunction
- uart_tx #(
- .CLK_HZ(CLK_HZ),
- .BAUD(BAUD)
- ) u_uart_tx (
- .clk(clk),
- .reset_n(reset_n),
- .start(uart_start),
- .data(uart_data),
- .tx(uart_tx_o),
- .busy(uart_busy),
- .done(uart_done)
- );
- always @(posedge clk or negedge reset_n) begin
- if (!reset_n) begin
- type_l <= 8'd0;
- seq_l <= 16'd0;
- event_l <= 16'd0;
- time_l <= 32'd0;
- data_l <= 32'd0;
- byte_index <= 5'd0;
- crc <= 8'd0;
- uart_start <= 1'b0;
- uart_data <= 8'd0;
- waiting_uart <= 1'b0;
- busy <= 1'b0;
- done <= 1'b0;
- end else begin
- uart_start <= 1'b0;
- done <= 1'b0;
- if (!busy) begin
- waiting_uart <= 1'b0;
- if (send) begin
- type_l <= pkt_type;
- seq_l <= seq;
- event_l <= event_id;
- time_l <= timestamp;
- data_l <= data;
- byte_index <= 5'd0;
- crc <= 8'h00;
- busy <= 1'b1;
- end
- end else begin
- if (!waiting_uart && !uart_busy) begin
- uart_data <= frame_byte(byte_index);
- uart_start <= 1'b1;
- waiting_uart <= 1'b1;
- end
- if (waiting_uart && uart_done) begin
- if ((byte_index >= 5'd2) && (byte_index <= 5'd14))
- crc <= crc8_update(crc, frame_byte(byte_index));
- waiting_uart <= 1'b0;
- if (byte_index == 5'd15) begin
- busy <= 1'b0;
- done <= 1'b1;
- end else begin
- byte_index <= byte_index + 1'b1;
- end
- end
- end
- end
- end
- endmodule
|