641 lines
24 KiB
Verilog
641 lines
24 KiB
Verilog
// © 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 SPRs and slowSPR Interface
|
|
//
|
|
//*****************************************************************************
|
|
|
|
`timescale 1 ns / 1 ns
|
|
|
|
`include "tri_a2o.vh"
|
|
|
|
module pcq_spr(
|
|
// Include model build parameters
|
|
`include "tri_a2o.vh"
|
|
|
|
inout vdd,
|
|
inout gnd,
|
|
input clk,
|
|
input rst,
|
|
// pervasive signals
|
|
input scan_dis_dc_b,
|
|
input lcb_clkoff_dc_b,
|
|
input lcb_mpw1_dc_b,
|
|
input lcb_mpw2_dc_b,
|
|
input lcb_delay_lclkr_dc,
|
|
input lcb_act_dis_dc,
|
|
input pc_pc_func_sl_thold_0,
|
|
input pc_pc_sg_0,
|
|
input func_scan_in,
|
|
output func_scan_out,
|
|
// slowSPR Interface
|
|
input slowspr_val_in,
|
|
input slowspr_rw_in,
|
|
input [0:1] slowspr_etid_in,
|
|
input [0:9] slowspr_addr_in,
|
|
input [64-`GPR_WIDTH:63] slowspr_data_in,
|
|
input slowspr_done_in,
|
|
input [0:`THREADS-1] cp_flush,
|
|
output slowspr_val_out,
|
|
output slowspr_rw_out,
|
|
output [0:1] slowspr_etid_out,
|
|
output [0:9] slowspr_addr_out,
|
|
output [64-`GPR_WIDTH:63] slowspr_data_out,
|
|
output slowspr_done_out,
|
|
// Event Mux Controls
|
|
output [0:39] pc_rv_event_mux_ctrls,
|
|
// CESR1 Controls
|
|
output pc_iu_event_bus_enable,
|
|
output pc_fu_event_bus_enable,
|
|
output pc_rv_event_bus_enable,
|
|
output pc_mm_event_bus_enable,
|
|
output pc_xu_event_bus_enable,
|
|
output pc_lq_event_bus_enable,
|
|
output [0:2] pc_iu_event_count_mode,
|
|
output [0:2] pc_fu_event_count_mode,
|
|
output [0:2] pc_rv_event_count_mode,
|
|
output [0:2] pc_mm_event_count_mode,
|
|
output [0:2] pc_xu_event_count_mode,
|
|
output [0:2] pc_lq_event_count_mode,
|
|
output sp_rg_trace_bus_enable,
|
|
output pc_iu_instr_trace_mode,
|
|
output pc_iu_instr_trace_tid,
|
|
output pc_lq_instr_trace_mode,
|
|
output pc_lq_instr_trace_tid,
|
|
output pc_xu_instr_trace_mode,
|
|
output pc_xu_instr_trace_tid,
|
|
output pc_lq_event_bus_seldbghi,
|
|
output pc_lq_event_bus_seldbglo,
|
|
input [0:`THREADS-1] xu_pc_perfmon_alert,
|
|
output [0:`THREADS-1] pc_xu_spr_cesr1_pmae,
|
|
// SRAMD data and load pulse
|
|
input rg_rg_load_sramd,
|
|
input [0:63] rg_rg_sramd_din,
|
|
// Trace/Trigger Signals
|
|
output [0:7] dbg_spr
|
|
);
|
|
|
|
|
|
//=====================================================================
|
|
// Signal Declarations
|
|
//=====================================================================
|
|
// Scan Ring Constants:
|
|
// Register sizes
|
|
parameter CESR1_SIZE = 12;
|
|
parameter CESR1_IS0_SIZE = 2;
|
|
parameter CESR1_IS1_SIZE = 2;
|
|
parameter RESR1_SIZE = 20;
|
|
parameter RESR2_SIZE = 20;
|
|
parameter SRAMD_SIZE = 64;
|
|
parameter MISC_SIZE = 2;
|
|
|
|
// start of func scan chain ordering
|
|
parameter CP_FLUSH_OFFSET = 0;
|
|
parameter SLOWSPR_VAL_OFFSET = CP_FLUSH_OFFSET + `THREADS;
|
|
parameter SLOWSPR_RW_OFFSET = SLOWSPR_VAL_OFFSET + 1;
|
|
parameter SLOWSPR_ETID_OFFSET = SLOWSPR_RW_OFFSET + 1;
|
|
parameter SLOWSPR_ADDR_OFFSET = SLOWSPR_ETID_OFFSET + 2;
|
|
parameter SLOWSPR_DATA_OFFSET = SLOWSPR_ADDR_OFFSET + 10;
|
|
parameter SLOWSPR_DONE_OFFSET = SLOWSPR_DATA_OFFSET + `GPR_WIDTH;
|
|
parameter CESR1_OFFSET = SLOWSPR_DONE_OFFSET + 1;
|
|
parameter CESR1_IS0_OFFSET = CESR1_OFFSET + CESR1_SIZE;
|
|
parameter CESR1_IS1_OFFSET = CESR1_IS0_OFFSET + CESR1_IS0_SIZE;
|
|
parameter RESR1_OFFSET = CESR1_IS1_OFFSET + CESR1_IS1_SIZE;
|
|
parameter RESR2_OFFSET = RESR1_OFFSET + RESR1_SIZE;
|
|
parameter SRAMD_OFFSET = RESR2_OFFSET + RESR2_SIZE;
|
|
parameter MISC_OFFSET = SRAMD_OFFSET + SRAMD_SIZE;
|
|
parameter FUNC_RIGHT = MISC_OFFSET + MISC_SIZE - 1;
|
|
// end of func scan chain ordering
|
|
|
|
parameter [32:63] CESR1_MASK = 32'b11111011110011110000000000000000;
|
|
parameter [32:63] EVENTMUX_32_MASK = 32'b11111111111111111111111111111111;
|
|
parameter [32:63] EVENTMUX_64_MASK = 32'b11111111111111111111000000000000;
|
|
parameter [32:63] EVENTMUX_128_MASK = 32'b11111111111111111111111100000000;
|
|
|
|
//--------------------------
|
|
// signals
|
|
//--------------------------
|
|
wire [0:`THREADS-1] cp_flush_l2;
|
|
wire slowspr_val_d;
|
|
wire slowspr_val_l2;
|
|
wire slowspr_rw_d;
|
|
wire slowspr_rw_l2;
|
|
wire [0:1] slowspr_etid_d;
|
|
wire [0:1] slowspr_etid_l2;
|
|
wire [0:9] slowspr_addr_d;
|
|
wire [0:9] slowspr_addr_l2;
|
|
wire [64-`GPR_WIDTH:63] slowspr_data_d;
|
|
wire [64-`GPR_WIDTH:63] slowspr_data_l2;
|
|
wire slowspr_done_d;
|
|
wire slowspr_done_l2;
|
|
|
|
wire pc_done_int;
|
|
wire [64-`GPR_WIDTH:63] pc_data_int;
|
|
wire [32:63] pc_reg_data;
|
|
|
|
wire cesr1_sel;
|
|
wire cesr1_wren;
|
|
wire cesr1_rden;
|
|
wire [32:32+CESR1_SIZE-1] cesr1_d;
|
|
wire [32:32+CESR1_SIZE-1] cesr1_l2;
|
|
wire [32:63] cesr1_out;
|
|
// Instruction Sampling PMAE/PMAO latches
|
|
wire [0:1] cesr1_is_wren;
|
|
wire [0:1] cesr1_is0_d;
|
|
wire [0:1] cesr1_is0_l2;
|
|
wire [0:1] cesr1_is1_d;
|
|
wire [0:1] cesr1_is1_l2;
|
|
wire [0:1] perfmon_alert_din;
|
|
wire [0:1] perfmon_alert_q;
|
|
wire [0:1] update_is_ctrls;
|
|
|
|
wire resr1_sel;
|
|
wire resr1_wren;
|
|
wire resr1_rden;
|
|
wire [32:32+RESR1_SIZE-1] resr1_d;
|
|
wire [32:32+RESR1_SIZE-1] resr1_l2;
|
|
wire [32:63] resr1_out;
|
|
|
|
wire resr2_sel;
|
|
wire resr2_wren;
|
|
wire resr2_rden;
|
|
wire [32:32+RESR2_SIZE-1] resr2_d;
|
|
wire [32:32+RESR2_SIZE-1] resr2_l2;
|
|
wire [32:63] resr2_out;
|
|
|
|
wire sramd_sel;
|
|
wire sramd_wren;
|
|
wire sramd_rden;
|
|
wire [0:SRAMD_SIZE-1] sramd_d;
|
|
wire [0:SRAMD_SIZE-1] sramd_l2;
|
|
wire [0:63] sramd_out;
|
|
|
|
wire [0:3] slowspr_tid;
|
|
|
|
// misc, pervasive signals
|
|
wire tiup;
|
|
wire pc_pc_func_sl_thold_0_b;
|
|
wire force_func;
|
|
wire [0:FUNC_RIGHT] func_siv;
|
|
wire [0:FUNC_RIGHT] func_sov;
|
|
|
|
|
|
(* analysis_not_referenced="true" *)
|
|
wire unused_signals;
|
|
assign unused_signals = (|slowspr_tid[2:3]);
|
|
|
|
|
|
//!! Bugspray Include: pcq_spr;
|
|
|
|
|
|
assign tiup = 1'b1;
|
|
|
|
//=====================================================================
|
|
// Latches
|
|
//=====================================================================
|
|
tri_rlmreg_p #(.WIDTH(`THREADS), .INIT(0), .NEEDS_SRESET(1)) cp_flush_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(tiup),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[CP_FLUSH_OFFSET:CP_FLUSH_OFFSET + `THREADS - 1]),
|
|
.scout(func_sov[CP_FLUSH_OFFSET:CP_FLUSH_OFFSET + `THREADS - 1]),
|
|
.din(cp_flush),
|
|
.dout(cp_flush_l2)
|
|
);
|
|
|
|
tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(1)) slowspr_val_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(tiup),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[SLOWSPR_VAL_OFFSET]),
|
|
.scout(func_sov[SLOWSPR_VAL_OFFSET]),
|
|
.din(slowspr_val_d),
|
|
.dout(slowspr_val_l2)
|
|
);
|
|
|
|
tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(1)) slowspr_rw_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(slowspr_val_d),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[SLOWSPR_RW_OFFSET]),
|
|
.scout(func_sov[SLOWSPR_RW_OFFSET]),
|
|
.din(slowspr_rw_d),
|
|
.dout(slowspr_rw_l2)
|
|
);
|
|
|
|
tri_rlmreg_p #(.WIDTH(2), .INIT(0), .NEEDS_SRESET(1)) slowspr_etid_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(slowspr_val_d),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[SLOWSPR_ETID_OFFSET:SLOWSPR_ETID_OFFSET + 2 - 1]),
|
|
.scout(func_sov[SLOWSPR_ETID_OFFSET:SLOWSPR_ETID_OFFSET + 2 - 1]),
|
|
.din(slowspr_etid_d),
|
|
.dout(slowspr_etid_l2)
|
|
);
|
|
|
|
tri_rlmreg_p #(.WIDTH(10), .INIT(0), .NEEDS_SRESET(1)) slowspr_addr_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(slowspr_val_d),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[SLOWSPR_ADDR_OFFSET:SLOWSPR_ADDR_OFFSET + 10 - 1]),
|
|
.scout(func_sov[SLOWSPR_ADDR_OFFSET:SLOWSPR_ADDR_OFFSET + 10 - 1]),
|
|
.din(slowspr_addr_d),
|
|
.dout(slowspr_addr_l2)
|
|
);
|
|
|
|
tri_rlmreg_p #(.WIDTH(`GPR_WIDTH), .INIT(0), .NEEDS_SRESET(1)) slowspr_data_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(slowspr_val_d),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[SLOWSPR_DATA_OFFSET:SLOWSPR_DATA_OFFSET + `GPR_WIDTH - 1]),
|
|
.scout(func_sov[SLOWSPR_DATA_OFFSET:SLOWSPR_DATA_OFFSET + `GPR_WIDTH - 1]),
|
|
.din(slowspr_data_d),
|
|
.dout(slowspr_data_l2)
|
|
);
|
|
|
|
tri_rlmlatch_p #(.INIT(0), .NEEDS_SRESET(1)) slowspr_done_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(tiup),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[SLOWSPR_DONE_OFFSET]),
|
|
.scout(func_sov[SLOWSPR_DONE_OFFSET]),
|
|
.din(slowspr_done_d),
|
|
.dout(slowspr_done_l2)
|
|
);
|
|
|
|
tri_ser_rlmreg_p #(.WIDTH(CESR1_SIZE), .INIT(0)) cesr1_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(cesr1_wren),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[CESR1_OFFSET:CESR1_OFFSET + CESR1_SIZE - 1]),
|
|
.scout(func_sov[CESR1_OFFSET:CESR1_OFFSET + CESR1_SIZE - 1]),
|
|
.din(cesr1_d),
|
|
.dout(cesr1_l2)
|
|
);
|
|
|
|
tri_ser_rlmreg_p #(.WIDTH(CESR1_IS0_SIZE), .INIT(0)) cesr1_is0_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(cesr1_is_wren[0]),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[CESR1_IS0_OFFSET:CESR1_IS0_OFFSET + CESR1_IS0_SIZE - 1]),
|
|
.scout(func_sov[CESR1_IS0_OFFSET:CESR1_IS0_OFFSET + CESR1_IS0_SIZE - 1]),
|
|
.din(cesr1_is0_d),
|
|
.dout(cesr1_is0_l2)
|
|
);
|
|
|
|
tri_ser_rlmreg_p #(.WIDTH(CESR1_IS1_SIZE), .INIT(0)) cesr1_is1_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(cesr1_is_wren[1]),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[CESR1_IS1_OFFSET:CESR1_IS1_OFFSET + CESR1_IS1_SIZE - 1]),
|
|
.scout(func_sov[CESR1_IS1_OFFSET:CESR1_IS1_OFFSET + CESR1_IS1_SIZE - 1]),
|
|
.din(cesr1_is1_d),
|
|
.dout(cesr1_is1_l2)
|
|
);
|
|
|
|
tri_ser_rlmreg_p #(.WIDTH(RESR1_SIZE), .INIT(0)) resr1_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(resr1_wren),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[RESR1_OFFSET:RESR1_OFFSET + RESR1_SIZE - 1]),
|
|
.scout(func_sov[RESR1_OFFSET:RESR1_OFFSET + RESR1_SIZE - 1]),
|
|
.din(resr1_d),
|
|
.dout(resr1_l2)
|
|
);
|
|
|
|
tri_ser_rlmreg_p #(.WIDTH(RESR2_SIZE), .INIT(0)) resr2_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(resr2_wren),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[RESR2_OFFSET:RESR2_OFFSET + RESR2_SIZE - 1]),
|
|
.scout(func_sov[RESR2_OFFSET:RESR2_OFFSET + RESR2_SIZE - 1]),
|
|
.din(resr2_d),
|
|
.dout(resr2_l2)
|
|
);
|
|
|
|
tri_ser_rlmreg_p #(.WIDTH(SRAMD_SIZE), .INIT(0)) sramd_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(sramd_wren),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[SRAMD_OFFSET:SRAMD_OFFSET + SRAMD_SIZE - 1]),
|
|
.scout(func_sov[SRAMD_OFFSET:SRAMD_OFFSET + SRAMD_SIZE - 1]),
|
|
.din(sramd_d),
|
|
.dout(sramd_l2)
|
|
);
|
|
|
|
tri_rlmreg_p #(.WIDTH(MISC_SIZE), .INIT(0)) misc_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(tiup),
|
|
.thold_b(pc_pc_func_sl_thold_0_b),
|
|
.sg(pc_pc_sg_0),
|
|
.force_t(force_func),
|
|
.delay_lclkr(lcb_delay_lclkr_dc),
|
|
.mpw1_b(lcb_mpw1_dc_b),
|
|
.mpw2_b(lcb_mpw2_dc_b),
|
|
.scin(func_siv[MISC_OFFSET:MISC_OFFSET + MISC_SIZE - 1]),
|
|
.scout(func_sov[MISC_OFFSET:MISC_OFFSET + MISC_SIZE - 1]),
|
|
.din(perfmon_alert_din),
|
|
.dout(perfmon_alert_q)
|
|
);
|
|
|
|
//=====================================================================
|
|
// inputs + staging
|
|
//=====================================================================
|
|
assign slowspr_val_d = slowspr_val_in & !(|(slowspr_tid[0:`THREADS-1] & cp_flush_l2));
|
|
assign slowspr_rw_d = slowspr_rw_in;
|
|
assign slowspr_etid_d = slowspr_etid_in;
|
|
assign slowspr_addr_d = slowspr_addr_in;
|
|
assign slowspr_data_d = slowspr_data_in;
|
|
assign slowspr_done_d = slowspr_done_in;
|
|
|
|
//=====================================================================
|
|
// Outputs
|
|
//=====================================================================
|
|
assign slowspr_tid = (slowspr_etid_in == 2'b00) ? 4'b1000 :
|
|
(slowspr_etid_in == 2'b01) ? 4'b0100 :
|
|
(slowspr_etid_in == 2'b10) ? 4'b0010 :
|
|
(slowspr_etid_in == 2'b11) ? 4'b0001 :
|
|
4'b0000;
|
|
assign slowspr_val_out = slowspr_val_l2;
|
|
assign slowspr_rw_out = slowspr_rw_l2;
|
|
assign slowspr_etid_out = slowspr_etid_l2;
|
|
assign slowspr_addr_out = slowspr_addr_l2;
|
|
assign slowspr_data_out = slowspr_data_l2 | pc_data_int;
|
|
assign slowspr_done_out = slowspr_done_l2 | pc_done_int;
|
|
|
|
assign pc_rv_event_mux_ctrls = {resr1_out[32:51], resr2_out[32:51]};
|
|
|
|
// CESR1 controls miscellaneous performance related functions:
|
|
// Event bus enable to all units.
|
|
assign pc_iu_event_bus_enable = cesr1_out[32];
|
|
assign pc_fu_event_bus_enable = cesr1_out[32];
|
|
assign pc_rv_event_bus_enable = cesr1_out[32];
|
|
assign pc_mm_event_bus_enable = cesr1_out[32];
|
|
assign pc_xu_event_bus_enable = cesr1_out[32];
|
|
assign pc_lq_event_bus_enable = cesr1_out[32];
|
|
// Count modes function to all units.
|
|
assign pc_iu_event_count_mode = cesr1_out[33:35];
|
|
assign pc_fu_event_count_mode = cesr1_out[33:35];
|
|
assign pc_rv_event_count_mode = cesr1_out[33:35];
|
|
assign pc_mm_event_count_mode = cesr1_out[33:35];
|
|
assign pc_xu_event_count_mode = cesr1_out[33:35];
|
|
assign pc_lq_event_count_mode = cesr1_out[33:35];
|
|
// Trace bus enable to all units (from pcq_regs).
|
|
assign sp_rg_trace_bus_enable = cesr1_out[36];
|
|
// Select trace bits for event counting.
|
|
assign pc_lq_event_bus_seldbghi = cesr1_out[38];
|
|
assign pc_lq_event_bus_seldbglo = cesr1_out[39];
|
|
// Instruction tracing.
|
|
assign pc_iu_instr_trace_mode = cesr1_out[40];
|
|
assign pc_iu_instr_trace_tid = cesr1_out[41];
|
|
assign pc_lq_instr_trace_mode = cesr1_out[40];
|
|
assign pc_lq_instr_trace_tid = cesr1_out[41];
|
|
assign pc_xu_instr_trace_mode = cesr1_out[40];
|
|
assign pc_xu_instr_trace_tid = cesr1_out[41];
|
|
|
|
//=====================================================================
|
|
// Instruction sampling
|
|
//=====================================================================
|
|
generate
|
|
if (`THREADS == 1)
|
|
begin : T1_INSTRSAMP
|
|
assign pc_xu_spr_cesr1_pmae = cesr1_is0_l2[0];
|
|
assign perfmon_alert_din = {xu_pc_perfmon_alert[0], 1'b0};
|
|
end
|
|
endgenerate
|
|
|
|
generate
|
|
if (`THREADS == 2)
|
|
begin : T2_INSTRSAMP
|
|
assign pc_xu_spr_cesr1_pmae = {cesr1_is0_l2[0], cesr1_is1_l2[0]};
|
|
assign perfmon_alert_din = xu_pc_perfmon_alert[0:1];
|
|
end
|
|
endgenerate
|
|
|
|
//=====================================================================
|
|
// register select
|
|
//=====================================================================
|
|
assign cesr1_sel = slowspr_val_l2 & slowspr_addr_l2 == 10'b1110010000; // 912
|
|
assign resr1_sel = slowspr_val_l2 & slowspr_addr_l2 == 10'b1110011010; // 922
|
|
assign resr2_sel = slowspr_val_l2 & slowspr_addr_l2 == 10'b1110011011; // 923
|
|
assign sramd_sel = slowspr_val_l2 & slowspr_addr_l2 == 10'b1101111110; // 894
|
|
|
|
assign pc_done_int = cesr1_sel | resr1_sel | resr2_sel | sramd_sel;
|
|
|
|
//=====================================================================
|
|
// register write
|
|
//=====================================================================
|
|
assign cesr1_wren = cesr1_sel & slowspr_rw_l2 == 1'b0;
|
|
assign resr1_wren = resr1_sel & slowspr_rw_l2 == 1'b0;
|
|
assign resr2_wren = resr2_sel & slowspr_rw_l2 == 1'b0;
|
|
assign sramd_wren = rg_rg_load_sramd;
|
|
|
|
assign cesr1_d = CESR1_MASK[32:32 + CESR1_SIZE - 1] & slowspr_data_l2[32:32 + CESR1_SIZE - 1];
|
|
assign resr1_d = EVENTMUX_64_MASK[32:32 + RESR1_SIZE - 1] & slowspr_data_l2[32:32 + RESR1_SIZE - 1];
|
|
assign resr2_d = EVENTMUX_64_MASK[32:32 + RESR2_SIZE - 1] & slowspr_data_l2[32:32 + RESR2_SIZE - 1];
|
|
assign sramd_d = rg_rg_sramd_din;
|
|
|
|
// Instruction Sampling
|
|
assign update_is_ctrls = {(perfmon_alert_q[0] & cesr1_is0_l2[0]), (perfmon_alert_q[1] & cesr1_is1_l2[0])};
|
|
assign cesr1_is_wren = {(cesr1_wren | update_is_ctrls[0]), (cesr1_wren | update_is_ctrls[1])};
|
|
|
|
assign cesr1_is0_d[0] = CESR1_MASK[44] & slowspr_data_l2[44] & (~update_is_ctrls[0]); // PMAE_T0 cleared on perfmon alert.
|
|
assign cesr1_is0_d[1] = (CESR1_MASK[45] & slowspr_data_l2[45] & (~update_is_ctrls[0])) | update_is_ctrls[0]; // PMAO_T0 set on perfmon alert.
|
|
assign cesr1_is1_d[0] = CESR1_MASK[46] & slowspr_data_l2[46] & (~update_is_ctrls[1]); // PMAE_T1 cleared on perfmon alert.
|
|
assign cesr1_is1_d[1] = (CESR1_MASK[47] & slowspr_data_l2[47] & (~update_is_ctrls[1])) | update_is_ctrls[1]; // PMAO_T1 set on perfmon alert.
|
|
|
|
//=====================================================================
|
|
// register read
|
|
//=====================================================================
|
|
assign cesr1_rden = cesr1_sel & slowspr_rw_l2 == 1'b1;
|
|
assign resr1_rden = resr1_sel & slowspr_rw_l2 == 1'b1;
|
|
assign resr2_rden = resr2_sel & slowspr_rw_l2 == 1'b1;
|
|
assign sramd_rden = sramd_sel & slowspr_rw_l2 == 1'b1;
|
|
|
|
assign cesr1_out[32:63] = {cesr1_l2, cesr1_is0_l2, cesr1_is1_l2, {64-(32+CESR1_SIZE+CESR1_IS0_SIZE+CESR1_IS1_SIZE){1'b0}} };
|
|
assign resr1_out[32:63] = {resr1_l2, {64-(32+RESR1_SIZE){1'b0}} };
|
|
assign resr2_out[32:63] = {resr2_l2, {64-(32+RESR2_SIZE){1'b0}} };
|
|
assign sramd_out[0:63] = sramd_l2;
|
|
|
|
assign pc_reg_data[32:63] = (cesr1_rden == 1'b1) ? cesr1_out :
|
|
(resr1_rden == 1'b1) ? resr1_out :
|
|
(resr2_rden == 1'b1) ? resr2_out :
|
|
(sramd_rden == 1'b1) ? sramd_out[32:63] :
|
|
{32{1'b0}};
|
|
|
|
generate
|
|
if (`GPR_WIDTH > 32)
|
|
begin : r64
|
|
assign pc_data_int[0:31] = (sramd_rden == 1'b1) ? sramd_out[0:31] :
|
|
{32{1'b0}};
|
|
end
|
|
endgenerate
|
|
assign pc_data_int[32:63] = pc_reg_data[32:63];
|
|
|
|
|
|
//=====================================================================
|
|
// Trace/Trigger Signals
|
|
//=====================================================================
|
|
assign dbg_spr = { cesr1_wren, // 0
|
|
sramd_wren, // 1
|
|
perfmon_alert_q[0:1], // 2:3
|
|
cesr1_is0_l2[0:1], // 4:5
|
|
cesr1_is1_l2[0:1] // 6:7
|
|
};
|
|
|
|
//=====================================================================
|
|
// Thold/SG Staging
|
|
//=====================================================================
|
|
// func_slp lcbor
|
|
tri_lcbor lcbor_funcslp(
|
|
.clkoff_b(lcb_clkoff_dc_b),
|
|
.thold(pc_pc_func_sl_thold_0),
|
|
.sg(pc_pc_sg_0),
|
|
.act_dis(lcb_act_dis_dc),
|
|
.force_t(force_func),
|
|
.thold_b(pc_pc_func_sl_thold_0_b)
|
|
);
|
|
|
|
//=====================================================================
|
|
// Scan Connections
|
|
//=====================================================================
|
|
// Func ring
|
|
assign func_siv[0:FUNC_RIGHT] = {func_scan_in, func_sov[0:FUNC_RIGHT - 1]};
|
|
assign func_scan_out = func_sov[FUNC_RIGHT] & scan_dis_dc_b;
|
|
|
|
|
|
endmodule
|