trace_capture_ram.v 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. `timescale 1ns/1ps
  2. // Capture-and-dump trace memory.
  3. //
  4. // V2.2 internal record width is deliberately reduced to 64 bits:
  5. // timestamp[15:0] + event/state ID[15:0] + data[31:0]
  6. //
  7. // The UART protocol still sends a 32-bit timestamp; the top expands the stored
  8. // 16-bit timestamp with zeroes. With the default TRACE_DEPTH=1024 and the
  9. // full-cycle template (one trace per active algorithm cycle), 16 timestamp bits
  10. // are far more than required and save block-RAM resources versus the old 80-bit
  11. // record.
  12. //
  13. // Memory is NOT cleared between runs. Only count/pointers are reset.
  14. module trace_capture_ram #(
  15. parameter integer TRACE_DEPTH = 1024,
  16. parameter integer TRACE_ADDR_W = 10
  17. )(
  18. input wire clk,
  19. input wire reset_n,
  20. input wire capture_reset,
  21. input wire trace_valid,
  22. input wire [15:0] trace_id,
  23. input wire [15:0] trace_timestamp,
  24. input wire [31:0] trace_data,
  25. output reg [15:0] captured_count,
  26. output reg [31:0] drop_count,
  27. output reg overflow,
  28. input wire rd_en,
  29. input wire [TRACE_ADDR_W-1:0] rd_addr,
  30. output reg [63:0] rd_data
  31. );
  32. reg [63:0] mem [0:TRACE_DEPTH-1];
  33. reg [TRACE_ADDR_W-1:0] wr_addr;
  34. always @(posedge clk or negedge reset_n) begin
  35. if (!reset_n) begin
  36. wr_addr <= {TRACE_ADDR_W{1'b0}};
  37. captured_count <= 16'd0;
  38. drop_count <= 32'd0;
  39. overflow <= 1'b0;
  40. end else if (capture_reset) begin
  41. wr_addr <= {TRACE_ADDR_W{1'b0}};
  42. captured_count <= 16'd0;
  43. drop_count <= 32'd0;
  44. overflow <= 1'b0;
  45. end else if (trace_valid) begin
  46. if (captured_count < TRACE_DEPTH) begin
  47. mem[wr_addr] <= {trace_timestamp, trace_id, trace_data};
  48. wr_addr <= wr_addr + 1'b1;
  49. captured_count <= captured_count + 1'b1;
  50. end else begin
  51. drop_count <= drop_count + 1'b1;
  52. overflow <= 1'b1;
  53. end
  54. end
  55. end
  56. // Synchronous read: friendlier to true block-RAM inference.
  57. always @(posedge clk) begin
  58. if (rd_en)
  59. rd_data <= mem[rd_addr];
  60. end
  61. endmodule