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.
537 lines
16 KiB
Verilog
537 lines
16 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.
|
|
|
|
`timescale 1 ns / 1 ns
|
|
|
|
// *********************************************************************
|
|
//
|
|
// This is the ENTITY for rv_perv
|
|
//
|
|
// *********************************************************************
|
|
|
|
module rv_perv( // 0 = ibm umbra, 1 = xilinx, 2 = ibm mpg
|
|
`include "tri_a2o.vh"
|
|
|
|
inout vdd,
|
|
inout gnd,
|
|
input clk,
|
|
input rst,
|
|
input rp_rv_ccflush_dc,
|
|
input rp_rv_func_sl_thold_3,
|
|
input rp_rv_gptr_sl_thold_3,
|
|
input rp_rv_sg_3,
|
|
input rp_rv_fce_3,
|
|
input an_ac_scan_diag_dc,
|
|
input an_ac_scan_dis_dc_b,
|
|
|
|
input d_mode,
|
|
|
|
output func_sl_thold_1,
|
|
output fce_1,
|
|
output sg_1,
|
|
|
|
output clkoff_dc_b,
|
|
output act_dis,
|
|
output [0:9] delay_lclkr_dc,
|
|
output [0:9] mpw1_dc_b,
|
|
output mpw2_dc_b,
|
|
input gptr_scan_in,
|
|
output gptr_scan_out,
|
|
input scan_in,
|
|
output scan_out,
|
|
|
|
//------------------------------------------------------------------------------------------------------------
|
|
// Debug and Perf
|
|
//------------------------------------------------------------------------------------------------------------
|
|
input [0:8*`THREADS-1] fx0_rvs_perf_bus,
|
|
input [0:31] fx0_rvs_dbg_bus,
|
|
input [0:8*`THREADS-1] fx1_rvs_perf_bus,
|
|
input [0:31] fx1_rvs_dbg_bus,
|
|
input [0:8*`THREADS-1] lq_rvs_perf_bus,
|
|
input [0:31] lq_rvs_dbg_bus,
|
|
input [0:8*`THREADS-1] axu0_rvs_perf_bus,
|
|
input [0:31] axu0_rvs_dbg_bus,
|
|
|
|
input [0:`THREADS-1] spr_msr_gs,
|
|
input [0:`THREADS-1] spr_msr_pr,
|
|
|
|
input pc_rv_trace_bus_enable,
|
|
input [0:10] pc_rv_debug_mux_ctrls,
|
|
input pc_rv_event_bus_enable,
|
|
input [0:2] pc_rv_event_count_mode,
|
|
input [0:39] pc_rv_event_mux_ctrls,
|
|
input [0:4*`THREADS-1] rv_event_bus_in,
|
|
output [0:4*`THREADS-1] rv_event_bus_out,
|
|
output [0:31] debug_bus_out,
|
|
input [0:31] debug_bus_in,
|
|
input [0:3] coretrace_ctrls_in,
|
|
output [0:3] coretrace_ctrls_out
|
|
);
|
|
|
|
wire func_sl_thold_2;
|
|
wire gptr_sl_thold_2;
|
|
|
|
wire sg_2;
|
|
wire fce_2;
|
|
|
|
wire gptr_sl_thold_1;
|
|
wire func_sl_thold_1_int;
|
|
wire sg_1_int;
|
|
|
|
wire gptr_sl_thold_0;
|
|
wire func_sl_thold_0;
|
|
|
|
wire force_t;
|
|
|
|
wire sg_0;
|
|
wire gptr_sio;
|
|
wire [0:9] prv_delay_lclkr_dc;
|
|
wire [0:9] prv_mpw1_dc_b;
|
|
wire prv_mpw2_dc_b;
|
|
wire prv_act_dis;
|
|
wire prv_clkoff_dc_b;
|
|
|
|
// Debug and Perf
|
|
wire trc_act;
|
|
wire evt_act;
|
|
wire delay_lclkr;
|
|
wire mpw1_b;
|
|
wire mpw2_b;
|
|
|
|
wire [0:31] debug_bus_mux;
|
|
wire [0:3] coretrace_ctrls_mux;
|
|
|
|
wire [0:10] debug_mux_ctrls;
|
|
wire [0:39] event_mux_ctrls;
|
|
wire [0:2] event_count_mode;
|
|
wire [0:`THREADS-1] spr_msr_gs_q;
|
|
wire [0:`THREADS-1] spr_msr_pr_q;
|
|
wire [0:`THREADS-1] event_en;
|
|
|
|
wire [0:32*`THREADS-1] event_bus_in;
|
|
wire [0:4*`THREADS-1] event_bus_d;
|
|
wire [0:4*`THREADS-1] event_bus_q;
|
|
|
|
|
|
|
|
wire [0:31] dbg_group0;
|
|
wire [0:31] dbg_group1;
|
|
wire [0:31] dbg_group2;
|
|
wire [0:31] dbg_group3;
|
|
|
|
// Unused Signals
|
|
(* analysis_not_referenced="TRUE" *)
|
|
wire act0_dis_dc;
|
|
(* analysis_not_referenced="TRUE" *)
|
|
wire d0_mode_dc;
|
|
(* analysis_not_referenced="TRUE" *)
|
|
wire clkoff1_dc_b;
|
|
(* analysis_not_referenced="TRUE" *)
|
|
wire act1_dis_dc;
|
|
(* analysis_not_referenced="TRUE" *)
|
|
wire d1_mode_dc;
|
|
(* analysis_not_referenced="TRUE" *)
|
|
wire nc_mpw2_dc_b;
|
|
(* analysis_not_referenced="TRUE" *)
|
|
wire unused;
|
|
|
|
wire func_sl_thold_0_b = 0; // wtf: dangling test sig
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------
|
|
// Scan Chains
|
|
//------------------------------------------------------------------------------------------------------------
|
|
parameter debug_bus_offset = 0 + 0;
|
|
parameter debug_mux_offset = debug_bus_offset + 32;
|
|
parameter event_bus_offset = debug_mux_offset + 11;
|
|
parameter event_count_offset = event_bus_offset + 4*`THREADS;
|
|
parameter spr_msr_gs_offset = event_count_offset + 3;
|
|
parameter spr_msr_pr_offset = spr_msr_gs_offset + `THREADS;
|
|
parameter event_mux_ctrls_offset = spr_msr_pr_offset + `THREADS;
|
|
parameter coretrace_ctrls_offset = event_mux_ctrls_offset + 40;
|
|
|
|
parameter scan_right = coretrace_ctrls_offset + 4;
|
|
wire [0:scan_right-1] siv;
|
|
wire [0:scan_right-1] sov;
|
|
|
|
assign unused = an_ac_scan_dis_dc_b ;
|
|
|
|
|
|
tri_plat #(.WIDTH(4))
|
|
perv_3to2_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.flush(rp_rv_ccflush_dc),
|
|
.din({rp_rv_func_sl_thold_3, rp_rv_gptr_sl_thold_3, rp_rv_sg_3, rp_rv_fce_3}),
|
|
.q({func_sl_thold_2, gptr_sl_thold_2, sg_2, fce_2})
|
|
);
|
|
|
|
|
|
tri_plat #(.WIDTH(4))
|
|
perv_2to1_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.flush(rp_rv_ccflush_dc),
|
|
.din({func_sl_thold_2, gptr_sl_thold_2, sg_2, fce_2}),
|
|
.q({func_sl_thold_1_int, gptr_sl_thold_1, sg_1_int, fce_1})
|
|
);
|
|
|
|
assign func_sl_thold_1 = func_sl_thold_1_int;
|
|
assign sg_1 = sg_1_int;
|
|
|
|
|
|
tri_plat #(.WIDTH(3))
|
|
perv_1to0_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.flush(rp_rv_ccflush_dc),
|
|
.din({gptr_sl_thold_1 , func_sl_thold_1_int, sg_1_int}),
|
|
.q({gptr_sl_thold_0, func_sl_thold_0, sg_0})
|
|
);
|
|
|
|
tri_lcbor
|
|
perv_lcbor(
|
|
.clkoff_b(prv_clkoff_dc_b),
|
|
.thold(func_sl_thold_0),
|
|
.sg(sg_0),
|
|
.act_dis(prv_act_dis),
|
|
.force_t(force_t),
|
|
.thold_b(func_sl_thold_0_b)
|
|
);
|
|
|
|
// Pipeline mapping of mpw1_b and delay_lclkr
|
|
// RF0
|
|
// RF1 0
|
|
// EX1 1
|
|
// EX2 2
|
|
// EX3 3
|
|
// EX4 4
|
|
// EX5 5
|
|
// EX6 6
|
|
// EX7 7
|
|
|
|
|
|
tri_lcbcntl_mac
|
|
perv_lcbctrl0(
|
|
.vdd(vdd),
|
|
.gnd(gnd),
|
|
.sg(sg_0),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.scan_in(gptr_scan_in),
|
|
.scan_diag_dc(an_ac_scan_diag_dc),
|
|
.thold(gptr_sl_thold_0),
|
|
.clkoff_dc_b(prv_clkoff_dc_b),
|
|
.delay_lclkr_dc(prv_delay_lclkr_dc[0:4]),
|
|
.act_dis_dc(act0_dis_dc),
|
|
.d_mode_dc(d0_mode_dc),
|
|
.mpw1_dc_b(prv_mpw1_dc_b[0:4]),
|
|
.mpw2_dc_b(prv_mpw2_dc_b),
|
|
.scan_out(gptr_sio)
|
|
);
|
|
|
|
|
|
tri_lcbcntl_mac
|
|
perv_lcbctrl1(
|
|
.vdd(vdd),
|
|
.gnd(gnd),
|
|
.sg(sg_0),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.scan_in(gptr_sio),
|
|
.scan_diag_dc(an_ac_scan_diag_dc),
|
|
.thold(gptr_sl_thold_0),
|
|
.clkoff_dc_b(clkoff1_dc_b),
|
|
.delay_lclkr_dc(prv_delay_lclkr_dc[5:9]),
|
|
.act_dis_dc(act1_dis_dc),
|
|
.d_mode_dc(d1_mode_dc),
|
|
.mpw1_dc_b(prv_mpw1_dc_b[5:9]),
|
|
.mpw2_dc_b(nc_mpw2_dc_b),
|
|
.scan_out(gptr_scan_out)
|
|
);
|
|
|
|
//Outputs
|
|
assign delay_lclkr_dc[0:9] = prv_delay_lclkr_dc[0:9];
|
|
assign mpw1_dc_b[0:9] = prv_mpw1_dc_b[0:9];
|
|
assign mpw2_dc_b = prv_mpw2_dc_b;
|
|
|
|
//never disable act pins, they are used functionally
|
|
assign prv_act_dis = 1'b0;
|
|
assign act_dis = prv_act_dis;
|
|
assign clkoff_dc_b = prv_clkoff_dc_b;
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------
|
|
// Perf bus
|
|
//------------------------------------------------------------------------------------------------------------
|
|
|
|
assign event_en = ( spr_msr_pr_q & {`THREADS{event_count_mode[0]}}) | //-- User
|
|
((~spr_msr_pr_q) & spr_msr_gs_q & {`THREADS{event_count_mode[1]}}) | //-- Guest Supervisor
|
|
((~spr_msr_pr_q) & (~spr_msr_gs_q) & {`THREADS{event_count_mode[2]}}); //-- Hypervisor
|
|
|
|
assign event_bus_in[ 0: 7] = fx0_rvs_perf_bus[0:7] & {8{event_en[0]}};
|
|
assign event_bus_in[ 8:15] = fx1_rvs_perf_bus[0:7] & {8{event_en[0]}};
|
|
assign event_bus_in[16:23] = lq_rvs_perf_bus[0:7] & {8{event_en[0]}};
|
|
assign event_bus_in[24:31] = axu0_rvs_perf_bus[0:7] & {8{event_en[0]}};
|
|
|
|
|
|
tri_event_mux1t #(.EVENTS_IN(32), .EVENTS_OUT(4))
|
|
event_mux0(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.event_bus_in(rv_event_bus_in[0:3]),
|
|
.event_bus_out(event_bus_d[0:3]),
|
|
.unit_events_in(event_bus_in[1:31]),
|
|
.select_bits(event_mux_ctrls[0:19])
|
|
);
|
|
|
|
`ifndef THREADS1
|
|
|
|
assign event_bus_in[32:39] = fx0_rvs_perf_bus[8:15] & {8{event_en[1]}};
|
|
assign event_bus_in[40:47] = fx1_rvs_perf_bus[8:15] & {8{event_en[1]}};
|
|
assign event_bus_in[48:55] = lq_rvs_perf_bus[8:15] & {8{event_en[1]}};
|
|
assign event_bus_in[56:63] = axu0_rvs_perf_bus[8:15] & {8{event_en[1]}};
|
|
|
|
tri_event_mux1t #(.EVENTS_IN(32), .EVENTS_OUT(4))
|
|
event_mux1(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.event_bus_in(rv_event_bus_in[4:7]),
|
|
.event_bus_out(event_bus_d[4:7]),
|
|
.unit_events_in(event_bus_in[32:63]),
|
|
.select_bits(event_mux_ctrls[20:39])
|
|
);
|
|
`endif
|
|
|
|
assign rv_event_bus_out = event_bus_q;
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------
|
|
// Debug bus
|
|
//------------------------------------------------------------------------------------------------------------
|
|
|
|
assign dbg_group0 = fx0_rvs_dbg_bus[0:31] ;
|
|
assign dbg_group1 = fx1_rvs_dbg_bus[0:31] ;
|
|
assign dbg_group2 = lq_rvs_dbg_bus[0:31] ;
|
|
assign dbg_group3 = axu0_rvs_dbg_bus[0:31] ;
|
|
|
|
tri_debug_mux4 #(.DBG_WIDTH(32))
|
|
dbg_mux(
|
|
.select_bits(debug_mux_ctrls),
|
|
.trace_data_in(debug_bus_in),
|
|
.dbg_group0(dbg_group0),
|
|
.dbg_group1(dbg_group1),
|
|
.dbg_group2(dbg_group2),
|
|
.dbg_group3(dbg_group3),
|
|
.trace_data_out(debug_bus_mux),
|
|
.coretrace_ctrls_in(coretrace_ctrls_in),
|
|
.coretrace_ctrls_out(coretrace_ctrls_mux)
|
|
);
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------
|
|
// Latches
|
|
//------------------------------------------------------------------------------------------------------------
|
|
assign trc_act = pc_rv_trace_bus_enable;
|
|
assign evt_act = pc_rv_event_bus_enable;
|
|
assign delay_lclkr = prv_delay_lclkr_dc[0];
|
|
assign mpw1_b = prv_mpw1_dc_b[0];
|
|
assign mpw2_b = prv_mpw2_dc_b;
|
|
|
|
tri_rlmreg_p #(.WIDTH(32), .INIT(0))
|
|
debug_bus_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(trc_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[debug_bus_offset:debug_bus_offset + 32 - 1]),
|
|
.scout(sov[debug_bus_offset:debug_bus_offset + 32 - 1]),
|
|
.din(debug_bus_mux),
|
|
.dout(debug_bus_out)
|
|
);
|
|
tri_rlmreg_p #(.WIDTH(11), .INIT(0))
|
|
debug_mux_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(trc_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[debug_mux_offset:debug_mux_offset + 11 - 1]),
|
|
.scout(sov[debug_mux_offset:debug_mux_offset + 11 - 1]),
|
|
.din(pc_rv_debug_mux_ctrls),
|
|
.dout(debug_mux_ctrls)
|
|
);
|
|
tri_rlmreg_p #(.WIDTH(4*`THREADS), .INIT(0))
|
|
event_bus_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(evt_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[event_bus_offset:event_bus_offset + 4*`THREADS - 1]),
|
|
.scout(sov[event_bus_offset:event_bus_offset + 4*`THREADS - 1]),
|
|
.din(event_bus_d),
|
|
.dout(event_bus_q)
|
|
);
|
|
tri_rlmreg_p #(.WIDTH(3), .INIT(0))
|
|
event_count_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(evt_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[event_count_offset:event_count_offset + 3 - 1]),
|
|
.scout(sov[event_count_offset:event_count_offset + 3 - 1]),
|
|
.din(pc_rv_event_count_mode),
|
|
.dout(event_count_mode)
|
|
);
|
|
tri_rlmreg_p #(.WIDTH(`THREADS), .INIT(0))
|
|
spr_msr_gs_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(evt_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[spr_msr_gs_offset:spr_msr_gs_offset + `THREADS - 1]),
|
|
.scout(sov[spr_msr_gs_offset:spr_msr_gs_offset + `THREADS - 1]),
|
|
.din(spr_msr_gs),
|
|
.dout(spr_msr_gs_q)
|
|
);
|
|
tri_rlmreg_p #(.WIDTH(`THREADS), .INIT(0))
|
|
spr_msr_pr_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(evt_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[spr_msr_pr_offset:spr_msr_pr_offset + `THREADS - 1]),
|
|
.scout(sov[spr_msr_pr_offset:spr_msr_pr_offset + `THREADS - 1]),
|
|
.din(spr_msr_pr),
|
|
.dout(spr_msr_pr_q)
|
|
);
|
|
tri_rlmreg_p #(.WIDTH(40), .INIT(0))
|
|
event_mux_ctrls_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(evt_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[event_mux_ctrls_offset:event_mux_ctrls_offset + 40 - 1]),
|
|
.scout(sov[event_mux_ctrls_offset:event_mux_ctrls_offset + 40 - 1]),
|
|
.din(pc_rv_event_mux_ctrls),
|
|
.dout(event_mux_ctrls)
|
|
);
|
|
tri_rlmreg_p #(.WIDTH(4), .INIT(0))
|
|
core_trace_ctrls_reg(
|
|
.vd(vdd),
|
|
.gd(gnd),
|
|
.clk(clk),
|
|
.rst(rst),
|
|
.act(trc_act),
|
|
.thold_b(func_sl_thold_0_b),
|
|
.sg(sg_0),
|
|
.force_t(force_t),
|
|
.delay_lclkr(delay_lclkr),
|
|
.mpw1_b(mpw1_b),
|
|
.mpw2_b(mpw2_b),
|
|
.d_mode(d_mode),
|
|
.scin(siv[coretrace_ctrls_offset:coretrace_ctrls_offset + 4 - 1]),
|
|
.scout(sov[coretrace_ctrls_offset:coretrace_ctrls_offset + 4 - 1]),
|
|
.din(coretrace_ctrls_mux),
|
|
.dout(coretrace_ctrls_out)
|
|
);
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------------------------------
|
|
// Scan Connections
|
|
//------------------------------------------------------------------------------------------------------------
|
|
|
|
assign siv[0:scan_right-1] = {sov[1:scan_right-1], scan_in};
|
|
assign scan_out = sov[0];
|
|
|
|
|
|
endmodule
|