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) \ `define BUFFER_EX(dst, src, ena, latency) \
VX_pipe_register #( \ VX_pipe_register #( \
.DATAW ($bits(dst)), \ .DATAW ($bits(dst)), \

View file

@ -21,10 +21,20 @@
input wire scope_bus_in, \ input wire scope_bus_in, \
output wire scope_bus_out, 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) \ `define SCOPE_IO_SWITCH(__count) \
wire scope_bus_in_w [__count]; \ wire [__count-1:0] scope_bus_in_w; \
wire scope_bus_out_w [__count]; \ wire [__count-1:0] scope_bus_out_w; \
`RESET_RELAY_EX(scope_reset_w, scope_reset, __count, `MAX_FANOUT); \ wire [__count-1:0] scope_reset_w = {__count{scope_reset}}; \
VX_scope_switch #( \ VX_scope_switch #( \
.N (__count) \ .N (__count) \
) scope_switch ( \ ) scope_switch ( \
@ -34,35 +44,42 @@
.rsp_out (scope_bus_out), \ .rsp_out (scope_bus_out), \
.req_out (scope_bus_in_w), \ .req_out (scope_bus_in_w), \
.rsp_in (scope_bus_out_w) \ .rsp_in (scope_bus_out_w) \
); )
`define SCOPE_IO_BIND(__i) \ `define SCOPE_TAP_EX(__idx, __id, __triggers_w, __probes_w, __triggers, __probes, __start, __stop, __depth) \
.scope_reset (scope_reset_w[__i]), \ VX_scope_tap #( \
.scope_bus_in (scope_bus_in_w[__i]), \ .SCOPE_ID (__id), \
.scope_bus_out (scope_bus_out_w[__i]), .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() \ `define SCOPE_TAP(__idx, __id, __triggers, __probes, __start, __stop, __depth) \
`UNUSED_VAR (scope_reset); \ `SCOPE_TAP_EX(__idx, __id, $bits(__triggers), $bits(__probes), __triggers, __probes, __start, __stop, __depth)
`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;
`else `else
`define SCOPE_IO_DECL `define SCOPE_IO_DECL
`define SCOPE_IO_SWITCH(__count)
`define SCOPE_IO_BIND(__i) `define SCOPE_IO_BIND(__i)
`define SCOPE_IO_UNUSED_W(__i)
`define SCOPE_IO_UNUSED(__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
`endif // VX_SCOPE_VH `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 [`VX_MEM_TAG_WIDTH-1:0] mem_rsp_tag;
wire mem_rsp_ready; wire mem_rsp_ready;
`SCOPE_IO_SWITCH (1) `SCOPE_IO_SWITCH (1);
Vortex vortex ( Vortex vortex (
`SCOPE_IO_BIND (0) `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_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; wire [`VX_DCR_DATA_WIDTH-1:0] vx_dcr_wr_data = cmd_dcr_data;
`SCOPE_IO_SWITCH (2) `SCOPE_IO_SWITCH (2);
Vortex vortex ( Vortex vortex (
`SCOPE_IO_BIND (1) `SCOPE_IO_BIND (1)
@ -1023,80 +1023,65 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
end end
wire state_changed = (state != state_prev); wire state_changed = (state != state_prev);
`define AFU_TRIGGERS { \ `NEG_EDGE (reset_negedge, reset);
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 \
}
`define AFU_PROBES { \ `SCOPE_TAP (0, 0, {
cmd_type, \ vx_reset,
state, \ vx_busy,
vx_mem_req_rw, \ vx_mem_req_fire,
vx_mem_req_byteen, \ vx_mem_rsp_fire,
vx_mem_req_addr, \ vx_dcr_wr_valid,
vx_mem_req_data, \ state_changed,
vx_mem_req_tag, \ avs_write_fire,
vx_mem_rsp_data, \ avs_read_fire,
vx_mem_rsp_tag, \ avs_waitrequest[0],
vx_dcr_wr_addr, \ avs_readdatavalid[0],
vx_dcr_wr_data, \ cp2af_sRxPort.c0.mmioRdValid,
mmio_req_hdr.address, \ cp2af_sRxPort.c0.mmioWrValid,
cp2af_sRxPort.c0.hdr.mdata, \ cp2af_sRxPort.c0.rspValid,
af2cp_sTxPort.c0.hdr.address, \ cp2af_sRxPort.c1.rspValid,
af2cp_sTxPort.c0.hdr.mdata, \ af2cp_sTxPort.c0.valid,
af2cp_sTxPort.c1.hdr.address, \ af2cp_sTxPort.c1.valid,
avs_address[0], \ cp2af_sRxPort.c0TxAlmFull,
avs_byteenable[0], \ cp2af_sRxPort.c1TxAlmFull,
avs_burstcount[0], \ af2cp_sTxPort.c2.mmioRdValid,
cci_mem_rd_req_ctr, \ cci_wr_req_fire,
cci_mem_wr_req_ctr, \ cci_wr_rsp_fire,
cci_rd_req_ctr, \ cci_rd_req_fire,
cci_rd_rsp_ctr, \ cci_rd_rsp_fire,
cci_wr_req_ctr \ cci_pending_reads_full,
} cci_pending_writes_empty,
cci_pending_writes_full
VX_scope_tap #( },{
.SCOPE_ID (0), cmd_type,
.TRIGGERW ($bits(`AFU_TRIGGERS)), state,
.PROBEW ($bits(`AFU_PROBES)), vx_mem_req_rw,
.DEPTH (4096) vx_mem_req_byteen,
) scope_tap ( vx_mem_req_addr,
.clk (clk), vx_mem_req_data,
.reset (scope_reset_w[0]), vx_mem_req_tag,
.start (1'b0), vx_mem_rsp_data,
.stop (1'b0), vx_mem_rsp_tag,
.triggers(`AFU_TRIGGERS), vx_dcr_wr_addr,
.probes (`AFU_PROBES), vx_dcr_wr_data,
.bus_in (scope_bus_in_w[0]), mmio_req_hdr.address,
.bus_out(scope_bus_out_w[0]) 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 `else
`SCOPE_IO_UNUSED_W(0) `SCOPE_IO_UNUSED(0)
`endif `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; assign m_axi_mem_araddr_a[i] = C_M_AXI_MEM_ADDR_WIDTH'(m_axi_mem_araddr_u[i]) + BANK_OFFSET;
end end
`SCOPE_IO_SWITCH (2) `SCOPE_IO_SWITCH (2);
Vortex_axi #( Vortex_axi #(
.AXI_DATA_WIDTH (C_M_AXI_MEM_DATA_WIDTH), .AXI_DATA_WIDTH (C_M_AXI_MEM_DATA_WIDTH),
@ -309,55 +309,41 @@ module VX_afu_wrap #(
`ifdef SCOPE `ifdef SCOPE
`ifdef DBG_SCOPE_AFU `ifdef DBG_SCOPE_AFU
`define AFU_TRIGGERS { \ `NEG_EDGE (reset_negedge, reset);
reset, \ `SCOPE_TAP (0, 0, {
ap_reset, \ ap_reset,
ap_start, \ ap_start,
ap_done, \ ap_done,
ap_idle, \ ap_idle,
interrupt, \ interrupt,
vx_reset, \ vx_reset,
vx_busy, \ vx_busy,
dcr_wr_valid, \ 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],
m_axi_mem_wready_a[0], \ m_axi_mem_wready_a[0],
m_axi_mem_bvalid_a[0], \ m_axi_mem_bvalid_a[0],
m_axi_mem_bready_a[0], \ m_axi_mem_bready_a[0],
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]
} }, {
`define AFU_PROBES { \ dcr_wr_addr,
dcr_wr_addr, \ dcr_wr_data,
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] \ },
} reset_negedge, 1'b0, 4096
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])
);
`else `else
`SCOPE_IO_UNUSED_W(0) `SCOPE_IO_UNUSED(0)
`endif `endif
`endif `endif
`ifdef CHIPSCOPE `ifdef CHIPSCOPE

View file

@ -84,7 +84,7 @@ module VX_core import VX_gpu_pkg::*; #(
.base_dcrs (base_dcrs) .base_dcrs (base_dcrs)
); );
`SCOPE_IO_SWITCH (3) `SCOPE_IO_SWITCH (3);
VX_schedule #( VX_schedule #(
.INSTANCE_ID ($sformatf("%s-schedule", INSTANCE_ID)), .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) .branch_ctl_if (branch_ctl_if)
); );
`SCOPE_IO_SWITCH (1) `SCOPE_IO_SWITCH (1);
VX_lsu_unit #( VX_lsu_unit #(
.INSTANCE_ID ($sformatf("%s-lsu", INSTANCE_ID)) .INSTANCE_ID ($sformatf("%s-lsu", INSTANCE_ID))

View file

@ -137,34 +137,24 @@ module VX_fetch import VX_gpu_pkg::*; #(
`ifdef SCOPE `ifdef SCOPE
`ifdef DBG_SCOPE_FETCH `ifdef DBG_SCOPE_FETCH
VX_scope_tap #( `SCOPE_IO_SWITCH (1);
.SCOPE_ID (1), `NEG_EDGE (reset_negedge, reset);
.TRIGGERW (4), `SCOPE_TAP_EX (0, 1, 3, (
.PROBEW (`UUID_WIDTH + `NW_WIDTH + `NUM_THREADS + `PC_BITS + `UUID_WIDTH + `NW_WIDTH + `NUM_THREADS + `PC_BITS + ICACHE_TAG_WIDTH + ICACHE_WORD_SIZE +
ICACHE_TAG_WIDTH + ICACHE_WORD_SIZE + ICACHE_ADDR_WIDTH + ICACHE_ADDR_WIDTH + (ICACHE_WORD_SIZE * 8) + ICACHE_TAG_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,
schedule_fire, schedule_fire,
icache_req_fire, icache_req_fire,
icache_rsp_fire icache_rsp_fire
}), }, {
.probes ({
schedule_if.data.uuid, schedule_if.data.wid, schedule_if.data.tmask, schedule_if.data.PC, 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.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 icache_bus_if.rsp_data.data, icache_bus_if.rsp_data.tag
}), },
.bus_in (scope_bus_in), reset_negedge, 1'b0, 4096
.bus_out (scope_bus_out)
); );
`else `else
`SCOPE_IO_UNUSED() `SCOPE_IO_UNUSED(0)
`endif `endif
`endif `endif
`ifdef CHIPSCOPE `ifdef CHIPSCOPE

View file

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

View file

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

View file

@ -536,23 +536,26 @@ module VX_lsu_slice import VX_gpu_pkg::*; #(
`ifdef SCOPE `ifdef SCOPE
`ifdef DBG_SCOPE_LSU `ifdef DBG_SCOPE_LSU
VX_scope_tap #( `SCOPE_IO_SWITCH (1);
.SCOPE_ID (3), `NEG_EDGE (reset_negedge, reset);
.TRIGGERW (2), `SCOPE_TAP_EX (0, 3, 2, (
.PROBEW (1 + NUM_LANES * (`XLEN + LSU_WORD_SIZE + LSU_WORD_SIZE * 8) + `UUID_WIDTH + NUM_LANES * LSU_WORD_SIZE * 8 + `UUID_WIDTH), 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 ( mem_req_fire,
.clk (clk), mem_rsp_fire
.reset (scope_reset), }, {
.start (1'b0), mem_req_rw,
.stop (1'b0), full_addr,
.triggers({mem_req_fire, mem_rsp_fire}), mem_req_byteen,
.probes ({mem_req_rw, full_addr, mem_req_byteen, mem_req_data, execute_if.data.uuid, rsp_data, rsp_uuid}), mem_req_data,
.bus_in (scope_bus_in), execute_if.data.uuid,
.bus_out(scope_bus_out) rsp_data,
rsp_uuid
},
reset_negedge, 1'b0, 4096
); );
`else `else
`SCOPE_IO_UNUSED() `SCOPE_IO_UNUSED(0)
`endif `endif
`endif `endif
`ifdef CHIPSCOPE `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 clk,
input wire reset, input wire reset,
input wire req_in, input wire req_in,
output wire req_out [N], output wire [N-1:0] req_out,
input wire rsp_in [N], input wire [N-1:0] rsp_in,
output wire rsp_out output wire rsp_out
); );
if (N > 1) begin : g_switch if (N > 1) begin : g_switch
@ -46,7 +46,10 @@ module VX_scope_switch #(
end end
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; assign rsp_out = rsp_out_r;
end else begin : g_passthru end else begin : g_passthru

View file

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

View file

@ -32,6 +32,8 @@
#define TIMEOUT_TIME (60*60) #define TIMEOUT_TIME (60*60)
#define MAX_DELAY_CYCLES 10000
#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)
@ -41,6 +43,7 @@
#define CMD_GET_DATA 3 #define CMD_GET_DATA 3
#define CMD_SET_START 4 #define CMD_SET_START 4
#define CMD_SET_STOP 5 #define CMD_SET_STOP 5
#define CMD_SET_DEPTH 6
#define CHECK_ERR(_expr) \ #define CHECK_ERR(_expr) \
do { \ do { \
@ -96,7 +99,7 @@ static void dump_module(std::ofstream& ofs,
auto itt = tails.find(name); auto itt = tails.find(name);
if (itt != tails.end()) { if (itt != tails.end()) {
for (auto& signal : itt->second->signals) { 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 << "$version Generated by Vortex Scope Analyzer $end" << std::endl;
ofs << "$timescale 1 ns $end" << std::endl; ofs << "$timescale 1 ns $end" << std::endl;
ofs << "$scope module TOP $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_map<std::string, std::unordered_set<std::string>> hierarchy;
std::unordered_set<std::string> heads; 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) { 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) { 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;
@ -350,7 +361,6 @@ int vx_scope_stop(vx_device_h hdevice) {
uint64_t cmd_count = (tap.id << 3) | CMD_GET_COUNT; uint64_t cmd_count = (tap.id << 3) | CMD_GET_COUNT;
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) if (count == 0)
continue; continue;
@ -385,7 +395,6 @@ int vx_scope_stop(vx_device_h hdevice) {
uint64_t cur_time = 0; uint64_t cur_time = 0;
auto tap = find_earliest_tap(taps); auto tap = find_earliest_tap(taps);
if (tap != nullptr) { if (tap != nullptr) {
cur_time = (tap->cycle_time > 0) ? (tap->cycle_time-1) : 0;
do { do {
// advance clock // advance clock
cur_time = advance_clock(ofs, cur_time, tap->cycle_time); 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); 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_); api_.fpgaClose(fpga_);
return err; return err;
}); });

View file

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