scope analyzer bug fixes

This commit is contained in:
Blaise Tine 2024-09-21 08:39:20 -07:00
parent 7938c7be5f
commit 00feb8b424
13 changed files with 241 additions and 242 deletions

View file

@ -170,8 +170,9 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
if (reset) begin
cmd_scope_reading <= 0;
cmd_scope_writing <= 0;
scope_bus_in <= 0;
scope_bus_in <= 0;
end else begin
scope_bus_in <= 0;
if (scope_bus_out) begin
cmd_scope_reading <= 1;
scope_bus_ctr <= 63;
@ -183,20 +184,21 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
scope_bus_ctr <= 63;
scope_bus_in <= 1;
end
end
if (cmd_scope_writing) begin
scope_bus_in <= 1'(cmd_scope_wdata >> scope_bus_ctr);
scope_bus_ctr <= scope_bus_ctr - 6'd1;
if (scope_bus_ctr == 0) begin
cmd_scope_writing <= 0;
scope_bus_in <= 0;
if (cmd_scope_writing) begin
scope_bus_in <= 1'(cmd_scope_wdata >> scope_bus_ctr);
scope_bus_ctr <= scope_bus_ctr - 6'd1;
if (scope_bus_ctr == 0) begin
cmd_scope_writing <= 0;
scope_bus_ctr <= 0;
end
end
end
if (cmd_scope_reading) begin
cmd_scope_rdata <= {cmd_scope_rdata[62:0], scope_bus_out};
scope_bus_ctr <= scope_bus_ctr - 6'd1;
if (scope_bus_ctr == 0) begin
cmd_scope_reading <= 0;
if (cmd_scope_reading) begin
cmd_scope_rdata <= {cmd_scope_rdata[62:0], scope_bus_out};
scope_bus_ctr <= scope_bus_ctr - 6'd1;
if (scope_bus_ctr == 0) begin
cmd_scope_reading <= 0;
scope_bus_ctr <= 0;
end
end
end
end
@ -327,7 +329,7 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
`ifdef SCOPE
MMIO_SCOPE_WRITE: begin
`ifdef DBG_TRACE_AFU
`TRACE(2, ("%t: AFU: MMIO_SCOPE_WRITE: data=0x%h\n", $time, cmd_scope_wdata))
`TRACE(2, ("%t: AFU: MMIO_SCOPE_WRITE: data=0x%h\n", $time, 64'(cp2af_sRxPort.c0.data)))
`endif
end
`endif
@ -918,7 +920,7 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
// Vortex ///////////////////////////////////////////////////////////////////
wire vx_dcr_wr_valid = (STATE_DCR_WRITE == state);
wire vx_dcr_wr_valid = (STATE_DCR_WRITE == state);
wire [`VX_DCR_ADDR_WIDTH-1:0] vx_dcr_wr_addr = cmd_dcr_addr;
wire [`VX_DCR_DATA_WIDTH-1:0] vx_dcr_wr_data = cmd_dcr_data;
@ -1002,11 +1004,10 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
// SCOPE //////////////////////////////////////////////////////////////////////
`ifdef DBG_SCOPE_AFU
wire mem_req_fire = mem_bus_if[0].req_valid && mem_bus_if[0].req_ready;
wire mem_rsp_fire = mem_bus_if[0].rsp_valid && mem_bus_if[0].rsp_ready;
wire avs_write_fire = avs_write[0] && ~avs_waitrequest[0];
wire avs_read_fire = avs_read[0] && ~avs_waitrequest[0];
wire [LMEM_ADDR_WIDTH-1:0] mem_bus_if_addr = mem_bus_if[0].req_data.addr;
wire avs_write_fire = avs_write[0] && ~avs_waitrequest[0];
wire avs_read_fire = avs_read[0] && ~avs_waitrequest[0];
wire vx_mem_req_fire = vx_mem_req_valid && vx_mem_req_ready;
wire vx_mem_rsp_fire = vx_mem_rsp_valid && vx_mem_rsp_ready;
reg [STATE_WIDTH-1:0] state_prev;
always @(posedge clk) begin
@ -1016,9 +1017,12 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
`define AFU_TRIGGERS { \
reset, \
vx_reset, \
vx_busy, \
vx_mem_req_fire, \
vx_mem_rsp_fire, \
vx_dcr_wr_valid, \
state_changed, \
mem_req_fire, \
mem_rsp_fire, \
avs_write_fire, \
avs_read_fire, \
avs_waitrequest[0], \
@ -1044,6 +1048,15 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
`define AFU_PROBES { \
cmd_type, \
state, \
vx_mem_req_rw, \
vx_mem_req_byteen, \
vx_mem_req_addr, \
vx_mem_req_data, \
vx_mem_req_tag, \
vx_mem_rsp_data, \
vx_mem_rsp_tag, \
vx_dcr_wr_addr, \
vx_dcr_wr_data, \
mmio_req_hdr.address, \
cp2af_sRxPort.c0.hdr.mdata, \
af2cp_sTxPort.c0.hdr.address, \
@ -1056,8 +1069,7 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
cci_mem_wr_req_ctr, \
cci_rd_req_ctr, \
cci_rd_rsp_ctr, \
cci_wr_req_ctr, \
mem_bus_if_addr \
cci_wr_req_ctr \
}
VX_scope_tap #(
@ -1066,13 +1078,13 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
.PROBEW ($bits(`AFU_PROBES)),
.DEPTH (4096)
) scope_tap (
.clk(clk),
.reset(scope_reset_w[0]),
.start(1'b0),
.stop(1'b0),
.clk (clk),
.reset (scope_reset_w[0]),
.start (1'b0),
.stop (1'b0),
.triggers(`AFU_TRIGGERS),
.probes(`AFU_PROBES),
.bus_in(scope_bus_in_w[0]),
.probes (`AFU_PROBES),
.bus_in (scope_bus_in_w[0]),
.bus_out(scope_bus_out_w[0])
);
`else

View file

@ -204,6 +204,7 @@ module VX_afu_ctrl #(
scope_bus_rdata <= '0;
scope_rdata_valid <= 0;
end else begin
scope_bus_out_r <= 0;
if (s_axi_aw_fire) begin
is_scope_waddr <= (s_axi_awaddr[ADDR_BITS-1:0] == ADDR_SCP_0)
|| (s_axi_awaddr[ADDR_BITS-1:0] == ADDR_SCP_1);
@ -221,7 +222,6 @@ module VX_afu_ctrl #(
scope_rdata_valid <= 0;
scope_bus_out_r <= 1;
scope_bus_ctr <= 63;
end
if (scope_bus_in) begin
cmd_scope_reading <= 1;
@ -234,6 +234,7 @@ module VX_afu_ctrl #(
if (scope_bus_ctr == 0) begin
cmd_scope_reading <= 0;
scope_rdata_valid <= 1;
scope_bus_ctr <= 0;
end
end
if (cmd_scope_writing) begin
@ -241,7 +242,7 @@ module VX_afu_ctrl #(
scope_bus_ctr <= scope_bus_ctr - 1;
if (scope_bus_ctr == 0) begin
cmd_scope_writing <= 0;
scope_bus_out_r <= '0;
scope_bus_ctr <= 0;
end
end
end

View file

@ -299,8 +299,8 @@ module VX_afu_wrap #(
// SCOPE //////////////////////////////////////////////////////////////////////
`ifdef DBG_SCOPE_AFU
`ifdef SCOPE
`ifdef DBG_SCOPE_AFU
`define AFU_TRIGGERS { \
reset, \
ap_reset, \
@ -308,9 +308,9 @@ module VX_afu_wrap #(
ap_done, \
ap_idle, \
interrupt, \
vx_busy_wait, \
vx_busy, \
vx_reset, \
vx_busy, \
dcr_wr_valid, \
m_axi_mem_awvalid_a[0], \
m_axi_mem_awready_a[0], \
m_axi_mem_wvalid_a[0], \
@ -320,19 +320,18 @@ module VX_afu_wrap #(
m_axi_mem_arvalid_a[0], \
m_axi_mem_arready_a[0], \
m_axi_mem_rvalid_a[0], \
m_axi_mem_rready_a[0], \
dcr_wr_valid \
m_axi_mem_rready_a[0] \
}
`define AFU_PROBES { \
dcr_wr_addr, \
dcr_wr_data, \
vx_pending_writes, \
m_axi_mem_awaddr_u[0], \
m_axi_mem_awid_a[0], \
m_axi_mem_bid_a[0], \
m_axi_mem_araddr_u[0], \
m_axi_mem_arid_a[0], \
m_axi_mem_rid_a[0], \
dcr_wr_addr, \
dcr_wr_data \
m_axi_mem_rid_a[0] \
}
VX_scope_tap #(
.SCOPE_ID (0),
@ -340,18 +339,19 @@ module VX_afu_wrap #(
.PROBEW ($bits(`AFU_PROBES)),
.DEPTH (4096)
) scope_tap (
.clk (clk),
.reset (scope_reset_w[0]),
.start (1'b0),
.stop (1'b0),
.triggers (`AFU_TRIGGERS),
.clk (clk),
.reset (scope_reset_w[0]),
.start (1'b0),
.stop (1'b0),
.triggers(`AFU_TRIGGERS),
.probes (`AFU_PROBES),
.bus_in (scope_bus_in_w[0]),
.bus_out (scope_bus_out_w[0])
.bus_out(scope_bus_out_w[0])
);
`else
`SCOPE_IO_UNUSED_W(0)
`endif
`endif
`ifdef CHIPSCOPE
ila_afu ila_afu_inst (
.clk (clk),
@ -373,7 +373,6 @@ module VX_afu_wrap #(
})
);
`endif
`endif
`ifdef SIMULATION
`ifndef VERILATOR

View file

@ -135,8 +135,8 @@ module VX_fetch import VX_gpu_pkg::*; #(
assign fetch_if.data.uuid = rsp_uuid;
assign icache_bus_if.rsp_ready = fetch_if.ready;
`ifdef DBG_SCOPE_FETCH
`ifdef SCOPE
`ifdef DBG_SCOPE_FETCH
VX_scope_tap #(
.SCOPE_ID (1),
.TRIGGERW (4),
@ -166,6 +166,7 @@ module VX_fetch import VX_gpu_pkg::*; #(
`else
`SCOPE_IO_UNUSED()
`endif
`endif
`ifdef CHIPSCOPE
ila_fetch ila_fetch_inst (
.clk (clk),
@ -174,7 +175,6 @@ module VX_fetch import VX_gpu_pkg::*; #(
.probe2 ({icache_bus_if.rsp_valid, icache_bus_if.rsp_data, icache_bus_if.rsp_ready})
);
`endif
`endif
`ifdef DBG_TRACE_MEM
always @(posedge clk) begin

View file

@ -93,8 +93,8 @@ module VX_issue_slice import VX_gpu_pkg::*; #(
.dispatch_if (dispatch_if)
);
`ifdef DBG_SCOPE_ISSUE
`ifdef SCOPE
`ifdef DBG_SCOPE_ISSUE
VX_scope_tap #(
.SCOPE_ID (2),
.TRIGGERW (2),
@ -133,6 +133,7 @@ module VX_issue_slice import VX_gpu_pkg::*; #(
`else
`SCOPE_IO_UNUSED()
`endif
`endif
`ifdef CHIPSCOPE
ila_issue ila_issue_inst (
.clk (clk),
@ -142,7 +143,6 @@ module VX_issue_slice import VX_gpu_pkg::*; #(
.probe3 ({writeback_if.valid, writeback_if.data})
);
`endif
`endif
`ifdef DBG_TRACE_PIPELINE
always @(posedge clk) begin

View file

@ -534,8 +534,8 @@ module VX_lsu_slice import VX_gpu_pkg::*; #(
end
`endif
`ifdef DBG_SCOPE_LSU
`ifdef SCOPE
`ifdef DBG_SCOPE_LSU
VX_scope_tap #(
.SCOPE_ID (3),
.TRIGGERW (2),
@ -554,6 +554,7 @@ module VX_lsu_slice import VX_gpu_pkg::*; #(
`else
`SCOPE_IO_UNUSED()
`endif
`endif
`ifdef CHIPSCOPE
ila_lsu ila_lsu_inst (
.clk (clk),
@ -562,6 +563,5 @@ module VX_lsu_slice import VX_gpu_pkg::*; #(
.probe2 ({lsu_mem_if.rsp_valid, lsu_mem_if.rsp_data, lsu_mem_if.rsp_ready})
);
`endif
`endif
endmodule

View file

@ -31,9 +31,7 @@ module VX_lsu_unit import VX_gpu_pkg::*; #(
localparam BLOCK_SIZE = `NUM_LSU_BLOCKS;
localparam NUM_LANES = `NUM_LSU_LANES;
`ifdef SCOPE
`SCOPE_IO_SWITCH (BLOCK_SIZE);
`endif
VX_execute_if #(
.NUM_LANES (NUM_LANES)

View file

@ -20,7 +20,7 @@ module VX_scope_tap #(
parameter TRIGGERW = 16, // trigger signals width
parameter PROBEW = 256, // probe signal width
parameter DEPTH = 1024, // trace buffer depth
parameter IDLE_CTRW = 16, // idle time between triggers counter width
parameter IDLE_CTRW = 32, // idle time between triggers counter width
parameter TX_DATAW = 64 // transfer data width
) (
input wire clk,
@ -64,33 +64,52 @@ module VX_scope_tap #(
localparam GET_TYPE_DATA = 2'd3;
localparam GET_TYPE_BITS = 2;
reg [`UP(TRIGGERW)-1:0] prev_triggers;
reg [IDLE_CTRW-1:0] delta;
reg [CTR_WIDTH-1:0] timestamp, start_time;
reg [ADDRW-1:0] waddr, waddr_end;
reg write_en;
reg cmd_start, delta_flush;
reg [CTR_WIDTH-1:0] start_delay, delay_cntr;
`STATIC_ASSERT ((IDLE_CTRW <= TX_DATAW), ("invalid parameter"))
reg [TAP_STATE_BITS-1:0] tap_state;
reg [CTRL_STATE_BITS-1:0] ctrl_state;
reg [GET_TYPE_BITS-1:0] get_type;
reg [CTR_WIDTH-1:0] timestamp, start_time;
reg [CTR_WIDTH-1:0] start_delay, delay_cntr;
reg [`UP(TRIGGERW)-1:0] prev_trig;
reg [IDLE_CTRW-1:0] delta;
reg cmd_start, dflush;
reg [ADDRW-1:0] waddr, waddr_end;
wire [DATAW-1:0] data_in;
wire write_en;
wire [DATAW-1:0] data_value;
wire [IDLE_CTRW-1:0] delta_value;
reg [TX_DATA_BITS-1:0] ser_tx_ctr;
reg [DATA_BITS-1:0] read_offset;
reg [ADDRW-1:0] raddr;
reg read_data;
wire [DATAW-1:0] data_in;
if (TRIGGERW != 0) begin
assign data_in = {probes, triggers};
end else begin
assign data_in = probes;
//
// trace capture
//
if (TRIGGERW != 0) begin : g_delta_store
assign data_in = {probes, triggers};
assign write_en = (tap_state == TAP_STATE_RUN) && (dflush || (triggers != prev_trig));
VX_dp_ram #(
.DATAW (IDLE_CTRW),
.SIZE (DEPTH),
.NO_RWCHECK (1)
) delta_store (
.clk (clk),
.reset (reset),
.read (1'b1),
.wren (1'b1),
.write (write_en),
.waddr (waddr),
.wdata (delta),
.raddr (raddr),
.rdata (delta_value)
);
end else begin : g_no_delta_store
assign data_in = probes;
assign write_en = (tap_state == TAP_STATE_RUN);
assign delta_value = '0;
end
VX_dp_ram #(
@ -109,76 +128,38 @@ module VX_scope_tap #(
.rdata (data_value)
);
if (TRIGGERW != 0) begin
VX_dp_ram #(
.DATAW (IDLE_CTRW),
.SIZE (DEPTH),
.NO_RWCHECK (1)
) delta_store (
.clk (clk),
.reset (reset),
.read (1'b1),
.wren (1'b1),
.write (write_en),
.waddr (waddr),
.wdata (delta),
.raddr (raddr),
.rdata (delta_value)
);
end else begin
assign delta_value = '0;
end
//
// trace capture
//
wire [ADDRW-1:0] raddr_n = raddr + ADDRW'(1);
wire [ADDRW:0] count = (ADDRW+1)'(waddr) + (ADDRW+1)'(1);
always @(*) begin
write_en = 0;
if (tap_state == TAP_STATE_RUN) begin
if (TRIGGERW != 0) begin
if (delta_flush || (triggers != prev_triggers)) begin
write_en = 1;
end
end else begin
write_en = 1;
end
always @(posedge clk) begin
if (reset) begin
timestamp <= '0;
end else begin
timestamp <= timestamp + CTR_WIDTH'(1);
end
end
always @(posedge clk) begin
if (reset) begin
tap_state <= TAP_STATE_IDLE;
raddr <= '0;
waddr <= '0;
delta <= '0;
prev_triggers <= '0;
read_offset <= '0;
read_data <= 0;
timestamp <= '0;
tap_state <= TAP_STATE_IDLE;
delta <= '0;
dflush <= 0;
prev_trig <= '0;
waddr <= '0;
end else begin
timestamp <= timestamp + CTR_WIDTH'(1);
case (tap_state)
TAP_STATE_IDLE: begin
if (start || cmd_start) begin
delta <= '0;
delta_flush <= 1;
delta <= '0;
dflush <= 1;
if (0 == start_delay) begin
tap_state <= TAP_STATE_RUN;
start_time <= timestamp;
`ifdef DBG_TRACE_SCOPE
`TRACE(2, ("%t: *** scope #%0d: recording start - time=%0d\n", $time, SCOPE_ID, timestamp))
`TRACE(2, ("%t: scope_tap%0d: recording start - time=%0d\n", $time, SCOPE_ID, timestamp))
`endif
end else begin
tap_state <= TAP_STATE_WAIT;
delay_cntr <= start_delay;
`ifdef DBG_TRACE_SCOPE
`TRACE(2, ("%t: *** scope #%0d: delayed start - time=%0d\n", $time, SCOPE_ID, start_delay))
`TRACE(2, ("%t: scope_tap%0d: delayed start - time=%0d\n", $time, SCOPE_ID, start_delay))
`endif
end
end
@ -189,65 +170,39 @@ module VX_scope_tap #(
tap_state <= TAP_STATE_RUN;
start_time <= timestamp;
`ifdef DBG_TRACE_SCOPE
`TRACE(2, ("%t: *** scope #%0d: recording start - time=%0d\n", $time, SCOPE_ID, timestamp))
`TRACE(2, ("%t: scope_tap%0d: recording start - time=%0d\n", $time, SCOPE_ID, timestamp))
`endif
end
end
TAP_STATE_RUN: begin
if (TRIGGERW != 0) begin
if (delta_flush || (triggers != prev_triggers)) begin
waddr <= waddr + ADDRW'(1);
delta <= '0;
delta_flush <= 0;
dflush <= 0;
if (!stop && (waddr < waddr_end)) begin
if (TRIGGERW != 0) begin
if (dflush || (triggers != prev_trig)) begin
waddr <= waddr + ADDRW'(1);
delta <= '0;
end else begin
delta <= delta + IDLE_CTRW'(1);
dflush <= (delta == IDLE_CTRW'(MAX_IDLE_CTR-1));
end
prev_trig <= triggers;
end else begin
delta <= delta + IDLE_CTRW'(1);
delta_flush <= (delta == IDLE_CTRW'(MAX_IDLE_CTR-1));
waddr <= waddr + ADDRW'(1);
end
prev_triggers <= triggers;
end else begin
waddr <= waddr + ADDRW'(1);
end
if (stop || (waddr >= waddr_end)) begin
waddr <= waddr;
`ifdef DBG_TRACE_SCOPE
`TRACE(2, ("%t: *** scope #%0d: recording stop - waddr=(%0d, %0d)\n", $time, SCOPE_ID, waddr, waddr_end))
`endif
tap_state <= TAP_STATE_IDLE;
`ifdef DBG_TRACE_SCOPE
`TRACE(2, ("%t: scope_tap%0d: recording stop - waddr=(%0d, %0d)\n", $time, SCOPE_ID, waddr, waddr_end))
`endif
end
end
default:;
endcase
if (ctrl_state == CTRL_STATE_SEND
&& get_type == GET_TYPE_DATA
&& ser_tx_ctr == 0) begin
if (~read_data) begin
read_data <= 1;
end else begin
if (DATAW > TX_DATAW) begin
`IGNORE_WARNINGS_BEGIN
if (read_offset < DATA_BITS'(DATAW-TX_DATAW)) begin
read_offset <= read_offset + DATA_BITS'(TX_DATAW);
end else begin
raddr <= raddr_n;
read_data <= 0;
read_offset <= '0;
end
`IGNORE_WARNINGS_END
end else begin
raddr <= raddr_n;
read_data <= 0;
end
if (raddr_n == waddr) begin
raddr <= 0;
end
end
end
end
end
//
// command controller
// trace controller
//
reg bus_out_r;
@ -256,35 +211,45 @@ module VX_scope_tap #(
wire [TX_DATAW-1:0] ser_buf_in_n = {ser_buf_in[TX_DATAW-2:0], bus_in};
`UNUSED_VAR (ser_buf_in)
reg [TX_DATA_BITS-1:0] ser_tx_ctr;
reg [DATA_BITS-1:0] read_offset;
reg is_read_data;
wire [CMD_TYPE_BITS-1:0] cmd_type = ser_buf_in[CMD_TYPE_BITS-1:0];
wire [SCOPE_IDW-1:0] cmd_scope_id = ser_buf_in_n[CMD_TYPE_BITS +: SCOPE_IDW];
wire [TX_DATAW-CMD_TYPE_BITS-SCOPE_IDW-1:0] cmd_data = ser_buf_in[TX_DATAW-1:CMD_TYPE_BITS+SCOPE_IDW];
wire [TX_DATAW-1:0] data_chunk = TX_DATAW'(DATAW'(data_value >> read_offset));
wire [TX_DATAW-1:0] get_data = read_data ? data_chunk : TX_DATAW'(delta_value);
wire [TX_DATAW-1:0] get_data = is_read_data ? data_chunk : TX_DATAW'(delta_value);
wire [ADDRW-1:0] raddr_n = raddr + ADDRW'(1);
always @(posedge clk) begin
if (reset) begin
ctrl_state <= CTRL_STATE_IDLE;
waddr_end <= ADDRW'(DEPTH-1);
cmd_start <= 0;
start_delay <= '0;
waddr_end <= ADDRW'(DEPTH-1);
bus_out_r <= 0;
read_offset <= '0;
raddr <= '0;
is_read_data<= 0;
ser_tx_ctr <= '0;
end else begin
bus_out_r <= 0;
cmd_start <= 0;
case (ctrl_state)
CTRL_STATE_IDLE: begin
if (bus_in) begin
ser_tx_ctr <= TX_DATA_BITS'(TX_DATAW-1);
ctrl_state <= CTRL_STATE_RECV;
end
ser_tx_ctr <= TX_DATA_BITS'(TX_DATAW-1);
end
CTRL_STATE_RECV: begin
ser_tx_ctr <= ser_tx_ctr - TX_DATA_BITS'(1);
ser_buf_in <= ser_buf_in_n;
if (ser_tx_ctr == 0) begin
// check if command is for this scope
ctrl_state <= (cmd_scope_id == SCOPE_ID) ? CTRL_STATE_CMD : CTRL_STATE_IDLE;
end
end
@ -302,33 +267,32 @@ module VX_scope_tap #(
CMD_GET_START,
CMD_GET_COUNT,
CMD_GET_DATA: begin
ctrl_state <= CTRL_STATE_SEND;
get_type <= GET_TYPE_BITS'(cmd_type);
ser_tx_ctr <= TX_DATA_BITS'(TX_DATAW-1);
bus_out_r <= 1;
ctrl_state <= CTRL_STATE_SEND;
end
default:;
endcase
`ifdef DBG_TRACE_SCOPE
`TRACE(2, ("%t: *** scope #%0d: CMD: type=%0d\n", $time, SCOPE_ID, cmd_type))
`TRACE(2, ("%t: scope_tap%0d: CMD: type=%0d\n", $time, SCOPE_ID, cmd_type))
`endif
end
CTRL_STATE_SEND: begin
ser_tx_ctr <= ser_tx_ctr - TX_DATA_BITS'(1);
case (get_type)
GET_TYPE_WIDTH: begin
bus_out_r <= 1'(DATAW >> ser_tx_ctr);
`ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin
`TRACE(2, ("%t: *** scope #%0d: SEND width=%0d\n", $time, SCOPE_ID, DATAW))
`TRACE(2, ("%t: scope_tap%0d: SEND width=%0d\n", $time, SCOPE_ID, DATAW))
end
`endif
end
GET_TYPE_COUNT: begin
bus_out_r <= 1'(count >> ser_tx_ctr);
bus_out_r <= 1'(waddr >> ser_tx_ctr);
`ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin
`TRACE(2, ("%t: *** scope #%0d: SEND count=%0d\n", $time, SCOPE_ID, count))
`TRACE(2, ("%t: scope_tap%0d: SEND count=%0d\n", $time, SCOPE_ID, waddr))
end
`endif
end
@ -336,20 +300,46 @@ module VX_scope_tap #(
bus_out_r <= 1'(start_time >> ser_tx_ctr);
`ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin
`TRACE(2, ("%t: *** scope #%0d: SEND start=%0d\n", $time, SCOPE_ID, start_time))
`TRACE(2, ("%t: scope_tap%0d: SEND start=%0d\n", $time, SCOPE_ID, start_time))
end
`endif
end
GET_TYPE_DATA: begin
bus_out_r <= 1'(get_data >> ser_tx_ctr);
if (ser_tx_ctr == 0) begin
if (is_read_data) begin
if (DATAW > TX_DATAW) begin
if (read_offset < DATA_BITS'(DATAW-TX_DATAW)) begin
read_offset <= read_offset + DATA_BITS'(TX_DATAW);
end else begin
read_offset <= '0;
raddr <= raddr_n;
is_read_data <= 0; // swutch delta mode
end
end else begin
raddr <= raddr_n;
is_read_data <= 0; // swutch delta mode
end
if (raddr_n == waddr) begin
raddr <= 0; // end-of-samples reset
end
end else begin
is_read_data <= 1; // switch to data mode
end
end
`ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin
`TRACE(2, ("%t: *** scope #%0d: SEND data=%0d\n", $time, SCOPE_ID, get_data))
if (is_read_data) begin
`TRACE(2, ("%t: scope_tap%0d: SEND data=0x%0h\n", $time, SCOPE_ID, get_data))
end else begin
`TRACE(2, ("%t: scope_tap%0d: SEND delta=0x%0h\n", $time, SCOPE_ID, get_data))
end
end
`endif
end
default:;
endcase
ser_tx_ctr <= ser_tx_ctr - TX_DATA_BITS'(1);
if (ser_tx_ctr == 0) begin
ctrl_state <= CTRL_STATE_IDLE;
end

View file

@ -28,7 +28,7 @@
#include <unordered_set>
#include <sstream>
#define FRAME_FLUSH_SIZE 100
#define SAMPLE_FLUSH_SIZE 100
#define MMIO_SCOPE_READ (AFU_IMAGE_MMIO_SCOPE_READ * 4)
#define MMIO_SCOPE_WRITE (AFU_IMAGE_MMIO_SCOPE_WRITE * 4)
@ -58,8 +58,8 @@ struct tap_signal_t {
struct tap_t {
uint32_t id;
uint32_t width;
uint32_t frames;
uint32_t cur_frame;
uint32_t samples;
uint32_t cur_sample;
uint64_t cycle_time;
std::string path;
std::vector<tap_signal_t> signals;
@ -135,22 +135,25 @@ static void dump_header(std::ofstream& ofs, std::vector<tap_t>& taps) {
ofs << "enddefinitions $end" << std::endl;
}
static tap_t* find_nearest_tap(std::vector<tap_t>& taps) {
tap_t* nearest = nullptr;
// return the earliest tap that has data to dump
static tap_t* find_earliest_tap(std::vector<tap_t>& taps) {
tap_t* earliest = nullptr;
for (auto& tap : taps) {
if (tap.cur_frame == tap.frames)
continue;
if (nearest != nullptr) {
if (tap.cycle_time < nearest->cycle_time)
nearest = &tap;
if (tap.samples == 0)
continue; // skip empty taps
if (tap.cur_sample == tap.samples)
continue; // skip finished taps
if (earliest != nullptr) {
if (tap.cycle_time < earliest->cycle_time)
earliest = &tap;
} else {
nearest = &tap;
earliest = &tap;
}
}
return nearest;
return earliest;
}
static uint64_t advance_time(std::ofstream& ofs, uint64_t next_time, uint64_t cur_time) {
static uint64_t advance_time(std::ofstream& ofs, uint64_t cur_time, uint64_t next_time) {
while (cur_time < next_time) {
ofs << '#' << (cur_time * 2 + 0) << std::endl;
ofs << "b0 0" << std::endl;
@ -163,7 +166,7 @@ static uint64_t advance_time(std::ofstream& ofs, uint64_t next_time, uint64_t cu
static int dump_tap(std::ofstream& ofs, tap_t* tap, vx_device_h hdevice) {
uint32_t signal_offset = 0;
uint32_t frame_offset = 0;
uint32_t sample_offset = 0;
uint64_t word;
std::vector<char> signal_data(tap->width);
@ -176,24 +179,24 @@ static int dump_tap(std::ofstream& ofs, tap_t* tap, vx_device_h hdevice) {
CHECK_ERR(g_callback.registerWrite(hdevice, cmd_data));
CHECK_ERR(g_callback.registerRead(hdevice, &word));
do {
uint32_t word_offset = frame_offset % 64;
uint32_t word_offset = sample_offset % 64;
signal_data[signal_width - signal_offset - 1] = ((word >> word_offset) & 0x1) ? '1' : '0';
++signal_offset;
++frame_offset;
++sample_offset;
if (signal_offset == signal_width) {
signal_data[signal_width] = 0; // string null termination
ofs << 'b' << signal_data.data() << ' ' << signal_it->id << std::endl;
if (frame_offset == tap->width) {
// end-of-frame
++tap->cur_frame;
if (tap->cur_frame != tap->frames) {
if (sample_offset == tap->width) {
// end-of-sample
++tap->cur_sample;
if (tap->cur_sample != tap->samples) {
// read next delta
CHECK_ERR(g_callback.registerWrite(hdevice, cmd_data));
CHECK_ERR(g_callback.registerRead(hdevice, &word));
tap->cycle_time += 1 + word;
if (0 == (tap->cur_frame % FRAME_FLUSH_SIZE)) {
if (0 == (tap->cur_sample % SAMPLE_FLUSH_SIZE)) {
ofs << std::flush;
std::cout << std::dec << "[SCOPE] flush tap #" << tap->id << ": "<< tap->cur_frame << "/" << tap->frames << " frames, next_time=" << tap->cycle_time << std::endl;
std::cout << std::dec << "[SCOPE] flush tap #" << tap->id << ": "<< tap->cur_sample << "/" << tap->samples << " samples, next_time=" << tap->cycle_time << std::endl;
}
}
break;
@ -202,8 +205,8 @@ static int dump_tap(std::ofstream& ofs, tap_t* tap, vx_device_h hdevice) {
++signal_it;
signal_width = signal_it->width;
}
} while ((frame_offset % 64) != 0);
} while (frame_offset != tap->width);
} while ((sample_offset % 64) != 0);
} while (sample_offset != tap->width);
return 0;
}
@ -285,8 +288,8 @@ int vx_scope_stop(vx_device_h hdevice) {
_tap.width = tap["width"].get<uint32_t>();
_tap.path = tap["path"].get<std::string>();
_tap.cycle_time = 0;
_tap.frames = 0;
_tap.cur_frame = 0;
_tap.samples = 0;
_tap.cur_sample = 0;
for (auto& signal : tap["signals"]) {
auto name = signal[0].get<std::string>();
@ -299,19 +302,15 @@ int vx_scope_stop(vx_device_h hdevice) {
}
}
// stop recording
std::cout << "[SCOPE] stop recording..." << std::endl;
for (auto& tap : taps) {
uint64_t cmd_stop = (0 << 11) | (tap.id << 3) | CMD_SET_STOP;
CHECK_ERR(g_callback.registerWrite(hdevice, cmd_stop));
}
std::cout << "[SCOPE] trace dump begin..." << std::endl;
std::cout << "[SCOPE] load trace info..." << std::endl;
std::ofstream ofs("scope.vcd");
dump_header(ofs, taps);
// load trace info
for (auto& tap : taps) {
uint64_t count, start, delta;
@ -320,39 +319,53 @@ int vx_scope_stop(vx_device_h hdevice) {
CHECK_ERR(g_callback.registerWrite(hdevice, cmd_count));
CHECK_ERR(g_callback.registerRead(hdevice, &count));
if (count == 0)
continue;
// get start
uint64_t cmd_start = (tap.id << 3) | CMD_GET_START;
CHECK_ERR(g_callback.registerWrite(hdevice, cmd_start));
CHECK_ERR(g_callback.registerRead(hdevice, &start));
// get data
// get delta
uint64_t cmd_data = (tap.id << 3) | CMD_GET_DATA;
CHECK_ERR(g_callback.registerWrite(hdevice, cmd_data));
CHECK_ERR(g_callback.registerRead(hdevice, &delta));
tap.frames = count;
tap.samples = count;
tap.cycle_time = 1 + start + delta;
std::cout << std::dec << "[SCOPE] tap #" << tap.id
<< ": width=" << tap.width
<< ", num_frames=" << tap.frames
<< ", num_samples=" << tap.samples
<< ", start_time=" << tap.cycle_time
<< ", path=" << tap.path << std::endl;
}
std::cout << "[SCOPE] dump header..." << std::endl;
std::ofstream ofs("scope.vcd");
dump_header(ofs, taps);
std::cout << "[SCOPE] dump taps..." << std::endl;
uint64_t cur_time = 0;
while (true) {
// find the nearest tap
auto tap = find_nearest_tap(taps);
auto tap = find_earliest_tap(taps);
if (tap == nullptr)
break;
// advance clock
cur_time = advance_time(ofs, tap->cycle_time, cur_time);
cur_time = advance_time(ofs, cur_time, tap->cycle_time);
// dump tap
CHECK_ERR(dump_tap(ofs, tap, hdevice));
};
// advance clock
advance_time(ofs, cur_time, cur_time + 1);
std::cout << "[SCOPE] trace dump done! - " << (cur_time/2) << " cycles" << std::endl;
return 0;

View file

@ -581,14 +581,14 @@ public:
return err;
});
#ifdef CPP_API
xrtBuffer.write(host_ptr, asize, bo_offset);
xrtBuffer.sync(XCL_BO_SYNC_BO_TO_DEVICE, asize, bo_offset);
xrtBuffer.write(host_ptr, size, bo_offset);
xrtBuffer.sync(XCL_BO_SYNC_BO_TO_DEVICE, size, bo_offset);
#else
CHECK_ERR(xrtBOWrite(xrtBuffer, host_ptr, asize, bo_offset), {
CHECK_ERR(xrtBOWrite(xrtBuffer, host_ptr, size, bo_offset), {
dump_xrt_error(xrtDevice_, err);
return err;
});
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_TO_DEVICE, asize, bo_offset), {
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_TO_DEVICE, size, bo_offset), {
dump_xrt_error(xrtDevice_, err);
return err;
});
@ -627,14 +627,14 @@ public:
return err;
});
#ifdef CPP_API
xrtBuffer.sync(XCL_BO_SYNC_BO_FROM_DEVICE, asize, bo_offset);
xrtBuffer.read(host_ptr, asize, bo_offset);
xrtBuffer.sync(XCL_BO_SYNC_BO_FROM_DEVICE, size, bo_offset);
xrtBuffer.read(host_ptr, size, bo_offset);
#else
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_FROM_DEVICE, asize, bo_offset), {
CHECK_ERR(xrtBOSync(xrtBuffer, XCL_BO_SYNC_BO_FROM_DEVICE, size, bo_offset), {
dump_xrt_error(xrtDevice_, err);
return err;
});
CHECK_ERR(xrtBORead(xrtBuffer, host_ptr, asize, bo_offset), {
CHECK_ERR(xrtBORead(xrtBuffer, host_ptr, size, bo_offset), {
dump_xrt_error(xrtDevice_, err);
return err;
});

View file

@ -66,7 +66,6 @@ extern int xrtDeviceClose(xrtDeviceHandle dhdl) {
if (dhdl == nullptr)
return -1;
auto sim = reinterpret_cast<xrt_sim*>(dhdl);
sim->shutdown();
delete sim;
return 0;
}

View file

@ -197,13 +197,6 @@ public:
return 0;
}
void shutdown() {
stop_ = true;
if (future_.valid()) {
future_.wait();
}
}
int mem_alloc(uint64_t size, uint32_t bank_id, uint64_t* addr) {
if (bank_id >= M_AXI_MEM_NUM_BANKS)
return -1;
@ -615,10 +608,6 @@ int xrt_sim::init() {
return impl_->init();
}
void xrt_sim::shutdown() {
impl_->shutdown();
}
int xrt_sim::mem_alloc(uint64_t size, uint32_t bank_id, uint64_t* addr) {
return impl_->mem_alloc(size, bank_id, addr);
}

View file

@ -25,8 +25,6 @@ public:
int init();
void shutdown();
int mem_alloc(uint64_t size, uint32_t bank_id, uint64_t* addr);
int mem_free(uint32_t bank_id, uint64_t addr);