Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : // Copyright 2020 Western Digital Corporation or it's affiliates.
3 : //
4 : // Licensed under the Apache License, Version 2.0 (the "License");
5 : // you may not use this file except in compliance with the License.
6 : // You may obtain a copy of the License at
7 : //
8 : // http://www.apache.org/licenses/LICENSE-2.0
9 : //
10 : // Unless required by applicable law or agreed to in writing, software
11 : // distributed under the License is distributed on an "AS IS" BASIS,
12 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : // See the License for the specific language governing permissions and
14 : // limitations under the License.
15 :
16 :
17 : //********************************************************************************
18 : // el2_dec_tlu_ctl.sv
19 : //
20 : //
21 : // Function: CSRs, Commit/WB, flushing, exceptions, interrupts
22 : // Comments:
23 : //
24 : //********************************************************************************
25 :
26 : module el2_dec_tlu_ctl
27 : import el2_pkg::*;
28 : #(
29 : `include "el2_param.vh"
30 : )
31 : (
32 69840565 : input logic clk,
33 69840565 : input logic free_clk,
34 69840565 : input logic free_l2clk,
35 338 : input logic rst_l,
36 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
37 : /*verilator coverage_off*/
38 : input logic scan_mode,
39 : /*verilator coverage_on*/
40 :
41 0 : input logic [31:1] rst_vec, // reset vector, from core pins
42 4 : input logic nmi_int, // nmi pin
43 16 : input logic [31:1] nmi_vec, // nmi vector
44 108 : input logic i_cpu_halt_req, // Asynchronous Halt request to CPU
45 108 : input logic i_cpu_run_req, // Asynchronous Restart request to CPU
46 :
47 4 : input logic lsu_fastint_stall_any, // needed by lsu for 2nd pass of dma with ecc correction, stall next cycle
48 :
49 :
50 : // perf counter inputs
51 6195679 : input logic ifu_pmu_instr_aligned, // aligned instructions
52 614908 : input logic ifu_pmu_fetch_stall, // fetch unit stalled
53 5888394 : input logic ifu_pmu_ic_miss, // icache miss
54 745248 : input logic ifu_pmu_ic_hit, // icache hit
55 8 : input logic ifu_pmu_bus_error, // Instruction side bus error
56 4461583 : input logic ifu_pmu_bus_busy, // Instruction side bus busy
57 10349957 : input logic ifu_pmu_bus_trxn, // Instruction side bus transaction
58 6195679 : input logic dec_pmu_instr_decoded, // decoded instructions
59 237726 : input logic dec_pmu_decode_stall, // decode stall
60 266 : input logic dec_pmu_presync_stall, // decode stall due to presync'd inst
61 14664 : input logic dec_pmu_postsync_stall,// decode stall due to postsync'd inst
62 59130 : input logic lsu_store_stall_any, // SB or WB is full, stall decode
63 0 : input logic dma_dccm_stall_any, // DMA stall of lsu
64 26 : input logic dma_iccm_stall_any, // DMA stall of ifu
65 410552 : input logic exu_pmu_i0_br_misp, // pipe 0 branch misp
66 2911037 : input logic exu_pmu_i0_br_ataken, // pipe 0 branch actual taken
67 3495269 : input logic exu_pmu_i0_pc4, // pipe 0 4 byte branch
68 1673139 : input logic lsu_pmu_bus_trxn, // D side bus transaction
69 36422 : input logic lsu_pmu_bus_misaligned, // D side bus misaligned
70 4 : input logic lsu_pmu_bus_error, // D side bus error
71 67742 : input logic lsu_pmu_bus_busy, // D side bus busy
72 890738 : input logic lsu_pmu_load_external_m, // D side bus load
73 812872 : input logic lsu_pmu_store_external_m, // D side bus store
74 0 : input logic dma_pmu_dccm_read, // DMA DCCM read
75 0 : input logic dma_pmu_dccm_write, // DMA DCCM write
76 0 : input logic dma_pmu_any_read, // DMA read
77 66 : input logic dma_pmu_any_write, // DMA write
78 :
79 24696 : input logic [31:1] lsu_fir_addr, // Fast int address
80 0 : input logic [1:0] lsu_fir_error, // Fast int lookup error
81 :
82 0 : input logic iccm_dma_sb_error, // I side dma single bit error
83 :
84 4 : input el2_lsu_error_pkt_t lsu_error_pkt_r, // lsu precise exception/error packet
85 4 : input logic lsu_single_ecc_error_incr, // LSU inc SB error counter
86 :
87 2 : input logic dec_pause_state, // Pause counter not zero
88 2 : input logic lsu_imprecise_error_store_any, // store bus error
89 2 : input logic lsu_imprecise_error_load_any, // store bus error
90 292 : input logic [31:0] lsu_imprecise_error_addr_any, // store bus error address
91 :
92 42453 : input logic dec_csr_wen_unq_d, // valid csr with write - for csr legal
93 86473 : input logic dec_csr_any_unq_d, // valid csr - for csr legal
94 1000 : input logic [11:0] dec_csr_rdaddr_d, // read address for csr
95 :
96 42288 : input logic dec_csr_wen_r, // csr write enable at wb
97 1566066 : input logic [11:0] dec_csr_rdaddr_r, // read address for csr
98 542 : input logic [11:0] dec_csr_wraddr_r, // write address for csr
99 1686 : input logic [31:0] dec_csr_wrdata_r, // csr write data at wb
100 :
101 1430 : input logic dec_csr_stall_int_ff, // csr is mie/mstatus
102 :
103 6195034 : input logic dec_tlu_i0_valid_r, // pipe 0 op at e4 is valid
104 :
105 344 : input logic [31:1] exu_npc_r, // for NPC tracking
106 :
107 339 : input logic [31:1] dec_tlu_i0_pc_r, // for PC/NPC tracking
108 :
109 280 : input el2_trap_pkt_t dec_tlu_packet_r, // exceptions known at decode
110 :
111 18 : input logic [31:0] dec_illegal_inst, // For mtval
112 6195679 : input logic dec_i0_decode_d, // decode valid, used for clean icache diagnostics
113 :
114 : // branch info from pipe0 for errors or counter updates
115 2721663 : input logic [1:0] exu_i0_br_hist_r, // history
116 26468 : input logic exu_i0_br_error_r, // error
117 9608 : input logic exu_i0_br_start_error_r, // start error
118 3012693 : input logic exu_i0_br_valid_r, // valid
119 410552 : input logic exu_i0_br_mp_r, // mispredict
120 2380332 : input logic exu_i0_br_middle_r, // middle of bank
121 :
122 : // branch info from pipe1 for errors or counter updates
123 :
124 2110720 : input logic exu_i0_br_way_r, // way hit or repl
125 :
126 2090538 : output logic dec_tlu_core_empty, // core is empty
127 : // Debug start
128 2558 : output logic dec_dbg_cmd_done, // abstract command done
129 0 : output logic dec_dbg_cmd_fail, // abstract command failed
130 120 : output logic dec_tlu_dbg_halted, // Core is halted and ready for debug command
131 118 : output logic dec_tlu_debug_mode, // Core is in debug mode
132 10 : output logic dec_tlu_resume_ack, // Resume acknowledge
133 122 : output logic dec_tlu_debug_stall, // stall decode while waiting on core to empty
134 :
135 232 : output logic dec_tlu_flush_noredir_r , // Tell fetch to idle on this flush
136 108 : output logic dec_tlu_mpc_halted_only, // Core is halted only due to MPC
137 2 : output logic dec_tlu_flush_leak_one_r, // single step
138 8 : output logic dec_tlu_flush_err_r, // iside perr/ecc rfpc. This is the D stage of the error
139 :
140 0 : output logic dec_tlu_flush_extint, // fast ext int started
141 0 : output logic [31:2] dec_tlu_meihap, // meihap for fast int
142 :
143 8 : input logic dbg_halt_req, // DM requests a halt
144 10 : input logic dbg_resume_req, // DM requests a resume
145 5887400 : input logic ifu_miss_state_idle, // I-side miss buffer empty
146 1345827 : input logic lsu_idle_any, // lsu is idle
147 159480 : input logic dec_div_active, // oop div is active
148 0 : output el2_trigger_pkt_t [3:0] trigger_pkt_any, // trigger info for trigger blocks
149 :
150 0 : input logic ifu_ic_error_start, // IC single bit error
151 8 : input logic ifu_iccm_rd_ecc_single_err, // ICCM single bit error
152 :
153 :
154 0 : input logic [70:0] ifu_ic_debug_rd_data, // diagnostic icache read data
155 20 : input logic ifu_ic_debug_rd_data_valid, // diagnostic icache read data valid
156 0 : output el2_cache_debug_pkt_t dec_tlu_ic_diag_pkt, // packet of DICAWICS, DICAD0/1, DICAGO info for icache diagnostics
157 : // Debug end
158 :
159 0 : input logic [7:0] pic_claimid, // pic claimid for csr
160 0 : input logic [3:0] pic_pl, // pic priv level for csr
161 0 : input logic mhwakeup, // high priority external int, wakeup if halted
162 :
163 0 : input logic mexintpend, // external interrupt pending
164 15 : input logic timer_int, // timer interrupt pending
165 17 : input logic soft_int, // software interrupt pending
166 :
167 108 : output logic o_cpu_halt_status, // PMU interface, halted
168 108 : output logic o_cpu_halt_ack, // halt req ack
169 108 : output logic o_cpu_run_ack, // run req ack
170 118 : output logic o_debug_mode_status, // Core to the PMU that core is in debug mode. When core is in debug mode, the PMU should refrain from sendng a halt or run request
171 :
172 0 : input logic [31:4] core_id, // Core ID
173 :
174 : // external MPC halt/run interface
175 108 : input logic mpc_debug_halt_req, // Async halt request
176 108 : input logic mpc_debug_run_req, // Async run request
177 338 : input logic mpc_reset_run_req, // Run/halt after reset
178 108 : output logic mpc_debug_halt_ack, // Halt ack
179 108 : output logic mpc_debug_run_ack, // Run ack
180 2 : output logic debug_brkpt_status, // debug breakpoint
181 :
182 0 : output logic [3:0] dec_tlu_meicurpl, // to PIC
183 0 : output logic [3:0] dec_tlu_meipt, // to PIC
184 :
185 :
186 7157 : output logic [31:0] dec_csr_rddata_d, // csr read data at wb
187 86351 : output logic dec_csr_legal_d, // csr indicates legal operation
188 :
189 782023 : output el2_br_tlu_pkt_t dec_tlu_br0_r_pkt, // branch pkt to bp
190 :
191 29688 : output logic dec_tlu_i0_kill_writeb_wb, // I0 is flushed, don't writeback any results to arch state
192 59220 : output logic dec_tlu_flush_lower_wb, // commit has a flush (exception, int, mispredict at e4)
193 6165278 : output logic dec_tlu_i0_commit_cmt, // committed an instruction
194 :
195 29688 : output logic dec_tlu_i0_kill_writeb_r, // I0 is flushed, don't writeback any results to arch state
196 59220 : output logic dec_tlu_flush_lower_r, // commit has a flush (exception, int)
197 24762 : output logic [31:1] dec_tlu_flush_path_r, // flush pc
198 18868 : output logic dec_tlu_fence_i_r, // flush is a fence_i rfnpc, flush icache
199 2 : output logic dec_tlu_wr_pause_r, // CSR write to pause reg is at R.
200 2 : output logic dec_tlu_flush_pause_r, // Flush is due to pause
201 :
202 534 : output logic dec_tlu_presync_d, // CSR read needs to be presync'd
203 20529 : output logic dec_tlu_postsync_d, // CSR needs to be presync'd
204 :
205 :
206 0 : output logic [31:0] dec_tlu_mrac_ff, // CSR for memory region control
207 :
208 0 : output logic dec_tlu_force_halt, // halt has been forced
209 :
210 340148 : output logic dec_tlu_perfcnt0, // toggles when pipe0 perf counter 0 has an event inc
211 514626 : output logic dec_tlu_perfcnt1, // toggles when pipe0 perf counter 1 has an event inc
212 312914 : output logic dec_tlu_perfcnt2, // toggles when pipe0 perf counter 2 has an event inc
213 48468 : output logic dec_tlu_perfcnt3, // toggles when pipe0 perf counter 3 has an event inc
214 :
215 5178 : output logic dec_tlu_i0_exc_valid_wb1, // pipe 0 exception valid
216 6164951 : output logic dec_tlu_i0_valid_wb1, // pipe 0 valid
217 20 : output logic dec_tlu_int_valid_wb1, // pipe 2 int valid
218 4 : output logic [4:0] dec_tlu_exc_cause_wb1, // exception or int cause
219 62 : output logic [31:0] dec_tlu_mtval_wb1, // MTVAL value
220 :
221 : // feature disable from mfdc
222 0 : output logic dec_tlu_external_ldfwd_disable, // disable external load forwarding
223 322 : output logic dec_tlu_sideeffect_posted_disable, // disable posted stores to side-effect address
224 8 : output logic dec_tlu_core_ecc_disable, // disable core ECC
225 0 : output logic dec_tlu_bpred_disable, // disable branch prediction
226 6 : output logic dec_tlu_wb_coalescing_disable, // disable writebuffer coalescing
227 0 : output logic dec_tlu_pipelining_disable, // disable pipelining
228 0 : output logic dec_tlu_trace_disable, // disable trace
229 345 : output logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:16]
230 :
231 : // clock gating overrides from mcgc
232 2 : output logic dec_tlu_misc_clk_override, // override misc clock domain gating
233 2 : output logic dec_tlu_dec_clk_override, // override decode clock domain gating
234 2 : output logic dec_tlu_ifu_clk_override, // override fetch clock domain gating
235 2 : output logic dec_tlu_lsu_clk_override, // override load/store clock domain gating
236 2 : output logic dec_tlu_bus_clk_override, // override bus clock domain gating
237 2 : output logic dec_tlu_pic_clk_override, // override PIC clock domain gating
238 341 : output logic dec_tlu_picio_clk_override,// override PICIO clock domain gating
239 2 : output logic dec_tlu_dccm_clk_override, // override DCCM clock domain gating
240 2 : output logic dec_tlu_icm_clk_override, // override ICCM clock domain gating
241 :
242 : `ifdef RV_USER_MODE
243 :
244 : // Privilege mode
245 : // 0 - machine, 1 - user
246 857 : output logic priv_mode,
247 953 : output logic priv_mode_eff,
248 857 : output logic priv_mode_ns,
249 :
250 : // mseccfg CSR content for PMP
251 2 : output logic [2:0] mseccfg,
252 :
253 : `endif
254 :
255 : // pmp
256 0 : output el2_pmp_cfg_pkt_t pmp_pmpcfg [pt.PMP_ENTRIES],
257 : output logic [31:0] pmp_pmpaddr [pt.PMP_ENTRIES]
258 : );
259 :
260 4 : logic clk_override, e4e5_int_clk, nmi_fir_type, nmi_lsu_load_type, nmi_lsu_store_type, nmi_int_detected_f, nmi_lsu_load_type_f,
261 108 : nmi_lsu_store_type_f, allow_dbg_halt_csr_write, dbg_cmd_done_ns, i_cpu_run_req_d1_raw, debug_mode_status, lsu_single_ecc_error_r_d1,
262 2 : sel_npc_r, sel_npc_resume, ce_int,
263 4 : nmi_in_debug_mode, dpc_capture_npc, dpc_capture_pc, tdata_load, tdata_opcode, tdata_action, perfcnt_halted, tdata_chain,
264 0 : tdata_kill_write;
265 :
266 :
267 338 : logic reset_delayed, reset_detect, reset_detected;
268 0 : logic wr_mstatus_r, wr_mtvec_r, wr_mcyclel_r, wr_mcycleh_r,
269 0 : wr_minstretl_r, wr_minstreth_r, wr_mscratch_r, wr_mepc_r, wr_mcause_r, wr_mscause_r, wr_mtval_r,
270 6 : wr_mrac_r, wr_meihap_r, wr_meicurpl_r, wr_meipt_r, wr_dcsr_r,
271 0 : wr_dpc_r, wr_meicidpl_r, wr_meivt_r, wr_meicpct_r, wr_micect_r, wr_miccmect_r, wr_mfdht_r, wr_mfdhs_r,
272 4 : wr_mdccmect_r,wr_mhpme3_r, wr_mhpme4_r, wr_mhpme5_r, wr_mhpme6_r;
273 0 : logic wr_mpmc_r;
274 0 : logic [1:1] mpmc_b_ns, mpmc, mpmc_b;
275 0 : logic set_mie_pmu_fw_halt, fw_halted_ns, fw_halted;
276 0 : logic wr_mcountinhibit_r;
277 : `ifdef RV_USER_MODE
278 36 : logic wr_mcounteren_r;
279 6 : logic [5:0] mcounteren; // HPM6, HPM5, HPM4, HPM3, IR, CY
280 40 : logic wr_mseccfg_r;
281 2795 : logic [2:0] mseccfg_ns;
282 : `endif
283 0 : logic [6:0] mcountinhibit;
284 6 : logic wr_mtsel_r, wr_mtdata1_t0_r, wr_mtdata1_t1_r, wr_mtdata1_t2_r, wr_mtdata1_t3_r, wr_mtdata2_t0_r, wr_mtdata2_t1_r, wr_mtdata2_t2_r, wr_mtdata2_t3_r;
285 0 : logic [31:0] mtdata2_t0, mtdata2_t1, mtdata2_t2, mtdata2_t3, mtdata2_tsel_out, mtdata1_tsel_out;
286 0 : logic [9:0] mtdata1_t0_ns, mtdata1_t0, mtdata1_t1_ns, mtdata1_t1, mtdata1_t2_ns, mtdata1_t2, mtdata1_t3_ns, mtdata1_t3;
287 4 : logic [9:0] tdata_wrdata_r;
288 4 : logic [1:0] mtsel_ns, mtsel;
289 29688 : logic tlu_i0_kill_writeb_r;
290 : `ifdef RV_USER_MODE
291 56 : logic [3:0] mstatus_ns, mstatus; // MPRV, MPP (inverted! 0-M, 1-U), MPIE, MIE
292 : `else
293 3482 : logic [1:0] mstatus_ns, mstatus;
294 : `endif
295 0 : logic [1:0] mfdhs_ns, mfdhs;
296 0 : logic [31:0] force_halt_ctr, force_halt_ctr_f;
297 0 : logic force_halt;
298 0 : logic [5:0] mfdht, mfdht_ns;
299 935 : logic mstatus_mie_ns;
300 0 : logic [30:0] mtvec_ns, mtvec;
301 0 : logic [15:2] dcsr_ns, dcsr;
302 2 : logic [5:0] mip_ns, mip;
303 0 : logic [5:0] mie_ns, mie;
304 54901 : logic [31:0] mcyclel_ns, mcyclel;
305 0 : logic [31:0] mcycleh_ns, mcycleh;
306 14468 : logic [31:0] minstretl_ns, minstretl;
307 0 : logic [31:0] minstreth_ns, minstreth;
308 0 : logic [31:0] micect_ns, micect, miccmect_ns, miccmect, mdccmect_ns, mdccmect;
309 0 : logic [26:0] micect_inc, miccmect_inc, mdccmect_inc;
310 1334 : logic [31:0] mscratch;
311 46 : logic [31:0] mhpmc3, mhpmc3_ns, mhpmc4, mhpmc4_ns, mhpmc5, mhpmc5_ns, mhpmc6, mhpmc6_ns;
312 0 : logic [31:0] mhpmc3h, mhpmc3h_ns, mhpmc4h, mhpmc4h_ns, mhpmc5h, mhpmc5h_ns, mhpmc6h, mhpmc6h_ns;
313 0 : logic [9:0] mhpme3, mhpme4, mhpme5, mhpme6;
314 0 : logic [31:0] mrac;
315 0 : logic [9:2] meihap;
316 1 : logic [31:10] meivt;
317 0 : logic [3:0] meicurpl_ns, meicurpl;
318 0 : logic [3:0] meicidpl_ns, meicidpl;
319 0 : logic [3:0] meipt_ns, meipt;
320 0 : logic [31:0] mdseac;
321 4 : logic mdseac_locked_ns, mdseac_locked_f, mdseac_en, nmi_lsu_detected;
322 173 : logic [31:1] mepc_ns, mepc;
323 0 : logic [31:1] dpc_ns, dpc;
324 0 : logic [31:0] mcause_ns, mcause;
325 8 : logic [3:0] mscause_ns, mscause, mscause_type;
326 62 : logic [31:0] mtval_ns, mtval;
327 2 : logic dec_pause_state_f, dec_tlu_wr_pause_r_d1, pause_expired_r, pause_expired_wb;
328 59220 : logic tlu_flush_lower_r, tlu_flush_lower_r_d1;
329 344 : logic [31:1] tlu_flush_path_r, tlu_flush_path_r_d1;
330 6164951 : logic i0_valid_wb;
331 6165278 : logic tlu_i0_commit_cmt;
332 22 : logic [31:1] vectored_path, interrupt_path;
333 0 : logic [16:0] dicawics_ns, dicawics;
334 10 : logic wr_dicawics_r, wr_dicad0_r, wr_dicad1_r, wr_dicad0h_r;
335 0 : logic [31:0] dicad0_ns, dicad0, dicad0h_ns, dicad0h;
336 :
337 0 : logic [6:0] dicad1_ns, dicad1_raw;
338 0 : logic [31:0] dicad1;
339 15926 : logic ebreak_r, ebreak_to_debug_mode_r, ecall_r, illegal_r, mret_r, inst_acc_r, fence_i_r,
340 0 : ic_perr_r, iccm_sbecc_r, ebreak_to_debug_mode_r_d1, kill_ebreak_count_r, inst_acc_second_r;
341 2 : logic ce_int_ready, ext_int_ready, timer_int_ready, soft_int_ready, int_timer0_int_ready, int_timer1_int_ready, mhwakeup_ready,
342 2 : take_ext_int, take_ce_int, take_timer_int, take_soft_int, take_int_timer0_int, take_int_timer1_int, take_nmi, take_nmi_r_d1, int_timer0_int_possible, int_timer1_int_possible;
343 5192 : logic i0_exception_valid_r, interrupt_valid_r, i0_exception_valid_r_d1, interrupt_valid_r_d1, exc_or_int_valid_r, exc_or_int_valid_r_d1, mdccme_ce_req, miccme_ce_req, mice_ce_req;
344 53156 : logic synchronous_flush_r;
345 4 : logic [4:0] exc_cause_r, exc_cause_wb;
346 219895 : logic mcyclel_cout, mcyclel_cout_f, mcyclela_cout;
347 54902 : logic [31:0] mcyclel_inc;
348 0 : logic [31:0] mcycleh_inc;
349 :
350 58284 : logic minstretl_cout, minstretl_cout_f, minstret_enable, minstretl_cout_ns, minstretl_couta;
351 :
352 14468 : logic [31:0] minstretl_inc, minstretl_read;
353 0 : logic [31:0] minstreth_inc, minstreth_read;
354 343 : logic [31:1] pc_r, pc_r_d1, npc_r, npc_r_d1;
355 86353 : logic valid_csr;
356 28866 : logic rfpc_i0_r;
357 4 : logic lsu_i0_rfnpc_r;
358 2419907 : logic dec_tlu_br0_error_r, dec_tlu_br0_start_error_r, dec_tlu_br0_v_r;
359 48 : logic lsu_i0_exc_r, lsu_i0_exc_r_raw, lsu_exc_ma_r, lsu_exc_acc_r, lsu_exc_st_r,
360 57924 : lsu_exc_valid_r, lsu_exc_valid_r_raw, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1, block_interrupts;
361 6195034 : logic i0_trigger_eval_r;
362 :
363 4 : logic request_debug_mode_r, request_debug_mode_r_d1, request_debug_mode_done, request_debug_mode_done_f;
364 676 : logic take_halt, halt_taken, halt_taken_f, internal_dbg_halt_mode, dbg_tlu_halted_f, take_reset,
365 2 : dbg_tlu_halted, core_empty, lsu_idle_any_f, ifu_miss_state_idle_f, resume_ack_ns,
366 2 : debug_halt_req_f, debug_resume_req_f_raw, debug_resume_req_f, enter_debug_halt_req, dcsr_single_step_done, dcsr_single_step_done_f,
367 2 : debug_halt_req_d1, debug_halt_req_ns, dcsr_single_step_running, dcsr_single_step_running_f, internal_dbg_halt_timers;
368 :
369 0 : logic [3:0] i0_trigger_r, trigger_action, trigger_enabled,
370 0 : i0_trigger_chain_masked_r;
371 4 : logic i0_trigger_hit_r, i0_trigger_hit_raw_r, i0_trigger_action_r,
372 6 : trigger_hit_r_d1,
373 2 : mepc_trigger_hit_sel_pc_r;
374 339 : logic [3:0] update_hit_bit_r, i0_iside_trigger_has_pri_r,i0trigger_qual_r, i0_lsu_trigger_has_pri_r;
375 108 : logic cpu_halt_status, cpu_halt_ack, cpu_run_ack, ext_halt_pulse, i_cpu_halt_req_d1, i_cpu_run_req_d1;
376 :
377 4 : logic inst_acc_r_raw, trigger_hit_dmode_r, trigger_hit_dmode_r_d1;
378 2 : logic [9:0] mcgc, mcgc_ns, mcgc_int;
379 0 : logic [18:0] mfdc;
380 108 : logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f, int_timer_stalled,
381 108 : fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode,
382 0 : internal_pmu_fw_halt_mode_f, int_timer0_int_hold, int_timer1_int_hold, int_timer0_int_hold_f, int_timer1_int_hold_f;
383 4 : logic nmi_int_delayed, nmi_int_detected;
384 0 : logic [3:0] trigger_execute, trigger_data, trigger_store;
385 108 : logic dec_tlu_pmu_fw_halted;
386 :
387 12 : logic mpc_run_state_ns, debug_brkpt_status_ns, mpc_debug_halt_ack_ns, mpc_debug_run_ack_ns, dbg_halt_state_ns, dbg_run_state_ns,
388 108 : dbg_halt_state_f, mpc_debug_halt_req_sync_f, mpc_debug_run_req_sync_f, mpc_halt_state_f, mpc_halt_state_ns, mpc_run_state_f, debug_brkpt_status_f,
389 108 : mpc_debug_halt_ack_f, mpc_debug_run_ack_f, dbg_run_state_f, mpc_debug_halt_req_sync_pulse,
390 108 : mpc_debug_run_req_sync_pulse, debug_brkpt_valid, debug_halt_req, debug_resume_req, dec_tlu_mpc_halted_only_ns;
391 0 : logic take_ext_int_start, ext_int_freeze, take_ext_int_start_d1, take_ext_int_start_d2,
392 4 : take_ext_int_start_d3, ext_int_freeze_d1, ignore_ext_int_due_to_lsu_stall;
393 32 : logic mcause_sel_nmi_store, mcause_sel_nmi_load, mcause_sel_nmi_ext, fast_int_meicpct;
394 0 : logic [1:0] mcause_fir_error_type;
395 8 : logic dbg_halt_req_held_ns, dbg_halt_req_held, dbg_halt_req_final;
396 6 : logic iccm_repair_state_ns, iccm_repair_state_d1, iccm_repair_state_rfnpc;
397 :
398 :
399 : // internal timer, isolated for size reasons
400 30 : logic [31:0] dec_timer_rddata_d;
401 8 : logic dec_timer_read_d, dec_timer_t0_pulse, dec_timer_t1_pulse;
402 :
403 : // PMP unit, isolated for size reasons
404 262 : logic [31:0] dec_pmp_rddata_d;
405 1738 : logic dec_pmp_read_d;
406 :
407 108 : logic nmi_int_sync, timer_int_sync, soft_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync, mpc_debug_halt_req_sync, mpc_debug_run_req_sync, mpc_debug_halt_req_sync_raw;
408 69840565 : logic csr_wr_clk;
409 118 : logic e4e5_clk, e4_valid, e5_valid, e4e5_valid, internal_dbg_halt_mode_f, internal_dbg_halt_mode_f2;
410 676050 : logic lsu_pmu_load_external_r, lsu_pmu_store_external_r;
411 2 : logic dec_tlu_flush_noredir_r_d1, dec_tlu_flush_pause_r_d1;
412 4 : logic lsu_single_ecc_error_r;
413 6 : logic [31:0] lsu_error_pkt_addr_r;
414 447 : logic mcyclel_cout_in;
415 6191480 : logic i0_valid_no_ebreak_ecall_r;
416 6161663 : logic minstret_enable_f;
417 58989 : logic sel_exu_npc_r, sel_flush_npc_r, sel_hold_npc_r;
418 6192476 : logic pc0_valid_r;
419 2028 : logic [15:0] mfdc_int, mfdc_ns;
420 434 : logic [31:0] mrac_in;
421 788 : logic [31:27] csr_sat;
422 2 : logic [8:6] dcsr_cause;
423 116 : logic enter_debug_halt_req_le, dcsr_cause_upgradeable;
424 20 : logic icache_rd_valid, icache_wr_valid, icache_rd_valid_f, icache_wr_valid_f;
425 48468 : logic [3:0] mhpmc_inc_r, mhpmc_inc_r_d1;
426 :
427 0 : logic [3:0][9:0] mhpme_vec;
428 340148 : logic mhpmc3_wr_en0, mhpmc3_wr_en1, mhpmc3_wr_en;
429 514626 : logic mhpmc4_wr_en0, mhpmc4_wr_en1, mhpmc4_wr_en;
430 312914 : logic mhpmc5_wr_en0, mhpmc5_wr_en1, mhpmc5_wr_en;
431 48468 : logic mhpmc6_wr_en0, mhpmc6_wr_en1, mhpmc6_wr_en;
432 340148 : logic mhpmc3h_wr_en0, mhpmc3h_wr_en;
433 514626 : logic mhpmc4h_wr_en0, mhpmc4h_wr_en;
434 312914 : logic mhpmc5h_wr_en0, mhpmc5h_wr_en;
435 48468 : logic mhpmc6h_wr_en0, mhpmc6h_wr_en;
436 46 : logic [63:0] mhpmc3_incr, mhpmc4_incr, mhpmc5_incr, mhpmc6_incr;
437 9371 : logic perfcnt_halted_d1, zero_event_r;
438 0 : logic [3:0] perfcnt_during_sleep;
439 32 : logic [9:0] event_r;
440 :
441 2157765 : el2_inst_pkt_t pmu_i0_itype_qual;
442 :
443 42288 : logic dec_csr_wen_r_mod;
444 :
445 934 : logic flush_clkvalid;
446 0 : logic sel_fir_addr;
447 314 : logic wr_mie_r;
448 3830 : logic mtval_capture_pc_r;
449 0 : logic mtval_capture_pc_plus2_r;
450 288 : logic mtval_capture_inst_r;
451 82 : logic mtval_capture_lsu_r;
452 998 : logic mtval_clear_r;
453 22 : logic wr_mcgc_r;
454 28 : logic wr_mfdc_r;
455 38 : logic wr_mdeau_r;
456 4 : logic trigger_hit_for_dscr_cause_r_d1;
457 0 : logic conditionally_illegal;
458 :
459 727 : logic [3:0] ifu_mscause ;
460 8 : logic ifu_ic_error_start_f, ifu_iccm_rd_ecc_single_err_f;
461 :
462 : // CSR address decoder
463 :
464 : // files "csrdecode_m" (machine mode only) and "csrdecode_mu" (machine mode plus
465 : // user mode) are human readable that have all of the CSR decodes defined and
466 : // are part of the git repo. Modify these files as needed.
467 :
468 : // to generate all the equations below from "csrdecode" except legal equation:
469 :
470 : // 1) coredecode -in csrdecode > corecsrdecode.e
471 :
472 : // 2) espresso -Dso -oeqntott < corecsrdecode.e | addassign > csrequations
473 :
474 : // to generate the legal CSR equation below:
475 :
476 : // 1) coredecode -in csrdecode -legal > csrlegal.e
477 :
478 : // 2) espresso -Dso -oeqntott < csrlegal.e | addassign > csrlegal_equation
479 :
480 : // coredecode -in csrdecode > corecsrdecode.e; espresso -Dso -oeqntott < corecsrdecode.e | addassign > csrequations; coredecode -in csrdecode -legal > csrlegal.e; espresso -Dso -oeqntott csrlegal.e | addassign > csrlegal_equation
481 :
482 : `ifdef RV_USER_MODE
483 :
484 : `include "el2_dec_csr_equ_mu.svh"
485 :
486 612 : logic csr_acc_r; // CSR access error
487 16697 : logic csr_wr_usr_r; // Write to an unprivileged/user-level CSR
488 1095060 : logic csr_rd_usr_r; // REad from an unprivileged/user-level CSR
489 :
490 : `else
491 :
492 : `include "el2_dec_csr_equ_m.svh"
493 :
494 : `endif
495 :
496 : el2_dec_timer_ctl #(.pt(pt)) int_timers(.*);
497 : // end of internal timers
498 :
499 : el2_dec_pmp_ctl #(.pt(pt)) pmp(.*);
500 : // end of pmp
501 :
502 : assign clk_override = dec_tlu_dec_clk_override;
503 :
504 : // Async inputs to the core have to be sync'd to the core clock.
505 : rvsyncss #(7) syncro_ff(.*,
506 : .clk(free_clk),
507 : .din ({nmi_int, timer_int, soft_int, i_cpu_halt_req, i_cpu_run_req, mpc_debug_halt_req, mpc_debug_run_req}),
508 : .dout({nmi_int_sync, timer_int_sync, soft_int_sync, i_cpu_halt_req_sync, i_cpu_run_req_sync, mpc_debug_halt_req_sync_raw, mpc_debug_run_req_sync}));
509 :
510 : // for CSRs that have inpipe writes only
511 :
512 : rvoclkhdr csrwr_r_cgc ( .en(dec_csr_wen_r_mod | clk_override), .l1clk(csr_wr_clk), .* );
513 :
514 : assign e4_valid = dec_tlu_i0_valid_r;
515 : assign e4e5_valid = e4_valid | e5_valid;
516 : assign flush_clkvalid = internal_dbg_halt_mode_f | i_cpu_run_req_d1 | interrupt_valid_r | interrupt_valid_r_d1 |
517 : reset_delayed | pause_expired_r | pause_expired_wb | ic_perr_r | iccm_sbecc_r |
518 : clk_override;
519 : rvoclkhdr e4e5_cgc ( .en(e4e5_valid | clk_override), .l1clk(e4e5_clk), .* );
520 : rvoclkhdr e4e5_int_cgc ( .en(e4e5_valid | flush_clkvalid), .l1clk(e4e5_int_clk), .* );
521 :
522 : rvdffie #(11) freeff (.*, .clk(free_l2clk),
523 : .din ({ifu_ic_error_start, ifu_iccm_rd_ecc_single_err, iccm_repair_state_ns, e4_valid, internal_dbg_halt_mode,
524 : lsu_pmu_load_external_m, lsu_pmu_store_external_m, tlu_flush_lower_r, tlu_i0_kill_writeb_r,
525 : internal_dbg_halt_mode_f, force_halt}),
526 : .dout({ifu_ic_error_start_f, ifu_iccm_rd_ecc_single_err_f, iccm_repair_state_d1, e5_valid, internal_dbg_halt_mode_f,
527 : lsu_pmu_load_external_r, lsu_pmu_store_external_r, tlu_flush_lower_r_d1, dec_tlu_i0_kill_writeb_wb,
528 : internal_dbg_halt_mode_f2, dec_tlu_force_halt}));
529 :
530 : assign dec_tlu_i0_kill_writeb_r = tlu_i0_kill_writeb_r;
531 :
532 : assign nmi_int_detected = (nmi_int_sync & ~nmi_int_delayed) | nmi_lsu_detected | (nmi_int_detected_f & ~take_nmi_r_d1) | nmi_fir_type;
533 : // if the first nmi is a lsu type, note it. If there's already an nmi pending, ignore. Simultaneous with FIR, drop.
534 : assign nmi_lsu_load_type = (nmi_lsu_detected & lsu_imprecise_error_load_any & ~(nmi_int_detected_f & ~take_nmi_r_d1)) |
535 : (nmi_lsu_load_type_f & ~take_nmi_r_d1);
536 : assign nmi_lsu_store_type = (nmi_lsu_detected & lsu_imprecise_error_store_any & ~(nmi_int_detected_f & ~take_nmi_r_d1)) |
537 : (nmi_lsu_store_type_f & ~take_nmi_r_d1);
538 :
539 : assign nmi_fir_type = ~nmi_int_detected_f & take_ext_int_start_d3 & |lsu_fir_error[1:0];
540 :
541 : // Filter subsequent bus errors after the first, until the lock on MDSEAC is cleared
542 : assign nmi_lsu_detected = ~mdseac_locked_f & (lsu_imprecise_error_load_any | lsu_imprecise_error_store_any) & ~nmi_fir_type;
543 :
544 :
545 : localparam MSTATUS_MIE = 0;
546 : localparam int MSTATUS_MPIE = 1;
547 : `ifdef RV_USER_MODE
548 : localparam MSTATUS_MPP = 2;
549 : localparam MSTATUS_MPRV = 3;
550 : `endif
551 :
552 : localparam MIP_MCEIP = 5;
553 : localparam MIP_MITIP0 = 4;
554 : localparam MIP_MITIP1 = 3;
555 : localparam MIP_MEIP = 2;
556 : localparam MIP_MTIP = 1;
557 : localparam MIP_MSIP = 0;
558 :
559 : localparam MIE_MCEIE = 5;
560 : localparam MIE_MITIE0 = 4;
561 : localparam MIE_MITIE1 = 3;
562 : localparam MIE_MEIE = 2;
563 : localparam MIE_MTIE = 1;
564 : localparam MIE_MSIE = 0;
565 :
566 : localparam DCSR_EBREAKM = 15;
567 : localparam DCSR_STEPIE = 11;
568 : localparam DCSR_STOPC = 10;
569 : localparam DCSR_STEP = 2;
570 :
571 : `ifdef RV_USER_MODE
572 : localparam MCOUNTEREN_CY = 0;
573 : localparam MCOUNTEREN_IR = 1;
574 : localparam MCOUNTEREN_HPM3 = 2;
575 : localparam MCOUNTEREN_HPM4 = 3;
576 : localparam MCOUNTEREN_HPM5 = 4;
577 : localparam MCOUNTEREN_HPM6 = 5;
578 :
579 : localparam MSECCFG_RLB = 2;
580 : localparam MSECCFG_MMWP = 1;
581 : localparam MSECCFG_MML = 0;
582 : `endif
583 :
584 : // ----------------------------------------------------------------------
585 : // MISA (RO)
586 : // [31:30] XLEN - implementation width, 2'b01 - 32 bits
587 : // [20] U - user mode support (if enabled in config)
588 : // [12] M - integer mul/div
589 : // [8] I - RV32I
590 : // [2] C - Compressed extension
591 : localparam MISA = 12'h301;
592 :
593 : // MVENDORID, MARCHID, MIMPID, MHARTID
594 : localparam MVENDORID = 12'hf11;
595 : localparam MARCHID = 12'hf12;
596 : localparam MIMPID = 12'hf13;
597 : localparam MHARTID = 12'hf14;
598 :
599 :
600 : // ----------------------------------------------------------------------
601 : // MSTATUS (RW)
602 : // [17] MPRV : Modify PRiVilege (if enabled in config)
603 : // [12:11] MPP : Prior priv level, either 2'b11 (machine) or 2'b00 (user)
604 : // [7] MPIE : Int enable previous [1]
605 : // [3] MIE : Int enable [0]
606 : localparam MSTATUS = 12'h300;
607 :
608 : // ----------------------------------------------------------------------
609 : // MTVEC (RW)
610 : // [31:2] BASE : Trap vector base address
611 : // [1] - Reserved, not implemented, reads zero
612 : // [0] MODE : 0 = Direct, 1 = Asyncs are vectored to BASE + (4 * CAUSE)
613 : localparam MTVEC = 12'h305;
614 :
615 : // ----------------------------------------------------------------------
616 : // MIP (RW)
617 : //
618 : // [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending
619 : // [29] MITIP0 : (RO) M-Mode Internal Timer0 interrupt pending
620 : // [28] MITIP1 : (RO) M-Mode Internal Timer1 interrupt pending
621 : // [11] MEIP : (RO) M-Mode external interrupt pending
622 : // [7] MTIP : (RO) M-Mode timer interrupt pending
623 : // [3] MSIP : (RO) M-Mode software interrupt pending
624 : localparam MIP = 12'h344;
625 :
626 : // ----------------------------------------------------------------------
627 : // MIE (RW)
628 : // [30] MCEIE : (RO) M-Mode Correctable Error interrupt enable
629 : // [29] MITIE0 : (RO) M-Mode Internal Timer0 interrupt enable
630 : // [28] MITIE1 : (RO) M-Mode Internal Timer1 interrupt enable
631 : // [11] MEIE : (RW) M-Mode external interrupt enable
632 : // [7] MTIE : (RW) M-Mode timer interrupt enable
633 : // [3] MSIE : (RW) M-Mode software interrupt enable
634 : localparam MIE = 12'h304;
635 :
636 : // ----------------------------------------------------------------------
637 : // MCYCLEL (RW)
638 : // [31:0] : Lower Cycle count
639 :
640 : localparam MCYCLEL = 12'hb00;
641 : localparam logic [11:0] CYCLEL = 12'hc00;
642 :
643 : // ----------------------------------------------------------------------
644 : // MCYCLEH (RW)
645 : // [63:32] : Higher Cycle count
646 : // Chained with mcyclel. Note: mcyclel overflow due to a mcycleh write gets ignored.
647 :
648 : localparam MCYCLEH = 12'hb80;
649 : localparam logic [11:0] CYCLEH = 12'hc80;
650 :
651 : // ----------------------------------------------------------------------
652 : // MINSTRETL (RW)
653 : // [31:0] : Lower Instruction retired count
654 : // From the spec "Some CSRs, such as the instructions retired counter, instret, may be modified as side effects
655 : // of instruction execution. In these cases, if a CSR access instruction reads a CSR, it reads the
656 : // value prior to the execution of the instruction. If a CSR access instruction writes a CSR, the
657 : // update occurs after the execution of the instruction. In particular, a value written to instret by
658 : // one instruction will be the value read by the following instruction (i.e., the increment of instret
659 : // caused by the first instruction retiring happens before the write of the new value)."
660 : localparam MINSTRETL = 12'hb02;
661 : localparam logic [11:0] INSTRETL = 12'hc02;
662 :
663 : // ----------------------------------------------------------------------
664 : // MINSTRETH (RW)
665 : // [63:32] : Higher Instret count
666 : // Chained with minstretl. Note: minstretl overflow due to a minstreth write gets ignored.
667 :
668 : localparam MINSTRETH = 12'hb82;
669 : localparam logic [11:0] INSTRETH = 12'hc82;
670 :
671 : // ----------------------------------------------------------------------
672 : // MSCRATCH (RW)
673 : // [31:0] : Scratch register
674 : localparam MSCRATCH = 12'h340;
675 :
676 : // ----------------------------------------------------------------------
677 : // MEPC (RW)
678 : // [31:1] : Exception PC
679 : localparam MEPC = 12'h341;
680 :
681 : // ----------------------------------------------------------------------
682 : // MCAUSE (RW)
683 : // [31:0] : Exception Cause
684 : localparam MCAUSE = 12'h342;
685 :
686 : // ----------------------------------------------------------------------
687 : // MSCAUSE (RW)
688 : // [2:0] : Secondary exception Cause
689 : localparam MSCAUSE = 12'h7ff;
690 :
691 : // ----------------------------------------------------------------------
692 : // MTVAL (RW)
693 : // [31:0] : Exception address if relevant
694 : localparam MTVAL = 12'h343;
695 :
696 : // ----------------------------------------------------------------------
697 : // MCGC (RW) Clock gating control
698 : // [31:10]: Reserved, reads 0x0
699 : // [9] : picio_clk_override
700 : // [7] : dec_clk_override
701 : // [6] : Unused
702 : // [5] : ifu_clk_override
703 : // [4] : lsu_clk_override
704 : // [3] : bus_clk_override
705 : // [2] : pic_clk_override
706 : // [1] : dccm_clk_override
707 : // [0] : icm_clk_override
708 : //
709 : localparam MCGC = 12'h7f8;
710 :
711 : // ----------------------------------------------------------------------
712 : // MFDC (RW) Feature Disable Control
713 : // [31:19] : Reserved, reads 0x0
714 : // [18:16] : DMA QoS Prty
715 : // [15:13] : Reserved, reads 0x0
716 : // [12] : Disable trace
717 : // [11] : Disable external load forwarding
718 : // [10] : Disable dual issue
719 : // [9] : Disable pic multiple ints
720 : // [8] : Disable core ecc
721 : // [7] : Disable secondary alu?s
722 : // [6] : Unused, 0x0
723 : // [5] : Disable non-blocking loads/divides
724 : // [4] : Disable fast divide
725 : // [3] : Disable branch prediction and return stack
726 : // [2] : Disable write buffer coalescing
727 : // [1] : Disable load misses that bypass the write buffer
728 : // [0] : Disable pipelining - Enable single instruction execution
729 : //
730 : localparam MFDC = 12'h7f9;
731 :
732 : // ----------------------------------------------------------------------
733 : // MRAC (RW)
734 : // [31:0] : Region Access Control Register, 16 regions, {side_effect, cachable} pairs
735 : localparam MRAC = 12'h7c0;
736 :
737 : // ----------------------------------------------------------------------
738 : // MDEAU (WAR0)
739 : // [31:0] : Dbus Error Address Unlock register
740 : //
741 : localparam MDEAU = 12'hbc0;
742 :
743 : // ----------------------------------------------------------------------
744 : // MDSEAC (R)
745 : // [31:0] : Dbus Store Error Address Capture register
746 : //
747 : localparam MDSEAC = 12'hfc0;
748 :
749 : // ----------------------------------------------------------------------
750 : // MPMC (R0W1)
751 : // [0] : FW halt
752 : // [1] : Set MSTATUS[MIE] on halt
753 : localparam MPMC = 12'h7c6;
754 :
755 : // ----------------------------------------------------------------------
756 : // MICECT (I-Cache error counter/threshold)
757 : // [31:27] : Icache parity error threshold
758 : // [26:0] : Icache parity error count
759 : localparam MICECT = 12'h7f0;
760 :
761 : // ----------------------------------------------------------------------
762 : // MICCMECT (ICCM error counter/threshold)
763 : // [31:27] : ICCM parity error threshold
764 : // [26:0] : ICCM parity error count
765 : localparam MICCMECT = 12'h7f1;
766 :
767 : // ----------------------------------------------------------------------
768 : // MDCCMECT (DCCM error counter/threshold)
769 : // [31:27] : DCCM parity error threshold
770 : // [26:0] : DCCM parity error count
771 : localparam MDCCMECT = 12'h7f2;
772 :
773 : // ----------------------------------------------------------------------
774 : // MFDHT (Force Debug Halt Threshold)
775 : // [5:1] : Halt timeout threshold (power of 2)
776 : // [0] : Halt timeout enabled
777 : localparam MFDHT = 12'h7ce;
778 :
779 : // ----------------------------------------------------------------------
780 : // MFDHS(RW)
781 : // [1] : LSU operation pending when debug halt threshold reached
782 : // [0] : IFU operation pending when debug halt threshold reached
783 : localparam MFDHS = 12'h7cf;
784 :
785 : // ----------------------------------------------------------------------
786 : // MEIVT (External Interrupt Vector Table (R/W))
787 : // [31:10]: Base address (R/W)
788 : // [9:0] : Reserved, reads 0x0
789 : localparam MEIVT = 12'hbc8;
790 :
791 : // ----------------------------------------------------------------------
792 : // MEICURPL (R/W)
793 : // [31:4] : Reserved (read 0x0)
794 : // [3:0] : CURRPRI - Priority level of current interrupt service routine (R/W)
795 : localparam MEICURPL = 12'hbcc;
796 :
797 : // ----------------------------------------------------------------------
798 : // MEICIDPL (R/W)
799 : // [31:4] : Reserved (read 0x0)
800 : // [3:0] : External Interrupt Claim ID's Priority Level Register
801 : localparam MEICIDPL = 12'hbcb;
802 :
803 : // ----------------------------------------------------------------------
804 : // MEICPCT (Capture CLAIMID in MEIHAP and PL in MEICIDPL
805 : // [31:1] : Reserved (read 0x0)
806 : // [0] : Capture (W1, Read 0)
807 : localparam MEICPCT = 12'hbca;
808 :
809 : // ----------------------------------------------------------------------
810 : // MEIPT (External Interrupt Priority Threshold)
811 : // [31:4] : Reserved (read 0x0)
812 : // [3:0] : PRITHRESH
813 : localparam MEIPT = 12'hbc9;
814 :
815 : // ----------------------------------------------------------------------
816 : // DCSR (R/W) (Only accessible in debug mode)
817 : // [31:28] : xdebugver (hard coded to 0x4) RO
818 : // [27:16] : 0x0, reserved
819 : // [15] : ebreakm
820 : // [14] : 0x0, reserved
821 : // [13] : ebreaks (0x0 for this core)
822 : // [12] : ebreaku (0x0 for this core)
823 : // [11] : stepie
824 : // [10] : stopcount
825 : // [9] : 0x0 //stoptime
826 : // [8:6] : cause (RO)
827 : // [5:4] : 0x0, reserved
828 : // [3] : nmip
829 : // [2] : step
830 : // [1:0] : prv (0x3 for this core)
831 : //
832 : localparam DCSR = 12'h7b0;
833 :
834 : // ----------------------------------------------------------------------
835 : // DPC (R/W) (Only accessible in debug mode)
836 : // [31:0] : Debug PC
837 : localparam DPC = 12'h7b1;
838 :
839 : // ----------------------------------------------------------------------
840 : // DICAWICS (R/W) (Only accessible in debug mode)
841 : // [31:25] : Reserved
842 : // [24] : Array select, 0 is data, 1 is tag
843 : // [23:22] : Reserved
844 : // [21:20] : Way select
845 : // [19:17] : Reserved
846 : // [16:3] : Index
847 : // [2:0] : Reserved
848 : localparam DICAWICS = 12'h7c8;
849 :
850 : // ----------------------------------------------------------------------
851 : // DICAD0 (R/W) (Only accessible in debug mode)
852 : //
853 : // If dicawics[array] is 0
854 : // [31:0] : inst data
855 : //
856 : // If dicawics[array] is 1
857 : // [31:16] : Tag
858 : // [15:7] : Reserved
859 : // [6:4] : LRU
860 : // [3:1] : Reserved
861 : // [0] : Valid
862 : localparam DICAD0 = 12'h7c9;
863 :
864 : // ----------------------------------------------------------------------
865 : // DICAD0H (R/W) (Only accessible in debug mode)
866 : //
867 : // If dicawics[array] is 0
868 : // [63:32] : inst data
869 : //
870 : localparam DICAD0H = 12'h7cc;
871 :
872 : // ----------------------------------------------------------------------
873 : // DICAGO (R/W) (Only accessible in debug mode)
874 : // [0] : Go
875 : localparam DICAGO = 12'h7cb;
876 :
877 : // ----------------------------------------------------------------------
878 : // MHPMC3H(RW), MHPMC3(RW)
879 : // [63:32][31:0] : Hardware Performance Monitor Counter 3
880 : localparam MHPMC3 = 12'hB03;
881 : localparam MHPMC3H = 12'hB83;
882 : `ifdef RV_USER_MODE
883 : localparam HPMC3 = 12'hC03;
884 : localparam HPMC3H = 12'hC83;
885 : `endif
886 :
887 : // ----------------------------------------------------------------------
888 : // MHPMC4H(RW), MHPMC4(RW)
889 : // [63:32][31:0] : Hardware Performance Monitor Counter 4
890 : localparam MHPMC4 = 12'hB04;
891 : localparam MHPMC4H = 12'hB84;
892 : `ifdef RV_USER_MODE
893 : localparam HPMC4 = 12'hC04;
894 : localparam HPMC4H = 12'hC84;
895 : `endif
896 :
897 : // ----------------------------------------------------------------------
898 : // MHPMC5H(RW), MHPMC5(RW)
899 : // [63:32][31:0] : Hardware Performance Monitor Counter 5
900 : localparam MHPMC5 = 12'hB05;
901 : localparam MHPMC5H = 12'hB85;
902 : `ifdef RV_USER_MODE
903 : localparam HPMC5 = 12'hC05;
904 : localparam HPMC5H = 12'hC85;
905 : `endif
906 :
907 : // ----------------------------------------------------------------------
908 : // MHPMC6H(RW), MHPMC6(RW)
909 : // [63:32][31:0] : Hardware Performance Monitor Counter 6
910 : localparam MHPMC6 = 12'hB06;
911 : localparam MHPMC6H = 12'hB86;
912 : `ifdef RV_USER_MODE
913 : localparam HPMC6 = 12'hC06;
914 : localparam HPMC6H = 12'hC86;
915 : `endif
916 :
917 : // ----------------------------------------------------------------------
918 : // MHPME3(RW)
919 : // [9:0] : Hardware Performance Monitor Event 3
920 : localparam MHPME3 = 12'h323;
921 :
922 : // ----------------------------------------------------------------------
923 : // MHPME4(RW)
924 : // [9:0] : Hardware Performance Monitor Event 4
925 : localparam MHPME4 = 12'h324;
926 :
927 : // ----------------------------------------------------------------------
928 : // MHPME5(RW)
929 : // [9:0] : Hardware Performance Monitor Event 5
930 : localparam MHPME5 = 12'h325;
931 :
932 : // ----------------------------------------------------------------------
933 : // MHPME6(RW)
934 : // [9:0] : Hardware Performance Monitor Event 6
935 : localparam MHPME6 = 12'h326;
936 :
937 : // MCOUNTINHIBIT(RW)
938 : // [31:7] : Reserved, read 0x0
939 : // [6] : HPM6 disable
940 : // [5] : HPM5 disable
941 : // [4] : HPM4 disable
942 : // [3] : HPM3 disable
943 : // [2] : MINSTRET disable
944 : // [1] : reserved, read 0x0
945 : // [0] : MCYCLE disable
946 :
947 : localparam MCOUNTINHIBIT = 12'h320;
948 :
949 : // ----------------------------------------------------------------------
950 : // MTSEL (R/W)
951 : // [1:0] : Trigger select : 00, 01, 10 are data/address triggers. 11 is inst count
952 : localparam MTSEL = 12'h7a0;
953 :
954 : // ----------------------------------------------------------------------
955 : // MTDATA1 (R/W)
956 : // [31:0] : Trigger Data 1
957 : localparam MTDATA1 = 12'h7a1;
958 :
959 : // ----------------------------------------------------------------------
960 : // MTDATA2 (R/W)
961 : // [31:0] : Trigger Data 2
962 : localparam MTDATA2 = 12'h7a2;
963 :
964 : assign reset_delayed = reset_detect ^ reset_detected;
965 :
966 : // ----------------------------------------------------------------------
967 : // MPC halt
968 : // - can interact with debugger halt and v-v
969 :
970 : // fast ints in progress have priority
971 : assign mpc_debug_halt_req_sync = mpc_debug_halt_req_sync_raw & ~ext_int_freeze_d1;
972 :
973 : rvdffie #(16) mpvhalt_ff (.*, .clk(free_l2clk),
974 : .din({1'b1, reset_detect,
975 : nmi_int_sync, nmi_int_detected, nmi_lsu_load_type, nmi_lsu_store_type,
976 : mpc_debug_halt_req_sync, mpc_debug_run_req_sync,
977 : mpc_halt_state_ns, mpc_run_state_ns, debug_brkpt_status_ns,
978 : mpc_debug_halt_ack_ns, mpc_debug_run_ack_ns,
979 : dbg_halt_state_ns, dbg_run_state_ns,
980 : dec_tlu_mpc_halted_only_ns}),
981 : .dout({reset_detect, reset_detected,
982 : nmi_int_delayed, nmi_int_detected_f, nmi_lsu_load_type_f, nmi_lsu_store_type_f,
983 : mpc_debug_halt_req_sync_f, mpc_debug_run_req_sync_f,
984 : mpc_halt_state_f, mpc_run_state_f, debug_brkpt_status_f,
985 : mpc_debug_halt_ack_f, mpc_debug_run_ack_f,
986 : dbg_halt_state_f, dbg_run_state_f,
987 : dec_tlu_mpc_halted_only}));
988 :
989 : // turn level sensitive requests into pulses
990 : assign mpc_debug_halt_req_sync_pulse = mpc_debug_halt_req_sync & ~mpc_debug_halt_req_sync_f;
991 : assign mpc_debug_run_req_sync_pulse = mpc_debug_run_req_sync & ~mpc_debug_run_req_sync_f;
992 :
993 : // states
994 : assign mpc_halt_state_ns = (mpc_halt_state_f | mpc_debug_halt_req_sync_pulse | (reset_delayed & ~mpc_reset_run_req)) & ~mpc_debug_run_req_sync;
995 : assign mpc_run_state_ns = (mpc_run_state_f | (mpc_debug_run_req_sync_pulse & ~mpc_debug_run_ack_f)) & (internal_dbg_halt_mode_f & ~dcsr_single_step_running_f);
996 :
997 : // note, MPC halt can allow the jtag debugger to just start sending commands. When that happens, set the interal debugger halt state to prevent
998 : // MPC run from starting the core.
999 : assign dbg_halt_state_ns = (dbg_halt_state_f | (dbg_halt_req_final | dcsr_single_step_done_f | trigger_hit_dmode_r_d1 | ebreak_to_debug_mode_r_d1)) & ~dbg_resume_req;
1000 : assign dbg_run_state_ns = (dbg_run_state_f | dbg_resume_req) & (internal_dbg_halt_mode_f & ~dcsr_single_step_running_f);
1001 :
1002 : // tell dbg we are only MPC halted
1003 : assign dec_tlu_mpc_halted_only_ns = ~dbg_halt_state_f & mpc_halt_state_f;
1004 :
1005 : // this asserts from detection of bkpt until after we leave debug mode
1006 : assign debug_brkpt_valid = ebreak_to_debug_mode_r_d1 | trigger_hit_dmode_r_d1;
1007 : assign debug_brkpt_status_ns = (debug_brkpt_valid | debug_brkpt_status_f) & (internal_dbg_halt_mode & ~dcsr_single_step_running_f);
1008 :
1009 : // acks back to interface
1010 : assign mpc_debug_halt_ack_ns = (mpc_halt_state_f & internal_dbg_halt_mode_f & mpc_debug_halt_req_sync & core_empty) | (mpc_debug_halt_ack_f & mpc_debug_halt_req_sync);
1011 : assign mpc_debug_run_ack_ns = (mpc_debug_run_req_sync & ~internal_dbg_halt_mode & ~mpc_debug_halt_req_sync) | (mpc_debug_run_ack_f & mpc_debug_run_req_sync) ;
1012 :
1013 : // Pins
1014 : assign mpc_debug_halt_ack = mpc_debug_halt_ack_f;
1015 : assign mpc_debug_run_ack = mpc_debug_run_ack_f;
1016 : assign debug_brkpt_status = debug_brkpt_status_f;
1017 :
1018 : // DBG halt req is a pulse, fast ext int in progress has priority
1019 : assign dbg_halt_req_held_ns = (dbg_halt_req | dbg_halt_req_held) & ext_int_freeze_d1;
1020 : assign dbg_halt_req_final = (dbg_halt_req | dbg_halt_req_held) & ~ext_int_freeze_d1;
1021 :
1022 : // combine MPC and DBG halt requests
1023 : assign debug_halt_req = (dbg_halt_req_final | mpc_debug_halt_req_sync | (reset_delayed & ~mpc_reset_run_req)) & ~internal_dbg_halt_mode_f & ~ext_int_freeze_d1;
1024 :
1025 : assign debug_resume_req = ~debug_resume_req_f & // squash back to back resumes
1026 : ((mpc_run_state_ns & ~dbg_halt_state_ns) | // MPC run req
1027 : (dbg_run_state_ns & ~mpc_halt_state_ns)); // dbg request is a pulse
1028 :
1029 :
1030 : // HALT
1031 : // dbg/pmu/fw requests halt, service as soon as lsu is not blocking interrupts
1032 : assign take_halt = (debug_halt_req_f | pmu_fw_halt_req_f) & ~synchronous_flush_r & ~mret_r & ~halt_taken_f & ~dec_tlu_flush_noredir_r_d1 & ~take_reset;
1033 :
1034 : // hold after we take a halt, so we don't keep taking halts
1035 : assign halt_taken = (dec_tlu_flush_noredir_r_d1 & ~dec_tlu_flush_pause_r_d1 & ~take_ext_int_start_d1) | (halt_taken_f & ~dbg_tlu_halted_f & ~pmu_fw_tlu_halted_f & ~interrupt_valid_r_d1);
1036 :
1037 : // After doing halt flush (RFNPC) wait until core is idle before asserting a particular halt mode
1038 : // It takes a cycle for mb_empty to assert after a fetch, take_halt covers that cycle
1039 : assign core_empty = force_halt |
1040 : (lsu_idle_any & lsu_idle_any_f & ifu_miss_state_idle & ifu_miss_state_idle_f & ~debug_halt_req & ~debug_halt_req_d1 & ~dec_div_active);
1041 :
1042 : assign dec_tlu_core_empty = core_empty;
1043 :
1044 : //--------------------------------------------------------------------------------
1045 : // Debug start
1046 : //
1047 :
1048 : assign enter_debug_halt_req = (~internal_dbg_halt_mode_f & debug_halt_req) | dcsr_single_step_done_f | trigger_hit_dmode_r_d1 | ebreak_to_debug_mode_r_d1;
1049 :
1050 : // dbg halt state active from request until non-step resume
1051 : assign internal_dbg_halt_mode = debug_halt_req_ns | (internal_dbg_halt_mode_f & ~(debug_resume_req_f & ~dcsr[DCSR_STEP]));
1052 : // dbg halt can access csrs as long as we are not stepping
1053 : assign allow_dbg_halt_csr_write = internal_dbg_halt_mode_f & ~dcsr_single_step_running_f;
1054 :
1055 :
1056 : // hold debug_halt_req_ns high until we enter debug halt
1057 : assign debug_halt_req_ns = enter_debug_halt_req | (debug_halt_req_f & ~dbg_tlu_halted);
1058 :
1059 : assign dbg_tlu_halted = (debug_halt_req_f & core_empty & halt_taken) | (dbg_tlu_halted_f & ~debug_resume_req_f);
1060 :
1061 : assign resume_ack_ns = (debug_resume_req_f & dbg_tlu_halted_f & dbg_run_state_ns);
1062 :
1063 : assign dcsr_single_step_done = dec_tlu_i0_valid_r & ~dec_tlu_dbg_halted & dcsr[DCSR_STEP] & ~rfpc_i0_r;
1064 :
1065 : assign dcsr_single_step_running = (debug_resume_req_f & dcsr[DCSR_STEP]) | (dcsr_single_step_running_f & ~dcsr_single_step_done_f);
1066 :
1067 : assign dbg_cmd_done_ns = dec_tlu_i0_valid_r & dec_tlu_dbg_halted;
1068 :
1069 : // used to hold off commits after an in-pipe debug mode request (triggers, DCSR)
1070 : assign request_debug_mode_r = (trigger_hit_dmode_r | ebreak_to_debug_mode_r) | (request_debug_mode_r_d1 & ~dec_tlu_flush_lower_wb);
1071 :
1072 : assign request_debug_mode_done = (request_debug_mode_r_d1 | request_debug_mode_done_f) & ~dbg_tlu_halted_f;
1073 :
1074 : rvdffie #(18) halt_ff (.*, .clk(free_l2clk),
1075 : .din({dec_tlu_flush_noredir_r, halt_taken, lsu_idle_any, ifu_miss_state_idle, dbg_tlu_halted,
1076 : resume_ack_ns, debug_halt_req_ns, debug_resume_req, trigger_hit_dmode_r,
1077 : dcsr_single_step_done, debug_halt_req, dec_tlu_wr_pause_r, dec_pause_state,
1078 : request_debug_mode_r, request_debug_mode_done, dcsr_single_step_running, dec_tlu_flush_pause_r,
1079 : dbg_halt_req_held_ns}),
1080 : .dout({dec_tlu_flush_noredir_r_d1, halt_taken_f, lsu_idle_any_f, ifu_miss_state_idle_f, dbg_tlu_halted_f,
1081 : dec_tlu_resume_ack , debug_halt_req_f, debug_resume_req_f_raw, trigger_hit_dmode_r_d1,
1082 : dcsr_single_step_done_f, debug_halt_req_d1, dec_tlu_wr_pause_r_d1, dec_pause_state_f,
1083 : request_debug_mode_r_d1, request_debug_mode_done_f, dcsr_single_step_running_f, dec_tlu_flush_pause_r_d1,
1084 : dbg_halt_req_held}));
1085 :
1086 : // MPC run collides with DBG halt, fix it here
1087 : assign debug_resume_req_f = debug_resume_req_f_raw & ~dbg_halt_req;
1088 :
1089 : assign dec_tlu_debug_stall = debug_halt_req_f;
1090 : assign dec_tlu_dbg_halted = dbg_tlu_halted_f;
1091 : assign dec_tlu_debug_mode = internal_dbg_halt_mode_f;
1092 : assign dec_tlu_pmu_fw_halted = pmu_fw_tlu_halted_f;
1093 :
1094 : // kill fetch redirection on flush if going to halt, or if there's a fence during db-halt
1095 : assign dec_tlu_flush_noredir_r = take_halt | (fence_i_r & internal_dbg_halt_mode) | dec_tlu_flush_pause_r | (i0_trigger_hit_r & trigger_hit_dmode_r) | take_ext_int_start;
1096 :
1097 : assign dec_tlu_flush_extint = take_ext_int_start;
1098 :
1099 : // 1 cycle after writing the PAUSE counter, flush with noredir to idle F1-D.
1100 : assign dec_tlu_flush_pause_r = dec_tlu_wr_pause_r_d1 & ~interrupt_valid_r & ~take_ext_int_start;
1101 :
1102 : // detect end of pause counter and rfpc
1103 : assign pause_expired_r = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | soft_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | nmi_int_detected | ext_int_freeze_d1) & ~interrupt_valid_r_d1 & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f;
1104 :
1105 : assign dec_tlu_flush_leak_one_r = dec_tlu_flush_lower_r & dcsr[DCSR_STEP] & (dec_tlu_resume_ack | dcsr_single_step_running) & ~dec_tlu_flush_noredir_r;
1106 : assign dec_tlu_flush_err_r = dec_tlu_flush_lower_r & (ic_perr_r | iccm_sbecc_r);
1107 :
1108 : // If DM attempts to access an illegal CSR, send cmd_fail back
1109 : assign dec_dbg_cmd_done = dbg_cmd_done_ns;
1110 : assign dec_dbg_cmd_fail = illegal_r & dec_dbg_cmd_done;
1111 :
1112 :
1113 : //--------------------------------------------------------------------------------
1114 : //--------------------------------------------------------------------------------
1115 : // Triggers
1116 : //
1117 : localparam MTDATA1_DMODE = 9;
1118 : localparam MTDATA1_SEL = 7;
1119 : localparam MTDATA1_ACTION = 6;
1120 : localparam MTDATA1_CHAIN = 5;
1121 : localparam MTDATA1_MATCH = 4;
1122 : localparam MTDATA1_M_ENABLED = 3;
1123 : localparam MTDATA1_EXE = 2;
1124 : localparam MTDATA1_ST = 1;
1125 : localparam MTDATA1_LD = 0;
1126 :
1127 : // Prioritize trigger hits with other exceptions.
1128 : //
1129 : // Trigger should have highest priority except:
1130 : // - trigger is an execute-data and there is an inst_access exception (lsu triggers won't fire, inst. is nop'd by decode)
1131 : // - trigger is a store-data and there is a lsu_acc_exc or lsu_ma_exc.
1132 : assign trigger_execute[3:0] = {mtdata1_t3[MTDATA1_EXE], mtdata1_t2[MTDATA1_EXE], mtdata1_t1[MTDATA1_EXE], mtdata1_t0[MTDATA1_EXE]};
1133 : assign trigger_data[3:0] = {mtdata1_t3[MTDATA1_SEL], mtdata1_t2[MTDATA1_SEL], mtdata1_t1[MTDATA1_SEL], mtdata1_t0[MTDATA1_SEL]};
1134 : assign trigger_store[3:0] = {mtdata1_t3[MTDATA1_ST], mtdata1_t2[MTDATA1_ST], mtdata1_t1[MTDATA1_ST], mtdata1_t0[MTDATA1_ST]};
1135 :
1136 : // MSTATUS[MIE] needs to be on to take triggers unless the action is trigger to debug mode.
1137 : assign trigger_enabled[3:0] = {(mtdata1_t3[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t3[MTDATA1_M_ENABLED],
1138 : (mtdata1_t2[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t2[MTDATA1_M_ENABLED],
1139 : (mtdata1_t1[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t1[MTDATA1_M_ENABLED],
1140 : (mtdata1_t0[MTDATA1_ACTION] | mstatus[MSTATUS_MIE]) & mtdata1_t0[MTDATA1_M_ENABLED]};
1141 :
1142 : // iside exceptions are always in i0
1143 : assign i0_iside_trigger_has_pri_r[3:0] = ~( (trigger_execute[3:0] & trigger_data[3:0] & {4{inst_acc_r_raw}}) | // exe-data with inst_acc
1144 : ({4{exu_i0_br_error_r | exu_i0_br_start_error_r}})); // branch error in i0
1145 :
1146 : // lsu excs have to line up with their respective triggers since the lsu op can be i0
1147 : assign i0_lsu_trigger_has_pri_r[3:0] = ~(trigger_store[3:0] & trigger_data[3:0] & {4{lsu_i0_exc_r_raw}});
1148 :
1149 : // trigger hits have to be eval'd to cancel side effect lsu ops even though the pipe is already frozen
1150 : assign i0_trigger_eval_r = dec_tlu_i0_valid_r;
1151 :
1152 : assign i0trigger_qual_r[3:0] = {4{i0_trigger_eval_r}} & dec_tlu_packet_r.i0trigger[3:0] & i0_iside_trigger_has_pri_r[3:0] & i0_lsu_trigger_has_pri_r[3:0] & trigger_enabled[3:0];
1153 :
1154 : // Qual trigger hits
1155 : assign i0_trigger_r[3:0] = ~{4{dec_tlu_flush_lower_wb | dec_tlu_dbg_halted}} & i0trigger_qual_r[3:0];
1156 :
1157 : // chaining can mask raw trigger info
1158 : assign i0_trigger_chain_masked_r[3:0] = {i0_trigger_r[3] & (~mtdata1_t2[MTDATA1_CHAIN] | i0_trigger_r[2]),
1159 : i0_trigger_r[2] & (~mtdata1_t2[MTDATA1_CHAIN] | i0_trigger_r[3]),
1160 : i0_trigger_r[1] & (~mtdata1_t0[MTDATA1_CHAIN] | i0_trigger_r[0]),
1161 : i0_trigger_r[0] & (~mtdata1_t0[MTDATA1_CHAIN] | i0_trigger_r[1])};
1162 :
1163 : // This is the highest priority by this point.
1164 : assign i0_trigger_hit_raw_r = |i0_trigger_chain_masked_r[3:0];
1165 :
1166 : assign i0_trigger_hit_r = i0_trigger_hit_raw_r;
1167 :
1168 : // Actions include breakpoint, or dmode. Dmode is only possible if the DMODE bit is set.
1169 : // Otherwise, take a breakpoint.
1170 : assign trigger_action[3:0] = {mtdata1_t3[MTDATA1_ACTION] & mtdata1_t3[MTDATA1_DMODE],
1171 : mtdata1_t2[MTDATA1_ACTION] & mtdata1_t2[MTDATA1_DMODE] & ~mtdata1_t2[MTDATA1_CHAIN],
1172 : mtdata1_t1[MTDATA1_ACTION] & mtdata1_t1[MTDATA1_DMODE],
1173 : mtdata1_t0[MTDATA1_ACTION] & mtdata1_t0[MTDATA1_DMODE] & ~mtdata1_t0[MTDATA1_CHAIN]};
1174 :
1175 : // this is needed to set the HIT bit in the triggers
1176 : assign update_hit_bit_r[3:0] = ({4{|i0_trigger_r[3:0] & ~rfpc_i0_r}} & {i0_trigger_chain_masked_r[3], i0_trigger_r[2], i0_trigger_chain_masked_r[1], i0_trigger_r[0]});
1177 :
1178 : // action, 1 means dmode. Simultaneous triggers with at least 1 set for dmode force entire action to dmode.
1179 : assign i0_trigger_action_r = |(i0_trigger_chain_masked_r[3:0] & trigger_action[3:0]);
1180 :
1181 : assign trigger_hit_dmode_r = (i0_trigger_hit_r & i0_trigger_action_r);
1182 :
1183 : assign mepc_trigger_hit_sel_pc_r = i0_trigger_hit_r & ~trigger_hit_dmode_r;
1184 :
1185 :
1186 : //
1187 : // Debug end
1188 : //--------------------------------------------------------------------------------
1189 :
1190 : //----------------------------------------------------------------------
1191 : //
1192 : // Commit
1193 : //
1194 : //----------------------------------------------------------------------
1195 :
1196 :
1197 :
1198 : //--------------------------------------------------------------------------------
1199 : // External halt (not debug halt)
1200 : // - Fully interlocked handshake
1201 : // i_cpu_halt_req ____|--------------|_______________
1202 : // core_empty ---------------|___________
1203 : // o_cpu_halt_ack _________________|----|__________
1204 : // o_cpu_halt_status _______________|---------------------|_________
1205 : // i_cpu_run_req ______|----------|____
1206 : // o_cpu_run_ack ____________|------|________
1207 : //
1208 :
1209 :
1210 : // debug mode has priority, ignore PMU/FW halt/run while in debug mode
1211 : assign i_cpu_halt_req_sync_qual = i_cpu_halt_req_sync & ~dec_tlu_debug_mode & ~ext_int_freeze_d1;
1212 : assign i_cpu_run_req_sync_qual = i_cpu_run_req_sync & ~dec_tlu_debug_mode & pmu_fw_tlu_halted_f & ~ext_int_freeze_d1;
1213 :
1214 : rvdffie #(10) exthaltff (.*, .clk(free_l2clk), .din({i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, cpu_halt_status,
1215 : cpu_halt_ack, cpu_run_ack, internal_pmu_fw_halt_mode,
1216 : pmu_fw_halt_req_ns, pmu_fw_tlu_halted,
1217 : int_timer0_int_hold, int_timer1_int_hold}),
1218 : .dout({i_cpu_halt_req_d1, i_cpu_run_req_d1_raw, o_cpu_halt_status,
1219 : o_cpu_halt_ack, o_cpu_run_ack, internal_pmu_fw_halt_mode_f,
1220 : pmu_fw_halt_req_f, pmu_fw_tlu_halted_f,
1221 : int_timer0_int_hold_f, int_timer1_int_hold_f}));
1222 :
1223 : // only happens if we aren't in dgb_halt
1224 : assign ext_halt_pulse = i_cpu_halt_req_sync_qual & ~i_cpu_halt_req_d1;
1225 :
1226 : assign enter_pmu_fw_halt_req = ext_halt_pulse | fw_halt_req;
1227 :
1228 : assign pmu_fw_halt_req_ns = (enter_pmu_fw_halt_req | (pmu_fw_halt_req_f & ~pmu_fw_tlu_halted)) & ~debug_halt_req_f;
1229 :
1230 : assign internal_pmu_fw_halt_mode = pmu_fw_halt_req_ns | (internal_pmu_fw_halt_mode_f & ~i_cpu_run_req_d1 & ~debug_halt_req_f);
1231 :
1232 : // debug halt has priority
1233 : assign pmu_fw_tlu_halted = ((pmu_fw_halt_req_f & core_empty & halt_taken & ~enter_debug_halt_req) | (pmu_fw_tlu_halted_f & ~i_cpu_run_req_d1)) & ~debug_halt_req_f;
1234 :
1235 : assign cpu_halt_ack = (i_cpu_halt_req_d1 & pmu_fw_tlu_halted_f) | (o_cpu_halt_ack & i_cpu_halt_req_sync);
1236 : assign cpu_halt_status = (pmu_fw_tlu_halted_f & ~i_cpu_run_req_d1) | (o_cpu_halt_status & ~i_cpu_run_req_d1 & ~internal_dbg_halt_mode_f);
1237 : assign cpu_run_ack = (~pmu_fw_tlu_halted_f & i_cpu_run_req_sync) | (o_cpu_halt_status & i_cpu_run_req_d1_raw) | (o_cpu_run_ack & i_cpu_run_req_sync);
1238 : assign debug_mode_status = internal_dbg_halt_mode_f;
1239 : assign o_debug_mode_status = debug_mode_status;
1240 :
1241 : `ifdef RV_ASSERT_ON
1242 : assert_commit_while_halted: assert #0 (~(tlu_i0_commit_cmt & o_cpu_halt_status)) else $display("ERROR: Commiting while cpu_halt_status asserted!");
1243 : assert_flush_while_fastint: assert #0 (~((take_ext_int_start_d1 | take_ext_int_start_d2) & dec_tlu_flush_lower_r)) else $display("ERROR: TLU Flushing inside fast interrupt procedure!");
1244 : `endif
1245 :
1246 : // high priority interrupts can wakeup from external halt, so can unmasked timer interrupts
1247 : assign i_cpu_run_req_d1 = i_cpu_run_req_d1_raw | ((nmi_int_detected | timer_int_ready | soft_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | (mhwakeup & mhwakeup_ready)) & o_cpu_halt_status & ~i_cpu_halt_req_d1);
1248 :
1249 : //--------------------------------------------------------------------------------
1250 : //--------------------------------------------------------------------------------
1251 :
1252 : assign lsu_single_ecc_error_r = lsu_single_ecc_error_incr;
1253 :
1254 : assign lsu_error_pkt_addr_r[31:0] = lsu_error_pkt_r.addr[31:0];
1255 :
1256 :
1257 : assign lsu_exc_valid_r_raw = lsu_error_pkt_r.exc_valid & ~dec_tlu_flush_lower_wb;
1258 :
1259 : assign lsu_i0_exc_r_raw = lsu_error_pkt_r.exc_valid;
1260 :
1261 : assign lsu_i0_exc_r = lsu_i0_exc_r_raw & lsu_exc_valid_r_raw & ~i0_trigger_hit_r & ~rfpc_i0_r;
1262 :
1263 : assign lsu_exc_valid_r = lsu_i0_exc_r;
1264 :
1265 : assign lsu_exc_ma_r = lsu_i0_exc_r & ~lsu_error_pkt_r.exc_type;
1266 : assign lsu_exc_acc_r = lsu_i0_exc_r & lsu_error_pkt_r.exc_type;
1267 : assign lsu_exc_st_r = lsu_i0_exc_r & lsu_error_pkt_r.inst_type;
1268 :
1269 : // Single bit ECC errors on loads are RFNPC corrected, with the corrected data written to the GPR.
1270 : // LSU turns the load into a store and patches the data in the DCCM
1271 : assign lsu_i0_rfnpc_r = dec_tlu_i0_valid_r & ~i0_trigger_hit_r &
1272 : (~lsu_error_pkt_r.inst_type & lsu_error_pkt_r.single_ecc_error);
1273 :
1274 : // Final commit valids
1275 : `ifdef RV_USER_MODE
1276 : assign tlu_i0_commit_cmt = dec_tlu_i0_valid_r &
1277 : ~rfpc_i0_r &
1278 : ~lsu_i0_exc_r &
1279 : ~inst_acc_r &
1280 : ~dec_tlu_dbg_halted &
1281 : ~request_debug_mode_r_d1 &
1282 : ~i0_trigger_hit_r &
1283 : ~csr_acc_r;
1284 : `else
1285 : assign tlu_i0_commit_cmt = dec_tlu_i0_valid_r &
1286 : ~rfpc_i0_r &
1287 : ~lsu_i0_exc_r &
1288 : ~inst_acc_r &
1289 : ~dec_tlu_dbg_halted &
1290 : ~request_debug_mode_r_d1 &
1291 : ~i0_trigger_hit_r;
1292 : `endif
1293 :
1294 : // unified place to manage the killing of arch state writebacks
1295 : `ifdef RV_USER_MODE
1296 : assign tlu_i0_kill_writeb_r = rfpc_i0_r | lsu_i0_exc_r | inst_acc_r | (illegal_r & dec_tlu_dbg_halted) | i0_trigger_hit_r | csr_acc_r;
1297 : `else
1298 : assign tlu_i0_kill_writeb_r = rfpc_i0_r | lsu_i0_exc_r | inst_acc_r | (illegal_r & dec_tlu_dbg_halted) | i0_trigger_hit_r;
1299 : `endif
1300 : assign dec_tlu_i0_commit_cmt = tlu_i0_commit_cmt;
1301 :
1302 :
1303 : // refetch PC, microarch flush
1304 : // ic errors only in pipe0
1305 : assign rfpc_i0_r = ((dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1 & (exu_i0_br_error_r | exu_i0_br_start_error_r)) | // inst commit with rfpc
1306 : ((ic_perr_r | iccm_sbecc_r) & ~ext_int_freeze_d1)) & // ic/iccm without inst commit
1307 : ~i0_trigger_hit_r & // unless there's a trigger. Err signal to ic/iccm will assert anyway to clear the error.
1308 : ~lsu_i0_rfnpc_r;
1309 :
1310 : // From the indication of a iccm single bit error until the first commit or flush, maintain a repair state. In the repair state, rfnpc i0 commits.
1311 : assign iccm_repair_state_ns = iccm_sbecc_r | (iccm_repair_state_d1 & ~dec_tlu_flush_lower_r);
1312 :
1313 :
1314 : localparam MCPC = 12'h7c2;
1315 :
1316 : // this is a flush of last resort, meaning only assert it if there is no other flush happening.
1317 : assign iccm_repair_state_rfnpc = tlu_i0_commit_cmt & iccm_repair_state_d1 &
1318 : ~(ebreak_r | ecall_r | mret_r | take_reset | illegal_r | (dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCPC)));
1319 :
1320 : if(pt.BTB_ENABLE==1) begin
1321 : // go ahead and repair the branch error on other flushes, doesn't have to be the rfpc flush
1322 : assign dec_tlu_br0_error_r = exu_i0_br_error_r & dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1;
1323 : assign dec_tlu_br0_start_error_r = exu_i0_br_start_error_r & dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1;
1324 : assign dec_tlu_br0_v_r = exu_i0_br_valid_r & dec_tlu_i0_valid_r & ~tlu_flush_lower_r_d1 & (~exu_i0_br_mp_r | ~exu_pmu_i0_br_ataken);
1325 :
1326 :
1327 : assign dec_tlu_br0_r_pkt.hist[1:0] = exu_i0_br_hist_r[1:0];
1328 : assign dec_tlu_br0_r_pkt.br_error = dec_tlu_br0_error_r;
1329 : assign dec_tlu_br0_r_pkt.br_start_error = dec_tlu_br0_start_error_r;
1330 : assign dec_tlu_br0_r_pkt.valid = dec_tlu_br0_v_r;
1331 : assign dec_tlu_br0_r_pkt.way = exu_i0_br_way_r;
1332 : assign dec_tlu_br0_r_pkt.middle = exu_i0_br_middle_r;
1333 : end // if (pt.BTB_ENABLE==1)
1334 : else begin
1335 : assign dec_tlu_br0_error_r = '0;
1336 : assign dec_tlu_br0_start_error_r = '0;
1337 : assign dec_tlu_br0_v_r = '0;
1338 : assign dec_tlu_br0_r_pkt = '0;
1339 : end // else: !if(pt.BTB_ENABLE==1)
1340 :
1341 :
1342 : // only expect these in pipe 0
1343 : assign ebreak_r = (dec_tlu_packet_r.pmu_i0_itype == EBREAK) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~dcsr[DCSR_EBREAKM] & ~rfpc_i0_r;
1344 : assign ecall_r = (dec_tlu_packet_r.pmu_i0_itype == ECALL) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r;
1345 : `ifdef RV_USER_MODE
1346 : assign illegal_r = (((dec_tlu_packet_r.pmu_i0_itype == MRET) & priv_mode) | ~dec_tlu_packet_r.legal) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r;
1347 : assign mret_r = ( (dec_tlu_packet_r.pmu_i0_itype == MRET) & ~priv_mode ) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r;
1348 : `else
1349 : assign illegal_r = ~dec_tlu_packet_r.legal & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r;
1350 : assign mret_r = (dec_tlu_packet_r.pmu_i0_itype == MRET) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r;
1351 : `endif
1352 : // fence_i includes debug only fence_i's
1353 : assign fence_i_r = (dec_tlu_packet_r.fence_i & dec_tlu_i0_valid_r & ~i0_trigger_hit_r) & ~rfpc_i0_r;
1354 : assign ic_perr_r = ifu_ic_error_start_f & ~ext_int_freeze_d1 & (~internal_dbg_halt_mode_f | dcsr_single_step_running) & ~internal_pmu_fw_halt_mode_f;
1355 : assign iccm_sbecc_r = ifu_iccm_rd_ecc_single_err_f & ~ext_int_freeze_d1 & (~internal_dbg_halt_mode_f | dcsr_single_step_running) & ~internal_pmu_fw_halt_mode_f;
1356 : assign inst_acc_r_raw = dec_tlu_packet_r.icaf & dec_tlu_i0_valid_r;
1357 : assign inst_acc_r = inst_acc_r_raw & ~rfpc_i0_r & ~i0_trigger_hit_r;
1358 : assign inst_acc_second_r = dec_tlu_packet_r.icaf_second;
1359 :
1360 : assign ebreak_to_debug_mode_r = (dec_tlu_packet_r.pmu_i0_itype == EBREAK) & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & dcsr[DCSR_EBREAKM] & ~rfpc_i0_r;
1361 :
1362 : rvdff #(1) exctype_wb_ff (.*, .clk(e4e5_clk),
1363 : .din (ebreak_to_debug_mode_r ),
1364 : .dout(ebreak_to_debug_mode_r_d1));
1365 :
1366 : assign dec_tlu_fence_i_r = fence_i_r;
1367 :
1368 : `ifdef RV_USER_MODE
1369 :
1370 : // CSR access
1371 : // Address bits 9:8 == 2'b00 indicate unprivileged / user-level CSR
1372 : assign csr_wr_usr_r = ~|dec_csr_wraddr_r[9:8];
1373 : assign csr_rd_usr_r = ~|dec_csr_rdaddr_r[9:8];
1374 :
1375 : // CSR access error
1376 : // cycle and instret CSR unprivileged access is controller by bits in mcounteren CSR
1377 0 : logic csr_wr_acc_r;
1378 568 : logic csr_rd_acc_r;
1379 :
1380 : assign csr_wr_acc_r = csr_wr_usr_r & (
1381 : ((dec_csr_wraddr_r[11:0] == CYCLEL) & mcounteren[MCOUNTEREN_CY]) |
1382 : ((dec_csr_wraddr_r[11:0] == CYCLEH) & mcounteren[MCOUNTEREN_CY]) |
1383 : ((dec_csr_wraddr_r[11:0] == INSTRETL) & mcounteren[MCOUNTEREN_IR]) |
1384 : ((dec_csr_wraddr_r[11:0] == INSTRETH) & mcounteren[MCOUNTEREN_IR]) |
1385 : ((dec_csr_wraddr_r[11:0] == HPMC3) & mcounteren[MCOUNTEREN_HPM3]) |
1386 : ((dec_csr_wraddr_r[11:0] == HPMC3H) & mcounteren[MCOUNTEREN_HPM3]) |
1387 : ((dec_csr_wraddr_r[11:0] == HPMC4) & mcounteren[MCOUNTEREN_HPM4]) |
1388 : ((dec_csr_wraddr_r[11:0] == HPMC4H) & mcounteren[MCOUNTEREN_HPM4]) |
1389 : ((dec_csr_wraddr_r[11:0] == HPMC5) & mcounteren[MCOUNTEREN_HPM5]) |
1390 : ((dec_csr_wraddr_r[11:0] == HPMC5H) & mcounteren[MCOUNTEREN_HPM5]) |
1391 : ((dec_csr_wraddr_r[11:0] == HPMC6) & mcounteren[MCOUNTEREN_HPM6]) |
1392 : ((dec_csr_wraddr_r[11:0] == HPMC6H) & mcounteren[MCOUNTEREN_HPM6]));
1393 :
1394 : assign csr_rd_acc_r = csr_rd_usr_r & (
1395 : ((dec_csr_rdaddr_r[11:0] == CYCLEL) & mcounteren[MCOUNTEREN_CY]) |
1396 : ((dec_csr_rdaddr_r[11:0] == CYCLEH) & mcounteren[MCOUNTEREN_CY]) |
1397 : ((dec_csr_rdaddr_r[11:0] == INSTRETL) & mcounteren[MCOUNTEREN_IR]) |
1398 : ((dec_csr_rdaddr_r[11:0] == INSTRETH) & mcounteren[MCOUNTEREN_IR]) |
1399 : ((dec_csr_rdaddr_r[11:0] == HPMC3) & mcounteren[MCOUNTEREN_HPM3]) |
1400 : ((dec_csr_rdaddr_r[11:0] == HPMC3H) & mcounteren[MCOUNTEREN_HPM3]) |
1401 : ((dec_csr_rdaddr_r[11:0] == HPMC4) & mcounteren[MCOUNTEREN_HPM4]) |
1402 : ((dec_csr_rdaddr_r[11:0] == HPMC4H) & mcounteren[MCOUNTEREN_HPM4]) |
1403 : ((dec_csr_rdaddr_r[11:0] == HPMC5) & mcounteren[MCOUNTEREN_HPM5]) |
1404 : ((dec_csr_rdaddr_r[11:0] == HPMC5H) & mcounteren[MCOUNTEREN_HPM5]) |
1405 : ((dec_csr_rdaddr_r[11:0] == HPMC6) & mcounteren[MCOUNTEREN_HPM6]) |
1406 : ((dec_csr_rdaddr_r[11:0] == HPMC6H) & mcounteren[MCOUNTEREN_HPM6]));
1407 :
1408 : assign csr_acc_r = priv_mode & dec_tlu_i0_valid_r & ~i0_trigger_hit_r & ~rfpc_i0_r & (
1409 : (dec_tlu_packet_r.pmu_i0_itype == CSRREAD) & ~csr_rd_acc_r |
1410 : (dec_tlu_packet_r.pmu_i0_itype == CSRWRITE) & ~csr_wr_acc_r |
1411 : (dec_tlu_packet_r.pmu_i0_itype == CSRRW) & ~csr_rd_acc_r & ~csr_wr_acc_r);
1412 :
1413 : `endif
1414 :
1415 : //
1416 : // Exceptions
1417 : //
1418 : // - MEPC <- PC
1419 : // - PC <- MTVEC, assert flush_lower
1420 : // - MCAUSE <- cause
1421 : // - MSCAUSE <- secondary cause
1422 : // - MTVAL <-
1423 : // - MPIE <- MIE
1424 : // - MIE <- 0
1425 : //
1426 : `ifdef RV_USER_MODE
1427 : assign i0_exception_valid_r = (ebreak_r | ecall_r | illegal_r | inst_acc_r | csr_acc_r) & ~rfpc_i0_r & ~dec_tlu_dbg_halted;
1428 : `else
1429 : assign i0_exception_valid_r = (ebreak_r | ecall_r | illegal_r | inst_acc_r) & ~rfpc_i0_r & ~dec_tlu_dbg_halted;
1430 : `endif
1431 :
1432 : // Cause:
1433 : //
1434 : // 0x2 : illegal
1435 : // 0x3 : breakpoint
1436 : // 0x8 : Environment call U-mode (if U-mode is enabled)
1437 : // 0xb : Environment call M-mode
1438 :
1439 :
1440 : assign exc_cause_r[4:0] = ( ({5{take_ext_int}} & 5'h0b) |
1441 : ({5{take_timer_int}} & 5'h07) |
1442 : ({5{take_soft_int}} & 5'h03) |
1443 : ({5{take_int_timer0_int}} & 5'h1d) |
1444 : ({5{take_int_timer1_int}} & 5'h1c) |
1445 : ({5{take_ce_int}} & 5'h1e) |
1446 : `ifdef RV_USER_MODE
1447 : ({5{illegal_r| csr_acc_r}} & 5'h02) |
1448 : ({5{ecall_r & priv_mode}} & 5'h08) |
1449 : ({5{ecall_r & ~priv_mode}} & 5'h0b) |
1450 : `else
1451 : ({5{illegal_r}} & 5'h02) |
1452 : ({5{ecall_r}} & 5'h0b) |
1453 : `endif
1454 : ({5{inst_acc_r}} & 5'h01) |
1455 : ({5{ebreak_r | i0_trigger_hit_r}} & 5'h03) |
1456 : ({5{lsu_exc_ma_r & ~lsu_exc_st_r}} & 5'h04) |
1457 : ({5{lsu_exc_acc_r & ~lsu_exc_st_r}} & 5'h05) |
1458 : ({5{lsu_exc_ma_r & lsu_exc_st_r}} & 5'h06) |
1459 : ({5{lsu_exc_acc_r & lsu_exc_st_r}} & 5'h07)
1460 : ) & ~{5{take_nmi}};
1461 :
1462 : //
1463 : // Interrupts
1464 : //
1465 : // exceptions that are committed have already happened and will cause an int at E4 to wait a cycle
1466 : // or more if MSTATUS[MIE] is cleared.
1467 : //
1468 : // -in priority order, highest to lowest
1469 : // -single cycle window where a csr write to MIE/MSTATUS is at E4 when the other conditions for externals are met.
1470 : // Hold off externals for a cycle to make sure we are consistent with what was just written
1471 : assign mhwakeup_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MEIP] & mie_ns[MIE_MEIE];
1472 : assign ext_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MEIP] & mie_ns[MIE_MEIE] & ~ignore_ext_int_due_to_lsu_stall;
1473 : assign ce_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MCEIP] & mie_ns[MIE_MCEIE];
1474 : assign soft_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MSIP] & mie_ns[MIE_MSIE];
1475 : assign timer_int_ready = ~dec_csr_stall_int_ff & mstatus_mie_ns & mip[MIP_MTIP] & mie_ns[MIE_MTIE];
1476 :
1477 : // MIP for internal timers pulses for 1 clock, resets the timer counter. Mip won't hold past the various stall conditions.
1478 : assign int_timer0_int_possible = mstatus_mie_ns & mie_ns[MIE_MITIE0];
1479 : assign int_timer0_int_ready = mip[MIP_MITIP0] & int_timer0_int_possible;
1480 : assign int_timer1_int_possible = mstatus_mie_ns & mie_ns[MIE_MITIE1];
1481 : assign int_timer1_int_ready = mip[MIP_MITIP1] & int_timer1_int_possible;
1482 :
1483 : // Internal timers pulse and reset. If core is PMU/FW halted, the pulse will cause an exit from halt, but won't stick around
1484 : // Make it sticky, also for 1 cycle stall conditions.
1485 : assign int_timer_stalled = dec_csr_stall_int_ff | synchronous_flush_r | exc_or_int_valid_r_d1 | mret_r;
1486 :
1487 : assign int_timer0_int_hold = (int_timer0_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer0_int_possible & int_timer0_int_hold_f & ~interrupt_valid_r & ~take_ext_int_start & ~internal_dbg_halt_mode_f);
1488 : assign int_timer1_int_hold = (int_timer1_int_ready & (pmu_fw_tlu_halted_f | int_timer_stalled)) | (int_timer1_int_possible & int_timer1_int_hold_f & ~interrupt_valid_r & ~take_ext_int_start & ~internal_dbg_halt_mode_f);
1489 :
1490 :
1491 : assign internal_dbg_halt_timers = internal_dbg_halt_mode_f & ~dcsr_single_step_running;
1492 :
1493 :
1494 : assign block_interrupts = ( (internal_dbg_halt_mode & (~dcsr_single_step_running | dec_tlu_i0_valid_r)) | // No ints in db-halt unless we are single stepping
1495 : internal_pmu_fw_halt_mode | i_cpu_halt_req_d1 |// No ints in PMU/FW halt. First we exit halt
1496 : take_nmi | // NMI is top priority
1497 : ebreak_to_debug_mode_r | // Heading to debug mode, hold off ints
1498 : synchronous_flush_r | // exception flush this cycle
1499 : exc_or_int_valid_r_d1 | // ext/int past cycle (need time for MIE to update)
1500 : mret_r | // mret in progress, for cases were ISR enables ints before mret
1501 : ext_int_freeze_d1 // Fast interrupt in progress (optional)
1502 : );
1503 :
1504 :
1505 : if (pt.FAST_INTERRUPT_REDIRECT) begin
1506 :
1507 :
1508 : assign take_ext_int_start = ext_int_ready & ~block_interrupts;
1509 :
1510 : assign ext_int_freeze = take_ext_int_start | take_ext_int_start_d1 | take_ext_int_start_d2 | take_ext_int_start_d3;
1511 : assign take_ext_int = take_ext_int_start_d3 & ~|lsu_fir_error[1:0];
1512 : assign fast_int_meicpct = csr_meicpct & dec_csr_any_unq_d; // MEICPCT becomes illegal if fast ints are enabled
1513 :
1514 : assign ignore_ext_int_due_to_lsu_stall = lsu_fastint_stall_any;
1515 : end
1516 : else begin
1517 : assign take_ext_int_start = 1'b0;
1518 : assign ext_int_freeze = 1'b0;
1519 : assign ext_int_freeze_d1 = 1'b0;
1520 : assign take_ext_int_start_d1 = 1'b0;
1521 : assign take_ext_int_start_d2 = 1'b0;
1522 : assign take_ext_int_start_d3 = 1'b0;
1523 : assign fast_int_meicpct = 1'b0;
1524 : assign ignore_ext_int_due_to_lsu_stall = 1'b0;
1525 :
1526 : assign take_ext_int = ext_int_ready & ~block_interrupts;
1527 : end
1528 :
1529 : assign take_ce_int = ce_int_ready & ~ext_int_ready & ~block_interrupts;
1530 : assign take_soft_int = soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
1531 : assign take_timer_int = timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
1532 : assign take_int_timer0_int = (int_timer0_int_ready | int_timer0_int_hold_f) & int_timer0_int_possible & ~dec_csr_stall_int_ff &
1533 : ~timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
1534 : assign take_int_timer1_int = (int_timer1_int_ready | int_timer1_int_hold_f) & int_timer1_int_possible & ~dec_csr_stall_int_ff &
1535 : ~(int_timer0_int_ready | int_timer0_int_hold_f) & ~timer_int_ready & ~soft_int_ready & ~ext_int_ready & ~ce_int_ready & ~block_interrupts;
1536 :
1537 : assign take_reset = reset_delayed & mpc_reset_run_req;
1538 : assign take_nmi = nmi_int_detected & ~internal_pmu_fw_halt_mode & (~internal_dbg_halt_mode | (dcsr_single_step_running_f & dcsr[DCSR_STEPIE] & ~dec_tlu_i0_valid_r & ~dcsr_single_step_done_f)) &
1539 : ~synchronous_flush_r & ~mret_r & ~take_reset & ~ebreak_to_debug_mode_r & (~ext_int_freeze_d1 | (take_ext_int_start_d3 & |lsu_fir_error[1:0]));
1540 :
1541 : assign interrupt_valid_r = take_ext_int | take_timer_int | take_soft_int | take_nmi | take_ce_int | take_int_timer0_int | take_int_timer1_int;
1542 :
1543 :
1544 : // Compute interrupt path:
1545 : // If vectored async is set in mtvec, flush path for interrupts is MTVEC + (4 * CAUSE);
1546 : assign vectored_path[31:1] = {mtvec[30:1], 1'b0} + {25'b0, exc_cause_r[4:0], 1'b0};
1547 : assign interrupt_path[31:1] = take_nmi ? nmi_vec[31:1] : ((mtvec[0] == 1'b1) ? vectored_path[31:1] : {mtvec[30:1], 1'b0});
1548 :
1549 : assign sel_npc_r = lsu_i0_rfnpc_r | fence_i_r | iccm_repair_state_rfnpc | (i_cpu_run_req_d1 & ~interrupt_valid_r) | (rfpc_i0_r & ~dec_tlu_i0_valid_r);
1550 : assign sel_npc_resume = (i_cpu_run_req_d1 & pmu_fw_tlu_halted_f) | pause_expired_r;
1551 :
1552 : assign sel_fir_addr = take_ext_int_start_d3 & ~|lsu_fir_error[1:0];
1553 :
1554 : assign synchronous_flush_r = i0_exception_valid_r | // exception
1555 : rfpc_i0_r | // rfpc
1556 : lsu_exc_valid_r | // lsu exception in either pipe 0 or pipe 1
1557 : fence_i_r | // fence, a rfnpc
1558 : lsu_i0_rfnpc_r | // lsu dccm sb ecc
1559 : iccm_repair_state_rfnpc | // Iccm sb ecc
1560 : debug_resume_req_f | // resume from debug halt, fetch the dpc
1561 : sel_npc_resume | // resume from pmu/fw halt, or from pause and fetch the NPC
1562 : dec_tlu_wr_pause_r_d1 | // flush at start of pause
1563 : i0_trigger_hit_r; // trigger hit, ebreak or goto debug mode
1564 :
1565 : assign tlu_flush_lower_r = interrupt_valid_r | mret_r | synchronous_flush_r | take_halt | take_reset | take_ext_int_start;
1566 :
1567 : assign tlu_flush_path_r[31:1] = take_reset ? rst_vec[31:1] :
1568 :
1569 : ( ({31{sel_fir_addr}} & lsu_fir_addr[31:1]) |
1570 : ({31{~take_nmi & sel_npc_r}} & npc_r[31:1]) |
1571 : ({31{~take_nmi & rfpc_i0_r & dec_tlu_i0_valid_r & ~sel_npc_r}} & dec_tlu_i0_pc_r[31:1]) |
1572 : ({31{interrupt_valid_r & ~sel_fir_addr}} & interrupt_path[31:1]) |
1573 : ({31{(i0_exception_valid_r | lsu_exc_valid_r |
1574 : (i0_trigger_hit_r & ~trigger_hit_dmode_r)) & ~interrupt_valid_r & ~sel_fir_addr}} & {mtvec[30:1],1'b0}) |
1575 : ({31{~take_nmi & mret_r}} & mepc[31:1]) |
1576 : ({31{~take_nmi & debug_resume_req_f}} & dpc[31:1]) |
1577 : ({31{~take_nmi & sel_npc_resume}} & npc_r_d1[31:1]) );
1578 :
1579 : rvdffpcie #(31) flush_lower_ff (.*, .en(tlu_flush_lower_r),
1580 : .din({tlu_flush_path_r[31:1]}),
1581 : .dout({tlu_flush_path_r_d1[31:1]}));
1582 :
1583 : assign dec_tlu_flush_lower_wb = tlu_flush_lower_r_d1;
1584 : assign dec_tlu_flush_lower_r = tlu_flush_lower_r;
1585 : assign dec_tlu_flush_path_r[31:1] = tlu_flush_path_r[31:1];
1586 :
1587 :
1588 : // this is used to capture mepc, etc.
1589 : assign exc_or_int_valid_r = lsu_exc_valid_r | i0_exception_valid_r | interrupt_valid_r | (i0_trigger_hit_r & ~trigger_hit_dmode_r);
1590 :
1591 :
1592 : rvdffie #(12) excinfo_wb_ff (.*,
1593 : .din({interrupt_valid_r, i0_exception_valid_r, exc_or_int_valid_r,
1594 : exc_cause_r[4:0], tlu_i0_commit_cmt & ~illegal_r, i0_trigger_hit_r,
1595 : take_nmi, pause_expired_r }),
1596 : .dout({interrupt_valid_r_d1, i0_exception_valid_r_d1, exc_or_int_valid_r_d1,
1597 : exc_cause_wb[4:0], i0_valid_wb, trigger_hit_r_d1,
1598 : take_nmi_r_d1, pause_expired_wb}));
1599 : `ifdef RV_USER_MODE
1600 :
1601 : //
1602 : // Privilege mode
1603 : //
1604 : assign priv_mode_ns = (mret_r & mstatus[MSTATUS_MPP]) |
1605 : (exc_or_int_valid_r & 1'b0 ) |
1606 : ((~mret_r & ~exc_or_int_valid_r) & priv_mode);
1607 :
1608 : rvdff #(1) priv_ff (
1609 : .clk (free_l2clk),
1610 : .rst_l (rst_l),
1611 : .din (priv_mode_ns),
1612 : .dout (priv_mode)
1613 : );
1614 :
1615 : `endif
1616 :
1617 : //----------------------------------------------------------------------
1618 : //
1619 : // CSRs
1620 : //
1621 : //----------------------------------------------------------------------
1622 :
1623 : // ----------------------------------------------------------------------
1624 : // MSTATUS (RW)
1625 : // [17] MPRV : Modify PRiVilege (if enabled in config)
1626 : // [12:11] MPP : Prior priv level, either 2'b11 (machine) or 2'b00 (user)
1627 : // [7] MPIE : Int enable previous [1]
1628 : // [3] MIE : Int enable [0]
1629 :
1630 :
1631 : //When executing a MRET instruction, supposing MPP holds the value 3, MIE
1632 : //is set to MPIE; the privilege mode is changed to 3; MPIE is set to 1; and MPP is set to 3
1633 : `ifdef RV_USER_MODE
1634 : assign dec_csr_wen_r_mod = dec_csr_wen_r & ~i0_trigger_hit_r & ~rfpc_i0_r & ~csr_acc_r;
1635 : `else
1636 : assign dec_csr_wen_r_mod = dec_csr_wen_r & ~i0_trigger_hit_r & ~rfpc_i0_r;
1637 : `endif
1638 :
1639 : assign wr_mstatus_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSTATUS);
1640 :
1641 : // set this even if we don't go to fwhalt due to debug halt. We committed the inst, so ...
1642 : assign set_mie_pmu_fw_halt = ~mpmc_b_ns[1] & fw_halt_req;
1643 :
1644 : `ifdef RV_USER_MODE
1645 : // mstatus[2] / mstatus_ns[2] actually stores inverse of the MPP field !
1646 : assign mstatus_ns[3:0] = ( ({4{~wr_mstatus_r & exc_or_int_valid_r}} & {mstatus[MSTATUS_MPRV], priv_mode, mstatus[MSTATUS_MIE], 1'b0}) |
1647 : ({4{ wr_mstatus_r & exc_or_int_valid_r}} & {mstatus[MSTATUS_MPRV], priv_mode, dec_csr_wrdata_r[3], 1'b0}) |
1648 : ({4{mret_r & ~exc_or_int_valid_r}} & {mstatus[MSTATUS_MPRV] & ~mstatus[MSTATUS_MPP], 1'b1, 1'b1, mstatus[MSTATUS_MPIE]}) |
1649 : ({4{set_mie_pmu_fw_halt}} & {mstatus[3:2], mstatus[MSTATUS_MPIE], 1'b1}) |
1650 : ({4{wr_mstatus_r & ~exc_or_int_valid_r}} & {dec_csr_wrdata_r[17], ~dec_csr_wrdata_r[12], dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]}) |
1651 : ({4{~wr_mstatus_r & ~exc_or_int_valid_r & ~mret_r & ~set_mie_pmu_fw_halt}} & mstatus[3:0]) );
1652 :
1653 : // gate MIE if we are single stepping and DCSR[STEPIE] is off
1654 : // in user mode machine interrupts are always enabled as per RISC-V privilege spec (chapter 3.1.6.1).
1655 : assign mstatus_mie_ns = (priv_mode | mstatus[MSTATUS_MIE]) & (~dcsr_single_step_running_f | dcsr[DCSR_STEPIE]);
1656 :
1657 : // set effective privilege mode according to MPRV and MPP
1658 : assign priv_mode_eff = ( mstatus[MSTATUS_MPRV] & mstatus[MSTATUS_MPP]) | // MPRV=1, use MPP
1659 : (~mstatus[MSTATUS_MPRV] & priv_mode); // MPRV=0, use current operating mode
1660 :
1661 : `else
1662 :
1663 : assign mstatus_ns[1:0] = ( ({2{~wr_mstatus_r & exc_or_int_valid_r}} & {mstatus[MSTATUS_MIE], 1'b0}) |
1664 : ({2{ wr_mstatus_r & exc_or_int_valid_r}} & {dec_csr_wrdata_r[3], 1'b0}) |
1665 : ({2{mret_r & ~exc_or_int_valid_r}} & {1'b1, mstatus[MSTATUS_MPIE]}) |
1666 : ({2{set_mie_pmu_fw_halt}} & {mstatus[MSTATUS_MPIE], 1'b1}) |
1667 : ({2{wr_mstatus_r & ~exc_or_int_valid_r}} & {dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]}) |
1668 : ({2{~wr_mstatus_r & ~exc_or_int_valid_r & ~mret_r & ~set_mie_pmu_fw_halt}} & mstatus[1:0]) );
1669 :
1670 : assign mstatus_mie_ns = mstatus[MSTATUS_MIE] & (~dcsr_single_step_running_f | dcsr[DCSR_STEPIE]);
1671 :
1672 : `endif
1673 :
1674 : // ----------------------------------------------------------------------
1675 : // MTVEC (RW)
1676 : // [31:2] BASE : Trap vector base address
1677 : // [1] - Reserved, not implemented, reads zero
1678 : // [0] MODE : 0 = Direct, 1 = Asyncs are vectored to BASE + (4 * CAUSE)
1679 :
1680 : assign wr_mtvec_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTVEC);
1681 : assign mtvec_ns[30:0] = {dec_csr_wrdata_r[31:2], dec_csr_wrdata_r[0]} ;
1682 : rvdffe #(31) mtvec_ff (.*, .en(wr_mtvec_r), .din(mtvec_ns[30:0]), .dout(mtvec[30:0]));
1683 :
1684 : // ----------------------------------------------------------------------
1685 : // MIP (RW)
1686 : //
1687 : // [30] MCEIP : (RO) M-Mode Correctable Error interrupt pending
1688 : // [29] MITIP0 : (RO) M-Mode Internal Timer0 interrupt pending
1689 : // [28] MITIP1 : (RO) M-Mode Internal Timer1 interrupt pending
1690 : // [11] MEIP : (RO) M-Mode external interrupt pending
1691 : // [7] MTIP : (RO) M-Mode timer interrupt pending
1692 : // [3] MSIP : (RO) M-Mode software interrupt pending
1693 :
1694 : assign ce_int = (mdccme_ce_req | miccme_ce_req | mice_ce_req);
1695 :
1696 : assign mip_ns[5:0] = {ce_int, dec_timer_t0_pulse, dec_timer_t1_pulse, mexintpend, timer_int_sync, soft_int_sync};
1697 :
1698 : // ----------------------------------------------------------------------
1699 : // MIE (RW)
1700 : // [30] MCEIE : (RO) M-Mode Correctable Error interrupt enable
1701 : // [29] MITIE0 : (RO) M-Mode Internal Timer0 interrupt enable
1702 : // [28] MITIE1 : (RO) M-Mode Internal Timer1 interrupt enable
1703 : // [11] MEIE : (RW) M-Mode external interrupt enable
1704 : // [7] MTIE : (RW) M-Mode timer interrupt enable
1705 : // [3] MSIE : (RW) M-Mode software interrupt enable
1706 :
1707 : assign wr_mie_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MIE);
1708 : assign mie_ns[5:0] = wr_mie_r ? {dec_csr_wrdata_r[30:28], dec_csr_wrdata_r[11], dec_csr_wrdata_r[7], dec_csr_wrdata_r[3]} : mie[5:0];
1709 : rvdff #(6) mie_ff (.*, .clk(csr_wr_clk), .din(mie_ns[5:0]), .dout(mie[5:0]));
1710 :
1711 :
1712 : // ----------------------------------------------------------------------
1713 : // MCYCLEL (RW)
1714 : // [31:0] : Lower Cycle count
1715 :
1716 : assign kill_ebreak_count_r = ebreak_to_debug_mode_r & dcsr[DCSR_STOPC];
1717 :
1718 : assign wr_mcyclel_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCYCLEL);
1719 :
1720 : assign mcyclel_cout_in = ~(kill_ebreak_count_r | (dec_tlu_dbg_halted & dcsr[DCSR_STOPC]) | dec_tlu_pmu_fw_halted | mcountinhibit[0]);
1721 :
1722 : // split for power
1723 : assign {mcyclela_cout, mcyclel_inc[7:0]} = mcyclel[7:0] + {7'b0, 1'b1};
1724 : assign {mcyclel_cout, mcyclel_inc[31:8]} = mcyclel[31:8] + {23'b0, mcyclela_cout};
1725 :
1726 : assign mcyclel_ns[31:0] = wr_mcyclel_r ? dec_csr_wrdata_r[31:0] : mcyclel_inc[31:0];
1727 :
1728 : rvdffe #(24) mcyclel_bff (.*, .clk(free_l2clk), .en(wr_mcyclel_r | (mcyclela_cout & mcyclel_cout_in)), .din(mcyclel_ns[31:8]), .dout(mcyclel[31:8]));
1729 : rvdffe #(8) mcyclel_aff (.*, .clk(free_l2clk), .en(wr_mcyclel_r | mcyclel_cout_in), .din(mcyclel_ns[7:0]), .dout(mcyclel[7:0]));
1730 :
1731 : // ----------------------------------------------------------------------
1732 : // MCYCLEH (RW)
1733 : // [63:32] : Higher Cycle count
1734 : // Chained with mcyclel. Note: mcyclel overflow due to a mcycleh write gets ignored.
1735 :
1736 : assign wr_mcycleh_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCYCLEH);
1737 :
1738 : assign mcycleh_inc[31:0] = mcycleh[31:0] + {31'b0, mcyclel_cout_f};
1739 : assign mcycleh_ns[31:0] = wr_mcycleh_r ? dec_csr_wrdata_r[31:0] : mcycleh_inc[31:0];
1740 :
1741 : rvdffe #(32) mcycleh_ff (.*, .clk(free_l2clk), .en(wr_mcycleh_r | mcyclel_cout_f), .din(mcycleh_ns[31:0]), .dout(mcycleh[31:0]));
1742 :
1743 : // ----------------------------------------------------------------------
1744 : // MINSTRETL (RW)
1745 : // [31:0] : Lower Instruction retired count
1746 : // From the spec "Some CSRs, such as the instructions retired counter, instret, may be modified as side effects
1747 : // of instruction execution. In these cases, if a CSR access instruction reads a CSR, it reads the
1748 : // value prior to the execution of the instruction. If a CSR access instruction writes a CSR, the
1749 : // update occurs after the execution of the instruction. In particular, a value written to instret by
1750 : // one instruction will be the value read by the following instruction (i.e., the increment of instret
1751 : // caused by the first instruction retiring happens before the write of the new value)."
1752 :
1753 : assign i0_valid_no_ebreak_ecall_r = dec_tlu_i0_valid_r & ~(ebreak_r | ecall_r | ebreak_to_debug_mode_r | illegal_r | mcountinhibit[2]);
1754 :
1755 : assign wr_minstretl_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MINSTRETL);
1756 :
1757 : assign {minstretl_couta, minstretl_inc[7:0]} = minstretl[7:0] + {7'b0,1'b1};
1758 : assign {minstretl_cout, minstretl_inc[31:8]} = minstretl[31:8] + {23'b0, minstretl_couta};
1759 :
1760 : assign minstret_enable = (i0_valid_no_ebreak_ecall_r & tlu_i0_commit_cmt) | wr_minstretl_r;
1761 :
1762 : assign minstretl_cout_ns = minstretl_cout & ~wr_minstreth_r & i0_valid_no_ebreak_ecall_r & ~dec_tlu_dbg_halted;
1763 :
1764 : assign minstretl_ns[31:0] = wr_minstretl_r ? dec_csr_wrdata_r[31:0] : minstretl_inc[31:0];
1765 : rvdffe #(24) minstretl_bff (.*, .en(wr_minstretl_r | (minstretl_couta & minstret_enable)),
1766 : .din(minstretl_ns[31:8]), .dout(minstretl[31:8]));
1767 : rvdffe #(8) minstretl_aff (.*, .en(minstret_enable),
1768 : .din(minstretl_ns[7:0]), .dout(minstretl[7:0]));
1769 :
1770 :
1771 : assign minstretl_read[31:0] = minstretl[31:0];
1772 : // ----------------------------------------------------------------------
1773 : // MINSTRETH (RW)
1774 : // [63:32] : Higher Instret count
1775 : // Chained with minstretl. Note: minstretl overflow due to a minstreth write gets ignored.
1776 :
1777 : assign wr_minstreth_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MINSTRETH);
1778 :
1779 : assign minstreth_inc[31:0] = minstreth[31:0] + {31'b0, minstretl_cout_f};
1780 : assign minstreth_ns[31:0] = wr_minstreth_r ? dec_csr_wrdata_r[31:0] : minstreth_inc[31:0];
1781 : rvdffe #(32) minstreth_ff (.*, .en((minstret_enable_f & minstretl_cout_f) | wr_minstreth_r), .din(minstreth_ns[31:0]), .dout(minstreth[31:0]));
1782 :
1783 : assign minstreth_read[31:0] = minstreth_inc[31:0];
1784 :
1785 : // ----------------------------------------------------------------------
1786 : // MSCRATCH (RW)
1787 : // [31:0] : Scratch register
1788 : assign wr_mscratch_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSCRATCH);
1789 :
1790 : rvdffe #(32) mscratch_ff (.*, .en(wr_mscratch_r), .din(dec_csr_wrdata_r[31:0]), .dout(mscratch[31:0]));
1791 :
1792 : // ----------------------------------------------------------------------
1793 : // MEPC (RW)
1794 : // [31:1] : Exception PC
1795 :
1796 : // NPC
1797 :
1798 : assign sel_exu_npc_r = ~dec_tlu_dbg_halted & ~tlu_flush_lower_r_d1 & dec_tlu_i0_valid_r;
1799 : assign sel_flush_npc_r = ~dec_tlu_dbg_halted & tlu_flush_lower_r_d1 & ~dec_tlu_flush_noredir_r_d1;
1800 : assign sel_hold_npc_r = ~sel_exu_npc_r & ~sel_flush_npc_r;
1801 :
1802 : assign npc_r[31:1] = ( ({31{sel_exu_npc_r}} & exu_npc_r[31:1]) |
1803 : ({31{~mpc_reset_run_req & reset_delayed}} & rst_vec[31:1]) | // init to reset vector for mpc halt on reset case
1804 : ({31{(sel_flush_npc_r)}} & tlu_flush_path_r_d1[31:1]) |
1805 : ({31{(sel_hold_npc_r)}} & npc_r_d1[31:1]) );
1806 :
1807 : rvdffpcie #(31) npwbc_ff (.*, .en(sel_exu_npc_r | sel_flush_npc_r | reset_delayed), .din(npc_r[31:1]), .dout(npc_r_d1[31:1]));
1808 :
1809 : // PC has to be captured for exceptions and interrupts. For MRET, we could execute it and then take an
1810 : // interrupt before the next instruction.
1811 : assign pc0_valid_r = ~dec_tlu_dbg_halted & dec_tlu_i0_valid_r;
1812 :
1813 : assign pc_r[31:1] = ( ({31{ pc0_valid_r}} & dec_tlu_i0_pc_r[31:1]) |
1814 : ({31{~pc0_valid_r}} & pc_r_d1[31:1]));
1815 :
1816 : rvdffpcie #(31) pwbc_ff (.*, .en(pc0_valid_r), .din(pc_r[31:1]), .dout(pc_r_d1[31:1]));
1817 :
1818 : assign wr_mepc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEPC);
1819 :
1820 : assign mepc_ns[31:1] = ( ({31{i0_exception_valid_r | lsu_exc_valid_r | mepc_trigger_hit_sel_pc_r}} & pc_r[31:1]) |
1821 : ({31{interrupt_valid_r}} & npc_r[31:1]) |
1822 : ({31{wr_mepc_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[31:1]) |
1823 : ({31{~wr_mepc_r & ~exc_or_int_valid_r}} & mepc[31:1]) );
1824 :
1825 :
1826 : rvdffe #(31) mepc_ff (.*, .en(i0_exception_valid_r | lsu_exc_valid_r | mepc_trigger_hit_sel_pc_r | interrupt_valid_r | wr_mepc_r), .din(mepc_ns[31:1]), .dout(mepc[31:1]));
1827 :
1828 : // ----------------------------------------------------------------------
1829 : // MCAUSE (RW)
1830 : // [31:0] : Exception Cause
1831 :
1832 : assign wr_mcause_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCAUSE);
1833 : assign mcause_sel_nmi_store = exc_or_int_valid_r & take_nmi & nmi_lsu_store_type;
1834 : assign mcause_sel_nmi_load = exc_or_int_valid_r & take_nmi & nmi_lsu_load_type;
1835 : assign mcause_sel_nmi_ext = exc_or_int_valid_r & take_nmi & take_ext_int_start_d3 & |lsu_fir_error[1:0] & ~nmi_int_detected_f;
1836 : // FIR value decoder
1837 : // 0 –no error
1838 : // 1 –uncorrectable ecc => f000_1000
1839 : // 2 –dccm region access error => f000_1001
1840 : // 3 –non dccm region access error => f000_1002
1841 : assign mcause_fir_error_type[1:0] = {&lsu_fir_error[1:0], lsu_fir_error[1] & ~lsu_fir_error[0]};
1842 :
1843 : assign mcause_ns[31:0] = ( ({32{mcause_sel_nmi_store}} & {32'hf000_0000}) |
1844 : ({32{mcause_sel_nmi_load}} & {32'hf000_0001}) |
1845 : ({32{mcause_sel_nmi_ext}} & {28'hf000_100, 2'b0, mcause_fir_error_type[1:0]}) |
1846 : ({32{exc_or_int_valid_r & ~take_nmi}} & {interrupt_valid_r, 26'b0, exc_cause_r[4:0]}) |
1847 : ({32{wr_mcause_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[31:0]) |
1848 : ({32{~wr_mcause_r & ~exc_or_int_valid_r}} & mcause[31:0]) );
1849 :
1850 : rvdffe #(32) mcause_ff (.*, .en(exc_or_int_valid_r | wr_mcause_r), .din(mcause_ns[31:0]), .dout(mcause[31:0]));
1851 : // ----------------------------------------------------------------------
1852 : // MSCAUSE (RW)
1853 : // [2:0] : Secondary exception Cause
1854 : assign wr_mscause_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSCAUSE);
1855 :
1856 : assign ifu_mscause[3:0] = (dec_tlu_packet_r.icaf_type[1:0] == 2'b00) ? 4'b1001 :
1857 : {2'b00 , dec_tlu_packet_r.icaf_type[1:0]} ;
1858 :
1859 : assign mscause_type[3:0] = ( ({4{lsu_i0_exc_r}} & lsu_error_pkt_r.mscause[3:0]) |
1860 : ({4{i0_trigger_hit_r}} & 4'b0001) |
1861 : ({4{ebreak_r}} & 4'b0010) |
1862 : ({4{inst_acc_r}} & ifu_mscause[3:0])
1863 : );
1864 :
1865 : assign mscause_ns[3:0] = ( ({4{exc_or_int_valid_r}} & mscause_type[3:0]) |
1866 : ({4{ wr_mscause_r & ~exc_or_int_valid_r}} & dec_csr_wrdata_r[3:0]) |
1867 : ({4{~wr_mscause_r & ~exc_or_int_valid_r}} & mscause[3:0])
1868 : );
1869 :
1870 : rvdff #(4) mscause_ff (.*, .clk(e4e5_int_clk), .din(mscause_ns[3:0]), .dout(mscause[3:0]));
1871 : // ----------------------------------------------------------------------
1872 : // MTVAL (RW)
1873 : // [31:0] : Exception address if relevant
1874 :
1875 : assign wr_mtval_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTVAL);
1876 : assign mtval_capture_pc_r = exc_or_int_valid_r & (ebreak_r | (inst_acc_r & ~inst_acc_second_r) | mepc_trigger_hit_sel_pc_r) & ~take_nmi;
1877 : assign mtval_capture_pc_plus2_r = exc_or_int_valid_r & (inst_acc_r & inst_acc_second_r) & ~take_nmi;
1878 : assign mtval_capture_inst_r = exc_or_int_valid_r & illegal_r & ~take_nmi;
1879 : assign mtval_capture_lsu_r = exc_or_int_valid_r & lsu_exc_valid_r & ~take_nmi;
1880 : assign mtval_clear_r = exc_or_int_valid_r & ~mtval_capture_pc_r & ~mtval_capture_inst_r & ~mtval_capture_lsu_r & ~mepc_trigger_hit_sel_pc_r;
1881 :
1882 :
1883 : assign mtval_ns[31:0] = (({32{mtval_capture_pc_r}} & {pc_r[31:1], 1'b0}) |
1884 : ({32{mtval_capture_pc_plus2_r}} & {pc_r[31:1] + 31'b1, 1'b0}) |
1885 : ({32{mtval_capture_inst_r}} & dec_illegal_inst[31:0]) |
1886 : ({32{mtval_capture_lsu_r}} & lsu_error_pkt_addr_r[31:0]) |
1887 : ({32{wr_mtval_r & ~interrupt_valid_r}} & dec_csr_wrdata_r[31:0]) |
1888 : ({32{~take_nmi & ~wr_mtval_r & ~mtval_capture_pc_r & ~mtval_capture_inst_r & ~mtval_clear_r & ~mtval_capture_lsu_r}} & mtval[31:0]) );
1889 :
1890 :
1891 : rvdffe #(32) mtval_ff (.*, .en(tlu_flush_lower_r | wr_mtval_r), .din(mtval_ns[31:0]), .dout(mtval[31:0]));
1892 :
1893 : // ----------------------------------------------------------------------
1894 : // MSECCFG
1895 : // [31:3] : Reserved, read 0x0
1896 : // [2] : RLB
1897 : // [1] : MMWP
1898 : // [0] : MML
1899 :
1900 : `ifdef RV_USER_MODE
1901 :
1902 : localparam MSECCFG = 12'h747;
1903 : localparam MSECCFGH = 12'h757;
1904 :
1905 : // Detect if any PMP region is locked regardless of being enabled. This is
1906 : // necessary for mseccfg.RLB bit write behavior
1907 0 : logic [pt.PMP_ENTRIES-1:0] pmp_region_locked;
1908 : for (genvar r = 0; r < pt.PMP_ENTRIES; r++) begin : g_regions
1909 : assign pmp_region_locked[r] = pmp_pmpcfg[r].lock;
1910 : end
1911 :
1912 10 : logic pmp_any_region_locked;
1913 : assign pmp_any_region_locked = |pmp_region_locked;
1914 :
1915 : // mseccfg
1916 : assign wr_mseccfg_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MSECCFG);
1917 : rvdffs #(3) mseccfg_ff (.*, .clk(csr_wr_clk), .en(wr_mseccfg_r), .din(mseccfg_ns), .dout(mseccfg));
1918 :
1919 : assign mseccfg_ns = {
1920 : pmp_any_region_locked ?
1921 : (dec_csr_wrdata_r[MSECCFG_RLB] & mseccfg[MSECCFG_RLB]) : // When any PMP region is locked this bit can only be cleared
1922 : dec_csr_wrdata_r[MSECCFG_RLB], // Otherwise regularly writeable
1923 : dec_csr_wrdata_r[MSECCFG_MMWP] | mseccfg[MSECCFG_MMWP], // Sticky bit, can only be set but not cleared
1924 : dec_csr_wrdata_r[MSECCFG_MML ] | mseccfg[MSECCFG_MML ] // Sticky bit, can only be set but never cleared
1925 : };
1926 :
1927 : `endif
1928 :
1929 : // ----------------------------------------------------------------------
1930 : // MCGC (RW) Clock gating control
1931 : // [31:10]: Reserved, reads 0x0
1932 : // [9] : picio_clk_override
1933 : // [7] : dec_clk_override
1934 : // [6] : Unused
1935 : // [5] : ifu_clk_override
1936 : // [4] : lsu_clk_override
1937 : // [3] : bus_clk_override
1938 : // [2] : pic_clk_override
1939 : // [1] : dccm_clk_override
1940 : // [0] : icm_clk_override
1941 : //
1942 : assign wr_mcgc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCGC);
1943 :
1944 : assign mcgc_ns[9:0] = wr_mcgc_r ? {~dec_csr_wrdata_r[9], dec_csr_wrdata_r[8:0]} : mcgc_int[9:0];
1945 : rvdffe #(10) mcgc_ff (.*, .en(wr_mcgc_r), .din(mcgc_ns[9:0]), .dout(mcgc_int[9:0]));
1946 :
1947 : assign mcgc[9:0] = {~mcgc_int[9], mcgc_int[8:0]};
1948 :
1949 : assign dec_tlu_picio_clk_override= mcgc[9];
1950 : assign dec_tlu_misc_clk_override = mcgc[8];
1951 : assign dec_tlu_dec_clk_override = mcgc[7];
1952 : //sign dec_tlu_exu_clk_override = mcgc[6];
1953 : assign dec_tlu_ifu_clk_override = mcgc[5];
1954 : assign dec_tlu_lsu_clk_override = mcgc[4];
1955 : assign dec_tlu_bus_clk_override = mcgc[3];
1956 : assign dec_tlu_pic_clk_override = mcgc[2];
1957 : assign dec_tlu_dccm_clk_override = mcgc[1];
1958 : assign dec_tlu_icm_clk_override = mcgc[0];
1959 :
1960 : // ----------------------------------------------------------------------
1961 : // MFDC (RW) Feature Disable Control
1962 : // [31:19] : Reserved, reads 0x0
1963 : // [18:16] : DMA QoS Prty
1964 : // [15:13] : Reserved, reads 0x0
1965 : // [12] : Disable trace
1966 : // [11] : Disable external load forwarding
1967 : // [10] : Disable dual issue
1968 : // [9] : Disable pic multiple ints
1969 : // [8] : Disable core ecc
1970 : // [7] : Disable secondary alu?s
1971 : // [6] : Unused, 0x0
1972 : // [5] : Disable non-blocking loads/divides
1973 : // [4] : Disable fast divide
1974 : // [3] : Disable branch prediction and return stack
1975 : // [2] : Disable write buffer coalescing
1976 : // [1] : Disable load misses that bypass the write buffer
1977 : // [0] : Disable pipelining - Enable single instruction execution
1978 : //
1979 :
1980 : assign wr_mfdc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MFDC);
1981 :
1982 : rvdffe #(16) mfdc_ff (.*, .en(wr_mfdc_r), .din({mfdc_ns[15:0]}), .dout(mfdc_int[15:0]));
1983 :
1984 : // flip poweron value of bit 6 for AXI build
1985 : if(pt.BUILD_AXI4==1) begin : axi4
1986 : // flip poweron valid of bit 12
1987 : assign mfdc_ns[15:0] = {~dec_csr_wrdata_r[18:16], dec_csr_wrdata_r[12], dec_csr_wrdata_r[11:7], ~dec_csr_wrdata_r[6], dec_csr_wrdata_r[5:0]};
1988 : assign mfdc[18:0] = {~mfdc_int[15:13], 3'b0, mfdc_int[12], mfdc_int[11:7], ~mfdc_int[6], mfdc_int[5:0]};
1989 : end
1990 : else begin
1991 : // flip poweron valid of bit 12
1992 : assign mfdc_ns[15:0] = {~dec_csr_wrdata_r[18:16],dec_csr_wrdata_r[12:0]};
1993 : assign mfdc[18:0] = {~mfdc_int[15:13], 3'b0, mfdc_int[12:0]};
1994 : end
1995 :
1996 :
1997 : assign dec_tlu_dma_qos_prty[2:0] = mfdc[18:16];
1998 : assign dec_tlu_trace_disable = mfdc[12];
1999 : assign dec_tlu_external_ldfwd_disable = mfdc[11];
2000 : assign dec_tlu_core_ecc_disable = mfdc[8];
2001 : assign dec_tlu_sideeffect_posted_disable = mfdc[6];
2002 : assign dec_tlu_bpred_disable = mfdc[3];
2003 : assign dec_tlu_wb_coalescing_disable = mfdc[2];
2004 : assign dec_tlu_pipelining_disable = mfdc[0];
2005 :
2006 : // ----------------------------------------------------------------------
2007 : // MCPC (RW) Pause counter
2008 : // [31:0] : Reads 0x0, decs in the wb register in decode_ctl
2009 :
2010 : assign dec_tlu_wr_pause_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCPC) & ~interrupt_valid_r & ~take_ext_int_start;
2011 :
2012 : // ----------------------------------------------------------------------
2013 : // MRAC (RW)
2014 : // [31:0] : Region Access Control Register, 16 regions, {side_effect, cachable} pairs
2015 :
2016 : assign wr_mrac_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MRAC);
2017 :
2018 : // prevent pairs of 0x11, side_effect and cacheable
2019 : assign mrac_in[31:0] = {dec_csr_wrdata_r[31], dec_csr_wrdata_r[30] & ~dec_csr_wrdata_r[31],
2020 : dec_csr_wrdata_r[29], dec_csr_wrdata_r[28] & ~dec_csr_wrdata_r[29],
2021 : dec_csr_wrdata_r[27], dec_csr_wrdata_r[26] & ~dec_csr_wrdata_r[27],
2022 : dec_csr_wrdata_r[25], dec_csr_wrdata_r[24] & ~dec_csr_wrdata_r[25],
2023 : dec_csr_wrdata_r[23], dec_csr_wrdata_r[22] & ~dec_csr_wrdata_r[23],
2024 : dec_csr_wrdata_r[21], dec_csr_wrdata_r[20] & ~dec_csr_wrdata_r[21],
2025 : dec_csr_wrdata_r[19], dec_csr_wrdata_r[18] & ~dec_csr_wrdata_r[19],
2026 : dec_csr_wrdata_r[17], dec_csr_wrdata_r[16] & ~dec_csr_wrdata_r[17],
2027 : dec_csr_wrdata_r[15], dec_csr_wrdata_r[14] & ~dec_csr_wrdata_r[15],
2028 : dec_csr_wrdata_r[13], dec_csr_wrdata_r[12] & ~dec_csr_wrdata_r[13],
2029 : dec_csr_wrdata_r[11], dec_csr_wrdata_r[10] & ~dec_csr_wrdata_r[11],
2030 : dec_csr_wrdata_r[9], dec_csr_wrdata_r[8] & ~dec_csr_wrdata_r[9],
2031 : dec_csr_wrdata_r[7], dec_csr_wrdata_r[6] & ~dec_csr_wrdata_r[7],
2032 : dec_csr_wrdata_r[5], dec_csr_wrdata_r[4] & ~dec_csr_wrdata_r[5],
2033 : dec_csr_wrdata_r[3], dec_csr_wrdata_r[2] & ~dec_csr_wrdata_r[3],
2034 : dec_csr_wrdata_r[1], dec_csr_wrdata_r[0] & ~dec_csr_wrdata_r[1]};
2035 :
2036 : rvdffe #(32) mrac_ff (.*, .en(wr_mrac_r), .din(mrac_in[31:0]), .dout(mrac[31:0]));
2037 :
2038 : // drive to LSU/IFU
2039 : assign dec_tlu_mrac_ff[31:0] = mrac[31:0];
2040 :
2041 : // ----------------------------------------------------------------------
2042 : // MDEAU (WAR0)
2043 : // [31:0] : Dbus Error Address Unlock register
2044 : //
2045 :
2046 : assign wr_mdeau_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MDEAU);
2047 :
2048 :
2049 : // ----------------------------------------------------------------------
2050 : // MDSEAC (R)
2051 : // [31:0] : Dbus Store Error Address Capture register
2052 : //
2053 :
2054 : // only capture error bus if the MDSEAC reg is not locked
2055 : assign mdseac_locked_ns = mdseac_en | (mdseac_locked_f & ~wr_mdeau_r);
2056 :
2057 : assign mdseac_en = (lsu_imprecise_error_store_any | lsu_imprecise_error_load_any) & ~nmi_int_detected_f & ~mdseac_locked_f;
2058 :
2059 : rvdffe #(32) mdseac_ff (.*, .en(mdseac_en), .din(lsu_imprecise_error_addr_any[31:0]), .dout(mdseac[31:0]));
2060 :
2061 : // ----------------------------------------------------------------------
2062 : // MPMC (R0W1)
2063 : // [0] : FW halt
2064 : // [1] : Set MSTATUS[MIE] on halt
2065 :
2066 : assign wr_mpmc_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MPMC);
2067 :
2068 : // allow the cycle of the dbg halt flush that contains the wr_mpmc_r to
2069 : // set the mstatus bit potentially, use delayed version of internal dbg halt.
2070 : assign fw_halt_req = wr_mpmc_r & dec_csr_wrdata_r[0] & ~internal_dbg_halt_mode_f2 & ~ext_int_freeze_d1;
2071 :
2072 : assign fw_halted_ns = (fw_halt_req | fw_halted) & ~set_mie_pmu_fw_halt;
2073 : assign mpmc_b_ns[1] = wr_mpmc_r ? ~dec_csr_wrdata_r[1] : ~mpmc[1];
2074 : rvdff #(1) mpmc_ff (.*, .clk(csr_wr_clk), .din(mpmc_b_ns[1]), .dout(mpmc_b[1]));
2075 : assign mpmc[1] = ~mpmc_b[1];
2076 :
2077 : // ----------------------------------------------------------------------
2078 : // MICECT (I-Cache error counter/threshold)
2079 : // [31:27] : Icache parity error threshold
2080 : // [26:0] : Icache parity error count
2081 :
2082 : assign csr_sat[31:27] = (dec_csr_wrdata_r[31:27] > 5'd26) ? 5'd26 : dec_csr_wrdata_r[31:27];
2083 :
2084 : assign wr_micect_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MICECT);
2085 : assign micect_inc[26:0] = micect[26:0] + {26'b0, ic_perr_r};
2086 : assign micect_ns = wr_micect_r ? {csr_sat[31:27], dec_csr_wrdata_r[26:0]} : {micect[31:27], micect_inc[26:0]};
2087 :
2088 : rvdffe #(32) micect_ff (.*, .en(wr_micect_r | ic_perr_r), .din(micect_ns[31:0]), .dout(micect[31:0]));
2089 :
2090 : assign mice_ce_req = |({32'hffffffff << micect[31:27]} & {5'b0, micect[26:0]});
2091 :
2092 : // ----------------------------------------------------------------------
2093 : // MICCMECT (ICCM error counter/threshold)
2094 : // [31:27] : ICCM parity error threshold
2095 : // [26:0] : ICCM parity error count
2096 :
2097 : assign wr_miccmect_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MICCMECT);
2098 : assign miccmect_inc[26:0] = miccmect[26:0] + {26'b0, iccm_sbecc_r | iccm_dma_sb_error};
2099 : assign miccmect_ns = wr_miccmect_r ? {csr_sat[31:27], dec_csr_wrdata_r[26:0]} : {miccmect[31:27], miccmect_inc[26:0]};
2100 :
2101 : rvdffe #(32) miccmect_ff (.*, .clk(free_l2clk), .en(wr_miccmect_r | iccm_sbecc_r | iccm_dma_sb_error), .din(miccmect_ns[31:0]), .dout(miccmect[31:0]));
2102 :
2103 : assign miccme_ce_req = |({32'hffffffff << miccmect[31:27]} & {5'b0, miccmect[26:0]});
2104 :
2105 : // ----------------------------------------------------------------------
2106 : // MDCCMECT (DCCM error counter/threshold)
2107 : // [31:27] : DCCM parity error threshold
2108 : // [26:0] : DCCM parity error count
2109 :
2110 : assign wr_mdccmect_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MDCCMECT);
2111 : assign mdccmect_inc[26:0] = mdccmect[26:0] + {26'b0, lsu_single_ecc_error_r_d1};
2112 : assign mdccmect_ns = wr_mdccmect_r ? {csr_sat[31:27], dec_csr_wrdata_r[26:0]} : {mdccmect[31:27], mdccmect_inc[26:0]};
2113 :
2114 : rvdffe #(32) mdccmect_ff (.*, .clk(free_l2clk), .en(wr_mdccmect_r | lsu_single_ecc_error_r_d1), .din(mdccmect_ns[31:0]), .dout(mdccmect[31:0]));
2115 :
2116 : assign mdccme_ce_req = |({32'hffffffff << mdccmect[31:27]} & {5'b0, mdccmect[26:0]});
2117 :
2118 :
2119 : // ----------------------------------------------------------------------
2120 : // MFDHT (Force Debug Halt Threshold)
2121 : // [5:1] : Halt timeout threshold (power of 2)
2122 : // [0] : Halt timeout enabled
2123 :
2124 : assign wr_mfdht_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MFDHT);
2125 :
2126 : assign mfdht_ns[5:0] = wr_mfdht_r ? dec_csr_wrdata_r[5:0] : mfdht[5:0];
2127 :
2128 : rvdffs #(6) mfdht_ff (.*, .clk(csr_wr_clk), .en(wr_mfdht_r), .din(mfdht_ns[5:0]), .dout(mfdht[5:0]));
2129 :
2130 : // ----------------------------------------------------------------------
2131 : // MFDHS(RW)
2132 : // [1] : LSU operation pending when debug halt threshold reached
2133 : // [0] : IFU operation pending when debug halt threshold reached
2134 :
2135 : assign wr_mfdhs_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MFDHS);
2136 :
2137 : assign mfdhs_ns[1:0] = wr_mfdhs_r ? dec_csr_wrdata_r[1:0] : ((dbg_tlu_halted & ~dbg_tlu_halted_f) ? {~lsu_idle_any_f, ~ifu_miss_state_idle_f} : mfdhs[1:0]);
2138 :
2139 : rvdffs #(2) mfdhs_ff (.*, .clk(free_clk), .en(wr_mfdhs_r | dbg_tlu_halted), .din(mfdhs_ns[1:0]), .dout(mfdhs[1:0]));
2140 :
2141 : assign force_halt_ctr[31:0] = debug_halt_req_f ? (force_halt_ctr_f[31:0] + 32'b1) : (dbg_tlu_halted_f ? 32'b0 : force_halt_ctr_f[31:0]);
2142 :
2143 : rvdffe #(32) forcehaltctr_ff (.*, .en(mfdht[0]), .din(force_halt_ctr[31:0]), .dout(force_halt_ctr_f[31:0]));
2144 :
2145 : assign force_halt = mfdht[0] & |(force_halt_ctr_f[31:0] & (32'hffffffff << mfdht[5:1]));
2146 :
2147 :
2148 : // ----------------------------------------------------------------------
2149 : // MEIVT (External Interrupt Vector Table (R/W))
2150 : // [31:10]: Base address (R/W)
2151 : // [9:0] : Reserved, reads 0x0
2152 : assign wr_meivt_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEIVT);
2153 :
2154 : rvdffe #(22) meivt_ff (.*, .en(wr_meivt_r), .din(dec_csr_wrdata_r[31:10]), .dout(meivt[31:10]));
2155 :
2156 :
2157 : // ----------------------------------------------------------------------
2158 : // MEIHAP (External Interrupt Handler Access Pointer (R))
2159 : // [31:10]: Base address (R/W)
2160 : // [9:2] : ClaimID (R)
2161 : // [1:0] : Reserved, 0x0
2162 :
2163 : assign wr_meihap_r = wr_meicpct_r;
2164 :
2165 : rvdffe #(8) meihap_ff (.*, .en(wr_meihap_r), .din(pic_claimid[7:0]), .dout(meihap[9:2]));
2166 :
2167 : assign dec_tlu_meihap[31:2] = {meivt[31:10], meihap[9:2]};
2168 :
2169 : // ----------------------------------------------------------------------
2170 : // MEICURPL (R/W)
2171 : // [31:4] : Reserved (read 0x0)
2172 : // [3:0] : CURRPRI - Priority level of current interrupt service routine (R/W)
2173 : assign wr_meicurpl_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEICURPL);
2174 : assign meicurpl_ns[3:0] = wr_meicurpl_r ? dec_csr_wrdata_r[3:0] : meicurpl[3:0];
2175 :
2176 : rvdff #(4) meicurpl_ff (.*, .clk(csr_wr_clk), .din(meicurpl_ns[3:0]), .dout(meicurpl[3:0]));
2177 :
2178 : // PIC needs this reg
2179 : assign dec_tlu_meicurpl[3:0] = meicurpl[3:0];
2180 :
2181 :
2182 : // ----------------------------------------------------------------------
2183 : // MEICIDPL (R/W)
2184 : // [31:4] : Reserved (read 0x0)
2185 : // [3:0] : External Interrupt Claim ID's Priority Level Register
2186 :
2187 : assign wr_meicidpl_r = (dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEICIDPL)) | take_ext_int_start;
2188 :
2189 : assign meicidpl_ns[3:0] = wr_meicpct_r ? pic_pl[3:0] : (wr_meicidpl_r ? dec_csr_wrdata_r[3:0] : meicidpl[3:0]);
2190 :
2191 :
2192 : // ----------------------------------------------------------------------
2193 : // MEICPCT (Capture CLAIMID in MEIHAP and PL in MEICIDPL
2194 : // [31:1] : Reserved (read 0x0)
2195 : // [0] : Capture (W1, Read 0)
2196 : assign wr_meicpct_r = (dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEICPCT)) | take_ext_int_start;
2197 :
2198 : // ----------------------------------------------------------------------
2199 : // MEIPT (External Interrupt Priority Threshold)
2200 : // [31:4] : Reserved (read 0x0)
2201 : // [3:0] : PRITHRESH
2202 :
2203 : assign wr_meipt_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MEIPT);
2204 : assign meipt_ns[3:0] = wr_meipt_r ? dec_csr_wrdata_r[3:0] : meipt[3:0];
2205 :
2206 : rvdff #(4) meipt_ff (.*, .clk(csr_wr_clk), .din(meipt_ns[3:0]), .dout(meipt[3:0]));
2207 :
2208 : // to PIC
2209 : assign dec_tlu_meipt[3:0] = meipt[3:0];
2210 : // ----------------------------------------------------------------------
2211 : // DCSR (R/W) (Only accessible in debug mode)
2212 : // [31:28] : xdebugver (hard coded to 0x4) RO
2213 : // [27:16] : 0x0, reserved
2214 : // [15] : ebreakm
2215 : // [14] : 0x0, reserved
2216 : // [13] : ebreaks (0x0 for this core)
2217 : // [12] : ebreaku (0x0 for this core)
2218 : // [11] : stepie
2219 : // [10] : stopcount
2220 : // [9] : 0x0 //stoptime
2221 : // [8:6] : cause (RO)
2222 : // [5:4] : 0x0, reserved
2223 : // [3] : nmip
2224 : // [2] : step
2225 : // [1:0] : prv (0x3 for this core)
2226 : //
2227 :
2228 : // RV has clarified that 'priority 4' in the spec means top priority.
2229 : // 4. single step. 3. Debugger request. 2. Ebreak. 1. Trigger.
2230 :
2231 : // RV debug spec indicates a cause priority change for trigger hits during single step.
2232 : assign trigger_hit_for_dscr_cause_r_d1 = trigger_hit_dmode_r_d1 | (trigger_hit_r_d1 & dcsr_single_step_done_f);
2233 :
2234 : assign dcsr_cause[8:6] = ( ({3{dcsr_single_step_done_f & ~ebreak_to_debug_mode_r_d1 & ~trigger_hit_for_dscr_cause_r_d1 & ~debug_halt_req}} & 3'b100) |
2235 : ({3{debug_halt_req & ~ebreak_to_debug_mode_r_d1 & ~trigger_hit_for_dscr_cause_r_d1}} & 3'b011) |
2236 : ({3{ebreak_to_debug_mode_r_d1 & ~trigger_hit_for_dscr_cause_r_d1}} & 3'b001) |
2237 : ({3{trigger_hit_for_dscr_cause_r_d1}} & 3'b010));
2238 :
2239 : assign wr_dcsr_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DCSR);
2240 :
2241 :
2242 :
2243 : // Multiple halt enter requests can happen before we are halted.
2244 : // We have to continue to upgrade based on dcsr_cause priority but we can't downgrade.
2245 : assign dcsr_cause_upgradeable = internal_dbg_halt_mode_f & (dcsr[8:6] == 3'b011);
2246 : assign enter_debug_halt_req_le = enter_debug_halt_req & (~dbg_tlu_halted | dcsr_cause_upgradeable);
2247 :
2248 : assign nmi_in_debug_mode = nmi_int_detected_f & internal_dbg_halt_mode_f;
2249 : assign dcsr_ns[15:2] = enter_debug_halt_req_le ? {dcsr[15:9], dcsr_cause[8:6], dcsr[5:2]} :
2250 : (wr_dcsr_r ? {dec_csr_wrdata_r[15], 3'b0, dec_csr_wrdata_r[11:10], 1'b0, dcsr[8:6], 2'b00, nmi_in_debug_mode | dcsr[3], dec_csr_wrdata_r[2]} :
2251 : {dcsr[15:4], nmi_in_debug_mode, dcsr[2]});
2252 :
2253 : rvdffe #(14) dcsr_ff (.*, .clk(free_l2clk), .en(enter_debug_halt_req_le | wr_dcsr_r | internal_dbg_halt_mode | take_nmi), .din(dcsr_ns[15:2]), .dout(dcsr[15:2]));
2254 :
2255 : // ----------------------------------------------------------------------
2256 : // DPC (R/W) (Only accessible in debug mode)
2257 : // [31:0] : Debug PC
2258 :
2259 : assign wr_dpc_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DPC);
2260 : assign dpc_capture_npc = dbg_tlu_halted & ~dbg_tlu_halted_f & ~request_debug_mode_done;
2261 : assign dpc_capture_pc = request_debug_mode_r;
2262 :
2263 : assign dpc_ns[31:1] = ( ({31{~dpc_capture_pc & ~dpc_capture_npc & wr_dpc_r}} & dec_csr_wrdata_r[31:1]) |
2264 : ({31{dpc_capture_pc}} & pc_r[31:1]) |
2265 : ({31{~dpc_capture_pc & dpc_capture_npc}} & npc_r[31:1]) );
2266 :
2267 : rvdffe #(31) dpc_ff (.*, .en(wr_dpc_r | dpc_capture_pc | dpc_capture_npc), .din(dpc_ns[31:1]), .dout(dpc[31:1]));
2268 :
2269 : // ----------------------------------------------------------------------
2270 : // DICAWICS (R/W) (Only accessible in debug mode)
2271 : // [31:25] : Reserved
2272 : // [24] : Array select, 0 is data, 1 is tag
2273 : // [23:22] : Reserved
2274 : // [21:20] : Way select
2275 : // [19:17] : Reserved
2276 : // [16:3] : Index
2277 : // [2:0] : Reserved
2278 :
2279 : assign dicawics_ns[16:0] = {dec_csr_wrdata_r[24], dec_csr_wrdata_r[21:20], dec_csr_wrdata_r[16:3]};
2280 : assign wr_dicawics_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAWICS);
2281 :
2282 : rvdffe #(17) dicawics_ff (.*, .en(wr_dicawics_r), .din(dicawics_ns[16:0]), .dout(dicawics[16:0]));
2283 :
2284 : // ----------------------------------------------------------------------
2285 : // DICAD0 (R/W) (Only accessible in debug mode)
2286 : //
2287 : // If dicawics[array] is 0
2288 : // [31:0] : inst data
2289 : //
2290 : // If dicawics[array] is 1
2291 : // [31:16] : Tag
2292 : // [15:7] : Reserved
2293 : // [6:4] : LRU
2294 : // [3:1] : Reserved
2295 : // [0] : Valid
2296 :
2297 : assign dicad0_ns[31:0] = wr_dicad0_r ? dec_csr_wrdata_r[31:0] : ifu_ic_debug_rd_data[31:0];
2298 :
2299 : assign wr_dicad0_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD0);
2300 :
2301 : rvdffe #(32) dicad0_ff (.*, .en(wr_dicad0_r | ifu_ic_debug_rd_data_valid), .din(dicad0_ns[31:0]), .dout(dicad0[31:0]));
2302 :
2303 : // ----------------------------------------------------------------------
2304 : // DICAD0H (R/W) (Only accessible in debug mode)
2305 : //
2306 : // If dicawics[array] is 0
2307 : // [63:32] : inst data
2308 : //
2309 :
2310 : assign dicad0h_ns[31:0] = wr_dicad0h_r ? dec_csr_wrdata_r[31:0] : ifu_ic_debug_rd_data[63:32];
2311 :
2312 : assign wr_dicad0h_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD0H);
2313 :
2314 : rvdffe #(32) dicad0h_ff (.*, .en(wr_dicad0h_r | ifu_ic_debug_rd_data_valid), .din(dicad0h_ns[31:0]), .dout(dicad0h[31:0]));
2315 :
2316 :
2317 : if (pt.ICACHE_ECC == 1) begin : genblock1
2318 : // ----------------------------------------------------------------------
2319 : // DICAD1 (R/W) (Only accessible in debug mode)
2320 : // [6:0] : ECC
2321 : localparam DICAD1 = 12'h7ca;
2322 :
2323 : assign dicad1_ns[6:0] = wr_dicad1_r ? dec_csr_wrdata_r[6:0] : ifu_ic_debug_rd_data[70:64];
2324 :
2325 : assign wr_dicad1_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD1);
2326 :
2327 : rvdffe #(.WIDTH(7), .OVERRIDE(1)) dicad1_ff (.*, .en(wr_dicad1_r | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[6:0]), .dout(dicad1_raw[6:0]));
2328 :
2329 : assign dicad1[31:0] = {25'b0, dicad1_raw[6:0]};
2330 :
2331 : end
2332 : else begin : genblock1
2333 : // ----------------------------------------------------------------------
2334 : // DICAD1 (R/W) (Only accessible in debug mode)
2335 : // [3:0] : Parity
2336 : localparam DICAD1 = 12'h7ca;
2337 :
2338 : assign dicad1_ns[3:0] = wr_dicad1_r ? dec_csr_wrdata_r[3:0] : ifu_ic_debug_rd_data[67:64];
2339 :
2340 : assign wr_dicad1_r = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAD1);
2341 :
2342 : rvdffs #(4) dicad1_ff (.*, .clk(free_clk), .en(wr_dicad1_r | ifu_ic_debug_rd_data_valid), .din(dicad1_ns[3:0]), .dout(dicad1_raw[3:0]));
2343 :
2344 : assign dicad1[31:0] = {28'b0, dicad1_raw[3:0]};
2345 : end
2346 : // ----------------------------------------------------------------------
2347 : // DICAGO (R/W) (Only accessible in debug mode)
2348 : // [0] : Go
2349 :
2350 : if (pt.ICACHE_ECC == 1)
2351 : assign dec_tlu_ic_diag_pkt.icache_wrdata[70:0] = { dicad1[6:0], dicad0h[31:0], dicad0[31:0]};
2352 : else
2353 : assign dec_tlu_ic_diag_pkt.icache_wrdata[70:0] = {3'b0, dicad1[3:0], dicad0h[31:0], dicad0[31:0]};
2354 :
2355 :
2356 : assign dec_tlu_ic_diag_pkt.icache_dicawics[16:0] = dicawics[16:0];
2357 :
2358 : assign icache_rd_valid = allow_dbg_halt_csr_write & dec_csr_any_unq_d & dec_i0_decode_d & ~dec_csr_wen_unq_d & (dec_csr_rdaddr_d[11:0] == DICAGO);
2359 : assign icache_wr_valid = allow_dbg_halt_csr_write & dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == DICAGO);
2360 :
2361 :
2362 : assign dec_tlu_ic_diag_pkt.icache_rd_valid = icache_rd_valid_f;
2363 : assign dec_tlu_ic_diag_pkt.icache_wr_valid = icache_wr_valid_f;
2364 :
2365 : // ----------------------------------------------------------------------
2366 : // MTSEL (R/W)
2367 : // [1:0] : Trigger select : 00, 01, 10 are data/address triggers. 11 is inst count
2368 :
2369 : assign wr_mtsel_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTSEL);
2370 : assign mtsel_ns[1:0] = wr_mtsel_r ? {dec_csr_wrdata_r[1:0]} : mtsel[1:0];
2371 :
2372 : rvdff #(2) mtsel_ff (.*, .clk(csr_wr_clk), .din(mtsel_ns[1:0]), .dout(mtsel[1:0]));
2373 :
2374 : // ----------------------------------------------------------------------
2375 : // MTDATA1 (R/W)
2376 : // [31:0] : Trigger Data 1
2377 :
2378 : // for triggers 0, 1, 2 and 3 aka Match Control
2379 : // [31:28] : type, hard coded to 0x2
2380 : // [27] : dmode
2381 : // [26:21] : hard coded to 0x1f
2382 : // [20] : hit
2383 : // [19] : select (0 - address, 1 - data)
2384 : // [18] : timing, always 'before', reads 0x0
2385 : // [17:12] : action, bits [17:13] not implemented and reads 0x0
2386 : // [11] : chain
2387 : // [10:7] : match, bits [10:8] not implemented and reads 0x0
2388 : // [6] : M
2389 : // [5:3] : not implemented, reads 0x0
2390 : // [2] : execute
2391 : // [1] : store
2392 : // [0] : load
2393 : //
2394 : // decoder ring
2395 : // [27] : => 9
2396 : // [20] : => 8
2397 : // [19] : => 7
2398 : // [12] : => 6
2399 : // [11] : => 5
2400 : // [7] : => 4
2401 : // [6] : => 3
2402 : // [2] : => 2
2403 : // [1] : => 1
2404 : // [0] : => 0
2405 :
2406 :
2407 : // don't allow setting load-data.
2408 : assign tdata_load = dec_csr_wrdata_r[0] & ~dec_csr_wrdata_r[19];
2409 : // don't allow setting execute-data.
2410 : assign tdata_opcode = dec_csr_wrdata_r[2] & ~dec_csr_wrdata_r[19];
2411 : // don't allow clearing DMODE and action=1
2412 : assign tdata_action = (dec_csr_wrdata_r[27] & dbg_tlu_halted_f) & dec_csr_wrdata_r[12];
2413 :
2414 : // Chain bit has conditions: WARL for triggers without chains. Force to zero if dmode is 0 but next trigger dmode is 1.
2415 : assign tdata_chain = mtsel[0] ? 1'b0 : // triggers 1 and 3 chain bit is always zero
2416 : mtsel[1] ? dec_csr_wrdata_r[11] & ~(mtdata1_t3[MTDATA1_DMODE] & ~dec_csr_wrdata_r[27]) : // trigger 2
2417 : dec_csr_wrdata_r[11] & ~(mtdata1_t1[MTDATA1_DMODE] & ~dec_csr_wrdata_r[27]); // trigger 0
2418 :
2419 : // Kill mtdata1 write if dmode=1 but prior trigger has dmode=0/chain=1. Only applies to T1 and T3
2420 : assign tdata_kill_write = mtsel[1] ? dec_csr_wrdata_r[27] & (~mtdata1_t2[MTDATA1_DMODE] & mtdata1_t2[MTDATA1_CHAIN]) : // trigger 3
2421 : dec_csr_wrdata_r[27] & (~mtdata1_t0[MTDATA1_DMODE] & mtdata1_t0[MTDATA1_CHAIN]) ; // trigger 1
2422 :
2423 :
2424 : assign tdata_wrdata_r[9:0] = {dec_csr_wrdata_r[27] & dbg_tlu_halted_f,
2425 : dec_csr_wrdata_r[20:19],
2426 : tdata_action,
2427 : tdata_chain,
2428 : dec_csr_wrdata_r[7:6],
2429 : tdata_opcode,
2430 : dec_csr_wrdata_r[1],
2431 : tdata_load};
2432 :
2433 : // If the DMODE bit is set, tdata1 can only be updated in debug_mode
2434 : assign wr_mtdata1_t0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b0) & (~mtdata1_t0[MTDATA1_DMODE] | dbg_tlu_halted_f);
2435 : assign mtdata1_t0_ns[9:0] = wr_mtdata1_t0_r ? tdata_wrdata_r[9:0] :
2436 : {mtdata1_t0[9], update_hit_bit_r[0] | mtdata1_t0[8], mtdata1_t0[7:0]};
2437 :
2438 : assign wr_mtdata1_t1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[MTDATA1_DMODE] | dbg_tlu_halted_f) & ~tdata_kill_write;
2439 : assign mtdata1_t1_ns[9:0] = wr_mtdata1_t1_r ? tdata_wrdata_r[9:0] :
2440 : {mtdata1_t1[9], update_hit_bit_r[1] | mtdata1_t1[8], mtdata1_t1[7:0]};
2441 :
2442 : assign wr_mtdata1_t2_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b10) & (~mtdata1_t2[MTDATA1_DMODE] | dbg_tlu_halted_f);
2443 : assign mtdata1_t2_ns[9:0] = wr_mtdata1_t2_r ? tdata_wrdata_r[9:0] :
2444 : {mtdata1_t2[9], update_hit_bit_r[2] | mtdata1_t2[8], mtdata1_t2[7:0]};
2445 :
2446 : assign wr_mtdata1_t3_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA1) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[MTDATA1_DMODE] | dbg_tlu_halted_f) & ~tdata_kill_write;
2447 : assign mtdata1_t3_ns[9:0] = wr_mtdata1_t3_r ? tdata_wrdata_r[9:0] :
2448 : {mtdata1_t3[9], update_hit_bit_r[3] | mtdata1_t3[8], mtdata1_t3[7:0]};
2449 :
2450 :
2451 : rvdffe #(10) mtdata1_t0_ff (.*, .en(trigger_enabled[0] | wr_mtdata1_t0_r), .din(mtdata1_t0_ns[9:0]), .dout(mtdata1_t0[9:0]));
2452 : rvdffe #(10) mtdata1_t1_ff (.*, .en(trigger_enabled[1] | wr_mtdata1_t1_r), .din(mtdata1_t1_ns[9:0]), .dout(mtdata1_t1[9:0]));
2453 : rvdffe #(10) mtdata1_t2_ff (.*, .en(trigger_enabled[2] | wr_mtdata1_t2_r), .din(mtdata1_t2_ns[9:0]), .dout(mtdata1_t2[9:0]));
2454 : rvdffe #(10) mtdata1_t3_ff (.*, .en(trigger_enabled[3] | wr_mtdata1_t3_r), .din(mtdata1_t3_ns[9:0]), .dout(mtdata1_t3[9:0]));
2455 :
2456 : assign mtdata1_tsel_out[31:0] = ( ({32{(mtsel[1:0] == 2'b00)}} & {4'h2, mtdata1_t0[9], 6'b011111, mtdata1_t0[8:7], 6'b0, mtdata1_t0[6:5], 3'b0, mtdata1_t0[4:3], 3'b0, mtdata1_t0[2:0]}) |
2457 : ({32{(mtsel[1:0] == 2'b01)}} & {4'h2, mtdata1_t1[9], 6'b011111, mtdata1_t1[8:7], 6'b0, mtdata1_t1[6:5], 3'b0, mtdata1_t1[4:3], 3'b0, mtdata1_t1[2:0]}) |
2458 : ({32{(mtsel[1:0] == 2'b10)}} & {4'h2, mtdata1_t2[9], 6'b011111, mtdata1_t2[8:7], 6'b0, mtdata1_t2[6:5], 3'b0, mtdata1_t2[4:3], 3'b0, mtdata1_t2[2:0]}) |
2459 : ({32{(mtsel[1:0] == 2'b11)}} & {4'h2, mtdata1_t3[9], 6'b011111, mtdata1_t3[8:7], 6'b0, mtdata1_t3[6:5], 3'b0, mtdata1_t3[4:3], 3'b0, mtdata1_t3[2:0]}));
2460 :
2461 : assign trigger_pkt_any[0].select = mtdata1_t0[MTDATA1_SEL];
2462 : assign trigger_pkt_any[0].match = mtdata1_t0[MTDATA1_MATCH];
2463 : assign trigger_pkt_any[0].store = mtdata1_t0[MTDATA1_ST];
2464 : assign trigger_pkt_any[0].load = mtdata1_t0[MTDATA1_LD];
2465 : assign trigger_pkt_any[0].execute = mtdata1_t0[MTDATA1_EXE];
2466 : assign trigger_pkt_any[0].m = mtdata1_t0[MTDATA1_M_ENABLED];
2467 :
2468 : assign trigger_pkt_any[1].select = mtdata1_t1[MTDATA1_SEL];
2469 : assign trigger_pkt_any[1].match = mtdata1_t1[MTDATA1_MATCH];
2470 : assign trigger_pkt_any[1].store = mtdata1_t1[MTDATA1_ST];
2471 : assign trigger_pkt_any[1].load = mtdata1_t1[MTDATA1_LD];
2472 : assign trigger_pkt_any[1].execute = mtdata1_t1[MTDATA1_EXE];
2473 : assign trigger_pkt_any[1].m = mtdata1_t1[MTDATA1_M_ENABLED];
2474 :
2475 : assign trigger_pkt_any[2].select = mtdata1_t2[MTDATA1_SEL];
2476 : assign trigger_pkt_any[2].match = mtdata1_t2[MTDATA1_MATCH];
2477 : assign trigger_pkt_any[2].store = mtdata1_t2[MTDATA1_ST];
2478 : assign trigger_pkt_any[2].load = mtdata1_t2[MTDATA1_LD];
2479 : assign trigger_pkt_any[2].execute = mtdata1_t2[MTDATA1_EXE];
2480 : assign trigger_pkt_any[2].m = mtdata1_t2[MTDATA1_M_ENABLED];
2481 :
2482 : assign trigger_pkt_any[3].select = mtdata1_t3[MTDATA1_SEL];
2483 : assign trigger_pkt_any[3].match = mtdata1_t3[MTDATA1_MATCH];
2484 : assign trigger_pkt_any[3].store = mtdata1_t3[MTDATA1_ST];
2485 : assign trigger_pkt_any[3].load = mtdata1_t3[MTDATA1_LD];
2486 : assign trigger_pkt_any[3].execute = mtdata1_t3[MTDATA1_EXE];
2487 : assign trigger_pkt_any[3].m = mtdata1_t3[MTDATA1_M_ENABLED];
2488 :
2489 :
2490 :
2491 :
2492 :
2493 : // ----------------------------------------------------------------------
2494 : // MTDATA2 (R/W)
2495 : // [31:0] : Trigger Data 2
2496 :
2497 : // If the DMODE bit is set, tdata2 can only be updated in debug_mode
2498 : assign wr_mtdata2_t0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b0) & (~mtdata1_t0[MTDATA1_DMODE] | dbg_tlu_halted_f);
2499 : assign wr_mtdata2_t1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[MTDATA1_DMODE] | dbg_tlu_halted_f);
2500 : assign wr_mtdata2_t2_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b10) & (~mtdata1_t2[MTDATA1_DMODE] | dbg_tlu_halted_f);
2501 : assign wr_mtdata2_t3_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MTDATA2) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[MTDATA1_DMODE] | dbg_tlu_halted_f);
2502 :
2503 : rvdffe #(32) mtdata2_t0_ff (.*, .en(wr_mtdata2_t0_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t0[31:0]));
2504 : rvdffe #(32) mtdata2_t1_ff (.*, .en(wr_mtdata2_t1_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t1[31:0]));
2505 : rvdffe #(32) mtdata2_t2_ff (.*, .en(wr_mtdata2_t2_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t2[31:0]));
2506 : rvdffe #(32) mtdata2_t3_ff (.*, .en(wr_mtdata2_t3_r), .din(dec_csr_wrdata_r[31:0]), .dout(mtdata2_t3[31:0]));
2507 :
2508 : assign mtdata2_tsel_out[31:0] = ( ({32{(mtsel[1:0] == 2'b00)}} & mtdata2_t0[31:0]) |
2509 : ({32{(mtsel[1:0] == 2'b01)}} & mtdata2_t1[31:0]) |
2510 : ({32{(mtsel[1:0] == 2'b10)}} & mtdata2_t2[31:0]) |
2511 : ({32{(mtsel[1:0] == 2'b11)}} & mtdata2_t3[31:0]));
2512 :
2513 : assign trigger_pkt_any[0].tdata2[31:0] = mtdata2_t0[31:0];
2514 : assign trigger_pkt_any[1].tdata2[31:0] = mtdata2_t1[31:0];
2515 : assign trigger_pkt_any[2].tdata2[31:0] = mtdata2_t2[31:0];
2516 : assign trigger_pkt_any[3].tdata2[31:0] = mtdata2_t3[31:0];
2517 :
2518 :
2519 : //----------------------------------------------------------------------
2520 : // Performance Monitor Counters section starts
2521 : //----------------------------------------------------------------------
2522 : localparam MHPME_NOEVENT = 10'd0;
2523 : localparam MHPME_CLK_ACTIVE = 10'd1; // OOP - out of pipe
2524 : localparam MHPME_ICACHE_HIT = 10'd2; // OOP
2525 : localparam MHPME_ICACHE_MISS = 10'd3; // OOP
2526 : localparam MHPME_INST_COMMIT = 10'd4;
2527 : localparam MHPME_INST_COMMIT_16B = 10'd5;
2528 : localparam MHPME_INST_COMMIT_32B = 10'd6;
2529 : localparam MHPME_INST_ALIGNED = 10'd7; // OOP
2530 : localparam MHPME_INST_DECODED = 10'd8; // OOP
2531 : localparam MHPME_INST_MUL = 10'd9;
2532 : localparam MHPME_INST_DIV = 10'd10;
2533 : localparam MHPME_INST_LOAD = 10'd11;
2534 : localparam MHPME_INST_STORE = 10'd12;
2535 : localparam MHPME_INST_MALOAD = 10'd13;
2536 : localparam MHPME_INST_MASTORE = 10'd14;
2537 : localparam MHPME_INST_ALU = 10'd15;
2538 : localparam MHPME_INST_CSRREAD = 10'd16;
2539 : localparam MHPME_INST_CSRRW = 10'd17;
2540 : localparam MHPME_INST_CSRWRITE = 10'd18;
2541 : localparam MHPME_INST_EBREAK = 10'd19;
2542 : localparam MHPME_INST_ECALL = 10'd20;
2543 : localparam MHPME_INST_FENCE = 10'd21;
2544 : localparam MHPME_INST_FENCEI = 10'd22;
2545 : localparam MHPME_INST_MRET = 10'd23;
2546 : localparam MHPME_INST_BRANCH = 10'd24;
2547 : localparam MHPME_BRANCH_MP = 10'd25;
2548 : localparam MHPME_BRANCH_TAKEN = 10'd26;
2549 : localparam MHPME_BRANCH_NOTP = 10'd27;
2550 : localparam MHPME_FETCH_STALL = 10'd28; // OOP
2551 : localparam MHPME_DECODE_STALL = 10'd30; // OOP
2552 : localparam MHPME_POSTSYNC_STALL = 10'd31; // OOP
2553 : localparam MHPME_PRESYNC_STALL = 10'd32; // OOP
2554 : localparam MHPME_LSU_SB_WB_STALL = 10'd34; // OOP
2555 : localparam MHPME_DMA_DCCM_STALL = 10'd35; // OOP
2556 : localparam MHPME_DMA_ICCM_STALL = 10'd36; // OOP
2557 : localparam MHPME_EXC_TAKEN = 10'd37;
2558 : localparam MHPME_TIMER_INT_TAKEN = 10'd38;
2559 : localparam MHPME_EXT_INT_TAKEN = 10'd39;
2560 : localparam MHPME_FLUSH_LOWER = 10'd40;
2561 : localparam MHPME_BR_ERROR = 10'd41;
2562 : localparam MHPME_IBUS_TRANS = 10'd42; // OOP
2563 : localparam MHPME_DBUS_TRANS = 10'd43; // OOP
2564 : localparam MHPME_DBUS_MA_TRANS = 10'd44; // OOP
2565 : localparam MHPME_IBUS_ERROR = 10'd45; // OOP
2566 : localparam MHPME_DBUS_ERROR = 10'd46; // OOP
2567 : localparam MHPME_IBUS_STALL = 10'd47; // OOP
2568 : localparam MHPME_DBUS_STALL = 10'd48; // OOP
2569 : localparam MHPME_INT_DISABLED = 10'd49; // OOP
2570 : localparam MHPME_INT_STALLED = 10'd50; // OOP
2571 : localparam MHPME_INST_BITMANIP = 10'd54;
2572 : localparam MHPME_DBUS_LOAD = 10'd55;
2573 : localparam MHPME_DBUS_STORE = 10'd56;
2574 : // Counts even during sleep state
2575 : localparam MHPME_SLEEP_CYC = 10'd512; // OOP
2576 : localparam MHPME_DMA_READ_ALL = 10'd513; // OOP
2577 : localparam MHPME_DMA_WRITE_ALL = 10'd514; // OOP
2578 : localparam MHPME_DMA_READ_DCCM = 10'd515; // OOP
2579 : localparam MHPME_DMA_WRITE_DCCM = 10'd516; // OOP
2580 :
2581 : // Pack the event selects into a vector for genvar
2582 : assign mhpme_vec[0][9:0] = mhpme3[9:0];
2583 : assign mhpme_vec[1][9:0] = mhpme4[9:0];
2584 : assign mhpme_vec[2][9:0] = mhpme5[9:0];
2585 : assign mhpme_vec[3][9:0] = mhpme6[9:0];
2586 :
2587 : // only consider committed itypes
2588 : //logic [3:0] pmu_i0_itype_qual;
2589 : assign pmu_i0_itype_qual[3:0] = dec_tlu_packet_r.pmu_i0_itype[3:0] & {4{tlu_i0_commit_cmt}};
2590 :
2591 : // Generate the muxed incs for all counters based on event type
2592 : for (genvar i=0 ; i < 4; i++) begin
2593 : assign mhpmc_inc_r[i] = {{~mcountinhibit[i+3]}} &
2594 : (
2595 : ({1{(mhpme_vec[i][9:0] == MHPME_CLK_ACTIVE )}} & 1'b1) |
2596 : ({1{(mhpme_vec[i][9:0] == MHPME_ICACHE_HIT )}} & {ifu_pmu_ic_hit}) |
2597 : ({1{(mhpme_vec[i][9:0] == MHPME_ICACHE_MISS )}} & {ifu_pmu_ic_miss}) |
2598 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_COMMIT )}} & {tlu_i0_commit_cmt & ~illegal_r}) |
2599 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_COMMIT_16B )}} & {tlu_i0_commit_cmt & ~exu_pmu_i0_pc4 & ~illegal_r}) |
2600 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_COMMIT_32B )}} & {tlu_i0_commit_cmt & exu_pmu_i0_pc4 & ~illegal_r}) |
2601 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_ALIGNED )}} & ifu_pmu_instr_aligned) |
2602 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_DECODED )}} & dec_pmu_instr_decoded) |
2603 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_MUL )}} & {(pmu_i0_itype_qual == MUL)}) |
2604 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_DIV )}} & {dec_tlu_packet_r.pmu_divide & tlu_i0_commit_cmt & ~illegal_r}) |
2605 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_LOAD )}} & {(pmu_i0_itype_qual == LOAD)}) |
2606 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_STORE )}} & {(pmu_i0_itype_qual == STORE)}) |
2607 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_MALOAD )}} & {(pmu_i0_itype_qual == LOAD)} &
2608 : {1{dec_tlu_packet_r.pmu_lsu_misaligned}}) |
2609 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_MASTORE )}} & {(pmu_i0_itype_qual == STORE)} &
2610 : {1{dec_tlu_packet_r.pmu_lsu_misaligned}}) |
2611 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_ALU )}} & {(pmu_i0_itype_qual == ALU)}) |
2612 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_CSRREAD )}} & {(pmu_i0_itype_qual == CSRREAD)}) |
2613 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_CSRWRITE )}} & {(pmu_i0_itype_qual == CSRWRITE)})|
2614 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_CSRRW )}} & {(pmu_i0_itype_qual == CSRRW)}) |
2615 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_EBREAK )}} & {(pmu_i0_itype_qual == EBREAK)}) |
2616 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_ECALL )}} & {(pmu_i0_itype_qual == ECALL)}) |
2617 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_FENCE )}} & {(pmu_i0_itype_qual == FENCE)}) |
2618 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_FENCEI )}} & {(pmu_i0_itype_qual == FENCEI)}) |
2619 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_MRET )}} & {(pmu_i0_itype_qual == MRET)}) |
2620 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_BRANCH )}} & {
2621 : ((pmu_i0_itype_qual == CONDBR) | (pmu_i0_itype_qual == JAL))}) |
2622 : ({1{(mhpme_vec[i][9:0] == MHPME_BRANCH_MP )}} & {exu_pmu_i0_br_misp & tlu_i0_commit_cmt & ~illegal_r}) |
2623 : ({1{(mhpme_vec[i][9:0] == MHPME_BRANCH_TAKEN )}} & {exu_pmu_i0_br_ataken & tlu_i0_commit_cmt & ~illegal_r}) |
2624 : ({1{(mhpme_vec[i][9:0] == MHPME_BRANCH_NOTP )}} & {dec_tlu_packet_r.pmu_i0_br_unpred & tlu_i0_commit_cmt & ~illegal_r}) |
2625 : ({1{(mhpme_vec[i][9:0] == MHPME_FETCH_STALL )}} & { ifu_pmu_fetch_stall}) |
2626 : ({1{(mhpme_vec[i][9:0] == MHPME_DECODE_STALL )}} & { dec_pmu_decode_stall}) |
2627 : ({1{(mhpme_vec[i][9:0] == MHPME_POSTSYNC_STALL )}} & {dec_pmu_postsync_stall}) |
2628 : ({1{(mhpme_vec[i][9:0] == MHPME_PRESYNC_STALL )}} & {dec_pmu_presync_stall}) |
2629 : ({1{(mhpme_vec[i][9:0] == MHPME_LSU_SB_WB_STALL )}} & { lsu_store_stall_any}) |
2630 : ({1{(mhpme_vec[i][9:0] == MHPME_DMA_DCCM_STALL )}} & { dma_dccm_stall_any}) |
2631 : ({1{(mhpme_vec[i][9:0] == MHPME_DMA_ICCM_STALL )}} & { dma_iccm_stall_any}) |
2632 : ({1{(mhpme_vec[i][9:0] == MHPME_EXC_TAKEN )}} & { (i0_exception_valid_r | i0_trigger_hit_r | lsu_exc_valid_r)}) |
2633 : ({1{(mhpme_vec[i][9:0] == MHPME_TIMER_INT_TAKEN )}} & { take_timer_int | take_int_timer0_int | take_int_timer1_int}) |
2634 : ({1{(mhpme_vec[i][9:0] == MHPME_EXT_INT_TAKEN )}} & { take_ext_int}) |
2635 : ({1{(mhpme_vec[i][9:0] == MHPME_FLUSH_LOWER )}} & { tlu_flush_lower_r}) |
2636 : ({1{(mhpme_vec[i][9:0] == MHPME_BR_ERROR )}} & {(dec_tlu_br0_error_r | dec_tlu_br0_start_error_r) & rfpc_i0_r}) |
2637 : ({1{(mhpme_vec[i][9:0] == MHPME_IBUS_TRANS )}} & {ifu_pmu_bus_trxn}) |
2638 : ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_TRANS )}} & {lsu_pmu_bus_trxn}) |
2639 : ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_MA_TRANS )}} & {lsu_pmu_bus_misaligned}) |
2640 : ({1{(mhpme_vec[i][9:0] == MHPME_IBUS_ERROR )}} & {ifu_pmu_bus_error}) |
2641 : ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_ERROR )}} & {lsu_pmu_bus_error}) |
2642 : ({1{(mhpme_vec[i][9:0] == MHPME_IBUS_STALL )}} & {ifu_pmu_bus_busy}) |
2643 : ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_STALL )}} & {lsu_pmu_bus_busy}) |
2644 : ({1{(mhpme_vec[i][9:0] == MHPME_INT_DISABLED )}} & {~mstatus[MSTATUS_MIE]}) |
2645 : ({1{(mhpme_vec[i][9:0] == MHPME_INT_STALLED )}} & {~mstatus[MSTATUS_MIE] & |(mip[5:0] & mie[5:0])}) |
2646 : ({1{(mhpme_vec[i][9:0] == MHPME_INST_BITMANIP )}} & {(pmu_i0_itype_qual == BITMANIPU)}) |
2647 : ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_LOAD )}} & {tlu_i0_commit_cmt & lsu_pmu_load_external_r & ~illegal_r}) |
2648 : ({1{(mhpme_vec[i][9:0] == MHPME_DBUS_STORE )}} & {tlu_i0_commit_cmt & lsu_pmu_store_external_r & ~illegal_r}) |
2649 : // These count even during sleep
2650 : ({1{(mhpme_vec[i][9:0] == MHPME_SLEEP_CYC )}} & {dec_tlu_pmu_fw_halted}) |
2651 : ({1{(mhpme_vec[i][9:0] == MHPME_DMA_READ_ALL )}} & {dma_pmu_any_read}) |
2652 : ({1{(mhpme_vec[i][9:0] == MHPME_DMA_WRITE_ALL )}} & {dma_pmu_any_write}) |
2653 : ({1{(mhpme_vec[i][9:0] == MHPME_DMA_READ_DCCM )}} & {dma_pmu_dccm_read}) |
2654 : ({1{(mhpme_vec[i][9:0] == MHPME_DMA_WRITE_DCCM )}} & {dma_pmu_dccm_write})
2655 : );
2656 : end
2657 :
2658 :
2659 : if(pt.FAST_INTERRUPT_REDIRECT) begin : genblock2
2660 :
2661 : `ifdef RV_USER_MODE
2662 : rvdffie #(33) mstatus_ff (.*, .clk(free_l2clk),
2663 : .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r,
2664 : take_ext_int_start, take_ext_int_start_d1, take_ext_int_start_d2, ext_int_freeze,
2665 : mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in,
2666 : minstret_enable, minstretl_cout_ns, fw_halted_ns,
2667 : meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted,
2668 : mstatus_ns[3:0]}),
2669 : .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1,
2670 : take_ext_int_start_d1, take_ext_int_start_d2, take_ext_int_start_d3, ext_int_freeze_d1,
2671 : mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f,
2672 : fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f,
2673 : mhpmc_inc_r_d1[3:0], perfcnt_halted_d1,
2674 : mstatus[3:0]}));
2675 : `else
2676 : rvdffie #(31) mstatus_ff (.*, .clk(free_l2clk),
2677 : .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r,
2678 : take_ext_int_start, take_ext_int_start_d1, take_ext_int_start_d2, ext_int_freeze,
2679 : mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in,
2680 : minstret_enable, minstretl_cout_ns, fw_halted_ns,
2681 : meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted,
2682 : mstatus_ns[1:0]}),
2683 : .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1,
2684 : take_ext_int_start_d1, take_ext_int_start_d2, take_ext_int_start_d3, ext_int_freeze_d1,
2685 : mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f,
2686 : fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f,
2687 : mhpmc_inc_r_d1[3:0], perfcnt_halted_d1,
2688 : mstatus[1:0]}));
2689 :
2690 : `endif
2691 :
2692 : end
2693 : else begin : genblock2
2694 : `ifdef RV_USER_MODE
2695 : rvdffie #(29) mstatus_ff (.*, .clk(free_l2clk),
2696 : .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r,
2697 : mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in,
2698 : minstret_enable, minstretl_cout_ns, fw_halted_ns,
2699 : meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted,
2700 : mstatus_ns[3:0]}),
2701 : .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1,
2702 : mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f,
2703 : fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f,
2704 : mhpmc_inc_r_d1[3:0], perfcnt_halted_d1,
2705 : mstatus[3:0]}));
2706 : `else
2707 : rvdffie #(27) mstatus_ff (.*, .clk(free_l2clk),
2708 : .din({mdseac_locked_ns, lsu_single_ecc_error_r, lsu_exc_valid_r, lsu_i0_exc_r,
2709 : mip_ns[5:0], mcyclel_cout & ~wr_mcycleh_r & mcyclel_cout_in,
2710 : minstret_enable, minstretl_cout_ns, fw_halted_ns,
2711 : meicidpl_ns[3:0], icache_rd_valid, icache_wr_valid, mhpmc_inc_r[3:0], perfcnt_halted,
2712 : mstatus_ns[1:0]}),
2713 : .dout({mdseac_locked_f, lsu_single_ecc_error_r_d1, lsu_exc_valid_r_d1, lsu_i0_exc_r_d1,
2714 : mip[5:0], mcyclel_cout_f, minstret_enable_f, minstretl_cout_f,
2715 : fw_halted, meicidpl[3:0], icache_rd_valid_f, icache_wr_valid_f,
2716 : mhpmc_inc_r_d1[3:0], perfcnt_halted_d1,
2717 : mstatus[1:0]}));
2718 : `endif
2719 : end
2720 :
2721 : assign perfcnt_halted = ((dec_tlu_dbg_halted & dcsr[DCSR_STOPC]) | dec_tlu_pmu_fw_halted);
2722 : assign perfcnt_during_sleep[3:0] = {4{~(dec_tlu_dbg_halted & dcsr[DCSR_STOPC])}} & {mhpme_vec[3][9],mhpme_vec[2][9],mhpme_vec[1][9],mhpme_vec[0][9]};
2723 :
2724 : assign dec_tlu_perfcnt0 = mhpmc_inc_r_d1[0] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[0]);
2725 : assign dec_tlu_perfcnt1 = mhpmc_inc_r_d1[1] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[1]);
2726 : assign dec_tlu_perfcnt2 = mhpmc_inc_r_d1[2] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[2]);
2727 : assign dec_tlu_perfcnt3 = mhpmc_inc_r_d1[3] & ~(perfcnt_halted_d1 & ~perfcnt_during_sleep[3]);
2728 :
2729 : // ----------------------------------------------------------------------
2730 : // MHPMC3H(RW), MHPMC3(RW)
2731 : // [63:32][31:0] : Hardware Performance Monitor Counter 3
2732 :
2733 : assign mhpmc3_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC3);
2734 : assign mhpmc3_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[0]) & (|(mhpmc_inc_r[0]));
2735 : assign mhpmc3_wr_en = mhpmc3_wr_en0 | mhpmc3_wr_en1;
2736 : assign mhpmc3_incr[63:0] = {mhpmc3h[31:0],mhpmc3[31:0]} + {63'b0, 1'b1};
2737 : assign mhpmc3_ns[31:0] = mhpmc3_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc3_incr[31:0];
2738 : rvdffe #(32) mhpmc3_ff (.*, .clk(free_l2clk), .en(mhpmc3_wr_en), .din(mhpmc3_ns[31:0]), .dout(mhpmc3[31:0]));
2739 :
2740 : assign mhpmc3h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC3H);
2741 : assign mhpmc3h_wr_en = mhpmc3h_wr_en0 | mhpmc3_wr_en1;
2742 : assign mhpmc3h_ns[31:0] = mhpmc3h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc3_incr[63:32];
2743 : rvdffe #(32) mhpmc3h_ff (.*, .clk(free_l2clk), .en(mhpmc3h_wr_en), .din(mhpmc3h_ns[31:0]), .dout(mhpmc3h[31:0]));
2744 :
2745 : // ----------------------------------------------------------------------
2746 : // MHPMC4H(RW), MHPMC4(RW)
2747 : // [63:32][31:0] : Hardware Performance Monitor Counter 4
2748 :
2749 : assign mhpmc4_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC4);
2750 : assign mhpmc4_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[1]) & (|(mhpmc_inc_r[1]));
2751 : assign mhpmc4_wr_en = mhpmc4_wr_en0 | mhpmc4_wr_en1;
2752 : assign mhpmc4_incr[63:0] = {mhpmc4h[31:0],mhpmc4[31:0]} + {63'b0,1'b1};
2753 : assign mhpmc4_ns[31:0] = mhpmc4_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc4_incr[31:0];
2754 : rvdffe #(32) mhpmc4_ff (.*, .clk(free_l2clk), .en(mhpmc4_wr_en), .din(mhpmc4_ns[31:0]), .dout(mhpmc4[31:0]));
2755 :
2756 : assign mhpmc4h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC4H);
2757 : assign mhpmc4h_wr_en = mhpmc4h_wr_en0 | mhpmc4_wr_en1;
2758 : assign mhpmc4h_ns[31:0] = mhpmc4h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc4_incr[63:32];
2759 : rvdffe #(32) mhpmc4h_ff (.*, .clk(free_l2clk), .en(mhpmc4h_wr_en), .din(mhpmc4h_ns[31:0]), .dout(mhpmc4h[31:0]));
2760 :
2761 : // ----------------------------------------------------------------------
2762 : // MHPMC5H(RW), MHPMC5(RW)
2763 : // [63:32][31:0] : Hardware Performance Monitor Counter 5
2764 :
2765 : assign mhpmc5_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC5);
2766 : assign mhpmc5_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[2]) & (|(mhpmc_inc_r[2]));
2767 : assign mhpmc5_wr_en = mhpmc5_wr_en0 | mhpmc5_wr_en1;
2768 : assign mhpmc5_incr[63:0] = {mhpmc5h[31:0],mhpmc5[31:0]} + {63'b0,1'b1};
2769 : assign mhpmc5_ns[31:0] = mhpmc5_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc5_incr[31:0];
2770 : rvdffe #(32) mhpmc5_ff (.*, .clk(free_l2clk), .en(mhpmc5_wr_en), .din(mhpmc5_ns[31:0]), .dout(mhpmc5[31:0]));
2771 :
2772 : assign mhpmc5h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC5H);
2773 : assign mhpmc5h_wr_en = mhpmc5h_wr_en0 | mhpmc5_wr_en1;
2774 : assign mhpmc5h_ns[31:0] = mhpmc5h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc5_incr[63:32];
2775 : rvdffe #(32) mhpmc5h_ff (.*, .clk(free_l2clk), .en(mhpmc5h_wr_en), .din(mhpmc5h_ns[31:0]), .dout(mhpmc5h[31:0]));
2776 :
2777 : // ----------------------------------------------------------------------
2778 : // MHPMC6H(RW), MHPMC6(RW)
2779 : // [63:32][31:0] : Hardware Performance Monitor Counter 6
2780 :
2781 : assign mhpmc6_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC6);
2782 : assign mhpmc6_wr_en1 = (~perfcnt_halted | perfcnt_during_sleep[3]) & (|(mhpmc_inc_r[3]));
2783 : assign mhpmc6_wr_en = mhpmc6_wr_en0 | mhpmc6_wr_en1;
2784 : assign mhpmc6_incr[63:0] = {mhpmc6h[31:0],mhpmc6[31:0]} + {63'b0,1'b1};
2785 : assign mhpmc6_ns[31:0] = mhpmc6_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc6_incr[31:0];
2786 : rvdffe #(32) mhpmc6_ff (.*, .clk(free_l2clk), .en(mhpmc6_wr_en), .din(mhpmc6_ns[31:0]), .dout(mhpmc6[31:0]));
2787 :
2788 : assign mhpmc6h_wr_en0 = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPMC6H);
2789 : assign mhpmc6h_wr_en = mhpmc6h_wr_en0 | mhpmc6_wr_en1;
2790 : assign mhpmc6h_ns[31:0] = mhpmc6h_wr_en0 ? dec_csr_wrdata_r[31:0] : mhpmc6_incr[63:32];
2791 : rvdffe #(32) mhpmc6h_ff (.*, .clk(free_l2clk), .en(mhpmc6h_wr_en), .din(mhpmc6h_ns[31:0]), .dout(mhpmc6h[31:0]));
2792 :
2793 : // ----------------------------------------------------------------------
2794 : // MHPME3(RW)
2795 : // [9:0] : Hardware Performance Monitor Event 3
2796 :
2797 : // we only have events 0-56 with holes, 512-516, HPME* are WARL so zero otherwise.
2798 : assign zero_event_r = ( (dec_csr_wrdata_r[9:0] > 10'd516) |
2799 : (|dec_csr_wrdata_r[31:10]) |
2800 : ((dec_csr_wrdata_r[9:0] < 10'd512) & (dec_csr_wrdata_r[9:0] > 10'd56)) |
2801 : ((dec_csr_wrdata_r[9:0] < 10'd54) & (dec_csr_wrdata_r[9:0] > 10'd50)) |
2802 : (dec_csr_wrdata_r[9:0] == 10'd29) |
2803 : (dec_csr_wrdata_r[9:0] == 10'd33)
2804 : );
2805 :
2806 : assign event_r[9:0] = zero_event_r ? '0 : dec_csr_wrdata_r[9:0];
2807 :
2808 : assign wr_mhpme3_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME3);
2809 : rvdffe #(10) mhpme3_ff (.*, .en(wr_mhpme3_r), .din(event_r[9:0]), .dout(mhpme3[9:0]));
2810 : // ----------------------------------------------------------------------
2811 : // MHPME4(RW)
2812 : // [9:0] : Hardware Performance Monitor Event 4
2813 :
2814 : assign wr_mhpme4_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME4);
2815 : rvdffe #(10) mhpme4_ff (.*, .en(wr_mhpme4_r), .din(event_r[9:0]), .dout(mhpme4[9:0]));
2816 : // ----------------------------------------------------------------------
2817 : // MHPME5(RW)
2818 : // [9:0] : Hardware Performance Monitor Event 5
2819 :
2820 : assign wr_mhpme5_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME5);
2821 : rvdffe #(10) mhpme5_ff (.*, .en(wr_mhpme5_r), .din(event_r[9:0]), .dout(mhpme5[9:0]));
2822 : // ----------------------------------------------------------------------
2823 : // MHPME6(RW)
2824 : // [9:0] : Hardware Performance Monitor Event 6
2825 :
2826 : assign wr_mhpme6_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MHPME6);
2827 : rvdffe #(10) mhpme6_ff (.*, .en(wr_mhpme6_r), .din(event_r[9:0]), .dout(mhpme6[9:0]));
2828 :
2829 : //----------------------------------------------------------------------
2830 : // Performance Monitor Counters section ends
2831 : //----------------------------------------------------------------------
2832 : // ----------------------------------------------------------------------
2833 :
2834 : // ----------------------------------------------------------------------
2835 : // MCOUNTEREN
2836 : // [31:3] : Reserved, read 0x0
2837 : // [2] : INSTRET user-mode access disable
2838 : // [1] : reserved, read 0x0
2839 : // [0] : CYCLE user-mode access disable
2840 :
2841 : `ifdef RV_USER_MODE
2842 :
2843 : localparam MCOUNTEREN = 12'h306;
2844 :
2845 : assign wr_mcounteren_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCOUNTEREN);
2846 : rvdffs #(6) mcounteren_ff (.*, .clk(csr_wr_clk), .en(wr_mcounteren_r), .din({dec_csr_wrdata_r[6:2], dec_csr_wrdata_r[0]}), .dout(mcounteren));
2847 :
2848 : `endif
2849 :
2850 : // MCOUNTINHIBIT(RW)
2851 : // [31:7] : Reserved, read 0x0
2852 : // [6] : HPM6 disable
2853 : // [5] : HPM5 disable
2854 : // [4] : HPM4 disable
2855 : // [3] : HPM3 disable
2856 : // [2] : MINSTRET disable
2857 : // [1] : reserved, read 0x0
2858 : // [0] : MCYCLE disable
2859 :
2860 : assign wr_mcountinhibit_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MCOUNTINHIBIT);
2861 : rvdffs #(6) mcountinhibit_ff (.*, .clk(csr_wr_clk), .en(wr_mcountinhibit_r), .din({dec_csr_wrdata_r[6:2], dec_csr_wrdata_r[0]}), .dout({mcountinhibit[6:2], mcountinhibit[0]}));
2862 : assign mcountinhibit[1] = 1'b0;
2863 :
2864 : //--------------------------------------------------------------------------------
2865 : // trace
2866 : //--------------------------------------------------------------------------------
2867 4 : logic [4:0] dec_tlu_exc_cause_wb1_raw, dec_tlu_exc_cause_wb2;
2868 20 : logic dec_tlu_int_valid_wb1_raw, dec_tlu_int_valid_wb2;
2869 :
2870 : assign {dec_tlu_i0_valid_wb1,
2871 : dec_tlu_i0_exc_valid_wb1,
2872 : dec_tlu_exc_cause_wb1_raw[4:0],
2873 : dec_tlu_int_valid_wb1_raw} = {8{~dec_tlu_trace_disable}} & {i0_valid_wb,
2874 : i0_exception_valid_r_d1 | lsu_i0_exc_r_d1 | (trigger_hit_r_d1 & ~trigger_hit_dmode_r_d1),
2875 : exc_cause_wb[4:0],
2876 : interrupt_valid_r_d1};
2877 :
2878 :
2879 :
2880 : // skid buffer for ints, reduces trace port count by 1
2881 : rvdffie #(.WIDTH(6), .OVERRIDE(1)) traceskidff (.*, .clk(clk),
2882 : .din ({dec_tlu_exc_cause_wb1_raw[4:0],
2883 : dec_tlu_int_valid_wb1_raw}),
2884 : .dout({dec_tlu_exc_cause_wb2[4:0],
2885 : dec_tlu_int_valid_wb2}));
2886 : //skid for ints
2887 : assign dec_tlu_exc_cause_wb1[4:0] = dec_tlu_int_valid_wb2 ? dec_tlu_exc_cause_wb2[4:0] : dec_tlu_exc_cause_wb1_raw[4:0];
2888 : assign dec_tlu_int_valid_wb1 = dec_tlu_int_valid_wb2;
2889 :
2890 : assign dec_tlu_mtval_wb1 = mtval[31:0];
2891 :
2892 : // end trace
2893 : //--------------------------------------------------------------------------------
2894 :
2895 :
2896 : // ----------------------------------------------------------------------
2897 : // CSR read mux
2898 : // ----------------------------------------------------------------------
2899 :
2900 : assign dec_tlu_presync_d = presync & dec_csr_any_unq_d & ~dec_csr_wen_unq_d;
2901 : assign dec_tlu_postsync_d = postsync & dec_csr_any_unq_d;
2902 :
2903 : // allow individual configuration of these features
2904 : assign conditionally_illegal = ((csr_mitcnt0 | csr_mitcnt1 | csr_mitb0 | csr_mitb1 | csr_mitctl0 | csr_mitctl1) & ~|pt.TIMER_LEGAL_EN);
2905 :
2906 : assign valid_csr = ( legal & (~(csr_dcsr | csr_dpc | csr_dmst | csr_dicawics | csr_dicad0 | csr_dicad0h | csr_dicad1 | csr_dicago) | dbg_tlu_halted_f)
2907 : & ~fast_int_meicpct & ~conditionally_illegal);
2908 :
2909 : assign dec_csr_legal_d = ( dec_csr_any_unq_d &
2910 : valid_csr & // of a valid CSR
2911 : ~(dec_csr_wen_unq_d & (csr_mvendorid | csr_marchid | csr_mimpid | csr_mhartid | csr_mdseac | csr_meihap)) // that's not a write to a RO CSR
2912 : );
2913 : // CSR read mux
2914 : assign dec_csr_rddata_d[31:0] = (
2915 : `ifdef RV_USER_MODE
2916 : ({32{csr_misa}} & 32'h40101104) |
2917 : `else
2918 : ({32{csr_misa}} & 32'h40001104) |
2919 : `endif
2920 : ({32{csr_mvendorid}} & 32'h00000045) |
2921 : ({32{csr_marchid}} & 32'h00000010) |
2922 : ({32{csr_mimpid}} & 32'h4) |
2923 : ({32{csr_mhartid}} & {core_id[31:4], 4'b0}) |
2924 : `ifdef RV_USER_MODE
2925 : ({32{csr_mstatus}} & {14'b0, mstatus[MSTATUS_MPRV], 4'b0, ~mstatus[MSTATUS_MPP], ~mstatus[MSTATUS_MPP], 3'b0, mstatus[MSTATUS_MPIE], 3'b0, mstatus[MSTATUS_MIE], 3'b0}) |
2926 : `else
2927 : ({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[MSTATUS_MPIE], 3'b0, mstatus[MSTATUS_MIE], 3'b0}) |
2928 : `endif
2929 : ({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) |
2930 : ({32{csr_mip}} & {1'b0, mip[5:3], 16'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
2931 : ({32{csr_mie}} & {1'b0, mie[5:3], 16'b0, mie[2], 3'b0, mie[1], 3'b0, mie[0], 3'b0}) |
2932 : ({32{csr_mcyclel}} & mcyclel[31:0]) |
2933 : ({32{csr_mcycleh}} & mcycleh_inc[31:0]) |
2934 : ({32{csr_minstretl}} & minstretl_read[31:0]) |
2935 : ({32{csr_minstreth}} & minstreth_read[31:0]) |
2936 : ({32{csr_mscratch}} & mscratch[31:0]) |
2937 : ({32{csr_mepc}} & {mepc[31:1], 1'b0}) |
2938 : ({32{csr_mcause}} & mcause[31:0]) |
2939 : ({32{csr_mscause}} & {28'b0, mscause[3:0]}) |
2940 : ({32{csr_mtval}} & mtval[31:0]) |
2941 : ({32{csr_mrac}} & mrac[31:0]) |
2942 : ({32{csr_mdseac}} & mdseac[31:0]) |
2943 : ({32{csr_meivt}} & {meivt[31:10], 10'b0}) |
2944 : ({32{csr_meihap}} & {meivt[31:10], meihap[9:2], 2'b0}) |
2945 : ({32{csr_meicurpl}} & {28'b0, meicurpl[3:0]}) |
2946 : ({32{csr_meicidpl}} & {28'b0, meicidpl[3:0]}) |
2947 : ({32{csr_meipt}} & {28'b0, meipt[3:0]}) |
2948 : ({32{csr_mcgc}} & {22'b0, mcgc[9:0]}) |
2949 : ({32{csr_mfdc}} & {13'b0, mfdc[18:0]}) |
2950 : ({32{csr_dcsr}} & {16'h4000, dcsr[15:2], 2'b11}) |
2951 : ({32{csr_dpc}} & {dpc[31:1], 1'b0}) |
2952 : ({32{csr_dicad0}} & dicad0[31:0]) |
2953 : ({32{csr_dicad0h}} & dicad0h[31:0]) |
2954 : ({32{csr_dicad1}} & dicad1[31:0]) |
2955 : ({32{csr_dicawics}} & {7'b0, dicawics[16], 2'b0, dicawics[15:14], 3'b0, dicawics[13:0], 3'b0}) |
2956 : ({32{csr_mtsel}} & {30'b0, mtsel[1:0]}) |
2957 : ({32{csr_mtdata1}} & {mtdata1_tsel_out[31:0]}) |
2958 : ({32{csr_mtdata2}} & {mtdata2_tsel_out[31:0]}) |
2959 : ({32{csr_micect}} & {micect[31:0]}) |
2960 : ({32{csr_miccmect}} & {miccmect[31:0]}) |
2961 : ({32{csr_mdccmect}} & {mdccmect[31:0]}) |
2962 : ({32{csr_mhpmc3}} & mhpmc3[31:0]) |
2963 : ({32{csr_mhpmc4}} & mhpmc4[31:0]) |
2964 : ({32{csr_mhpmc5}} & mhpmc5[31:0]) |
2965 : ({32{csr_mhpmc6}} & mhpmc6[31:0]) |
2966 : ({32{csr_mhpmc3h}} & mhpmc3h[31:0]) |
2967 : ({32{csr_mhpmc4h}} & mhpmc4h[31:0]) |
2968 : ({32{csr_mhpmc5h}} & mhpmc5h[31:0]) |
2969 : ({32{csr_mhpmc6h}} & mhpmc6h[31:0]) |
2970 : ({32{csr_mfdht}} & {26'b0, mfdht[5:0]}) |
2971 : ({32{csr_mfdhs}} & {30'b0, mfdhs[1:0]}) |
2972 : ({32{csr_mhpme3}} & {22'b0,mhpme3[9:0]}) |
2973 : ({32{csr_mhpme4}} & {22'b0,mhpme4[9:0]}) |
2974 : ({32{csr_mhpme5}} & {22'b0,mhpme5[9:0]}) |
2975 : ({32{csr_mhpme6}} & {22'b0,mhpme6[9:0]}) |
2976 : `ifdef RV_USER_MODE
2977 : ({32{csr_menvcfg}} & 32'd0) |
2978 : ({32{csr_menvcfgh}} & 32'd0) |
2979 : ({32{csr_mcounteren}} & {25'b0, mcounteren[5:1], 1'b0, mcounteren[0]}) |
2980 : ({32{csr_cyclel}} & mcyclel[31:0]) |
2981 : ({32{csr_cycleh}} & mcycleh_inc[31:0]) |
2982 : ({32{csr_instretl}} & minstretl_read[31:0]) |
2983 : ({32{csr_instreth}} & minstreth_read[31:0]) |
2984 : ({32{csr_hpmc3}} & mhpmc3[31:0]) |
2985 : ({32{csr_hpmc4}} & mhpmc4[31:0]) |
2986 : ({32{csr_hpmc5}} & mhpmc5[31:0]) |
2987 : ({32{csr_hpmc6}} & mhpmc6[31:0]) |
2988 : ({32{csr_hpmc3h}} & mhpmc3h[31:0]) |
2989 : ({32{csr_hpmc4h}} & mhpmc4h[31:0]) |
2990 : ({32{csr_hpmc5h}} & mhpmc5h[31:0]) |
2991 : ({32{csr_hpmc6h}} & mhpmc6h[31:0]) |
2992 : ({32{csr_mseccfgl}} & {29'd0, mseccfg}) |
2993 : ({32{csr_mseccfgh}} & 32'd0) | // All bits are WPRI
2994 : `endif
2995 : ({32{csr_mcountinhibit}} & {25'b0, mcountinhibit[6:0]}) |
2996 : ({32{csr_mpmc}} & {30'b0, mpmc[1], 1'b0}) |
2997 : ({32{dec_timer_read_d}} & dec_timer_rddata_d[31:0]) |
2998 : ({32{dec_pmp_read_d}} & dec_pmp_rddata_d[31:0])
2999 : );
3000 :
3001 :
3002 :
3003 : endmodule // el2_dec_tlu_ctl
3004 :
3005 : module el2_dec_timer_ctl
3006 : import el2_pkg::*;
3007 : #(
3008 : `include "el2_param.vh"
3009 : )
3010 : (
3011 69840565 : input logic clk,
3012 69840565 : input logic free_l2clk,
3013 69840565 : input logic csr_wr_clk,
3014 338 : input logic rst_l,
3015 42288 : input logic dec_csr_wen_r_mod, // csr write enable at wb
3016 542 : input logic [11:0] dec_csr_wraddr_r, // write address for csr
3017 1686 : input logic [31:0] dec_csr_wrdata_r, // csr write data at wb
3018 :
3019 16 : input logic csr_mitctl0,
3020 16 : input logic csr_mitctl1,
3021 16 : input logic csr_mitb0,
3022 14 : input logic csr_mitb1,
3023 10 : input logic csr_mitcnt0,
3024 18 : input logic csr_mitcnt1,
3025 :
3026 :
3027 2 : input logic dec_pause_state, // Paused
3028 108 : input logic dec_tlu_pmu_fw_halted, // pmu/fw halted
3029 120 : input logic internal_dbg_halt_timers, // debug halted
3030 :
3031 30 : output logic [31:0] dec_timer_rddata_d, // timer CSR read data
3032 82 : output logic dec_timer_read_d, // timer CSR address match
3033 354 : output logic dec_timer_t0_pulse, // timer0 int
3034 342 : output logic dec_timer_t1_pulse, // timer1 int
3035 :
3036 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
3037 : /*verilator coverage_off*/
3038 : input logic scan_mode
3039 : /*verilator coverage_on*/
3040 : );
3041 : localparam MITCTL_ENABLE = 0;
3042 : localparam MITCTL_ENABLE_HALTED = 1;
3043 : localparam MITCTL_ENABLE_PAUSED = 2;
3044 :
3045 47151 : logic [31:0] mitcnt0_ns, mitcnt0, mitcnt1_ns, mitcnt1, mitb0, mitb1, mitb0_b, mitb1_b, mitcnt0_inc, mitcnt1_inc;
3046 0 : logic [2:0] mitctl0_ns, mitctl0;
3047 0 : logic [3:0] mitctl1_ns, mitctl1;
3048 2 : logic wr_mitcnt0_r, wr_mitcnt1_r, wr_mitb0_r, wr_mitb1_r, wr_mitctl0_r, wr_mitctl1_r;
3049 571 : logic mitcnt0_inc_ok, mitcnt1_inc_ok;
3050 188893 : logic mitcnt0_inc_cout, mitcnt1_inc_cout;
3051 354 : logic mit0_match_ns;
3052 342 : logic mit1_match_ns;
3053 2 : logic mitctl0_0_b_ns;
3054 2 : logic mitctl0_0_b;
3055 2 : logic mitctl1_0_b_ns;
3056 2 : logic mitctl1_0_b;
3057 :
3058 : assign mit0_match_ns = (mitcnt0[31:0] >= mitb0[31:0]);
3059 : assign mit1_match_ns = (mitcnt1[31:0] >= mitb1[31:0]);
3060 :
3061 : assign dec_timer_t0_pulse = mit0_match_ns;
3062 : assign dec_timer_t1_pulse = mit1_match_ns;
3063 : // ----------------------------------------------------------------------
3064 : // MITCNT0 (RW)
3065 : // [31:0] : Internal Timer Counter 0
3066 :
3067 : localparam MITCNT0 = 12'h7d2;
3068 :
3069 : assign wr_mitcnt0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCNT0);
3070 :
3071 : assign mitcnt0_inc_ok = mitctl0[MITCTL_ENABLE] & (~dec_pause_state | mitctl0[MITCTL_ENABLE_PAUSED]) & (~dec_tlu_pmu_fw_halted | mitctl0[MITCTL_ENABLE_HALTED]) & ~internal_dbg_halt_timers;
3072 :
3073 : assign {mitcnt0_inc_cout, mitcnt0_inc[7:0]} = mitcnt0[7:0] + {7'b0, 1'b1};
3074 : assign mitcnt0_inc[31:8] = mitcnt0[31:8] + {23'b0, mitcnt0_inc_cout};
3075 :
3076 : assign mitcnt0_ns[31:0] = wr_mitcnt0_r ? dec_csr_wrdata_r[31:0] : mit0_match_ns ? 'b0 : mitcnt0_inc[31:0];
3077 :
3078 : rvdffe #(24) mitcnt0_ffb (.*, .clk(free_l2clk), .en(wr_mitcnt0_r | (mitcnt0_inc_ok & mitcnt0_inc_cout) | mit0_match_ns), .din(mitcnt0_ns[31:8]), .dout(mitcnt0[31:8]));
3079 : rvdffe #(8) mitcnt0_ffa (.*, .clk(free_l2clk), .en(wr_mitcnt0_r | mitcnt0_inc_ok | mit0_match_ns), .din(mitcnt0_ns[7:0]), .dout(mitcnt0[7:0]));
3080 :
3081 : // ----------------------------------------------------------------------
3082 : // MITCNT1 (RW)
3083 : // [31:0] : Internal Timer Counter 0
3084 :
3085 : localparam MITCNT1 = 12'h7d5;
3086 :
3087 : assign wr_mitcnt1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCNT1);
3088 :
3089 : assign mitcnt1_inc_ok = mitctl1[MITCTL_ENABLE] &
3090 : (~dec_pause_state | mitctl1[MITCTL_ENABLE_PAUSED]) &
3091 : (~dec_tlu_pmu_fw_halted | mitctl1[MITCTL_ENABLE_HALTED]) &
3092 : ~internal_dbg_halt_timers &
3093 : (~mitctl1[3] | mit0_match_ns);
3094 :
3095 : // only inc MITCNT1 if not cascaded with 0, or if 0 overflows
3096 : assign {mitcnt1_inc_cout, mitcnt1_inc[7:0]} = mitcnt1[7:0] + {7'b0, 1'b1};
3097 : assign mitcnt1_inc[31:8] = mitcnt1[31:8] + {23'b0, mitcnt1_inc_cout};
3098 :
3099 : assign mitcnt1_ns[31:0] = wr_mitcnt1_r ? dec_csr_wrdata_r[31:0] : mit1_match_ns ? 'b0 : mitcnt1_inc[31:0];
3100 :
3101 : rvdffe #(24) mitcnt1_ffb (.*, .clk(free_l2clk), .en(wr_mitcnt1_r | (mitcnt1_inc_ok & mitcnt1_inc_cout) | mit1_match_ns), .din(mitcnt1_ns[31:8]), .dout(mitcnt1[31:8]));
3102 : rvdffe #(8) mitcnt1_ffa (.*, .clk(free_l2clk), .en(wr_mitcnt1_r | mitcnt1_inc_ok | mit1_match_ns), .din(mitcnt1_ns[7:0]), .dout(mitcnt1[7:0]));
3103 :
3104 :
3105 : // ----------------------------------------------------------------------
3106 : // MITB0 (RW)
3107 : // [31:0] : Internal Timer Bound 0
3108 :
3109 : localparam MITB0 = 12'h7d3;
3110 :
3111 : assign wr_mitb0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITB0);
3112 :
3113 : rvdffe #(32) mitb0_ff (.*, .en(wr_mitb0_r), .din(~dec_csr_wrdata_r[31:0]), .dout(mitb0_b[31:0]));
3114 : assign mitb0[31:0] = ~mitb0_b[31:0];
3115 :
3116 : // ----------------------------------------------------------------------
3117 : // MITB1 (RW)
3118 : // [31:0] : Internal Timer Bound 1
3119 :
3120 : localparam MITB1 = 12'h7d6;
3121 :
3122 : assign wr_mitb1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITB1);
3123 :
3124 : rvdffe #(32) mitb1_ff (.*, .en(wr_mitb1_r), .din(~dec_csr_wrdata_r[31:0]), .dout(mitb1_b[31:0]));
3125 : assign mitb1[31:0] = ~mitb1_b[31:0];
3126 :
3127 : // ----------------------------------------------------------------------
3128 : // MITCTL0 (RW) Internal Timer Ctl 0
3129 : // [31:3] : Reserved, reads 0x0
3130 : // [2] : Enable while PAUSEd
3131 : // [1] : Enable while HALTed
3132 : // [0] : Enable (resets to 0x1)
3133 :
3134 : localparam MITCTL0 = 12'h7d4;
3135 :
3136 : assign wr_mitctl0_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCTL0);
3137 : assign mitctl0_ns[2:0] = wr_mitctl0_r ? {dec_csr_wrdata_r[2:0]} : {mitctl0[2:0]};
3138 :
3139 : assign mitctl0_0_b_ns = ~mitctl0_ns[0];
3140 : rvdffs #(3) mitctl0_ff (.*, .clk(csr_wr_clk), .en(wr_mitctl0_r), .din({mitctl0_ns[2:1], mitctl0_0_b_ns}), .dout({mitctl0[2:1], mitctl0_0_b}));
3141 : assign mitctl0[0] = ~mitctl0_0_b;
3142 :
3143 : // ----------------------------------------------------------------------
3144 : // MITCTL1 (RW) Internal Timer Ctl 1
3145 : // [31:4] : Reserved, reads 0x0
3146 : // [3] : Cascade
3147 : // [2] : Enable while PAUSEd
3148 : // [1] : Enable while HALTed
3149 : // [0] : Enable (resets to 0x1)
3150 :
3151 : localparam MITCTL1 = 12'h7d7;
3152 :
3153 : assign wr_mitctl1_r = dec_csr_wen_r_mod & (dec_csr_wraddr_r[11:0] == MITCTL1);
3154 : assign mitctl1_ns[3:0] = wr_mitctl1_r ? {dec_csr_wrdata_r[3:0]} : {mitctl1[3:0]};
3155 :
3156 : assign mitctl1_0_b_ns = ~mitctl1_ns[0];
3157 : rvdffs #(4) mitctl1_ff (.*, .clk(csr_wr_clk), .en(wr_mitctl1_r), .din({mitctl1_ns[3:1], mitctl1_0_b_ns}), .dout({mitctl1[3:1], mitctl1_0_b}));
3158 : assign mitctl1[0] = ~mitctl1_0_b;
3159 : assign dec_timer_read_d = csr_mitcnt1 | csr_mitcnt0 | csr_mitb1 | csr_mitb0 | csr_mitctl0 | csr_mitctl1;
3160 : assign dec_timer_rddata_d[31:0] = ( ({32{csr_mitcnt0}} & mitcnt0[31:0]) |
3161 : ({32{csr_mitcnt1}} & mitcnt1[31:0]) |
3162 : ({32{csr_mitb0}} & mitb0[31:0]) |
3163 : ({32{csr_mitb1}} & mitb1[31:0]) |
3164 : ({32{csr_mitctl0}} & {29'b0, mitctl0[2:0]}) |
3165 : ({32{csr_mitctl1}} & {28'b0, mitctl1[3:0]})
3166 : );
3167 :
3168 :
3169 : endmodule // dec_timer_ctl
|