extending scope triggering to capture continous firing events

This commit is contained in:
Blaise Tine 2024-09-27 11:36:31 -07:00
parent f2c970868e
commit 6e40162027
8 changed files with 105 additions and 46 deletions

View file

@ -46,10 +46,11 @@
.rsp_in (scope_bus_out_w) \
)
`define SCOPE_TAP_EX(__idx, __id, __triggers_w, __probes_w, __triggers, __probes, __start, __stop, __depth) \
`define SCOPE_TAP_EX(__idx, __id, __xtriggers_w, __htriggers_w, __probes_w, __xtriggers, __htriggers, __probes, __start, __stop, __depth) \
VX_scope_tap #( \
.SCOPE_ID (__id), \
.TRIGGERW (__triggers_w), \
.XTRIGGERW(__xtriggers_w), \
.HTRIGGERW(__htriggers_w), \
.PROBEW (__probes_w), \
.DEPTH (__depth) \
) scope_tap_``idx ( \
@ -57,14 +58,15 @@
.reset (scope_reset_w[__idx]), \
.start (__start), \
.stop (__stop), \
.triggers(__triggers), \
.xtriggers(__xtriggers), \
.htriggers(__htriggers), \
.probes (__probes), \
.bus_in (scope_bus_in_w[__idx]), \
.bus_out(scope_bus_out_w[__idx]) \
)
`define SCOPE_TAP(__idx, __id, __triggers, __probes, __start, __stop, __depth) \
`SCOPE_TAP_EX(__idx, __id, $bits(__triggers), $bits(__probes), __triggers, __probes, __start, __stop, __depth)
`define SCOPE_TAP(__idx, __id, __xtriggers, __htriggers, __probes, __start, __stop, __depth) \
`SCOPE_TAP_EX(__idx, __id, $bits(__xtriggers), $bits(__htriggers), $bits(__probes), __xtriggers, __htriggers, __probes, __start, __stop, __depth)
`else
@ -76,9 +78,9 @@
`define SCOPE_IO_SWITCH(__count)
`define SCOPE_TAP(__idx, __id, __triggers, __probes, __depth)
`define SCOPE_TAP(__idx, __id, __xtriggers, __probes, __depth)
`define SCOPE_TAP_EX(__idx, __id, __triggers_w, __probes_w, __triggers, __probes, __depth)
`define SCOPE_TAP_EX(__idx, __id, __xtriggers_w, __probes_w, __xtriggers, __probes, __depth)
`endif

View file

@ -1016,10 +1016,12 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
always @(posedge clk) begin
state_prev <= state;
end
wire state_changed = (state != state_prev);
wire state_changed = (state != state_prev);
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;
wire avs_req_fire = (avs_write[0] || avs_read[0]) && ~avs_waitrequest[0];
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP (0, 0, {
vx_reset,
vx_busy,
@ -1027,21 +1029,29 @@ module vortex_afu import ccip_if_pkg::*; import local_mem_cfg_pkg::*; import VX_
vx_mem_req_ready,
vx_mem_rsp_valid,
vx_mem_rsp_ready,
vx_dcr_wr_valid,
state_changed,
avs_read[0],
avs_write[0],
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
cp2af_sRxPort.c1TxAlmFull
},{
state_changed,
vx_dcr_wr_valid, // ack-free
avs_readdatavalid[0], // ack-free
cp2af_sRxPort.c0.mmioRdValid, // ack-free
cp2af_sRxPort.c0.mmioWrValid, // ack-free
af2cp_sTxPort.c2.mmioRdValid, // ack-free
cp2af_sRxPort.c0.rspValid, // ack-free
cp2af_sRxPort.c1.rspValid, // ack-free
cci_rd_req_fire,
cci_wr_req_fire,
avs_req_fire,
vx_mem_req_fire,
vx_mem_rsp_fire
},{
cmd_type,
state,

View file

@ -309,6 +309,11 @@ module VX_afu_wrap #(
`ifdef SCOPE
`ifdef DBG_SCOPE_AFU
wire m_axi_mem_awfire_0 = m_axi_mem_awvalid_a[0] & m_axi_mem_awready_a[0];
wire m_axi_mem_arfire_0 = m_axi_mem_arvalid_a[0] & m_axi_mem_arready_a[0];
wire m_axi_mem_wfire_0 = m_axi_mem_wvalid_a[0] & m_axi_mem_wready_a[0];
wire m_axi_mem_bfire_0 = m_axi_mem_bvalid_a[0] & m_axi_mem_bready_a[0];
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP (0, 0, {
ap_reset,
@ -318,7 +323,6 @@ module VX_afu_wrap #(
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],
@ -330,6 +334,12 @@ module VX_afu_wrap #(
m_axi_mem_rvalid_a[0],
m_axi_mem_rready_a[0]
}, {
dcr_wr_valid,
m_axi_mem_awfire_0,
m_axi_mem_arfire_0,
m_axi_mem_wfire_0,
m_axi_mem_bfire_0
},{
dcr_wr_addr,
dcr_wr_data,
vx_pending_writes,

View file

@ -134,8 +134,11 @@ module VX_fetch import VX_gpu_pkg::*; #(
`ifdef SCOPE
`ifdef DBG_SCOPE_FETCH
`SCOPE_IO_SWITCH (1);
wire schedule_fire = schedule_if.valid && schedule_if.ready;
wire icache_bus_req_fire = icache_bus_if.req_valid && icache_bus_if.req_ready;
wire icache_bus_rsp_fire = icache_bus_if.rsp_valid && icache_bus_if.rsp_ready;
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP_EX (0, 1, 6, (
`SCOPE_TAP_EX (0, 1, 6, 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
), {
@ -146,6 +149,10 @@ module VX_fetch import VX_gpu_pkg::*; #(
icache_bus_if.rsp_valid,
icache_bus_if.rsp_ready
}, {
schedule_fire,
icache_bus_req_fire,
icache_bus_rsp_fire
},{
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

View file

@ -91,15 +91,18 @@ module VX_issue_slice import VX_gpu_pkg::*; #(
`ifdef SCOPE
`ifdef DBG_SCOPE_ISSUE
`SCOPE_IO_SWITCH (1);
wire operands_fire = operands_if.valid && operands_if.ready;
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP_EX (0, 2, 3, (
`SCOPE_TAP_EX (0, 2, 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
), {
operands_if.valid,
operands_if.ready,
writeback_if.valid
operands_if.ready
}, {
operands_fire,
writeback_if.valid // ack-free
}, {
operands_if.data.uuid,
operands_if.data.tmask,

View file

@ -536,13 +536,16 @@ module VX_lsu_slice import VX_gpu_pkg::*; #(
`ifdef DBG_SCOPE_LSU
`SCOPE_IO_SWITCH (1);
`NEG_EDGE (reset_negedge, reset);
`SCOPE_TAP_EX (0, 3, 4, (
`SCOPE_TAP_EX (0, 3, 4, 2, (
1 + NUM_LANES * (`XLEN + LSU_WORD_SIZE + LSU_WORD_SIZE * 8) + `UUID_WIDTH + NUM_LANES * LSU_WORD_SIZE * 8 + `UUID_WIDTH
), {
mem_req_valid,
mem_req_ready,
mem_rsp_valid,
mem_rsp_ready
}, {
mem_req_fire,
mem_rsp_fire
}, {
mem_req_rw,
full_addr,

View file

@ -17,9 +17,10 @@
module VX_scope_tap #(
parameter SCOPE_ID = 0, // scope identifier
parameter SCOPE_IDW = 8, // scope identifier width
parameter TRIGGERW = 32, // trigger signals width
parameter PROBEW = 4999, // probe signal width
parameter DEPTH = 8192, // trace buffer depth
parameter XTRIGGERW = 0, // changed trigger signals width
parameter HTRIGGERW = 0, // high trigger signals width
parameter PROBEW = 1, // probe signal width
parameter DEPTH = 256, // trace buffer depth
parameter IDLE_CTRW = 32, // idle time between triggers counter width
parameter TX_DATAW = 64 // transfer data width
) (
@ -27,14 +28,15 @@ module VX_scope_tap #(
input wire reset,
input wire start,
input wire stop,
input wire [`UP(TRIGGERW)-1:0] triggers,
input wire [`UP(XTRIGGERW)-1:0] xtriggers,
input wire [`UP(HTRIGGERW)-1:0] htriggers,
input wire [PROBEW-1:0] probes,
input wire bus_in,
output wire bus_out
);
localparam CTR_WIDTH = 64;
localparam SER_CTR_WIDTH = `LOG2UP(TX_DATAW);
localparam DATAW = PROBEW + TRIGGERW;
localparam DATAW = PROBEW + XTRIGGERW + HTRIGGERW;
localparam ADDRW = `CLOG2(DEPTH);
localparam SIZEW = `CLOG2(DEPTH+1);
localparam MAX_IDLE_CTR = (2 ** IDLE_CTRW) - 1;
@ -76,7 +78,7 @@ module VX_scope_tap #(
reg [CTR_WIDTH-1:0] timestamp, start_time;
reg [CTR_WIDTH-1:0] start_delay, stop_delay;
reg [`UP(TRIGGERW)-1:0] prev_trig;
reg [`UP(XTRIGGERW)-1:0] prev_xtrig;
reg [IDLE_CTRW-1:0] delta;
reg cmd_start, cmd_stop;
reg dflush;
@ -93,9 +95,16 @@ module VX_scope_tap #(
// 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));
if (XTRIGGERW != 0 || HTRIGGERW != 0) begin : g_delta_store
if (XTRIGGERW != 0 && HTRIGGERW != 0) begin : g_data_in_pxh
assign data_in = {probes, xtriggers, htriggers};
end else if (XTRIGGERW != 0) begin : g_data_in_px
assign data_in = {probes, xtriggers};
end else begin : g_data_in_ph
assign data_in = {probes, htriggers};
end
wire has_triggered = (xtriggers != prev_xtrig) || (htriggers != 0);
assign write_en = (tap_state == TAP_STATE_RUN) && (has_triggered || dflush);
VX_dp_ram #(
.DATAW (IDLE_CTRW),
.SIZE (DEPTH),
@ -150,7 +159,7 @@ module VX_scope_tap #(
tap_state <= TAP_STATE_IDLE;
delta <= '0;
dflush <= 0;
prev_trig <= '0;
prev_xtrig <= '0;
waddr <= '0;
end else begin
case (tap_state)
@ -167,15 +176,15 @@ module VX_scope_tap #(
TAP_STATE_RUN: begin
dflush <= 0;
if (!(stop || cmd_stop) && (waddr < waddr_end)) begin
if (TRIGGERW != 0) begin
if (dflush || (triggers != prev_trig)) begin
if (XTRIGGERW != 0) begin
if (dflush || (xtriggers != prev_xtrig)) begin
waddr <= waddr + SIZEW'(1);
delta <= '0;
end else begin
delta <= delta + IDLE_CTRW'(1);
dflush <= (delta == IDLE_CTRW'(MAX_IDLE_CTR-1));
end
prev_trig <= triggers;
prev_xtrig <= xtriggers;
end else begin
waddr <= waddr + SIZEW'(1);
end

View file

@ -181,10 +181,11 @@ def parse_xml(filename, max_taps):
xml_modules = xml_doc.findall(".//module/[@origName='VX_scope_tap']")
for xml_module in xml_modules:
scope_id = parse_vl_int(xml_module.find(".//var/[@name='SCOPE_ID']/const").get("name"))
triggerw = parse_vl_int(xml_module.find(".//var/[@name='TRIGGERW']/const").get("name"))
xtriggerw = parse_vl_int(xml_module.find(".//var/[@name='XTRIGGERW']/const").get("name"))
htriggerw = parse_vl_int(xml_module.find(".//var/[@name='HTRIGGERW']/const").get("name"))
probew = parse_vl_int(xml_module.find(".//var/[@name='PROBEW']/const").get("name"))
module_name = xml_module.get("name")
modules[module_name] = [scope_id, triggerw, probew]
modules[module_name] = [scope_id, xtriggerw, htriggerw, probew]
taps = []
xml_instances = xml_doc.iter("instance")
@ -195,22 +196,36 @@ def parse_xml(filename, max_taps):
module = modules.get(defName)
if module is None:
continue
triggers = []
xtriggers = []
htriggers = []
probes = []
w = parse_vl_port(xml_doc, xml_instance.find(".//port/[@name='triggers']/*"), triggers)
if w != module[1]:
raise ET.ParseError("invalid triggers width: actual=" + str(w) + ", expected=" + str(module[1]))
if module[1] > 0:
w = parse_vl_port(xml_doc, xml_instance.find(".//port/[@name='xtriggers']/*"), xtriggers)
if w != module[1]:
raise ET.ParseError("invalid xtriggers width: actual=" + str(w) + ", expected=" + str(module[1]))
if module[2] > 0:
w = parse_vl_port(xml_doc, xml_instance.find(".//port/[@name='htriggers']/*"), htriggers)
if w != module[2]:
raise ET.ParseError("invalid htriggers width: actual=" + str(w) + ", expected=" + str(module[2]))
w = parse_vl_port(xml_doc, xml_instance.find(".//port/[@name='probes']/*"), probes)
if w != module[2]:
raise ET.ParseError("invalid probes width: actual=" + str(w) + ", expected=" + str(module[2]))
if w != module[3]:
raise ET.ParseError("invalid probes width: actual=" + str(w) + ", expected=" + str(module[3]))
signals = probes
for trigger in triggers:
signals.append(trigger)
for xtrigger in xtriggers:
signals.append(xtrigger)
for htrigger in htriggers:
signals.append(htrigger)
loc = xml_instance.get("loc")
hier = xml_doc.find(".//cell/[@loc='" + loc + "']").get("hier")
path = hier.rsplit(".", 1)[0]
taps.append({"id":module[0],
"width":module[1] + module[2],
"width":module[1] + module[2] + module[3],
"signals":signals,
"path":path})