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

@ -172,6 +172,7 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
cmd_scope_writing <= 0; cmd_scope_writing <= 0;
scope_bus_in <= 0; scope_bus_in <= 0;
end else begin end else begin
scope_bus_in <= 0;
if (scope_bus_out) begin if (scope_bus_out) begin
cmd_scope_reading <= 1; cmd_scope_reading <= 1;
scope_bus_ctr <= 63; scope_bus_ctr <= 63;
@ -183,13 +184,12 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
scope_bus_ctr <= 63; scope_bus_ctr <= 63;
scope_bus_in <= 1; scope_bus_in <= 1;
end end
end
if (cmd_scope_writing) begin if (cmd_scope_writing) begin
scope_bus_in <= 1'(cmd_scope_wdata >> scope_bus_ctr); scope_bus_in <= 1'(cmd_scope_wdata >> scope_bus_ctr);
scope_bus_ctr <= scope_bus_ctr - 6'd1; scope_bus_ctr <= scope_bus_ctr - 6'd1;
if (scope_bus_ctr == 0) begin if (scope_bus_ctr == 0) begin
cmd_scope_writing <= 0; cmd_scope_writing <= 0;
scope_bus_in <= 0; scope_bus_ctr <= 0;
end end
end end
if (cmd_scope_reading) begin if (cmd_scope_reading) begin
@ -197,6 +197,8 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
scope_bus_ctr <= scope_bus_ctr - 6'd1; scope_bus_ctr <= scope_bus_ctr - 6'd1;
if (scope_bus_ctr == 0) begin if (scope_bus_ctr == 0) begin
cmd_scope_reading <= 0; cmd_scope_reading <= 0;
scope_bus_ctr <= 0;
end
end end
end end
end end
@ -327,7 +329,7 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
`ifdef SCOPE `ifdef SCOPE
MMIO_SCOPE_WRITE: begin MMIO_SCOPE_WRITE: begin
`ifdef DBG_TRACE_AFU `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 `endif
end end
`endif `endif
@ -1002,11 +1004,10 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
// SCOPE ////////////////////////////////////////////////////////////////////// // SCOPE //////////////////////////////////////////////////////////////////////
`ifdef DBG_SCOPE_AFU `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_write_fire = avs_write[0] && ~avs_waitrequest[0];
wire avs_read_fire = avs_read[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 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; reg [STATE_WIDTH-1:0] state_prev;
always @(posedge clk) begin 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 { \ `define AFU_TRIGGERS { \
reset, \ reset, \
vx_reset, \
vx_busy, \
vx_mem_req_fire, \
vx_mem_rsp_fire, \
vx_dcr_wr_valid, \
state_changed, \ state_changed, \
mem_req_fire, \
mem_rsp_fire, \
avs_write_fire, \ avs_write_fire, \
avs_read_fire, \ avs_read_fire, \
avs_waitrequest[0], \ avs_waitrequest[0], \
@ -1044,6 +1048,15 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
`define AFU_PROBES { \ `define AFU_PROBES { \
cmd_type, \ cmd_type, \
state, \ 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, \ mmio_req_hdr.address, \
cp2af_sRxPort.c0.hdr.mdata, \ cp2af_sRxPort.c0.hdr.mdata, \
af2cp_sTxPort.c0.hdr.address, \ 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_mem_wr_req_ctr, \
cci_rd_req_ctr, \ cci_rd_req_ctr, \
cci_rd_rsp_ctr, \ cci_rd_rsp_ctr, \
cci_wr_req_ctr, \ cci_wr_req_ctr \
mem_bus_if_addr \
} }
VX_scope_tap #( VX_scope_tap #(

View file

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

View file

@ -299,8 +299,8 @@ module VX_afu_wrap #(
// SCOPE ////////////////////////////////////////////////////////////////////// // SCOPE //////////////////////////////////////////////////////////////////////
`ifdef DBG_SCOPE_AFU
`ifdef SCOPE `ifdef SCOPE
`ifdef DBG_SCOPE_AFU
`define AFU_TRIGGERS { \ `define AFU_TRIGGERS { \
reset, \ reset, \
ap_reset, \ ap_reset, \
@ -308,9 +308,9 @@ module VX_afu_wrap #(
ap_done, \ ap_done, \
ap_idle, \ ap_idle, \
interrupt, \ interrupt, \
vx_busy_wait, \
vx_busy, \
vx_reset, \ vx_reset, \
vx_busy, \
dcr_wr_valid, \
m_axi_mem_awvalid_a[0], \ m_axi_mem_awvalid_a[0], \
m_axi_mem_awready_a[0], \ m_axi_mem_awready_a[0], \
m_axi_mem_wvalid_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_arvalid_a[0], \
m_axi_mem_arready_a[0], \ m_axi_mem_arready_a[0], \
m_axi_mem_rvalid_a[0], \ m_axi_mem_rvalid_a[0], \
m_axi_mem_rready_a[0], \ m_axi_mem_rready_a[0] \
dcr_wr_valid \
} }
`define AFU_PROBES { \ `define AFU_PROBES { \
dcr_wr_addr, \
dcr_wr_data, \
vx_pending_writes, \ vx_pending_writes, \
m_axi_mem_awaddr_u[0], \ m_axi_mem_awaddr_u[0], \
m_axi_mem_awid_a[0], \ m_axi_mem_awid_a[0], \
m_axi_mem_bid_a[0], \ m_axi_mem_bid_a[0], \
m_axi_mem_araddr_u[0], \ m_axi_mem_araddr_u[0], \
m_axi_mem_arid_a[0], \ m_axi_mem_arid_a[0], \
m_axi_mem_rid_a[0], \ m_axi_mem_rid_a[0] \
dcr_wr_addr, \
dcr_wr_data \
} }
VX_scope_tap #( VX_scope_tap #(
.SCOPE_ID (0), .SCOPE_ID (0),
@ -352,6 +351,7 @@ module VX_afu_wrap #(
`else `else
`SCOPE_IO_UNUSED_W(0) `SCOPE_IO_UNUSED_W(0)
`endif `endif
`endif
`ifdef CHIPSCOPE `ifdef CHIPSCOPE
ila_afu ila_afu_inst ( ila_afu ila_afu_inst (
.clk (clk), .clk (clk),
@ -373,7 +373,6 @@ module VX_afu_wrap #(
}) })
); );
`endif `endif
`endif
`ifdef SIMULATION `ifdef SIMULATION
`ifndef VERILATOR `ifndef VERILATOR

View file

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

View file

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

View file

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

View file

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

View file

@ -20,7 +20,7 @@ module VX_scope_tap #(
parameter TRIGGERW = 16, // trigger signals width parameter TRIGGERW = 16, // trigger signals width
parameter PROBEW = 256, // probe signal width parameter PROBEW = 256, // probe signal width
parameter DEPTH = 1024, // trace buffer depth 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 parameter TX_DATAW = 64 // transfer data width
) ( ) (
input wire clk, input wire clk,
@ -64,33 +64,52 @@ module VX_scope_tap #(
localparam GET_TYPE_DATA = 2'd3; localparam GET_TYPE_DATA = 2'd3;
localparam GET_TYPE_BITS = 2; localparam GET_TYPE_BITS = 2;
reg [`UP(TRIGGERW)-1:0] prev_triggers; `STATIC_ASSERT ((IDLE_CTRW <= TX_DATAW), ("invalid parameter"))
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;
reg [TAP_STATE_BITS-1:0] tap_state; reg [TAP_STATE_BITS-1:0] tap_state;
reg [CTRL_STATE_BITS-1:0] ctrl_state; reg [CTRL_STATE_BITS-1:0] ctrl_state;
reg [GET_TYPE_BITS-1:0] get_type; 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 [DATAW-1:0] data_value;
wire [IDLE_CTRW-1:0] delta_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 [ADDRW-1:0] raddr;
reg read_data;
wire [DATAW-1:0] data_in; //
if (TRIGGERW != 0) begin // trace capture
//
if (TRIGGERW != 0) begin : g_delta_store
assign data_in = {probes, triggers}; assign data_in = {probes, triggers};
end else begin 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 data_in = probes;
assign write_en = (tap_state == TAP_STATE_RUN);
assign delta_value = '0;
end end
VX_dp_ram #( VX_dp_ram #(
@ -109,76 +128,38 @@ module VX_scope_tap #(
.rdata (data_value) .rdata (data_value)
); );
if (TRIGGERW != 0) begin always @(posedge clk) begin
VX_dp_ram #( if (reset) begin
.DATAW (IDLE_CTRW), timestamp <= '0;
.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 end else begin
assign delta_value = '0; timestamp <= timestamp + CTR_WIDTH'(1);
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
end end
end end
always @(posedge clk) begin always @(posedge clk) begin
if (reset) begin if (reset) begin
tap_state <= TAP_STATE_IDLE; tap_state <= TAP_STATE_IDLE;
raddr <= '0;
waddr <= '0;
delta <= '0; delta <= '0;
prev_triggers <= '0; dflush <= 0;
read_offset <= '0; prev_trig <= '0;
read_data <= 0; waddr <= '0;
timestamp <= '0;
end else begin end else begin
timestamp <= timestamp + CTR_WIDTH'(1);
case (tap_state) case (tap_state)
TAP_STATE_IDLE: begin TAP_STATE_IDLE: begin
if (start || cmd_start) begin if (start || cmd_start) begin
delta <= '0; delta <= '0;
delta_flush <= 1; dflush <= 1;
if (0 == start_delay) begin if (0 == start_delay) begin
tap_state <= TAP_STATE_RUN; tap_state <= TAP_STATE_RUN;
start_time <= timestamp; start_time <= timestamp;
`ifdef DBG_TRACE_SCOPE `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 `endif
end else begin end else begin
tap_state <= TAP_STATE_WAIT; tap_state <= TAP_STATE_WAIT;
delay_cntr <= start_delay; delay_cntr <= start_delay;
`ifdef DBG_TRACE_SCOPE `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 `endif
end end
end end
@ -189,65 +170,39 @@ module VX_scope_tap #(
tap_state <= TAP_STATE_RUN; tap_state <= TAP_STATE_RUN;
start_time <= timestamp; start_time <= timestamp;
`ifdef DBG_TRACE_SCOPE `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 `endif
end end
end end
TAP_STATE_RUN: begin TAP_STATE_RUN: begin
dflush <= 0;
if (!stop && (waddr < waddr_end)) begin
if (TRIGGERW != 0) begin if (TRIGGERW != 0) begin
if (delta_flush || (triggers != prev_triggers)) begin if (dflush || (triggers != prev_trig)) begin
waddr <= waddr + ADDRW'(1); waddr <= waddr + ADDRW'(1);
delta <= '0; delta <= '0;
delta_flush <= 0;
end else begin end else begin
delta <= delta + IDLE_CTRW'(1); delta <= delta + IDLE_CTRW'(1);
delta_flush <= (delta == IDLE_CTRW'(MAX_IDLE_CTR-1)); dflush <= (delta == IDLE_CTRW'(MAX_IDLE_CTR-1));
end end
prev_triggers <= triggers; prev_trig <= triggers;
end else begin end else begin
waddr <= waddr + ADDRW'(1); waddr <= waddr + ADDRW'(1);
end end
if (stop || (waddr >= waddr_end)) begin end else 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; 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
end end
default:; default:;
endcase 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
end end
// //
// command controller // trace controller
// //
reg bus_out_r; 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}; wire [TX_DATAW-1:0] ser_buf_in_n = {ser_buf_in[TX_DATAW-2:0], bus_in};
`UNUSED_VAR (ser_buf_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 [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 [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-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] 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 always @(posedge clk) begin
if (reset) begin if (reset) begin
ctrl_state <= CTRL_STATE_IDLE; ctrl_state <= CTRL_STATE_IDLE;
waddr_end <= ADDRW'(DEPTH-1);
cmd_start <= 0; cmd_start <= 0;
start_delay <= '0; start_delay <= '0;
waddr_end <= ADDRW'(DEPTH-1);
bus_out_r <= 0; bus_out_r <= 0;
read_offset <= '0;
raddr <= '0;
is_read_data<= 0;
ser_tx_ctr <= '0;
end else begin end else begin
bus_out_r <= 0; bus_out_r <= 0;
cmd_start <= 0; cmd_start <= 0;
case (ctrl_state) case (ctrl_state)
CTRL_STATE_IDLE: begin CTRL_STATE_IDLE: begin
if (bus_in) begin if (bus_in) begin
ser_tx_ctr <= TX_DATA_BITS'(TX_DATAW-1);
ctrl_state <= CTRL_STATE_RECV; ctrl_state <= CTRL_STATE_RECV;
end end
ser_tx_ctr <= TX_DATA_BITS'(TX_DATAW-1);
end end
CTRL_STATE_RECV: begin CTRL_STATE_RECV: begin
ser_tx_ctr <= ser_tx_ctr - TX_DATA_BITS'(1); ser_tx_ctr <= ser_tx_ctr - TX_DATA_BITS'(1);
ser_buf_in <= ser_buf_in_n; ser_buf_in <= ser_buf_in_n;
if (ser_tx_ctr == 0) begin 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; ctrl_state <= (cmd_scope_id == SCOPE_ID) ? CTRL_STATE_CMD : CTRL_STATE_IDLE;
end end
end end
@ -302,33 +267,32 @@ module VX_scope_tap #(
CMD_GET_START, CMD_GET_START,
CMD_GET_COUNT, CMD_GET_COUNT,
CMD_GET_DATA: begin CMD_GET_DATA: begin
ctrl_state <= CTRL_STATE_SEND;
get_type <= GET_TYPE_BITS'(cmd_type); get_type <= GET_TYPE_BITS'(cmd_type);
ser_tx_ctr <= TX_DATA_BITS'(TX_DATAW-1); ser_tx_ctr <= TX_DATA_BITS'(TX_DATAW-1);
bus_out_r <= 1; bus_out_r <= 1;
ctrl_state <= CTRL_STATE_SEND;
end end
default:; default:;
endcase endcase
`ifdef DBG_TRACE_SCOPE `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 `endif
end end
CTRL_STATE_SEND: begin CTRL_STATE_SEND: begin
ser_tx_ctr <= ser_tx_ctr - TX_DATA_BITS'(1);
case (get_type) case (get_type)
GET_TYPE_WIDTH: begin GET_TYPE_WIDTH: begin
bus_out_r <= 1'(DATAW >> ser_tx_ctr); bus_out_r <= 1'(DATAW >> ser_tx_ctr);
`ifdef DBG_TRACE_SCOPE `ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin 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 end
`endif `endif
end end
GET_TYPE_COUNT: begin GET_TYPE_COUNT: begin
bus_out_r <= 1'(count >> ser_tx_ctr); bus_out_r <= 1'(waddr >> ser_tx_ctr);
`ifdef DBG_TRACE_SCOPE `ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin 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 end
`endif `endif
end end
@ -336,20 +300,46 @@ module VX_scope_tap #(
bus_out_r <= 1'(start_time >> ser_tx_ctr); bus_out_r <= 1'(start_time >> ser_tx_ctr);
`ifdef DBG_TRACE_SCOPE `ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin 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 end
`endif `endif
end end
GET_TYPE_DATA: begin GET_TYPE_DATA: begin
bus_out_r <= 1'(get_data >> ser_tx_ctr); 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 `ifdef DBG_TRACE_SCOPE
if (ser_tx_ctr == 0) begin 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 end
`endif `endif
end end
default:; default:;
endcase endcase
ser_tx_ctr <= ser_tx_ctr - TX_DATA_BITS'(1);
if (ser_tx_ctr == 0) begin if (ser_tx_ctr == 0) begin
ctrl_state <= CTRL_STATE_IDLE; ctrl_state <= CTRL_STATE_IDLE;
end end

View file

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

View file

@ -581,14 +581,14 @@ public:
return err; return err;
}); });
#ifdef CPP_API #ifdef CPP_API
xrtBuffer.write(host_ptr, asize, bo_offset); xrtBuffer.write(host_ptr, size, bo_offset);
xrtBuffer.sync(XCL_BO_SYNC_BO_TO_DEVICE, asize, bo_offset); xrtBuffer.sync(XCL_BO_SYNC_BO_TO_DEVICE, size, bo_offset);
#else #else
CHECK_ERR(xrtBOWrite(xrtBuffer, host_ptr, asize, bo_offset), { CHECK_ERR(xrtBOWrite(xrtBuffer, host_ptr, size, bo_offset), {
dump_xrt_error(xrtDevice_, err); dump_xrt_error(xrtDevice_, err);
return 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); dump_xrt_error(xrtDevice_, err);
return err; return err;
}); });
@ -627,14 +627,14 @@ public:
return err; return err;
}); });
#ifdef CPP_API #ifdef CPP_API
xrtBuffer.sync(XCL_BO_SYNC_BO_FROM_DEVICE, asize, bo_offset); xrtBuffer.sync(XCL_BO_SYNC_BO_FROM_DEVICE, size, bo_offset);
xrtBuffer.read(host_ptr, asize, bo_offset); xrtBuffer.read(host_ptr, size, bo_offset);
#else #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); dump_xrt_error(xrtDevice_, err);
return 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); dump_xrt_error(xrtDevice_, err);
return err; return err;
}); });

View file

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

View file

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

View file

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