You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

453 lines
20 KiB
VHDL

-- © IBM Corp. 2020
-- Licensed under the Apache License, Version 2.0 (the "License"), as modified by
-- the terms below; you may not use the files in this repository except in
-- compliance with the License as modified.
-- You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
--
-- Modified Terms:
--
-- 1) For the purpose of the patent license granted to you in Section 3 of the
-- License, the "Work" hereby includes implementations of the work of authorship
-- in physical form.
--
-- 2) Notwithstanding any terms to the contrary in the License, any licenses
-- necessary for implementation of the Work that are available from OpenPOWER
-- via the Power ISA End User License Agreement (EULA) are explicitly excluded
-- hereunder, and may be obtained from OpenPOWER under the terms and conditions
-- of the EULA.
--
-- Unless required by applicable law or agreed to in writing, the reference design
-- 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.
--
-- Additional rights, including the ability to physically implement a softcore that
-- is compliant with the required sections of the Power ISA Specification, are
-- available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be
-- obtained (along with the Power ISA) here: https://openpowerfoundation.org.
--
-- Description: Pervasive Core Thread Controls
--
--*****************************************************************************
library ieee;
use ieee.std_logic_1164.all;
library ibm;
use ibm.std_ulogic_support.all;
use ibm.std_ulogic_function_support.all;
use ibm.std_ulogic_unsigned.all;
library support;
use support.power_logic_pkg.all;
library tri;
use tri.tri_latches_pkg.all;
entity pcq_ctrl is
generic(expand_type : integer := 2 -- 0 = ibm (Umbra), 1 = non-ibm, 2 = ibm (MPG)
);
port(
vdd : inout power_logic;
gnd : inout power_logic;
nclk : in clk_logic;
scan_dis_dc_b : in std_ulogic;
lcb_clkoff_dc_b : in std_ulogic;
lcb_mpw1_dc_b : in std_ulogic;
lcb_mpw2_dc_b : in std_ulogic;
lcb_delay_lclkr_dc : in std_ulogic;
lcb_act_dis_dc : in std_ulogic;
pc_pc_func_slp_sl_thold_0 : in std_ulogic;
pc_pc_sg_0 : in std_ulogic;
func_scan_in : in std_ulogic;
func_scan_out : out std_ulogic;
-- Reset Related
an_ac_reset_1_complete : in std_ulogic;
an_ac_reset_2_complete : in std_ulogic;
an_ac_reset_3_complete : in std_ulogic;
an_ac_reset_wd_complete : in std_ulogic;
pc_xu_reset_1_cmplt : out std_ulogic;
pc_xu_reset_2_cmplt : out std_ulogic;
pc_xu_reset_3_cmplt : out std_ulogic;
pc_xu_reset_wd_cmplt : out std_ulogic;
pc_xu_init_reset : out std_ulogic;
pc_iu_init_reset : out std_ulogic;
ct_rg_hold_during_init : out std_ulogic;
-- Power Management
ct_rg_power_managed : out std_ulogic_vector(0 to 3);
ct_rg_pm_thread_stop : out std_ulogic_vector(0 to 3);
an_ac_pm_thread_stop : in std_ulogic_vector(0 to 3);
ac_an_power_managed : out std_ulogic;
ac_an_rvwinkle_mode : out std_ulogic;
ct_ck_pm_ccflush_disable : out std_ulogic;
ct_ck_pm_raise_tholds : out std_ulogic;
rg_ct_dis_pwr_savings : in std_ulogic;
xu_pc_spr_ccr0_pme : in std_ulogic_vector(0 to 1);
xu_pc_spr_ccr0_we : in std_ulogic_vector(0 to 3);
-- Trace/Trigger Signals
dbg_ctrls : out std_ulogic_vector(0 to 36)
);
-- synopsys translate_off
-- synopsys translate_on
end pcq_ctrl;
architecture pcq_ctrl of pcq_ctrl is
--=====================================================================
-- Signal Declarations
--=====================================================================
constant initactive_size : positive := 1;
constant resetsm_size : positive := 5;
constant initerat_size : positive := 1;
constant pmstate_size : positive := 14;
constant sprccr0_size : positive := 6;
constant pmstop_size : positive := 4;
constant resetstat_size : positive := 4;
constant sparectrl_size : positive := 6;
-----------------------------------------------------------------------
-- Scan Ring Ordering:
-- start of func scan chain ordering
constant initactive_offset : natural := 0;
constant resetsm_offset : natural := initactive_offset + initactive_size;
constant initerat_offset : natural := resetsm_offset + resetsm_size;
constant pmstate_offset : natural := initerat_offset + initerat_size;
constant sprccr0_offset : natural := pmstate_offset + pmstate_size;
constant pmstop_offset : natural := sprccr0_offset + sprccr0_size;
constant resetstat_offset : natural := pmstop_offset + pmstop_size;
constant sparectrl_offset : natural := resetstat_offset + resetstat_size;
constant func_right : natural := sparectrl_offset + sparectrl_size - 1;
-- end of func scan chain ordering
-----------------------------------------------------------------------
-- Reset State Machine:
constant ResSM_Idle : std_ulogic_vector(0 to 4) := "00000";
constant ResSM_Start : std_ulogic_vector(0 to 4) := "00001";
constant ResSM_InitErat : std_ulogic_vector(0 to 4) := "00111";
constant ResSM_Return : std_ulogic_vector(0 to 4) := "10111";
-----------------------------------------------------------------------
-- Basic/Misc signals
signal tiup : std_ulogic;
signal func_siv, func_sov : std_ulogic_vector(0 to func_right);
signal pc_pc_func_slp_sl_thold_0_b : std_ulogic;
signal force_funcslp : std_ulogic;
-- Reset Signals
signal resetsm_active : std_ulogic;
signal resetsm_act_ctrl : std_ulogic;
-- Power management Signals
signal spr_ccr0_pme_q : std_ulogic_vector(0 to 1);
signal spr_ccr0_we_q : std_ulogic_vector(0 to 3);
signal pm_sleep_enable : std_ulogic;
signal pm_rvw_enable : std_ulogic;
signal thread_stopped : std_ulogic_vector(0 to 3);
-- Latch definitions begin
signal resetsm_d, resetsm_q : std_ulogic_vector(0 to resetsm_size-1);
signal init_active_d, init_active_q : std_ulogic;
signal initerat_d, initerat_q : std_ulogic;
signal pmstate_d, pmstate_q : std_ulogic_vector(0 to 3);
signal pmstate_all_d, pmstate_all_q : std_ulogic;
signal pmclkctrl_dly_d, pmclkctrl_dly_q : std_ulogic_vector(0 to 7);
signal rvwinkled_d, rvwinkled_q : std_ulogic;
signal pmstop_q : std_ulogic_vector(0 to pmstop_size-1);
signal reset_complete_q : std_ulogic_vector(0 to resetstat_size-1);
signal pm_ccflush_disable_int : std_ulogic;
signal pm_raise_tholds_int : std_ulogic;
signal spare_ctrl_wrapped_q : std_ulogic_vector(0 to sparectrl_size-1);
begin
tiup <= '1';
--=====================================================================
-- Reset State Machine
--=====================================================================
-- Counter used to generate reset control pulses.
-- Starts when clocks start because init_active_q inits to 1.
-- Keeps counting until init_active_q is reset, then returns to Idle state.
resetsm_d <= (others=>'0') when (resetsm_q=ResSM_Idle and init_active_q='0') else
ResSM_Start when (resetsm_q=ResSM_Idle and init_active_q='1') else
ResSM_Idle when init_active_q='0' else
resetsm_q + "00001";
resetsm_active <= or_reduce(resetsm_q);
resetsm_act_ctrl <= init_active_q or resetsm_active;
-- The initerat latch controls the init_reset signals to IU and XU.
-- Goes active when ResSM=8. Goes inactive 16 clock cycles later when ResSM returns to Idle.
initerat_d <= '0' when resetsm_q=ResSM_Idle else
'0' when resetsm_q=ResSM_Return else
'1' when resetsm_q=ResSM_InitErat else
initerat_q;
-- init_active_q initializes to '1'; cleared when Reset_SM count completes (ResSM >= 24).
init_active_d <= '0' when resetsm_q(0 to 1)="11" else init_active_q;
--=====================================================================
-- Power Management Latches
--=====================================================================
-- XU signals indicate when power-savings is enabled (sleep or rvw modes), and which
-- threads are stopped.
-- The pmstate latch tracks which threads are stopped when either power-savings mode
-- is enabled. The rvwinkled latch only when pm_rvw_enable is set.
-- If all threads are stopped when power-savings is enabled, then signals to the
-- clock control macro will initiate power savings actions. These controls force
-- ccflush_dc inactive to ensure all PLATs are clocking. After a delay period, the
-- run tholds will be raised to stop clocks.
-- When coming out of power-savings, the tholds will be disabled prior to deactivating
-- ccflush_dc.
pm_sleep_enable <= not spr_ccr0_pme_q(0) and spr_ccr0_pme_q(1);
pm_rvw_enable <= spr_ccr0_pme_q(0) and not spr_ccr0_pme_q(1);
thread_stopped <= spr_ccr0_we_q;
pmstate_d <= gate_and((pm_sleep_enable or pm_rvw_enable) and not resetsm_active,
thread_stopped(0 to 3));
pmstate_all_d <= and_reduce(pmstate_q);
pmclkctrl_dly_d(0 to 7) <= pmstate_all_q & pmclkctrl_dly_q(0 to 6);
rvwinkled_d <= pmclkctrl_dly_q(6) and pm_rvw_enable;
--=====================================================================
-- Outputs
--=====================================================================
-- Used as part of thread stop signal to XU.
-- Keeps threads stopped until after the Reset SM completes count.
ct_rg_hold_during_init <= init_active_q;
-- Init pulse to IU and XU to force initialization of I/D-ERATs.
-- IU also holds instruction fetch until init signal released.
pc_iu_init_reset <= initerat_q;
pc_xu_init_reset <= initerat_q;
-- Software initiated reset status to XU for DBSR[MRR] and TSR[WRS]
pc_xu_reset_1_cmplt <= reset_complete_q(0);
pc_xu_reset_2_cmplt <= reset_complete_q(1);
pc_xu_reset_3_cmplt <= reset_complete_q(2);
pc_xu_reset_wd_cmplt <= reset_complete_q(3);
-- To THRCTL[Tx_PM]; indicates core power-managed due to external input.
ct_rg_pm_thread_stop <= pmstop_q;
-- To THRCTL[Tx_PM]; indicates core power-managed via software actions.
ct_rg_power_managed <= pmstate_q;
-- Core in rvwinkle power-savings state. L2 can prepare for Chiplet power-down.
ac_an_rvwinkle_mode <= rvwinkled_q;
-- Core in power-savings state due to any combination of power-savings instructions
ac_an_power_managed <= pmclkctrl_dly_q(7);
-- Goes to clock controls to disable plat flush controls
pm_ccflush_disable_int <= pmstate_all_q or pmclkctrl_dly_q(7);
ct_ck_pm_ccflush_disable <= pm_ccflush_disable_int and not rg_ct_dis_pwr_savings;
-- Goes to clock controls to activate run tholds
pm_raise_tholds_int <= pmstate_all_q and pmclkctrl_dly_q(7);
ct_ck_pm_raise_tholds <= pm_raise_tholds_int and not rg_ct_dis_pwr_savings;
--=====================================================================
-- Trace/Trigger Signals
--=====================================================================
dbg_ctrls <= init_active_q & -- 0
resetsm_q(0 to 4) & -- 1:5
initerat_q & -- 6
reset_complete_q(0 to 3) & -- 7:10
pmstop_q(0 to 3) & -- 11:14
pmstate_q(0 to 3) & -- 15:18
rvwinkled_q & -- 19
spr_ccr0_pme_q(0 to 1) & -- 20:21
spr_ccr0_we_q(0 to 3) & -- 22:25
pmclkctrl_dly_q(0 to 7) & -- 26:33
rg_ct_dis_pwr_savings & -- 34
pm_ccflush_disable_int & -- 35
pm_raise_tholds_int ; -- 36
--=====================================================================
-- Latches
--=====================================================================
-- func ring registers start
initactive: tri_rlmlatch_p
generic map (init => 1, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => tiup,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(initactive_offset),
scout => func_sov(initactive_offset),
din => init_active_d,
dout => init_active_q);
resetsm: tri_rlmreg_p
generic map (width => resetsm_size, init => 0, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => resetsm_act_ctrl,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(resetsm_offset to resetsm_offset + resetsm_size-1),
scout => func_sov(resetsm_offset to resetsm_offset + resetsm_size-1),
din => resetsm_d,
dout => resetsm_q );
initerat: tri_rlmlatch_p
generic map (init => 0, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => resetsm_active,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(initerat_offset),
scout => func_sov(initerat_offset),
din => initerat_d,
dout => initerat_q );
pmstate: tri_rlmreg_p
generic map (width => pmstate_size, init => 0, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => tiup,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(pmstate_offset to pmstate_offset + pmstate_size-1),
scout => func_sov(pmstate_offset to pmstate_offset + pmstate_size-1),
din(0 to 3) => pmstate_d,
din(4) => pmstate_all_d,
din(5) => rvwinkled_d,
din(6 to 13) => pmclkctrl_dly_d,
dout(0 to 3) => pmstate_q,
dout(4) => pmstate_all_q,
dout(5) => rvwinkled_q,
dout(6 to 13) => pmclkctrl_dly_q );
sprccr0: tri_rlmreg_p
generic map (width => sprccr0_size, init => 0, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => tiup,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(sprccr0_offset to sprccr0_offset + sprccr0_size-1),
scout => func_sov(sprccr0_offset to sprccr0_offset + sprccr0_size-1),
din(0 to 1) => xu_pc_spr_ccr0_pme,
din(2 to 5) => xu_pc_spr_ccr0_we,
dout(0 to 1) => spr_ccr0_pme_q,
dout(2 to 5) => spr_ccr0_we_q );
pmstop: tri_rlmreg_p
generic map (width => pmstop_size, init => 0, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => tiup,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(pmstop_offset to pmstop_offset + pmstop_size-1),
scout => func_sov(pmstop_offset to pmstop_offset + pmstop_size-1),
din => an_ac_pm_thread_stop,
dout => pmstop_q );
resetstat: tri_rlmreg_p
generic map (width => resetstat_size, init => 0, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => tiup,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(resetstat_offset to resetstat_offset + resetstat_size-1),
scout => func_sov(resetstat_offset to resetstat_offset + resetstat_size-1),
din(0) => an_ac_reset_1_complete,
din(1) => an_ac_reset_2_complete,
din(2) => an_ac_reset_3_complete,
din(3) => an_ac_reset_wd_complete,
dout => reset_complete_q );
sparectrl: tri_rlmreg_p
generic map (width => sparectrl_size, init => 0, expand_type => expand_type)
port map (vd => vdd,
gd => gnd,
nclk => nclk,
act => tiup,
thold_b => pc_pc_func_slp_sl_thold_0_b,
sg => pc_pc_sg_0,
forcee => force_funcslp,
delay_lclkr => lcb_delay_lclkr_dc,
mpw1_b => lcb_mpw1_dc_b,
mpw2_b => lcb_mpw2_dc_b,
scin => func_siv(sparectrl_offset to sparectrl_offset + sparectrl_size-1),
scout => func_sov(sparectrl_offset to sparectrl_offset + sparectrl_size-1),
din => spare_ctrl_wrapped_q,
dout => spare_ctrl_wrapped_q );
-- func ring registers end
--=====================================================================
-- Thold/SG Staging
--=====================================================================
-- func_slp lcbor
lcbor_funcslp: tri_lcbor
generic map (expand_type => expand_type )
port map (
clkoff_b => lcb_clkoff_dc_b,
thold => pc_pc_func_slp_sl_thold_0,
sg => pc_pc_sg_0,
act_dis => lcb_act_dis_dc,
forcee => force_funcslp,
thold_b => pc_pc_func_slp_sl_thold_0_b );
--=====================================================================
-- Scan Connections
--=====================================================================
-- Func ring
func_siv(0 TO func_right) <= func_scan_in & func_sov(0 to func_right-1);
func_scan_out <= func_sov(func_right) and scan_dis_dc_b;
-----------------------------------------------------------------------
end pcq_ctrl;