Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / tcu / rtl / tcu_dbg_ctl.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: tcu_dbg_ctl.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
//
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
//
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// have any questions.
//
// ========== Copyright Header End ============================================
module tcu_dbg_ctl (
scan_in,
tcu_int_se,
tcu_int_aclk,
tcu_int_bclk,
tcu_int_ce,
tcu_pce_ov,
l2clk,
scan_out,
cmp_io_sync_en_local,
io_cmp_sync_en_local,
cmp_io2x_sync_en_local,
spc_hstop_req,
spc_sstop_req,
spc_tp,
reset_event,
spc_crstat,
spc_crs,
spc_ss_comp,
doss_stat,
tcu_ss_request,
ssreq_upd_sync,
tcu_ss_mode,
tcu_do_mode,
dbg1_tcu_soc_hard_stop,
dbg1_tcu_soc_asrt_trigout,
trigout_pulse,
mio_tcu_trigin,
cycle_stretch,
mbist_clk_stop_req,
mbist_clk_stop,
jtag_clock_start,
jtscan_off,
cyc_count,
cyc_count_upd_sync,
tcudcr_data,
tcudcr_upd_sync,
decnt_data,
decnt_upd_sync,
core_sel,
core_sel_upd_sync,
spc_doss_enab,
doss_mode,
doss_enab,
csmode,
csmode_upd_sync,
cs_mode,
cs_mode_active,
jtagclkstop_ov,
de_count,
cycle_count,
tcu_dcr,
debug_cycle_counter_stop,
clock_domain_data,
dbg_upd_clock_domain,
tcu_dcr_en,
spc_ss_mode,
spc_ss_sel,
dbg_creg_access,
dbg_creg_addr,
dbg_creg_data,
dbg_creg_wr_en,
dbg_creg_addr_en,
dbg_creg_data_en,
ucb_csr_wr_sync,
ucb_csr_addr,
ucb_data_out);
wire l1en;
wire pce_ov;
wire stop;
wire se;
wire siclk;
wire soclk;
wire l1clk;
wire ucb_sel_cycle_count;
wire ucb_sel_dcr;
wire ucb_sel_trigout;
wire ucb_sel_dec;
wire ucb_wr_cycle_count;
wire ucb_wr_dcr;
wire ucb_wr_trigout;
wire ucb_wr_dec;
wire dbg_cyccnt_reg_scanin;
wire dbg_cyccnt_reg_scanout;
wire [63:0] next_cycle_count;
wire cycle_count_dec;
wire xxxrst_count_dec;
wire cycxxx_count_dec;
wire [63:0] cycxxx_count;
wire cycle_count_begin;
wire de_count_stop;
wire dbg_evnt_hld;
wire do_mode_active;
wire cycle_count_stop;
wire cycrst_count_beg;
wire reset_count_stop;
wire dbg_tcudcr_reg_scanin;
wire dbg_tcudcr_reg_scanout;
wire [3:0] next_tcu_dcr;
wire sstop_all_spcs;
wire dbg_decnt_reg_scanin;
wire dbg_decnt_reg_scanout;
wire [31:0] next_de_count;
wire de_count_dec;
wire de_count_begin;
wire dbg_event_active;
wire soc_hs_active;
wire soc_hard_stop;
wire trigin_sync;
wire spc_hs_active;
wire spc_ss_active;
wire spc_tp_active;
wire dbg1_tcu_soc_asrt_trigout_sync;
wire dbg_eventhold_reg_scanin;
wire dbg_eventhold_reg_scanout;
wire evnt_hld_en;
wire [3:0] dbg_event;
wire [3:0] dbg_event_hold;
wire jtag_clock_start_sync;
wire soc_hs_hold;
wire spc_tp_hold;
wire spc_hs_hold;
wire spc_ss_hold;
wire dbg_sshold_reg_scanin;
wire dbg_sshold_reg_scanout;
wire ss_evnt_hld_en;
wire [7:0] spc_sstop_din;
wire [7:0] ss_hold;
wire ss_hold_active;
wire [7:0] spc_sstop_qual;
wire [7:0] spc_clk_dom;
wire cntrs_stopped;
wire crstat_ss_vld;
wire tcu_dcr_one;
wire tcu_dcr_three;
wire tcu_dcr_two;
wire rst_evnt_trigger;
wire rst_evnt_trigger_2nd;
wire dbg_trigout_reg_scanin;
wire dbg_trigout_reg_scanout;
wire trigout;
wire trigout_q;
wire trigout2;
wire trigout2_q;
wire trigout_qq;
wire trigout2_qq;
wire [63:0] core_run;
wire [63:0] do_core_run;
wire dbg_creg_access_din;
wire dbg_creg_ad_enab;
wire dbg_creg_wr_enab;
wire dbg_cregreq_reg_scanin;
wire dbg_cregreq_reg_scanout;
wire dbg_creg_ad_enab_q;
wire dbg_creg_wr_enab_q;
wire dbg_cregreqb_reg_scanin;
wire dbg_cregreqb_reg_scanout;
wire dbg_creg_ad_enab_qq;
wire dbg_creg_wr_enab_qq;
wire dbg_creg_access_reg_scanin;
wire dbg_creg_access_reg_scanout;
wire [63:0] do_park;
wire [7:0] spc_dolap_enab;
wire [63:0] do_unpark;
wire ss_mode_active;
wire [7:0] spc_sstep_enab;
wire [7:0] singstep_mode;
wire dbg_ssupd_reg_scanin;
wire dbg_ssupd_reg_scanout;
wire ss_request;
wire ss_request_pulse;
wire [7:0] singstep_request;
wire dbg_ssmode_reg_scanin;
wire dbg_ssmode_reg_scanout;
wire dbg_ssreq_reg_scanin;
wire dbg_ssreq_reg_scanout;
wire [7:0] disbolap_mode;
wire dbg_domode_reg_scanin;
wire dbg_domode_reg_scanout;
wire dbg_cstep_reg_scanin;
wire dbg_cstep_reg_scanout;
wire next_cs_mode;
wire dbg_sochs_sync_reg_scanin;
wire dbg_sochs_sync_reg_scanout;
wire sochs_en;
wire dbg_trigreq_sync_reg_scanin;
wire dbg_trigreq_sync_reg_scanout;
wire trigreq_en;
wire dbg_trigin_sync_reg_scanin;
wire dbg_trigin_sync_reg_scanout;
wire mio_tcu_trigin_mission;
wire dbg_clkst_sync_reg_scanin;
wire dbg_clkst_sync_reg_scanout;
// Scan Control
input scan_in;
input tcu_int_se;
input tcu_int_aclk;
input tcu_int_bclk;
input tcu_int_ce;
input tcu_pce_ov;
input l2clk;
output scan_out;
// Synchronizer
input cmp_io_sync_en_local;
input io_cmp_sync_en_local;
input cmp_io2x_sync_en_local;
// Debug Event Requests from SPC Cores
input [7:0] spc_hstop_req;
input [7:0] spc_sstop_req;
input [7:0] spc_tp;
// End of POR as a Debug Event Request
input reset_event;
// Core_running Status
input [7:0] spc_crstat;
input [63:0] spc_crs;
input [7:0] spc_ss_comp; // single-step complete
// Disable Overlap & Single-Step
output [7:0] doss_stat; // to jtag
output [7:0] tcu_ss_request;
input ssreq_upd_sync; // from jtag
output [7:0] tcu_ss_mode; // single-step
output [7:0] tcu_do_mode; // Disable Overlap
// Hard Stop from SOC
input dbg1_tcu_soc_hard_stop;
// Watchpoint Trigger
input dbg1_tcu_soc_asrt_trigout;
output trigout_pulse; // to TRIGOUT package pin
// Trigger Input from Pin
input mio_tcu_trigin;
// Cycle stretch
output cycle_stretch;
// MBIST Clock Stop
input mbist_clk_stop_req;
output mbist_clk_stop;
// From JTAG
input jtag_clock_start;
input jtscan_off;
input [63:0] cyc_count;
input cyc_count_upd_sync;
input [3:0] tcudcr_data;
input tcudcr_upd_sync;
input [31:0] decnt_data;
input decnt_upd_sync;
input [7:0] core_sel;
input core_sel_upd_sync;
input [7:0] spc_doss_enab;
input [1:0] doss_mode;
input [63:0] doss_enab;
input csmode;
input csmode_upd_sync;
output cs_mode;
output cs_mode_active;
output jtagclkstop_ov;
// To JTAG
output [31:0] de_count;
output [63:0] cycle_count;
output [3:0] tcu_dcr;
// To Clock Sequencer
output debug_cycle_counter_stop;
output [23:0] clock_domain_data;
output dbg_upd_clock_domain;
output tcu_dcr_en; // bit[2]
output spc_ss_mode; // soft-stop
output [7:0] spc_ss_sel;
// To UCB Control
output dbg_creg_access;
output [39:0] dbg_creg_addr;
output [63:0] dbg_creg_data;
output dbg_creg_wr_en;
output dbg_creg_addr_en;
output dbg_creg_data_en;
// CSR (mbist_ctl)
input ucb_csr_wr_sync;
input [5:0] ucb_csr_addr;
input [63:0] ucb_data_out;
// Scan reassigns
assign l1en = tcu_int_ce; // 1'b1;
assign pce_ov = tcu_pce_ov; // 1'b1;
assign stop = 1'b0;
assign se = tcu_int_se;
assign siclk = tcu_int_aclk;
assign soclk = tcu_int_bclk;
// clock header
tcu_dbg_ctl_l1clkhdr_ctl_macro dbgctl_clkgen
(
.l2clk (l2clk ),
.l1clk (l1clk ),
.l1en(l1en),
.pce_ov(pce_ov),
.stop(stop),
.se(se)
);
assign ucb_sel_cycle_count = (ucb_csr_addr == 6'h20);
assign ucb_sel_dcr = (ucb_csr_addr == 6'h21);
assign ucb_sel_trigout = (ucb_csr_addr == 6'h22);
assign ucb_sel_dec = (ucb_csr_addr == 6'h23);
assign ucb_wr_cycle_count = ucb_csr_wr_sync && ucb_sel_cycle_count;
assign ucb_wr_dcr = ucb_csr_wr_sync && ucb_sel_dcr;
assign ucb_wr_trigout = ucb_csr_wr_sync && ucb_sel_trigout;
assign ucb_wr_dec = ucb_csr_wr_sync && ucb_sel_dec;
//// Synchronizer Pulse from cluster header
// msff_ctl_macro dbg_cmpiosync_reg (width=3)
//(
// .scan_in(dbg_cmpiosync_reg_scanin),
// .scan_out(dbg_cmpiosync_reg_scanout),
// .l1clk (l1clk),
// .din ({cmp_io_sync_en, io_cmp_sync_en, cmp_io2x_sync_en}),
// .dout ({cmp_io_sync_en_local, io_cmp_sync_en_local, cmp_io2x_sync_en_local})
// );
//********************************************************************
// Cycle Counter
//********************************************************************
// 64-bit for non-reset event; tcu_dcr[2]==1 ==> 2 32-bit counters
// where upper word is cycle counter, lower word is reset counter
// When tcu_dcr[2]==0, cycle counter waits until debug events counter
// reaches zero
tcu_dbg_ctl_msff_ctl_macro__width_64 dbg_cyccnt_reg
(
.scan_in(dbg_cyccnt_reg_scanin),
.scan_out(dbg_cyccnt_reg_scanout),
.l1clk (l1clk),
.din (next_cycle_count[63:0]),
.dout (cycle_count[63:0]),
.siclk(siclk),
.soclk(soclk)
);
assign next_cycle_count[63:0] = cycle_count_dec ? (cycle_count[63:0] - 64'b1)
: xxxrst_count_dec ? (cycle_count[63:0] - 64'b1)
: cycxxx_count_dec ? cycxxx_count[63:0]
: cyc_count_upd_sync ? cyc_count[63:0]
: ucb_wr_cycle_count ? ucb_data_out[63:0]
: cycle_count[63:0];
assign cycle_count_begin = ~tcu_dcr_en
& ((de_count_stop & dbg_evnt_hld) | do_mode_active | cs_mode
| mbist_clk_stop_req);
assign cycle_count_dec = cycle_count_begin & ~cycle_count_stop;
assign cycle_count_stop = (cycle_count[63:0] == 64'b0);
assign cycrst_count_beg = tcu_dcr_en & reset_event;
assign xxxrst_count_dec = cycrst_count_beg & ~reset_count_stop;
assign cycxxx_count_dec = cycrst_count_beg & reset_count_stop & ~cycle_count_stop;
assign reset_count_stop = (cycle_count[31:0] == 32'b0);
assign cycxxx_count[63:0] = (cycle_count[63:0] - 64'b1) & 64'hFFFFFFFF00000000;
//assign cc_gt_f = |cycle_count[63:4];
//********************************************************************
// TCU DCR: Debug event Control Register
//********************************************************************
// 4 bits; [2] makes Cycle Counter operate as Cycle[63:32]/Reset[31:0]
// Counter and enables End-of-POR-Sequence as a debug event
// bit[3] enables all spc's to be softstopped if any requests a sstop
tcu_dbg_ctl_msff_ctl_macro__width_4 dbg_tcudcr_reg
(
.scan_in(dbg_tcudcr_reg_scanin),
.scan_out(dbg_tcudcr_reg_scanout),
.l1clk (l1clk),
.din (next_tcu_dcr[3:0]),
.dout (tcu_dcr[3:0]),
.siclk(siclk),
.soclk(soclk)
);
assign next_tcu_dcr[3:0] = tcudcr_upd_sync ? tcudcr_data[3:0]
: ucb_wr_dcr ? ucb_data_out[3:0]
: tcu_dcr[3:0];
assign tcu_dcr_en = tcu_dcr[2];
assign sstop_all_spcs = tcu_dcr[3] & ~tcu_dcr[2];
//********************************************************************
// Debug Events Counter
//********************************************************************
// Counts Debug Events: decrements until zero
// enabled if tcu_dcr[2]=0
tcu_dbg_ctl_msff_ctl_macro__width_32 dbg_decnt_reg
(
.scan_in(dbg_decnt_reg_scanin),
.scan_out(dbg_decnt_reg_scanout),
.l1clk (l1clk),
.din (next_de_count[31:0]),
.dout (de_count[31:0]),
.siclk(siclk),
.soclk(soclk)
);
assign next_de_count[31:0] = de_count_dec ? (de_count[31:0] - 32'b1)
: decnt_upd_sync ? decnt_data[31:0]
: ucb_wr_dec ? ucb_data_out[31:0]
: de_count[31:0];
// counter stops after reaching 0
assign de_count_dec = (de_count_begin & dbg_event_active)
& ~(de_count_stop);
assign de_count_begin = ~tcu_dcr_en;
assign de_count_stop = (de_count[31:0] == 32'b0) | tcu_dcr_en;
//********************************************************************
// Detect Edge of Any Debug Request and Hold the Request (from spc/soc)
//********************************************************************
// Only after all debug events have been counted per de_counter
assign soc_hs_active = soc_hard_stop | trigin_sync;
assign spc_hs_active = |spc_hstop_req[7:0];
assign spc_ss_active = |spc_sstop_req[7:0];
assign spc_tp_active = |spc_tp[7:0] | dbg1_tcu_soc_asrt_trigout_sync;
tcu_dbg_ctl_msff_ctl_macro__en_1__width_4 dbg_eventhold_reg
(
.scan_in(dbg_eventhold_reg_scanin),
.scan_out(dbg_eventhold_reg_scanout),
.l1clk (l1clk),
.en (evnt_hld_en),
.din (dbg_event[3:0]),
.dout (dbg_event_hold[3:0]),
.siclk(siclk),
.soclk(soclk)
);
assign dbg_event[3:0] = {soc_hs_active,spc_tp_active,spc_hs_active,spc_ss_active};
assign dbg_evnt_hld = |dbg_event_hold[3:0];
assign evnt_hld_en = (de_count_stop & ~dbg_evnt_hld) | jtag_clock_start_sync;
assign soc_hs_hold = dbg_event_hold[3];
assign spc_tp_hold = dbg_event_hold[2];
assign spc_hs_hold = dbg_event_hold[1];
assign spc_ss_hold = dbg_event_hold[0];
assign dbg_event_active = |dbg_event[3:0];
//********************************************************************
// Detect Edge of Soft Stop Debug Request and Hold It
//********************************************************************
// This doubles as core select reg for JTAG
tcu_dbg_ctl_msff_ctl_macro__en_1__width_8 dbg_sshold_reg
(
.scan_in(dbg_sshold_reg_scanin),
.scan_out(dbg_sshold_reg_scanout),
.l1clk (l1clk),
.en (ss_evnt_hld_en),
.din (spc_sstop_din[7:0]),
.dout (ss_hold[7:0]),
.siclk(siclk),
.soclk(soclk)
);
assign ss_hold_active = ~(|ss_hold[7:0]) & de_count_stop;
assign ss_evnt_hld_en = (ss_hold_active | core_sel_upd_sync) | jtag_clock_start_sync;
assign spc_sstop_qual[7:0]= {8{sstop_all_spcs & spc_ss_active}} | spc_sstop_req[7:0];
assign spc_sstop_din[7:0] = core_sel_upd_sync ? core_sel[7:0] : spc_sstop_qual[7:0];
//assign spc_sstop_din[7:0] = core_sel_upd_sync ? core_sel[7:0] : spc_sstop_req[7:0];
//********************************************************************
// Interface to Clock Sequencer
//********************************************************************
// Soft Stop - only stop clocks to target SPC cores
// Start with SPC0
assign spc_ss_mode = spc_ss_hold;
assign spc_ss_sel[7:0] = ss_hold[7:0];
// Hard Stop - stop all clocks, start with target SPC core or SOC0
assign clock_domain_data[23:8] = soc_hs_active ? 16'b1 : 16'b0;
assign spc_clk_dom[7:0] = spc_hs_active ? spc_hstop_req[7:0]
: spc_ss_active ? 8'b1 // start w/spc0
: 8'b0;
assign clock_domain_data[7:0] = spc_clk_dom[7:0];
assign dbg_upd_clock_domain = ~tcu_dcr_en & evnt_hld_en
& (soc_hs_active | spc_hs_active | spc_ss_active);
//assign dbg_upd_clock_domain = ~tcu_dcr_en & dbg_evnt_hld;
assign cntrs_stopped = de_count_stop & cycle_count_stop & ~tcu_dcr_en;
assign debug_cycle_counter_stop = cntrs_stopped & ( spc_hs_hold | soc_hs_hold
| (spc_ss_hold & crstat_ss_vld))
| (reset_count_stop
& reset_event & tcu_dcr_one)
| (cycle_count_stop
& reset_event & tcu_dcr_three) ;
assign mbist_clk_stop = cycle_count_stop & ~tcu_dcr_en & mbist_clk_stop_req;
//********************************************************************
// End of Reset Sequence as an Event
//********************************************************************
assign tcu_dcr_one = tcu_dcr[2:0]==3'b101;
assign tcu_dcr_two = tcu_dcr[2:0]==3'b110;
assign tcu_dcr_three = &tcu_dcr[2:0];
assign rst_evnt_trigger = reset_count_stop & tcu_dcr_en & reset_event;
assign rst_evnt_trigger_2nd = cycle_count_stop & tcu_dcr_three & reset_event;
assign cycle_stretch = reset_count_stop & (tcu_dcr_two | tcu_dcr_three) & reset_event;
//********************************************************************
// Trigger Pulse
//********************************************************************
// Send pulse to TRIGOUT package pin, in io_clk domain
tcu_dbg_ctl_msff_ctl_macro__en_1__width_4 dbg_trigout_reg
(
.scan_in(dbg_trigout_reg_scanin),
.scan_out(dbg_trigout_reg_scanout),
.l1clk (l1clk),
.en (cmp_io2x_sync_en_local),
.din ({trigout, trigout_q, trigout2, trigout2_q }),
.dout ({trigout_q,trigout_qq, trigout2_q, trigout2_qq}),
.siclk(siclk),
.soclk(soclk)
);
assign trigout = ucb_wr_trigout | rst_evnt_trigger | (cntrs_stopped & spc_tp_hold);
//| dbg1_tcu_soc_asrt_trigout_sync;
assign trigout2 = rst_evnt_trigger_2nd;
assign trigout_pulse = (trigout_q & ~trigout_qq) |
(trigout2_q & ~trigout2_qq);
//********************************************************************
// Core Parking and Run Status Detection
//********************************************************************
// Send request to NCU to park targeted SPC Core(s) for Soft-stop or Disable Overlap
// Generate data for parking cores for soft stop
assign core_run[7:0] = ~ss_hold[0] ? spc_crs[7:0] : 8'b0;
assign core_run[15:8] = ~ss_hold[1] ? spc_crs[15:8] : 8'b0;
assign core_run[23:16] = ~ss_hold[2] ? spc_crs[23:16] : 8'b0;
assign core_run[31:24] = ~ss_hold[3] ? spc_crs[31:24] : 8'b0;
assign core_run[39:32] = ~ss_hold[4] ? spc_crs[39:32] : 8'b0;
assign core_run[47:40] = ~ss_hold[5] ? spc_crs[47:40] : 8'b0;
assign core_run[55:48] = ~ss_hold[6] ? spc_crs[55:48] : 8'b0;
assign core_run[63:56] = ~ss_hold[7] ? spc_crs[63:56] : 8'b0;
// Generate Core Run Address & Data to send over UCB to NCU; this is to
// park cores that should be soft-stopped
assign dbg_creg_data[63:0] = spc_ss_hold ? core_run[63:0] : do_core_run[63:0];
assign dbg_creg_addr[39:0] = 40'h9001040050;
// Tells ucb to use dbg signals instead of jtag signals
assign dbg_creg_access_din = (spc_ss_hold & ~tcu_dcr_en) | do_mode_active;
// Send addr/data 'enables' to ucb as one pulse synch'd to io clk domain
assign dbg_creg_ad_enab = (spc_ss_hold & ~tcu_dcr_en) | (do_mode_active & cycle_count_dec); // & ~cc_gt_f);
assign dbg_creg_wr_enab = (spc_ss_hold & cntrs_stopped) | (do_mode_active & cycle_count_dec); // & ~cc_gt_f);
tcu_dbg_ctl_msff_ctl_macro__en_1__width_2 dbg_cregreq_reg
(
.scan_in(dbg_cregreq_reg_scanin),
.scan_out(dbg_cregreq_reg_scanout),
.l1clk (l1clk),
.en (cmp_io_sync_en_local),
.din ({dbg_creg_ad_enab,dbg_creg_wr_enab}),
.dout ({dbg_creg_ad_enab_q,dbg_creg_wr_enab_q}),
.siclk(siclk),
.soclk(soclk)
);
tcu_dbg_ctl_msff_ctl_macro__en_1__width_2 dbg_cregreqb_reg
(
.scan_in(dbg_cregreqb_reg_scanin),
.scan_out(dbg_cregreqb_reg_scanout),
.l1clk (l1clk),
.en (cmp_io_sync_en_local),
.din ({dbg_creg_ad_enab_q,dbg_creg_wr_enab_q}),
.dout ({dbg_creg_ad_enab_qq,dbg_creg_wr_enab_qq}),
.siclk(siclk),
.soclk(soclk)
);
tcu_dbg_ctl_msff_ctl_macro__en_1__width_1 dbg_creg_access_reg (
.scan_in ( dbg_creg_access_reg_scanin ),
.scan_out ( dbg_creg_access_reg_scanout ),
.l1clk ( l1clk ),
.en ( cmp_io_sync_en_local ),
.din ( dbg_creg_access_din ),
.dout ( dbg_creg_access ),
.siclk(siclk),
.soclk(soclk));
assign dbg_creg_data_en = dbg_creg_ad_enab_q & ~dbg_creg_ad_enab_qq
| (~dbg_creg_ad_enab_q & dbg_creg_ad_enab_qq & do_mode_active);
assign dbg_creg_wr_en = dbg_creg_wr_enab_q & ~dbg_creg_wr_enab_qq
| (~dbg_creg_wr_enab_q & dbg_creg_wr_enab_qq & do_mode_active);
assign dbg_creg_addr_en = dbg_creg_data_en;
// This signal is set when targeted cores say they are parked via Core_Run_Status
assign crstat_ss_vld = (~ss_hold[0] | (ss_hold[0] & ~spc_crstat[0]))
& (~ss_hold[1] | (ss_hold[1] & ~spc_crstat[1]))
& (~ss_hold[2] | (ss_hold[2] & ~spc_crstat[2]))
& (~ss_hold[3] | (ss_hold[3] & ~spc_crstat[3]))
& (~ss_hold[4] | (ss_hold[4] & ~spc_crstat[4]))
& (~ss_hold[5] | (ss_hold[5] & ~spc_crstat[5]))
& (~ss_hold[6] | (ss_hold[6] & ~spc_crstat[6]))
& (~ss_hold[7] | (ss_hold[7] & ~spc_crstat[7]));
// Generate data for parking cores for disable overlap
assign do_park[7:0] = ~spc_dolap_enab[0] ? spc_crs[7:0] : 8'b0;
assign do_park[15:8] = ~spc_dolap_enab[1] ? spc_crs[15:8] : 8'b0;
assign do_park[23:16] = ~spc_dolap_enab[2] ? spc_crs[23:16] : 8'b0;
assign do_park[31:24] = ~spc_dolap_enab[3] ? spc_crs[31:24] : 8'b0;
assign do_park[39:32] = ~spc_dolap_enab[4] ? spc_crs[39:32] : 8'b0;
assign do_park[47:40] = ~spc_dolap_enab[5] ? spc_crs[47:40] : 8'b0;
assign do_park[55:48] = ~spc_dolap_enab[6] ? spc_crs[55:48] : 8'b0;
assign do_park[63:56] = ~spc_dolap_enab[7] ? spc_crs[63:56] : 8'b0;
assign do_unpark[7:0] = ~spc_dolap_enab[0] ? spc_crs[7:0] : doss_enab[7:0];
assign do_unpark[15:8] = ~spc_dolap_enab[1] ? spc_crs[15:8] : doss_enab[15:8];
assign do_unpark[23:16] = ~spc_dolap_enab[2] ? spc_crs[23:16] : doss_enab[23:16];
assign do_unpark[31:24] = ~spc_dolap_enab[3] ? spc_crs[31:24] : doss_enab[31:24];
assign do_unpark[39:32] = ~spc_dolap_enab[4] ? spc_crs[39:32] : doss_enab[39:32];
assign do_unpark[47:40] = ~spc_dolap_enab[5] ? spc_crs[47:40] : doss_enab[47:40];
assign do_unpark[55:48] = ~spc_dolap_enab[6] ? spc_crs[55:48] : doss_enab[55:48];
assign do_unpark[63:56] = ~spc_dolap_enab[7] ? spc_crs[63:56] : doss_enab[63:56];
assign do_core_run[63:0] = cycle_count_stop ? do_park[63:0]: do_unpark[63:0];
//********************************************************************
// Single Step Mode
//********************************************************************
// Detect when all physical cores that should be in single-step mode
// become parked & send a tcu_ss_mode signal to those cores; only update
// when core becomes parked; single step does not stop clocks to cores
assign ss_mode_active = &doss_mode[1:0];
assign spc_sstep_enab[7:0] = spc_doss_enab[7:0] & {8{ss_mode_active}};
assign singstep_mode[0] = ~spc_crstat[0] ? spc_sstep_enab[0] : tcu_ss_mode[0];
assign singstep_mode[1] = ~spc_crstat[1] ? spc_sstep_enab[1] : tcu_ss_mode[1];
assign singstep_mode[2] = ~spc_crstat[2] ? spc_sstep_enab[2] : tcu_ss_mode[2];
assign singstep_mode[3] = ~spc_crstat[3] ? spc_sstep_enab[3] : tcu_ss_mode[3];
assign singstep_mode[4] = ~spc_crstat[4] ? spc_sstep_enab[4] : tcu_ss_mode[4];
assign singstep_mode[5] = ~spc_crstat[5] ? spc_sstep_enab[5] : tcu_ss_mode[5];
assign singstep_mode[6] = ~spc_crstat[6] ? spc_sstep_enab[6] : tcu_ss_mode[6];
assign singstep_mode[7] = ~spc_crstat[7] ? spc_sstep_enab[7] : tcu_ss_mode[7];
// Create single-step request pulses to target SPC cores
tcu_dbg_ctl_msff_ctl_macro__en_1__width_1 dbg_ssupd_reg
(
.scan_in(dbg_ssupd_reg_scanin),
.scan_out(dbg_ssupd_reg_scanout),
.l1clk (l1clk),
.en (ss_mode_active),
.din (ssreq_upd_sync),
.dout (ss_request),
.siclk(siclk),
.soclk(soclk)
);
assign ss_request_pulse = ~ss_request & ssreq_upd_sync;
assign singstep_request[7:0] = singstep_mode[7:0] & {8{ss_request_pulse}};
// Outputs to SPC Cores for Single Step
tcu_dbg_ctl_msff_ctl_macro__en_1__width_8 dbg_ssmode_reg
(
.scan_in(dbg_ssmode_reg_scanin),
.scan_out(dbg_ssmode_reg_scanout),
.l1clk (l1clk),
.en (io_cmp_sync_en_local),
.din (singstep_mode[7:0]),
.dout (tcu_ss_mode[7:0]),
.siclk(siclk),
.soclk(soclk)
);
tcu_dbg_ctl_msff_ctl_macro__width_8 dbg_ssreq_reg
(
.scan_in(dbg_ssreq_reg_scanin),
.scan_out(dbg_ssreq_reg_scanout),
.l1clk (l1clk),
.din (singstep_request[7:0]),
.dout (tcu_ss_request[7:0]),
.siclk(siclk),
.soclk(soclk)
);
//********************************************************************
// Disable Overlap Mode
//********************************************************************
// disable overlap does not stop clocks to cores
assign do_mode_active = doss_mode[1] & ~doss_mode[0];
assign spc_dolap_enab[7:0] = spc_doss_enab[7:0] & {8{do_mode_active}};
assign disbolap_mode[0] = ~spc_crstat[0] ? spc_dolap_enab[0] : tcu_do_mode[0];
assign disbolap_mode[1] = ~spc_crstat[1] ? spc_dolap_enab[1] : tcu_do_mode[1];
assign disbolap_mode[2] = ~spc_crstat[2] ? spc_dolap_enab[2] : tcu_do_mode[2];
assign disbolap_mode[3] = ~spc_crstat[3] ? spc_dolap_enab[3] : tcu_do_mode[3];
assign disbolap_mode[4] = ~spc_crstat[4] ? spc_dolap_enab[4] : tcu_do_mode[4];
assign disbolap_mode[5] = ~spc_crstat[5] ? spc_dolap_enab[5] : tcu_do_mode[5];
assign disbolap_mode[6] = ~spc_crstat[6] ? spc_dolap_enab[6] : tcu_do_mode[6];
assign disbolap_mode[7] = ~spc_crstat[7] ? spc_dolap_enab[7] : tcu_do_mode[7];
// Outputs to SPC Cores for Disable Overlap
tcu_dbg_ctl_msff_ctl_macro__clr__1__en_1__width_8 dbg_domode_reg
(
.scan_in(dbg_domode_reg_scanin),
.scan_out(dbg_domode_reg_scanout),
.l1clk (l1clk),
.en (io_cmp_sync_en_local),
.clr_ (do_mode_active),
.din (disbolap_mode[7:0]),
.dout (tcu_do_mode[7:0]),
.siclk(siclk),
.soclk(soclk)
);
// Single-step complete status back to JTAG; spc_ss_comp is spc_single-step_complete
// Also Disable Overlap Running Status when enabled and counter is done and parked
assign doss_stat[0] = (singstep_mode[0] & spc_ss_comp[0]) | (spc_dolap_enab[0] & ~cycle_count_dec & ~spc_crstat[0]);
assign doss_stat[1] = (singstep_mode[1] & spc_ss_comp[1]) | (spc_dolap_enab[1] & ~cycle_count_dec & ~spc_crstat[1]);
assign doss_stat[2] = (singstep_mode[2] & spc_ss_comp[2]) | (spc_dolap_enab[2] & ~cycle_count_dec & ~spc_crstat[2]);
assign doss_stat[3] = (singstep_mode[3] & spc_ss_comp[3]) | (spc_dolap_enab[3] & ~cycle_count_dec & ~spc_crstat[3]);
assign doss_stat[4] = (singstep_mode[4] & spc_ss_comp[4]) | (spc_dolap_enab[4] & ~cycle_count_dec & ~spc_crstat[4]);
assign doss_stat[5] = (singstep_mode[5] & spc_ss_comp[5]) | (spc_dolap_enab[5] & ~cycle_count_dec & ~spc_crstat[5]);
assign doss_stat[6] = (singstep_mode[6] & spc_ss_comp[6]) | (spc_dolap_enab[6] & ~cycle_count_dec & ~spc_crstat[6]);
assign doss_stat[7] = (singstep_mode[7] & spc_ss_comp[7]) | (spc_dolap_enab[7] & ~cycle_count_dec & ~spc_crstat[7]);
//********************************************************************
// Cycle Step Mode
//********************************************************************
tcu_dbg_ctl_msff_ctl_macro__width_1 dbg_cstep_reg
(
.scan_in(dbg_cstep_reg_scanin),
.scan_out(dbg_cstep_reg_scanout),
.l1clk (l1clk),
.din (next_cs_mode),
.dout (cs_mode),
.siclk(siclk),
.soclk(soclk)
);
assign next_cs_mode = csmode_upd_sync ? csmode
: cs_mode;
assign cs_mode_active = cycle_count_stop & cs_mode;
assign jtagclkstop_ov = ~cycle_count_stop & cs_mode; // overrides jtag clk stop
//********************************************************************
// SOC Hard Stop
//********************************************************************
// In io_clk domain, synchronize to cmp
tcu_dbg_ctl_msff_ctl_macro__en_1__width_1 dbg_sochs_sync_reg
(
.scan_in(dbg_sochs_sync_reg_scanin),
.scan_out(dbg_sochs_sync_reg_scanout),
.l1clk (l1clk),
.en (sochs_en),
.din (dbg1_tcu_soc_hard_stop),
.dout (soc_hard_stop),
.siclk(siclk),
.soclk(soclk)
);
assign sochs_en = io_cmp_sync_en_local & jtscan_off;
//********************************************************************
// DBG Generated Trigger Pulse Request
//********************************************************************
// From io2x_clk domain, receive with io2x sync enable
tcu_dbg_ctl_msff_ctl_macro__en_1__width_1 dbg_trigreq_sync_reg
(
.scan_in(dbg_trigreq_sync_reg_scanin),
.scan_out(dbg_trigreq_sync_reg_scanout),
.l1clk (l1clk),
.en (trigreq_en),
.din (dbg1_tcu_soc_asrt_trigout),
.dout (dbg1_tcu_soc_asrt_trigout_sync),
.siclk(siclk),
.soclk(soclk)
);
assign trigreq_en = io_cmp_sync_en_local & jtscan_off;
//********************************************************************
// Trigger In Request from Pins
//********************************************************************
// Incoming from MIO, asynchronous
cl_sc1_clksyncff_4x dbg_trigin_sync_reg
(
.si (dbg_trigin_sync_reg_scanin),
.so (dbg_trigin_sync_reg_scanout),
.l1clk (l1clk),
.d (mio_tcu_trigin_mission),
.q (trigin_sync),
.siclk(siclk),
.soclk(soclk)
);
// once it's set, hold the trigger_in and kick off a hard clock stop
// - treat as a pulse, it will get held in other logic
assign mio_tcu_trigin_mission = mio_tcu_trigin & jtscan_off;
// ********************************************************************
// Synchronizer for JTAG Clock Start, from instr_clock_start
// ********************************************************************
// This is so a jtag clock start instruction can turn off the debug event
// that is active, thus restarting clocks
cl_sc1_clksyncff_4x dbg_clkst_sync_reg
(.si (dbg_clkst_sync_reg_scanin),
.so (dbg_clkst_sync_reg_scanout),
.l1clk (l1clk),
.d (jtag_clock_start),
.q (jtag_clock_start_sync),
.siclk(siclk),
.soclk(soclk)
);
// fixscan start:
//assign dbg_cmpiosync_reg_scanin = scan_in ;
//assign dbg_cyccnt_reg_scanin = dbg_cmpiosync_reg_scanout;
assign dbg_cyccnt_reg_scanin = scan_in ;
assign dbg_tcudcr_reg_scanin = dbg_cyccnt_reg_scanout ;
assign dbg_decnt_reg_scanin = dbg_tcudcr_reg_scanout ;
assign dbg_eventhold_reg_scanin = dbg_decnt_reg_scanout ;
assign dbg_sshold_reg_scanin = dbg_eventhold_reg_scanout;
assign dbg_trigout_reg_scanin = dbg_sshold_reg_scanout ;
assign dbg_cregreq_reg_scanin = dbg_trigout_reg_scanout ;
assign dbg_cregreqb_reg_scanin = dbg_cregreq_reg_scanout ;
assign dbg_creg_access_reg_scanin = dbg_cregreqb_reg_scanout;
assign dbg_ssupd_reg_scanin = dbg_creg_access_reg_scanout;
assign dbg_ssmode_reg_scanin = dbg_ssupd_reg_scanout ;
assign dbg_ssreq_reg_scanin = dbg_ssmode_reg_scanout ;
assign dbg_domode_reg_scanin = dbg_ssreq_reg_scanout ;
assign dbg_cstep_reg_scanin = dbg_domode_reg_scanout ;
assign dbg_sochs_sync_reg_scanin = dbg_cstep_reg_scanout ;
assign dbg_trigreq_sync_reg_scanin = dbg_sochs_sync_reg_scanout;
assign dbg_trigin_sync_reg_scanin = dbg_trigreq_sync_reg_scanout;
assign dbg_clkst_sync_reg_scanin = dbg_trigin_sync_reg_scanout;
assign scan_out = dbg_clkst_sync_reg_scanout;
// fixscan end:
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_l1clkhdr_ctl_macro (
l2clk,
l1en,
pce_ov,
stop,
se,
l1clk);
input l2clk;
input l1en;
input pce_ov;
input stop;
input se;
output l1clk;
cl_sc1_l1hdr_8x c_0 (
.l2clk(l2clk),
.pce(l1en),
.l1clk(l1clk),
.se(se),
.pce_ov(pce_ov),
.stop(stop)
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__width_64 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [63:0] fdin;
wire [62:0] so;
input [63:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [63:0] dout;
output scan_out;
assign fdin[63:0] = din[63:0];
dff #(64) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[63:0]),
.si({scan_in,so[62:0]}),
.so({so[62:0],scan_out}),
.q(dout[63:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__width_4 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [3:0] fdin;
wire [2:0] so;
input [3:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [3:0] dout;
output scan_out;
assign fdin[3:0] = din[3:0];
dff #(4) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[3:0]),
.si({scan_in,so[2:0]}),
.so({so[2:0],scan_out}),
.q(dout[3:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__width_32 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [31:0] fdin;
wire [30:0] so;
input [31:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [31:0] dout;
output scan_out;
assign fdin[31:0] = din[31:0];
dff #(32) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[31:0]),
.si({scan_in,so[30:0]}),
.so({so[30:0],scan_out}),
.q(dout[31:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__en_1__width_4 (
din,
en,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [3:0] fdin;
wire [2:0] so;
input [3:0] din;
input en;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [3:0] dout;
output scan_out;
assign fdin[3:0] = (din[3:0] & {4{en}}) | (dout[3:0] & ~{4{en}});
dff #(4) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[3:0]),
.si({scan_in,so[2:0]}),
.so({so[2:0],scan_out}),
.q(dout[3:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__en_1__width_8 (
din,
en,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [7:0] fdin;
wire [6:0] so;
input [7:0] din;
input en;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [7:0] dout;
output scan_out;
assign fdin[7:0] = (din[7:0] & {8{en}}) | (dout[7:0] & ~{8{en}});
dff #(8) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[7:0]),
.si({scan_in,so[6:0]}),
.so({so[6:0],scan_out}),
.q(dout[7:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__en_1__width_2 (
din,
en,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [1:0] fdin;
wire [0:0] so;
input [1:0] din;
input en;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [1:0] dout;
output scan_out;
assign fdin[1:0] = (din[1:0] & {2{en}}) | (dout[1:0] & ~{2{en}});
dff #(2) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[1:0]),
.si({scan_in,so[0:0]}),
.so({so[0:0],scan_out}),
.q(dout[1:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__en_1__width_1 (
din,
en,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [0:0] fdin;
input [0:0] din;
input en;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [0:0] dout;
output scan_out;
assign fdin[0:0] = (din[0:0] & {1{en}}) | (dout[0:0] & ~{1{en}});
dff #(1) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[0:0]),
.si(scan_in),
.so(scan_out),
.q(dout[0:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__width_8 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [7:0] fdin;
wire [6:0] so;
input [7:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [7:0] dout;
output scan_out;
assign fdin[7:0] = din[7:0];
dff #(8) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[7:0]),
.si({scan_in,so[6:0]}),
.so({so[6:0],scan_out}),
.q(dout[7:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__clr__1__en_1__width_8 (
din,
en,
clr_,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [7:0] fdin;
wire [6:0] so;
input [7:0] din;
input en;
input clr_;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [7:0] dout;
output scan_out;
assign fdin[7:0] = (din[7:0] & {8{en}} & ~{8{(~clr_)}}) | (dout[7:0] & ~{8{en}} & ~{8{(~clr_)}});
dff #(8) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[7:0]),
.si({scan_in,so[6:0]}),
.so({so[6:0],scan_out}),
.q(dout[7:0])
);
endmodule
// any PARAMS parms go into naming of macro
module tcu_dbg_ctl_msff_ctl_macro__width_1 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [0:0] fdin;
input [0:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [0:0] dout;
output scan_out;
assign fdin[0:0] = din[0:0];
dff #(1) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[0:0]),
.si(scan_in),
.so(scan_out),
.q(dout[0:0])
);
endmodule