Commit e495ff21 authored by Jaco Hofmann's avatar Jaco Hofmann

Adds performance counters to BlueDMA

    - Closes #89
    - Adopts DebugScreen accordingly
    - Implements all registers requested in #89 expect for
      * Host read delay
      * FPGA read delay
parent 9b59398d
......@@ -23,6 +23,8 @@ public:
for(int i = 0; i < pba_vecs; ++i) {
intr.pba.push_back(0);
}
uint64_t accumulated_delay = 199;
platform::platform_write_ctl(0x300000 + 96, sizeof(accumulated_delay), &accumulated_delay, platform::PLATFORM_CTL_FLAGS_RAW);
}
virtual ~BlueDebugScreen() {}
......@@ -54,13 +56,10 @@ protected:
platform::platform_read_ctl(0x300000 + 40, sizeof(dma.status), &dma.status, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 48, sizeof(dma.read_requests), &dma.read_requests, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 56, sizeof(dma.write_requests), &dma.write_requests, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 64, sizeof(dma.ack_count), &dma.ack_count, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 120, sizeof(dma.reads_faulty), &dma.reads_faulty, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 128, sizeof(dma.writes_faulty), &dma.writes_faulty, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 136, sizeof(dma.get_delay), &dma.get_delay, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 144, sizeof(dma.put_delay), &dma.put_delay, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 152, sizeof(dma.last_written), &dma.last_written, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 160, sizeof(dma.last_read), &dma.last_read, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 64, sizeof(dma.last_request), &dma.last_request, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 72, sizeof(dma.cycles_between), &dma.cycles_between, platform::PLATFORM_CTL_FLAGS_RAW);
platform::platform_read_ctl(0x300000 + 96, sizeof(dma.cycles_between_set), &dma.cycles_between_set, platform::PLATFORM_CTL_FLAGS_RAW);
++dma.cycles_between_set; // Register contains num requests - 1
// Update Interrupt data
uint32_t base_addr = 0x500000;
......@@ -97,13 +96,9 @@ private:
uint64_t status;
uint64_t read_requests;
uint64_t write_requests;
uint64_t ack_count;
uint64_t reads_faulty;
uint64_t writes_faulty;
uint64_t get_delay;
uint64_t put_delay;
uint64_t last_written;
uint64_t last_read;
uint64_t last_request;
uint64_t cycles_between;
uint64_t cycles_between_set;
};
struct interrupt_data {
......@@ -124,37 +119,33 @@ private:
dma_regs dma;
intr_regs intr;
const int32_t total_interrupts = 64;
const int32_t total_interrupts = 131;
void render_dma(int start_row, int start_col) {
mvprintw(start_row++, start_col, "Host Address: %016lx, FPGA Address: %016lx", dma.host_addr, dma.fpga_addr);
mvprintw(start_row++, start_col, "Bytes to Transfer: %ld", dma.transfer_length);
mvprintw(start_row++, start_col, "Read requests: %ld, Reads faulty: %ld", dma.read_requests, dma.reads_faulty);
mvprintw(start_row++, start_col, "Write requests: %ld, Writes faulty: %ld", dma.write_requests, dma.writes_faulty);
mvprintw(start_row++, start_col, "ACKs: %ld", dma.ack_count);
mvprintw(start_row++, start_col, "Last written: %lx, Last read: %lx", dma.last_written, dma.last_read);
uint32_t total_gets = (dma.get_delay & 0xFFFFFFFF);
uint32_t total_puts = (dma.put_delay & 0xFFFFFFFF);
uint32_t get_delay = (dma.get_delay >> 32);
uint32_t put_delay = (dma.put_delay >> 32);
double get_latency = (double) get_delay / (double) total_gets;
double put_latency = (double) put_delay / (double) total_puts;
mvprintw(start_row++, start_col, "Put Delay: %f, Total Puts: %d %d", put_latency, total_puts, put_delay);
mvprintw(start_row++, start_col, "Get Delay: %f, Total Gets: %d %d", get_latency, total_gets, get_delay);
mvprintw(start_row++, start_col, "Host Address: %lx, FPGA Address: %lx", dma.host_addr, dma.fpga_addr);
mvprintw(start_row++, start_col, "Transfer length: %ld, CMD: %lx", dma.transfer_length, dma.cmd);
mvprintw(start_row++, start_col, "Read Requests: %ld, Write Requests: %ld", dma.read_requests, dma.write_requests);
float frequency = 250000000.0f;
float transfer_ms = (dma.last_request/frequency) * 1000;
float transfer_mib = ((1000.0f / transfer_ms) * dma.transfer_length) / (1024.0f * 1024.0f);
mvprintw(start_row++, start_col, "ms for last request: %f / %f MiB", transfer_ms, transfer_mib);
transfer_ms = ((dma.cycles_between/dma.cycles_between_set)/frequency) * 1000;
transfer_mib = ((1000.0f / transfer_ms) * dma.transfer_length) / (1024.0f * 1024.0f);
mvprintw(start_row++, start_col, "ms averaged over last %ld request(s): %f / %f MiB", dma.cycles_between_set, transfer_ms, transfer_mib);
}
void render_msix(int start_row, int start_col) {
mvprintw(start_row++, start_col, "Core ID: %x", intr.core_id);
for(int i = 0; i < total_interrupts; ++i) {
for(int i = 0; i < 8; ++i) {
if(!intr.interrupts[i].vector_control) {
mvprintw(start_row++, start_col, "Interrupt %d Address: %016lx Data: %08x Vector: %08x", i, intr.interrupts[i].addr, intr.interrupts[i].data, intr.interrupts[i].vector_control);
}
}
int pba_vecs = (total_interrupts / 64) + ((total_interrupts % 64) != 0);
for(int i = 0; i < pba_vecs; ++i) {
mvprintw(start_row++, start_col, "PBA %d - %d: %16lx", i * 64, i * 64 + 63, intr.pba[i]);
mvprintw(start_row++, start_col, "PBA %3d - %3d: %16lx", i * 64, i * 64 + 63, intr.pba[i]);
}
mvprintw(start_row++, start_col, "Enable: %x Mask: %x", (intr.enableAndMask >> 16) & 0x1, intr.enableAndMask & 0x1);
mvprintw(start_row++, start_col, "Sent Interrupts: %d", intr.sentInterrupts);
......
This diff is collapsed.
// Copyright (c) 2000-2013 Bluespec, Inc.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// $Revision: 30617 $
// $Date: 2013-02-20 17:47:41 +0000 (Wed, 20 Feb 2013) $
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
`endif
`ifdef BSV_POSITIVE_RESET
`define BSV_RESET_VALUE 1'b1
`define BSV_RESET_EDGE posedge
`else
`define BSV_RESET_VALUE 1'b0
`define BSV_RESET_EDGE negedge
`endif
//
// Transfer takes 2 dCLK to see data,
// sRDY recovers takes 2 dCLK + 2 sCLK
module SyncHandshake(
sCLK,
sRST,
dCLK,
sEN,
sRDY,
dPulse
);
parameter init = 1'b0;
parameter delayreturn = 1'b0;
// Source clock port signal
input sCLK ;
input sRST ;
input sEN ;
output sRDY ;
// Destination clock port signal
input dCLK ;
output dPulse ;
// Flops to hold data
reg dSyncReg1, dSyncReg2 ;
reg dLastState ;
reg sToggleReg ;
reg sSyncReg1, sSyncReg2 ;
// Output signal
assign dPulse = dSyncReg2 != dLastState ;
assign sRDY = sSyncReg2 == sToggleReg;
wire ackValue = delayreturn ? dLastState : dSyncReg2 ;
always @(posedge sCLK or `BSV_RESET_EDGE sRST)
begin
if (sRST == `BSV_RESET_VALUE)
begin
sSyncReg1 <= `BSV_ASSIGNMENT_DELAY ! init ; // Reset hi so sRDY is low during reset
sSyncReg2 <= `BSV_ASSIGNMENT_DELAY ! init ;
sToggleReg <= `BSV_ASSIGNMENT_DELAY init ;
end
else
begin
// hadshake return synchronizer
sSyncReg1 <= `BSV_ASSIGNMENT_DELAY ackValue ;// clock domain crossing
sSyncReg2 <= `BSV_ASSIGNMENT_DELAY sSyncReg1 ;
// Pulse send
if ( sEN )
begin
sToggleReg <= `BSV_ASSIGNMENT_DELAY ! sToggleReg ;
end // if ( sEN )
end
end // always @ (posedge sCLK or `BSV_RESET_EDGE sRST)
always @(posedge dCLK or `BSV_RESET_EDGE sRST)
begin
if (sRST == `BSV_RESET_VALUE)
begin
dSyncReg1 <= `BSV_ASSIGNMENT_DELAY init;
dSyncReg2 <= `BSV_ASSIGNMENT_DELAY init;
dLastState <= `BSV_ASSIGNMENT_DELAY init ;
end
else
begin
dSyncReg1 <= `BSV_ASSIGNMENT_DELAY sToggleReg ;// domain crossing
dSyncReg2 <= `BSV_ASSIGNMENT_DELAY dSyncReg1 ;
dLastState <= `BSV_ASSIGNMENT_DELAY dSyncReg2 ;
end
end // always @ (posedge dCLK or `BSV_RESET_EDGE sRST)
`ifdef BSV_NO_INITIAL_BLOCKS
`else // not BSV_NO_INITIAL_BLOCKS
// synopsys translate_off
initial
begin
dSyncReg1 = init ;
dSyncReg2 = init ;
dLastState = init ;
sToggleReg = init ;
sSyncReg1 = ! init ;
sSyncReg2 = ! init ;
end // initial begin
// synopsys translate_on
`endif // BSV_NO_INITIAL_BLOCKS
endmodule // HandshakeSync
// Copyright (c) 2000-2013 Bluespec, Inc.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// $Revision: 30617 $
// $Date: 2013-02-20 17:47:41 +0000 (Wed, 20 Feb 2013) $
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
`endif
`ifdef BSV_POSITIVE_RESET
`define BSV_RESET_VALUE 1'b1
`define BSV_RESET_EDGE posedge
`else
`define BSV_RESET_VALUE 1'b0
`define BSV_RESET_EDGE negedge
`endif
// A register synchronization module across clock domains.
// Uses a Handshake Pulse protocol to trigger the load on
// destination side registers
// Transfer takes 3 dCLK for destination side to see data,
// sRDY recovers takes 3 dCLK + 3 sCLK
module SyncRegister(
sCLK,
sRST,
dCLK,
sEN,
sRDY,
sD_IN,
dD_OUT
);
parameter width = 1 ;
parameter init = { width {1'b0 }} ;
// Source clock domain ports
input sCLK ;
input sRST ;
input sEN ;
input [width -1 : 0] sD_IN ;
output sRDY ;
// Destination clock domain ports
input dCLK ;
output [width -1 : 0] dD_OUT ;
wire dPulse ;
reg [width -1 : 0] sDataSyncIn ;
reg [width -1 : 0] dD_OUT ;
// instantiate a Handshake Sync
SyncHandshake #(.init(0),.delayreturn(1))
sync( .sCLK(sCLK), .sRST(sRST),
.dCLK(dCLK),
.sEN(sEN), .sRDY(sRDY),
.dPulse(dPulse) ) ;
always @(posedge sCLK or `BSV_RESET_EDGE sRST)
begin
if (sRST == `BSV_RESET_VALUE)
begin
sDataSyncIn <= `BSV_ASSIGNMENT_DELAY init ;
end // if (sRST == `BSV_RESET_VALUE)
else
begin
if ( sEN )
begin
sDataSyncIn <= `BSV_ASSIGNMENT_DELAY sD_IN ;
end // if ( sEN )
end // else: !if(sRST == `BSV_RESET_VALUE)
end // always @ (posedge sCLK or `BSV_RESET_EDGE sRST)
// Transfer the data to destination domain when dPulsed is asserted.
// Setup and hold time are assured since at least 2 dClks occured since
// sDataSyncIn have been written.
always @(posedge dCLK or `BSV_RESET_EDGE sRST)
begin
if (sRST == `BSV_RESET_VALUE)
begin
dD_OUT <= `BSV_ASSIGNMENT_DELAY init ;
end // if (sRST == `BSV_RESET_VALUE)
else
begin
if ( dPulse )
begin
dD_OUT <= `BSV_ASSIGNMENT_DELAY sDataSyncIn ;// clock domain crossing
end // if ( dPulse )
end // else: !if(sRST == `BSV_RESET_VALUE)
end // always @ (posedge dCLK or `BSV_RESET_EDGE sRST)
`ifdef BSV_NO_INITIAL_BLOCKS
`else // not BSV_NO_INITIAL_BLOCKS
// synopsys translate_off
initial
begin
sDataSyncIn = {((width + 1)/2){2'b10}} ;
dD_OUT = {((width + 1)/2){2'b10}} ;
end // initial begin
// synopsys translate_on
`endif // BSV_NO_INITIAL_BLOCKS
endmodule // RegisterSync
`ifdef testBluespec
module testSyncRegister() ;
parameter dsize = 8;
wire sCLK, sRST, dCLK ;
wire sEN ;
wire sRDY ;
reg [dsize -1:0] sCNT ;
wire [dsize -1:0] sDIN, dDOUT ;
ClockGen#(20,9,10) sc( sCLK );
ClockGen#(11,12,26) dc( dCLK );
initial
begin
sCNT = 0;
$dumpfile("SyncRegister.dump");
$dumpvars(5) ;
$dumpon ;
#100000 $finish ;
end
SyncRegister #(dsize)
dut( sCLK, sRST, dCLK,
sEN, sRDY, sDIN,
dDOUT ) ;
assign sDIN = sCNT ;
assign sEN = sRDY ;
always @(posedge sCLK)
begin
if (sRDY )
begin
sCNT <= `BSV_ASSIGNMENT_DELAY sCNT + 1;
end
end // always @ (posedge sCLK)
endmodule // testSyncFIFO
`endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment