scope_tap bug fixes and improvements

This commit is contained in:
Blaise Tine 2024-09-25 10:28:19 -07:00
parent 0e3206747a
commit 4f11278d2c
17 changed files with 312 additions and 276 deletions

View file

@ -317,6 +317,18 @@
///////////////////////////////////////////////////////////////////////////////
`define NEG_EDGE(dst, src) \
wire dst; \
VX_edge_trigger #( \
.POS (0), \
.INIT (0) \
) __``dst``__ ( \
.clk (clk), \
.reset (1'b0), \
.data_in (src), \
.data_out (dst) \
)
`define BUFFER_EX(dst, src, ena, latency) \
VX_pipe_register #( \
.DATAW ($bits(dst)), \

View file

@ -21,10 +21,20 @@
input wire scope_bus_in, \
output wire scope_bus_out,
`define SCOPE_IO_BIND(__i) \
.scope_reset (scope_reset_w[__i]), \
.scope_bus_in (scope_bus_in_w[__i]), \
.scope_bus_out (scope_bus_out_w[__i]),
`define SCOPE_IO_UNUSED(__i) \
`UNUSED_VAR (scope_reset_w[__i]); \
`UNUSED_VAR (scope_bus_in_w[__i]); \
assign scope_bus_out_w[__i] = 0;
`define SCOPE_IO_SWITCH(__count) \
wire scope_bus_in_w [__count]; \
wire scope_bus_out_w [__count]; \
`RESET_RELAY_EX(scope_reset_w, scope_reset, __count, `MAX_FANOUT); \
wire [__count-1:0] scope_bus_in_w; \
wire [__count-1:0] scope_bus_out_w; \
wire [__count-1:0] scope_reset_w = {__count{scope_reset}}; \
VX_scope_switch #( \
.N (__count) \
) scope_switch ( \
@ -34,35 +44,42 @@
.rsp_out (scope_bus_out), \
.req_out (scope_bus_in_w), \
.rsp_in (scope_bus_out_w) \
);
)
`define SCOPE_IO_BIND(__i) \
.scope_reset (scope_reset_w[__i]), \
.scope_bus_in (scope_bus_in_w[__i]), \
.scope_bus_out (scope_bus_out_w[__i]),
`define SCOPE_TAP_EX(__idx, __id, __triggers_w, __probes_w, __triggers, __probes, __start, __stop, __depth) \
VX_scope_tap #( \
.SCOPE_ID (__id), \
.TRIGGERW (__triggers_w), \
.PROBEW (__probes_w), \
.DEPTH (__depth) \
) scope_tap_``idx ( \
.clk (clk), \
.reset (scope_reset_w[__idx]), \
.start (__start), \
.stop (__stop), \
.triggers(__triggers), \
.probes (__probes), \
.bus_in (scope_bus_in_w[__idx]), \
.bus_out(scope_bus_out_w[__idx]) \
)
`define SCOPE_IO_UNUSED() \
`UNUSED_VAR (scope_reset); \
`UNUSED_VAR (scope_bus_in); \
assign scope_bus_out = 0;
`define SCOPE_IO_UNUSED_W(__i) \
`UNUSED_VAR (scope_reset_w[__i]); \
`UNUSED_VAR (scope_bus_in_w[__i]); \
assign scope_bus_out_w[__i] = 0;
`define SCOPE_TAP(__idx, __id, __triggers, __probes, __start, __stop, __depth) \
`SCOPE_TAP_EX(__idx, __id, $bits(__triggers), $bits(__probes), __triggers, __probes, __start, __stop, __depth)
`else
`define SCOPE_IO_DECL
`define SCOPE_IO_SWITCH(__count)
`define SCOPE_IO_BIND(__i)
`define SCOPE_IO_UNUSED_W(__i)
`define SCOPE_IO_UNUSED(__i)
`define SCOPE_IO_SWITCH(__count)
`define SCOPE_TAP(__idx, __id, __triggers, __probes, __depth)
`define SCOPE_TAP_EX(__idx, __id, __triggers_w, __probes_w, __triggers, __probes, __depth)
`endif
`endif // VX_SCOPE_VH

View file

@ -100,7 +100,7 @@ module Vortex_axi import VX_gpu_pkg::*; #(
wire [`VX_MEM_TAG_WIDTH-1:0] mem_rsp_tag;
wire mem_rsp_ready;
`SCOPE_IO_SWITCH (1)
`SCOPE_IO_SWITCH (1);
Vortex vortex (
`SCOPE_IO_BIND (0)

View file

@ -932,7 +932,7 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
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;
`SCOPE_IO_SWITCH (2)
`SCOPE_IO_SWITCH (2);
Vortex vortex (
`SCOPE_IO_BIND (1)
@ -1023,80 +1023,65 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
end
wire state_changed = (state != state_prev);
`define AFU_TRIGGERS { \
reset, \
vx_reset, \
vx_busy, \
vx_mem_req_fire, \
vx_mem_rsp_fire, \
vx_dcr_wr_valid, \
state_changed, \
avs_write_fire, \
avs_read_fire, \
avs_waitrequest[0], \
avs_readdatavalid[0], \
cp2af_sRxPort.c0.mmioRdValid, \
cp2af_sRxPort.c0.mmioWrValid, \
cp2af_sRxPort.c0.rspValid, \
cp2af_sRxPort.c1.rspValid, \
af2cp_sTxPort.c0.valid, \
af2cp_sTxPort.c1.valid, \
cp2af_sRxPort.c0TxAlmFull, \
cp2af_sRxPort.c1TxAlmFull, \
af2cp_sTxPort.c2.mmioRdValid, \
cci_wr_req_fire, \
cci_wr_rsp_fire, \
cci_rd_req_fire, \
cci_rd_rsp_fire, \
cci_pending_reads_full, \
cci_pending_writes_empty, \
cci_pending_writes_full \
}
`NEG_EDGE (reset_negedge, reset);
`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, \
af2cp_sTxPort.c0.hdr.mdata, \
af2cp_sTxPort.c1.hdr.address, \
avs_address[0], \
avs_byteenable[0], \
avs_burstcount[0], \
cci_mem_rd_req_ctr, \
cci_mem_wr_req_ctr, \
cci_rd_req_ctr, \
cci_rd_rsp_ctr, \
cci_wr_req_ctr \
}
VX_scope_tap #(
.SCOPE_ID (0),
.TRIGGERW ($bits(`AFU_TRIGGERS)),
.PROBEW ($bits(`AFU_PROBES)),
.DEPTH (4096)
) scope_tap (
.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])
);
`SCOPE_TAP (0, 0, {
vx_reset,
vx_busy,
vx_mem_req_fire,
vx_mem_rsp_fire,
vx_dcr_wr_valid,
state_changed,
avs_write_fire,
avs_read_fire,
avs_waitrequest[0],
avs_readdatavalid[0],
cp2af_sRxPort.c0.mmioRdValid,
cp2af_sRxPort.c0.mmioWrValid,
cp2af_sRxPort.c0.rspValid,
cp2af_sRxPort.c1.rspValid,
af2cp_sTxPort.c0.valid,
af2cp_sTxPort.c1.valid,
cp2af_sRxPort.c0TxAlmFull,
cp2af_sRxPort.c1TxAlmFull,
af2cp_sTxPort.c2.mmioRdValid,
cci_wr_req_fire,
cci_wr_rsp_fire,
cci_rd_req_fire,
cci_rd_rsp_fire,
cci_pending_reads_full,
cci_pending_writes_empty,
cci_pending_writes_full
},{
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,
af2cp_sTxPort.c0.hdr.mdata,
af2cp_sTxPort.c1.hdr.address,
avs_address[0],
avs_byteenable[0],
avs_burstcount[0],
cci_mem_rd_req_ctr,
cci_mem_wr_req_ctr,
cci_rd_req_ctr,
cci_rd_rsp_ctr,
cci_wr_req_ctr
},
reset_negedge, 1'b0, 4096
);
`else
`SCOPE_IO_UNUSED_W(0)
`SCOPE_IO_UNUSED(0)
`endif
///////////////////////////////////////////////////////////////////////////////

View file

@ -241,7 +241,7 @@ module VX_afu_wrap #(
assign m_axi_mem_araddr_a[i] = C_M_AXI_MEM_ADDR_WIDTH'(m_axi_mem_araddr_u[i]) + BANK_OFFSET;
end
`SCOPE_IO_SWITCH (2)
`SCOPE_IO_SWITCH (2);
Vortex_axi #(
.AXI_DATA_WIDTH (C_M_AXI_MEM_DATA_WIDTH),
@ -309,55 +309,41 @@ module VX_afu_wrap #(
`ifdef SCOPE
`ifdef DBG_SCOPE_AFU
`define AFU_TRIGGERS { \
reset, \
ap_reset, \
ap_start, \
ap_done, \
ap_idle, \
interrupt, \
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], \
m_axi_mem_wready_a[0], \
m_axi_mem_bvalid_a[0], \
m_axi_mem_bready_a[0], \
m_axi_mem_arvalid_a[0], \
m_axi_mem_arready_a[0], \
m_axi_mem_rvalid_a[0], \
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] \
}
VX_scope_tap #(
.SCOPE_ID (0),
.TRIGGERW ($bits(`AFU_TRIGGERS)),
.PROBEW ($bits(`AFU_PROBES)),
.DEPTH (4096)
) scope_tap (
.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])
);
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP (0, 0, {
ap_reset,
ap_start,
ap_done,
ap_idle,
interrupt,
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],
m_axi_mem_wready_a[0],
m_axi_mem_bvalid_a[0],
m_axi_mem_bready_a[0],
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_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]
},
reset_negedge, 1'b0, 4096
);
`else
`SCOPE_IO_UNUSED_W(0)
`SCOPE_IO_UNUSED(0)
`endif
`endif
`ifdef CHIPSCOPE

View file

@ -84,7 +84,7 @@ module VX_core import VX_gpu_pkg::*; #(
.base_dcrs (base_dcrs)
);
`SCOPE_IO_SWITCH (3)
`SCOPE_IO_SWITCH (3);
VX_schedule #(
.INSTANCE_ID ($sformatf("%s-schedule", INSTANCE_ID)),

View file

@ -61,7 +61,7 @@ module VX_execute import VX_gpu_pkg::*; #(
.branch_ctl_if (branch_ctl_if)
);
`SCOPE_IO_SWITCH (1)
`SCOPE_IO_SWITCH (1);
VX_lsu_unit #(
.INSTANCE_ID ($sformatf("%s-lsu", INSTANCE_ID))

View file

@ -137,34 +137,24 @@ module VX_fetch import VX_gpu_pkg::*; #(
`ifdef SCOPE
`ifdef DBG_SCOPE_FETCH
VX_scope_tap #(
.SCOPE_ID (1),
.TRIGGERW (4),
.PROBEW (`UUID_WIDTH + `NW_WIDTH + `NUM_THREADS + `PC_BITS +
ICACHE_TAG_WIDTH + ICACHE_WORD_SIZE + ICACHE_ADDR_WIDTH +
(ICACHE_WORD_SIZE * 8) + ICACHE_TAG_WIDTH),
.DEPTH (4096)
) scope_tap (
.clk (clk),
.reset (scope_reset),
.start (1'b0),
.stop (1'b0),
.triggers ({
reset,
`SCOPE_IO_SWITCH (1);
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP_EX (0, 1, 3, (
`UUID_WIDTH + `NW_WIDTH + `NUM_THREADS + `PC_BITS + ICACHE_TAG_WIDTH + ICACHE_WORD_SIZE +
ICACHE_ADDR_WIDTH + (ICACHE_WORD_SIZE * 8) + ICACHE_TAG_WIDTH
), {
schedule_fire,
icache_req_fire,
icache_rsp_fire
}),
.probes ({
}, {
schedule_if.data.uuid, schedule_if.data.wid, schedule_if.data.tmask, schedule_if.data.PC,
icache_bus_if.req_data.tag, icache_bus_if.req_data.byteen, icache_bus_if.req_data.addr,
icache_bus_if.rsp_data.data, icache_bus_if.rsp_data.tag
}),
.bus_in (scope_bus_in),
.bus_out (scope_bus_out)
},
reset_negedge, 1'b0, 4096
);
`else
`SCOPE_IO_UNUSED()
`SCOPE_IO_UNUSED(0)
`endif
`endif
`ifdef CHIPSCOPE

View file

@ -50,7 +50,7 @@ module VX_issue import VX_gpu_pkg::*; #(
wire [`ISSUE_WIDTH-1:0] decode_ready_in;
assign decode_if.ready = decode_ready_in[decode_isw];
`SCOPE_IO_SWITCH (`ISSUE_WIDTH)
`SCOPE_IO_SWITCH (`ISSUE_WIDTH);
for (genvar issue_id = 0; issue_id < `ISSUE_WIDTH; ++issue_id) begin : g_issue_slices
VX_decode_if #(

View file

@ -95,23 +95,16 @@ module VX_issue_slice import VX_gpu_pkg::*; #(
`ifdef SCOPE
`ifdef DBG_SCOPE_ISSUE
VX_scope_tap #(
.SCOPE_ID (2),
.TRIGGERW (2),
.PROBEW (`UUID_WIDTH + `NUM_THREADS + `EX_BITS + `INST_OP_BITS +
`SCOPE_IO_SWITCH (1);
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP_EX (0, 2, 2, (
`UUID_WIDTH + `NUM_THREADS + `EX_BITS + `INST_OP_BITS +
1 + `NR_BITS + (`NUM_THREADS * 3 * `XLEN) +
`UUID_WIDTH + `NUM_THREADS + `NR_BITS + (`NUM_THREADS*`XLEN) + 1),
.DEPTH (4096)
) scope_tap (
.clk (clk),
.reset (scope_reset),
.start (1'b0),
.stop (1'b0),
.triggers ({
`UUID_WIDTH + `NUM_THREADS + `NR_BITS + (`NUM_THREADS*`XLEN) + 1
), {
operands_if_fire,
writeback_if_valid
}),
.probes ({
}, {
operands_if.data.uuid,
operands_if.data.tmask,
operands_if.data.ex_type,
@ -126,12 +119,11 @@ module VX_issue_slice import VX_gpu_pkg::*; #(
writeback_if.data.rd,
writeback_if.data.data,
writeback_if.data.eop
}),
.bus_in (scope_bus_in),
.bus_out (scope_bus_out)
},
reset_negedge, 1'b0, 4096
);
`else
`SCOPE_IO_UNUSED()
`SCOPE_IO_UNUSED(0)
`endif
`endif
`ifdef CHIPSCOPE

View file

@ -536,23 +536,26 @@ module VX_lsu_slice import VX_gpu_pkg::*; #(
`ifdef SCOPE
`ifdef DBG_SCOPE_LSU
VX_scope_tap #(
.SCOPE_ID (3),
.TRIGGERW (2),
.PROBEW (1 + NUM_LANES * (`XLEN + LSU_WORD_SIZE + LSU_WORD_SIZE * 8) + `UUID_WIDTH + NUM_LANES * LSU_WORD_SIZE * 8 + `UUID_WIDTH),
.DEPTH (4096)
) scope_tap (
.clk (clk),
.reset (scope_reset),
.start (1'b0),
.stop (1'b0),
.triggers({mem_req_fire, mem_rsp_fire}),
.probes ({mem_req_rw, full_addr, mem_req_byteen, mem_req_data, execute_if.data.uuid, rsp_data, rsp_uuid}),
.bus_in (scope_bus_in),
.bus_out(scope_bus_out)
`SCOPE_IO_SWITCH (1);
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP_EX (0, 3, 2, (
1 + NUM_LANES * (`XLEN + LSU_WORD_SIZE + LSU_WORD_SIZE * 8) + `UUID_WIDTH + NUM_LANES * LSU_WORD_SIZE * 8 + `UUID_WIDTH
), {
mem_req_fire,
mem_rsp_fire
}, {
mem_req_rw,
full_addr,
mem_req_byteen,
mem_req_data,
execute_if.data.uuid,
rsp_data,
rsp_uuid
},
reset_negedge, 1'b0, 4096
);
`else
`SCOPE_IO_UNUSED()
`SCOPE_IO_UNUSED(0)
`endif
`endif
`ifdef CHIPSCOPE

View file

@ -0,0 +1,43 @@
// Copyright © 2019-2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
`include "VX_platform.vh"
`TRACING_OFF
module VX_edge_trigger #(
parameter POS = 0,
parameter INIT = 0
) (
input wire clk,
input wire reset,
input wire data_in,
output wire data_out
);
reg prev;
always @(posedge clk) begin
if (reset) begin
prev <= INIT;
end else begin
prev <= data_in;
end
end
if (POS != 0) begin : g_pos
assign data_out = data_in & ~prev;
end else begin : g_neg
assign data_out = ~data_in & prev;
end
endmodule
`TRACING_ON

View file

@ -20,8 +20,8 @@ module VX_scope_switch #(
input wire clk,
input wire reset,
input wire req_in,
output wire req_out [N],
input wire rsp_in [N],
output wire [N-1:0] req_out,
input wire [N-1:0] rsp_in,
output wire rsp_out
);
if (N > 1) begin : g_switch
@ -46,7 +46,10 @@ module VX_scope_switch #(
end
end
assign req_out = req_out_r;
for (genvar i = 0; i < N; ++i) begin : g_req_out
assign req_out[i] = req_out_r[i];
end
assign rsp_out = rsp_out_r;
end else begin : g_passthru

View file

@ -33,12 +33,13 @@ module VX_scope_tap #(
output wire bus_out
);
localparam CTR_WIDTH = 64;
localparam DATA_IDX_WISTH = `LOG2UP(TX_DATAW);
localparam SER_CTR_WIDTH = `LOG2UP(TX_DATAW);
localparam DATAW = PROBEW + TRIGGERW;
localparam ADDRW = `CLOG2(DEPTH);
localparam SIZEW = `CLOG2(DEPTH+1);
localparam MAX_IDLE_CTR = (2 ** IDLE_CTRW) - 1;
localparam DATA_BLOCKS = `CDIV(DATAW, TX_DATAW);
localparam BLOCK_IDX_WISTH = `LOG2UP(DATA_BLOCKS);
localparam BLOCK_IDX_WIDTH = `LOG2UP(DATA_BLOCKS);
localparam CTRL_STATE_IDLE = 2'd0;
localparam CTRL_STATE_RECV = 2'd1;
@ -47,8 +48,8 @@ module VX_scope_tap #(
localparam CTRL_STATE_BITS = 2;
localparam TAP_STATE_IDLE = 2'd0;
localparam TAP_STATE_WAIT = 2'd1;
localparam TAP_STATE_RUN = 2'd2;
localparam TAP_STATE_RUN = 2'd1;
localparam TAP_STATE_DONE = 2'd2;
localparam TAP_STATE_BITS = 2;
localparam CMD_GET_WIDTH = 3'd0;
@ -57,13 +58,14 @@ module VX_scope_tap #(
localparam CMD_GET_DATA = 3'd3;
localparam CMD_SET_START = 3'd4;
localparam CMD_SET_STOP = 3'd5;
localparam CMD_SET_DEPTH = 3'd6;
localparam CMD_TYPE_BITS = 3;
localparam SEND_TYPE_WIDTH = 2'd0;
localparam SEND_TYPE_COUNT = 2'd1;
localparam SEND_TYPE_START = 2'd2;
localparam SEND_TYPE_DATA = 2'd3;
localparam SEND_TYPE_BITS = 2;
localparam SEND_TYPE_WIDTH = 2'd0;
localparam SEND_TYPE_COUNT = 2'd1;
localparam SEND_TYPE_START = 2'd2;
localparam SEND_TYPE_DATA = 2'd3;
localparam SEND_TYPE_BITS = 2;
`STATIC_ASSERT ((IDLE_CTRW <= TX_DATAW), ("invalid parameter"))
`STATIC_ASSERT(`IS_POW2(DEPTH), ("depth must be a power of 2!"))
@ -73,12 +75,13 @@ module VX_scope_tap #(
reg [SEND_TYPE_BITS-1:0] send_type;
reg [CTR_WIDTH-1:0] timestamp, start_time;
reg [CTR_WIDTH-1:0] start_delay, delay_cntr;
reg [CTR_WIDTH-1:0] start_delay, stop_delay;
reg [`UP(TRIGGERW)-1:0] prev_trig;
reg [IDLE_CTRW-1:0] delta;
reg cmd_start, dflush;
reg cmd_start, cmd_stop;
reg dflush;
reg [ADDRW-1:0] waddr, waddr_end;
reg [SIZEW-1:0] waddr, waddr_end;
wire [DATAW-1:0] data_in;
wire write_en;
@ -105,7 +108,7 @@ module VX_scope_tap #(
.read (1'b1),
.wren (1'b1),
.write (write_en),
.waddr (waddr),
.waddr (waddr[ADDRW-1:0]),
.wdata (delta),
.raddr (raddr),
.rdata (delta_value)
@ -128,7 +131,7 @@ module VX_scope_tap #(
.read (1'b1),
.wren (1'b1),
.write (write_en),
.waddr (waddr),
.waddr (waddr[ADDRW-1:0]),
.wdata (data_in),
.raddr (raddr),
.rdata (data_value)
@ -144,35 +147,16 @@ module VX_scope_tap #(
always @(posedge clk) begin
if (reset) begin
tap_state <= TAP_STATE_IDLE;
delta <= '0;
dflush <= 0;
prev_trig <= '0;
waddr <= '0;
tap_state <= TAP_STATE_IDLE;
delta <= '0;
dflush <= 0;
prev_trig <= '0;
waddr <= '0;
end else begin
case (tap_state)
TAP_STATE_IDLE: begin
if (start || cmd_start) begin
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_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_tap%0d: delayed start - time=%0d\n", $time, SCOPE_ID, start_delay))
`endif
end
end
end
TAP_STATE_WAIT: begin
delay_cntr <= delay_cntr - CTR_WIDTH'(1);
if (1 == delay_cntr) begin
dflush <= 1;
tap_state <= TAP_STATE_RUN;
start_time <= timestamp;
`ifdef DBG_TRACE_SCOPE
@ -182,10 +166,10 @@ module VX_scope_tap #(
end
TAP_STATE_RUN: begin
dflush <= 0;
if (!stop && (waddr < waddr_end)) begin
if (!(stop || cmd_stop) && (waddr < waddr_end)) begin
if (TRIGGERW != 0) begin
if (dflush || (triggers != prev_trig)) begin
waddr <= waddr + ADDRW'(1);
waddr <= waddr + SIZEW'(1);
delta <= '0;
end else begin
delta <= delta + IDLE_CTRW'(1);
@ -193,10 +177,10 @@ module VX_scope_tap #(
end
prev_trig <= triggers;
end else begin
waddr <= waddr + ADDRW'(1);
waddr <= waddr + SIZEW'(1);
end
end else begin
tap_state <= TAP_STATE_IDLE;
tap_state <= TAP_STATE_DONE;
`ifdef DBG_TRACE_SCOPE
`TRACE(2, ("%t: scope_tap%0d: recording stop - waddr=(%0d, %0d)\n", $time, SCOPE_ID, waddr, waddr_end))
`endif
@ -218,8 +202,8 @@ module VX_scope_tap #(
`UNUSED_VAR (ser_buf_in)
wire [DATA_BLOCKS-1:0][TX_DATAW-1:0] data_blocks;
logic [BLOCK_IDX_WISTH-1:0] data_block_idx;
reg [DATA_IDX_WISTH-1:0] ser_tx_ctr;
logic [BLOCK_IDX_WIDTH-1:0] data_block_idx;
reg [SER_CTR_WIDTH-1:0] ser_tx_ctr;
reg is_read_data;
reg is_get_data;
@ -246,8 +230,8 @@ module VX_scope_tap #(
&& (send_type == SEND_TYPE_DATA)
&& (ser_tx_ctr == 0)
&& is_read_data) begin
if (data_block_idx < BLOCK_IDX_WISTH'(DATA_BLOCKS-1)) begin
data_block_idx <= data_block_idx + BLOCK_IDX_WISTH'(1);
if (data_block_idx < BLOCK_IDX_WIDTH'(DATA_BLOCKS-1)) begin
data_block_idx <= data_block_idx + BLOCK_IDX_WIDTH'(1);
end else begin
data_block_idx <= '0;
end
@ -257,15 +241,15 @@ module VX_scope_tap #(
assign data_block_idx = 0;
end
wire [ADDRW-1:0] raddr_n = raddr + ADDRW'(1);
always @(posedge clk) begin
if (reset) begin
ctrl_state <= CTRL_STATE_IDLE;
send_type <= SEND_TYPE_BITS'(SEND_TYPE_WIDTH);
waddr_end <= ADDRW'(DEPTH-1);
waddr_end <= SIZEW'(DEPTH);
cmd_start <= 0;
cmd_stop <= 0;
start_delay <= '0;
stop_delay <= '0;
bus_out_r <= 0;
raddr <= '0;
is_read_data<= 0;
@ -273,17 +257,28 @@ module VX_scope_tap #(
is_get_data <= 0;
end else begin
bus_out_r <= 0;
cmd_start <= 0;
is_get_data <= 0;
if (start_delay != 0) begin
start_delay <= start_delay - CTR_WIDTH'(1);
end
if (stop_delay != 0) begin
stop_delay <= stop_delay - CTR_WIDTH'(1);
end
cmd_start <= (start_delay == CTR_WIDTH'(1));
cmd_stop <= (stop_delay == CTR_WIDTH'(1));
case (ctrl_state)
CTRL_STATE_IDLE: begin
if (bus_in) begin
ser_tx_ctr <= DATA_IDX_WISTH'(TX_DATAW-1);
ser_tx_ctr <= SER_CTR_WIDTH'(TX_DATAW-1);
ctrl_state <= CTRL_STATE_RECV;
end
end
CTRL_STATE_RECV: begin
ser_tx_ctr <= ser_tx_ctr - DATA_IDX_WISTH'(1);
ser_tx_ctr <= ser_tx_ctr - SER_CTR_WIDTH'(1);
ser_buf_in <= ser_buf_in_n;
if (ser_tx_ctr == 0) begin
// check if command is for this scope
@ -294,18 +289,22 @@ module VX_scope_tap #(
ctrl_state <= CTRL_STATE_IDLE;
case (cmd_type)
CMD_SET_START: begin
start_delay <= 64'(cmd_data);
cmd_start <= 1;
start_delay <= CTR_WIDTH'(cmd_data);
cmd_start <= (cmd_data == 0);
end
CMD_SET_STOP: begin
waddr_end <= ADDRW'(cmd_data);
stop_delay <= CTR_WIDTH'(cmd_data);
cmd_stop <= (cmd_data == 0);
end
CMD_SET_DEPTH: begin
waddr_end <= SIZEW'(cmd_data);
end
CMD_GET_WIDTH,
CMD_GET_START,
CMD_GET_COUNT,
CMD_GET_DATA: begin
send_type <= SEND_TYPE_BITS'(cmd_type);
ser_tx_ctr <= DATA_IDX_WISTH'(TX_DATAW-1);
send_type <= SEND_TYPE_BITS'(cmd_type);
ser_tx_ctr <= SER_CTR_WIDTH'(TX_DATAW-1);
ctrl_state <= CTRL_STATE_SEND;
bus_out_r <= 1;
end
@ -345,12 +344,9 @@ module VX_scope_tap #(
is_get_data <= 1;
if (ser_tx_ctr == 0) begin
if (is_read_data) begin
if (data_block_idx == BLOCK_IDX_WISTH'(DATA_BLOCKS-1)) begin
raddr <= raddr_n;
if (data_block_idx == BLOCK_IDX_WIDTH'(DATA_BLOCKS-1)) begin
raddr <= raddr + ADDRW'(1);
is_read_data <= 0; // switch to delta mode
if (raddr_n == waddr) begin
raddr <= 0; // end-of-samples reset
end
end
end else begin
is_read_data <= 1; // switch to data mode
@ -368,7 +364,7 @@ module VX_scope_tap #(
end
default:;
endcase
ser_tx_ctr <= ser_tx_ctr - DATA_IDX_WISTH'(1);
ser_tx_ctr <= ser_tx_ctr - SER_CTR_WIDTH'(1);
if (ser_tx_ctr == 0) begin
ctrl_state <= CTRL_STATE_IDLE;
end
@ -378,12 +374,12 @@ module VX_scope_tap #(
end
end
wire [BLOCK_IDX_WISTH-1:0] data_block_idx_r;
wire [DATA_IDX_WISTH-1:0] ser_tx_ctr_r;
wire [BLOCK_IDX_WIDTH-1:0] data_block_idx_r;
wire [SER_CTR_WIDTH-1:0] ser_tx_ctr_r;
wire is_read_data_r;
VX_pipe_register #(
.DATAW (1 + DATA_IDX_WISTH + BLOCK_IDX_WISTH)
.DATAW (1 + SER_CTR_WIDTH + BLOCK_IDX_WIDTH)
) data_sel_buf (
.clk (clk),
.reset (reset),

View file

@ -32,6 +32,8 @@
#define TIMEOUT_TIME (60*60)
#define MAX_DELAY_CYCLES 10000
#define MMIO_SCOPE_READ (AFU_IMAGE_MMIO_SCOPE_READ * 4)
#define MMIO_SCOPE_WRITE (AFU_IMAGE_MMIO_SCOPE_WRITE * 4)
@ -41,6 +43,7 @@
#define CMD_GET_DATA 3
#define CMD_SET_START 4
#define CMD_SET_STOP 5
#define CMD_SET_DEPTH 6
#define CHECK_ERR(_expr) \
do { \
@ -96,7 +99,7 @@ static void dump_module(std::ofstream& ofs,
auto itt = tails.find(name);
if (itt != tails.end()) {
for (auto& signal : itt->second->signals) {
ofs << indent << " $var reg " << signal.width << " " << signal.id << " " << signal.name << " $end" << std::endl;
ofs << indent << " $var wire " << signal.width << " " << signal.id << " " << signal.name << " $end" << std::endl;
}
}
@ -114,7 +117,7 @@ static void dump_header(std::ofstream& ofs, std::vector<tap_t>& taps) {
ofs << "$version Generated by Vortex Scope Analyzer $end" << std::endl;
ofs << "$timescale 1 ns $end" << std::endl;
ofs << "$scope module TOP $end" << std::endl;
ofs << " $var reg 1 0 clk $end" << std::endl;
ofs << " $var wire 1 0 clk $end" << std::endl;
std::unordered_map<std::string, std::unordered_set<std::string>> hierarchy;
std::unordered_set<std::string> heads;
@ -160,6 +163,14 @@ static tap_t* find_earliest_tap(std::vector<tap_t>& taps) {
}
static uint64_t advance_clock(std::ofstream& ofs, uint64_t cur_time, uint64_t next_time) {
uint64_t delta = next_time - cur_time;
if (delta > MAX_DELAY_CYCLES) {
ofs << '#' << (cur_time * 2 + 0) << std::endl;
ofs << "bx 0" << std::endl;
ofs << '#' << (cur_time * 2 + 1) << std::endl;
ofs << "bx 0" << std::endl;
cur_time = next_time - MAX_DELAY_CYCLES;
}
while (cur_time < next_time) {
ofs << '#' << (cur_time * 2 + 0) << std::endl;
ofs << "b0 0" << std::endl;
@ -350,7 +361,6 @@ int vx_scope_stop(vx_device_h hdevice) {
uint64_t cmd_count = (tap.id << 3) | CMD_GET_COUNT;
CHECK_ERR(g_callback.registerWrite(hdevice, cmd_count));
CHECK_ERR(g_callback.registerRead(hdevice, &count));
if (count == 0)
continue;
@ -385,7 +395,6 @@ int vx_scope_stop(vx_device_h hdevice) {
uint64_t cur_time = 0;
auto tap = find_earliest_tap(taps);
if (tap != nullptr) {
cur_time = (tap->cycle_time > 0) ? (tap->cycle_time-1) : 0;
do {
// advance clock
cur_time = advance_clock(ofs, cur_time, tap->cycle_time);

View file

@ -195,7 +195,7 @@ public:
return device->api_.fpgaReadMMIO64(device->fpga_, 0, MMIO_SCOPE_READ, value);
};
CHECK_ERR(vx_scope_start(&callback, this, 0, -1), {
CHECK_ERR(vx_scope_start(&callback, this, -1, -1), {
api_.fpgaClose(fpga_);
return err;
});

View file

@ -265,7 +265,7 @@ public:
*value = (((uint64_t)value_hi) << 32) | value_lo;
return 0;
};
CHECK_ERR(vx_scope_start(&callback, this, 0, -1), {
CHECK_ERR(vx_scope_start(&callback, this, -1, -1), {
return err;
});
}