-
Notifications
You must be signed in to change notification settings - Fork 2
/
cluster_icache_ctrl_unit.sv
97 lines (78 loc) · 3.72 KB
/
cluster_icache_ctrl_unit.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2024 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
// Michael Rogenmoser <[email protected]>
module cluster_icache_ctrl_unit import snitch_icache_pkg::*; #(
parameter int unsigned NR_FETCH_PORTS = -1,
parameter type reg_req_t = logic,
parameter type reg_rsp_t = logic
) (
input logic clk_i,
input logic rst_ni,
input reg_req_t reg_req_i,
output reg_rsp_t reg_rsp_o,
output logic enable_prefetching_o,
output logic [NR_FETCH_PORTS-1:0] flush_valid_o,
input logic [NR_FETCH_PORTS-1:0] flush_ready_i,
input icache_l0_events_t [NR_FETCH_PORTS-1:0] l0_events_i,
input icache_l1_events_t l1_events_i
);
import cluster_icache_ctrl_reg_pkg::*;
initial begin
assert(NumL0Events == $bits(icache_l0_events_t));
assert(NumL1Events == $bits(icache_l1_events_t));
assert(NumAvailableCounters >= NumL1Events + NR_FETCH_PORTS*NumL0Events);
assert(NR_FETCH_PORTS <= NumCores);
end
cluster_icache_ctrl_reg2hw_t reg2hw;
cluster_icache_ctrl_hw2reg_t hw2reg;
cluster_icache_ctrl_reg_top #(
.reg_req_t(reg_req_t),
.reg_rsp_t(reg_rsp_t)
) i_regs (
.clk_i,
.rst_ni,
.reg_req_i,
.reg_rsp_o,
.reg2hw (reg2hw),
.hw2reg (hw2reg)
);
cluster_icache_ctrl_hw2reg_counters_mreg_t [NumAvailableCounters-1:0] counters_reg;
always_comb begin : gen_counters_reg
// set up defaults - increment but not active
for (int unsigned i = 0; i < NumAvailableCounters; i++) begin
counters_reg[i].d = reg2hw.counters[i].q + 1;
counters_reg[i].de = '0;
end
// Activate increment counters
counters_reg[0].de = reg2hw.enable_counters.q & l1_events_i.l1_miss;
counters_reg[1].de = reg2hw.enable_counters.q & l1_events_i.l1_hit;
counters_reg[2].de = reg2hw.enable_counters.q & l1_events_i.l1_stall;
counters_reg[3].de = reg2hw.enable_counters.q & l1_events_i.l1_handler_stall;
counters_reg[5].de = reg2hw.enable_counters.q & l1_events_i.l1_tag_parity_error;
counters_reg[6].de = reg2hw.enable_counters.q & l1_events_i.l1_data_parity_error;
for (int unsigned i = 0; i < NR_FETCH_PORTS; i++) begin
counters_reg[NumL1Events + i*NumL0Events + 0].de = reg2hw.enable_counters.q & l0_events_i[i].l0_miss;
counters_reg[NumL1Events + i*NumL0Events + 1].de = reg2hw.enable_counters.q & l0_events_i[i].l0_hit;
counters_reg[NumL1Events + i*NumL0Events + 2].de = reg2hw.enable_counters.q & l0_events_i[i].l0_prefetch;
counters_reg[NumL1Events + i*NumL0Events + 3].de = reg2hw.enable_counters.q & l0_events_i[i].l0_double_hit;
counters_reg[NumL1Events + i*NumL0Events + 4].de = reg2hw.enable_counters.q & l0_events_i[i].l0_stall;
end
// Clear on global clear signal
if (reg2hw.clear_counters.q) begin
for (int unsigned i = 0; i < NumAvailableCounters; i++) begin
counters_reg[i].d = '0;
counters_reg[i].de = '1;
end
end
end
assign enable_prefetching_o = reg2hw.enable_prefetch.q;
assign flush_valid_o = ({NR_FETCH_PORTS{reg2hw.flush.q}} & {NR_FETCH_PORTS{reg2hw.flush.qe}}) |
(reg2hw.sel_flush_icache.q[NR_FETCH_PORTS-1:0] &
{NR_FETCH_PORTS{reg2hw.sel_flush_icache.qe}});
assign hw2reg.flush.d = ~|flush_ready_i;
assign hw2reg.flush_l1_only.d = '0;
assign hw2reg.sel_flush_icache.d = ~flush_ready_i;
assign hw2reg.clear_counters.d = '0;
assign hw2reg.counters = counters_reg;
endmodule