custom axi interconnect
custom axi interconnect
[!tip] goal
- create an axi interconnect between an in-order processor and memory (memory controller?)
- implement custom logic (hardware rtl) inside the axi interconnect to measure the average memory access times
todo
- implement a simple axi interconnect in sv
- simulate and test in sv and verilator
- plan the custom logic for latency measurement
- implement the logic separately and test
- try to integrate axi interconnect and the custom logic
sort
- Start with a standard AXI interconnect structure
- Add latency measurement logic
- Implement a control signal interface
- Create a mechanism to provide the measured latency to the processor
Let’s break this down step by step:
-
Standard AXI Interconnect:
- Implement the basic AXI protocol handling for read and write channels
- Ensure proper routing between the processor (master) and memory (slave)
-
Latency Measurement Logic:
- Add counters to track the time between request initiation and completion
- Implement separate tracking for read and write transactions
- Calculate running averages of latencies
-
Control Signal Interface:
- Add a dedicated input signal for triggering latency reporting
- Implement a state machine to handle the control signal
-
Latency Reporting Mechanism:
- Design a method to transfer the latency data to the processor
- This could be through a dedicated AXI-Lite interface or custom signals
Here’s a basic Verilog implementation outline for this enhanced AXI interconnect:
module axi_interconnect_with_latency ( input wire clk, input wire rst_n,
// AXI slave interface (from processor) input wire [31:0] s_axi_awaddr, input wire s_axi_awvalid, output wire s_axi_awready, input wire [31:0] s_axi_wdata, input wire s_axi_wvalid, output wire s_axi_wready, output wire [1:0] s_axi_bresp, output wire s_axi_bvalid, input wire s_axi_bready, input wire [31:0] s_axi_araddr, input wire s_axi_arvalid, output wire s_axi_arready, output wire [31:0] s_axi_rdata, output wire [1:0] s_axi_rresp, output wire s_axi_rvalid, input wire s_axi_rready,
// AXI master interface (to memory) output wire [31:0] m_axi_awaddr, output wire m_axi_awvalid, input wire m_axi_awready, output wire [31:0] m_axi_wdata, output wire m_axi_wvalid, input wire m_axi_wready, input wire [1:0] m_axi_bresp, input wire m_axi_bvalid, output wire m_axi_bready, output wire [31:0] m_axi_araddr, output wire m_axi_arvalid, input wire m_axi_arready, input wire [31:0] m_axi_rdata, input wire [1:0] m_axi_rresp, input wire m_axi_rvalid, output wire m_axi_rready,
// Control and status signals input wire measure_latency, output reg [31:0] avg_read_latency, output reg [31:0] avg_write_latency);
// Latency measurement variables reg [31:0] read_start_time, write_start_time; reg [31:0] read_latency_sum, write_latency_sum; reg [31:0] read_count, write_count;
// State machine states localparam IDLE = 2'b00, MEASURE = 2'b01, REPORT = 2'b10; reg [1:0] state;
// AXI interconnect logic (simplified for brevity) assign m_axi_awaddr = s_axi_awaddr; assign m_axi_awvalid = s_axi_awvalid; assign s_axi_awready = m_axi_awready; assign m_axi_wdata = s_axi_wdata; assign m_axi_wvalid = s_axi_wvalid; assign s_axi_wready = m_axi_wready; assign s_axi_bresp = m_axi_bresp; assign s_axi_bvalid = m_axi_bvalid; assign m_axi_bready = s_axi_bready; assign m_axi_araddr = s_axi_araddr; assign m_axi_arvalid = s_axi_arvalid; assign s_axi_arready = m_axi_arready; assign s_axi_rdata = m_axi_rdata; assign s_axi_rresp = m_axi_rresp; assign s_axi_rvalid = m_axi_rvalid; assign m_axi_rready = s_axi_rready;
// Latency measurement logic always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= IDLE; read_latency_sum <= 0; write_latency_sum <= 0; read_count <= 0; write_count <= 0; avg_read_latency <= 0; avg_write_latency <= 0; end else begin case (state) IDLE: begin if (measure_latency) state <= MEASURE; end
MEASURE: begin // Start read transaction if (s_axi_arvalid && s_axi_arready) read_start_time <= $time;
// End read transaction if (s_axi_rvalid && s_axi_rready) begin read_latency_sum <= read_latency_sum + ($time - read_start_time); read_count <= read_count + 1; end
// Start write transaction if (s_axi_awvalid && s_axi_awready) write_start_time <= $time;
// End write transaction if (s_axi_bvalid && s_axi_bready) begin write_latency_sum <= write_latency_sum + ($time - write_start_time); write_count <= write_count + 1; end
// Transition to REPORT state when measurement period ends if (!measure_latency) state <= REPORT; end
REPORT: begin // Calculate average latencies avg_read_latency <= (read_count > 0) ? read_latency_sum / read_count : 0; avg_write_latency <= (write_count > 0) ? write_latency_sum / write_count : 0;
// Reset counters and return to IDLE read_latency_sum <= 0; write_latency_sum <= 0; read_count <= 0; write_count <= 0; state <= IDLE; end endcase end end
endmoduleThis implementation provides a basic framework for an AXI interconnect with latency measurement capabilities. Here’s a breakdown of its key components:
-
AXI Interfaces: The module includes both slave (processor-facing) and master (memory-facing) AXI interfaces.
-
Latency Measurement: The module tracks the start and end times of read and write transactions, accumulating the total latency and transaction count.
-
Control Signal: The
measure_latencyinput signal triggers the latency measurement period. -
State Machine: A simple state machine (IDLE, MEASURE, REPORT) controls the measurement and reporting process.
-
Latency Reporting: The average read and write latencies are output as
avg_read_latencyandavg_write_latency.
To use this interconnect:
- Integrate it between your processor (AXI master) and memory (AXI slave).
- Connect the
measure_latencysignal to your processor’s control logic. - When the processor needs latency information, it should:
a. Assert the
measure_latencysignal for the desired measurement period. b. De-assertmeasure_latencyto trigger the calculation of average latencies. c. Read theavg_read_latencyandavg_write_latencyoutputs.
Note that this is a simplified implementation and may need additional features depending on your specific requirements, such as:
- Support for multiple AXI slaves
- More sophisticated latency calculations (e.g., min/max latencies, histograms)
- AXI-Lite interface for configuration and status reporting
- Clock domain crossing if the processor and memory operate at different frequencies
references
https://zipcpu.com/blog/2021/08/14/axiperf.html https://github.com/alexforencich/verilog-axi/tree/38915fb5330cb8270b454afc0140a94489dc56db/rtl