diff --git a/src/ctrl_unit/cluster_icache_ctrl.hjson b/src/ctrl_unit/cluster_icache_ctrl.hjson index bcfe6a1..4a39a4e 100644 --- a/src/ctrl_unit/cluster_icache_ctrl.hjson +++ b/src/ctrl_unit/cluster_icache_ctrl.hjson @@ -17,9 +17,17 @@ desc: "Number of cores", default: "8" }, + { name: "NumL0Events", + desc: "Number of L0 events", + default: "5" + }, + { name: "NumL1Events", + desc: "Number of L1 events", + default: "6" + }, { name: "NumAvailableCounters", desc: "Number of available counters", - default: "44" // NumL1Events + NumCores * NumL0Events + default: "46" // NumL1Events + NumCores * NumL0Events }, ], diff --git a/src/ctrl_unit/cluster_icache_ctrl_reg_pkg.sv b/src/ctrl_unit/cluster_icache_ctrl_reg_pkg.sv index 8df9fbe..4370993 100644 --- a/src/ctrl_unit/cluster_icache_ctrl_reg_pkg.sv +++ b/src/ctrl_unit/cluster_icache_ctrl_reg_pkg.sv @@ -8,7 +8,9 @@ package cluster_icache_ctrl_reg_pkg; // Param list parameter int NumCores = 8; - parameter int NumAvailableCounters = 44; + parameter int NumL0Events = 5; + parameter int NumL1Events = 6; + parameter int NumAvailableCounters = 46; // Address widths within the block parameter int BlockAw = 8; @@ -76,23 +78,23 @@ package cluster_icache_ctrl_reg_pkg; // Register -> HW type typedef struct packed { - cluster_icache_ctrl_reg2hw_enable_reg_t enable; // [1425:1425] - cluster_icache_ctrl_reg2hw_flush_reg_t flush; // [1424:1423] - cluster_icache_ctrl_reg2hw_flush_l1_only_reg_t flush_l1_only; // [1422:1421] - cluster_icache_ctrl_reg2hw_sel_flush_icache_reg_t sel_flush_icache; // [1420:1412] - cluster_icache_ctrl_reg2hw_clear_counters_reg_t clear_counters; // [1411:1410] - cluster_icache_ctrl_reg2hw_enable_counters_reg_t enable_counters; // [1409:1409] - cluster_icache_ctrl_reg2hw_enable_prefetch_reg_t enable_prefetch; // [1408:1408] - cluster_icache_ctrl_reg2hw_counters_mreg_t [43:0] counters; // [1407:0] + cluster_icache_ctrl_reg2hw_enable_reg_t enable; // [1489:1489] + cluster_icache_ctrl_reg2hw_flush_reg_t flush; // [1488:1487] + cluster_icache_ctrl_reg2hw_flush_l1_only_reg_t flush_l1_only; // [1486:1485] + cluster_icache_ctrl_reg2hw_sel_flush_icache_reg_t sel_flush_icache; // [1484:1476] + cluster_icache_ctrl_reg2hw_clear_counters_reg_t clear_counters; // [1475:1474] + cluster_icache_ctrl_reg2hw_enable_counters_reg_t enable_counters; // [1473:1473] + cluster_icache_ctrl_reg2hw_enable_prefetch_reg_t enable_prefetch; // [1472:1472] + cluster_icache_ctrl_reg2hw_counters_mreg_t [45:0] counters; // [1471:0] } cluster_icache_ctrl_reg2hw_t; // HW -> register type typedef struct packed { - cluster_icache_ctrl_hw2reg_flush_reg_t flush; // [1462:1462] - cluster_icache_ctrl_hw2reg_flush_l1_only_reg_t flush_l1_only; // [1461:1461] - cluster_icache_ctrl_hw2reg_sel_flush_icache_reg_t sel_flush_icache; // [1460:1453] - cluster_icache_ctrl_hw2reg_clear_counters_reg_t clear_counters; // [1452:1452] - cluster_icache_ctrl_hw2reg_counters_mreg_t [43:0] counters; // [1451:0] + cluster_icache_ctrl_hw2reg_flush_reg_t flush; // [1528:1528] + cluster_icache_ctrl_hw2reg_flush_l1_only_reg_t flush_l1_only; // [1527:1527] + cluster_icache_ctrl_hw2reg_sel_flush_icache_reg_t sel_flush_icache; // [1526:1519] + cluster_icache_ctrl_hw2reg_clear_counters_reg_t clear_counters; // [1518:1518] + cluster_icache_ctrl_hw2reg_counters_mreg_t [45:0] counters; // [1517:0] } cluster_icache_ctrl_hw2reg_t; // Register offsets @@ -147,6 +149,8 @@ package cluster_icache_ctrl_reg_pkg; parameter logic [BlockAw-1:0] CLUSTER_ICACHE_CTRL_COUNTERS_41_OFFSET = 8'h c4; parameter logic [BlockAw-1:0] CLUSTER_ICACHE_CTRL_COUNTERS_42_OFFSET = 8'h c8; parameter logic [BlockAw-1:0] CLUSTER_ICACHE_CTRL_COUNTERS_43_OFFSET = 8'h cc; + parameter logic [BlockAw-1:0] CLUSTER_ICACHE_CTRL_COUNTERS_44_OFFSET = 8'h d0; + parameter logic [BlockAw-1:0] CLUSTER_ICACHE_CTRL_COUNTERS_45_OFFSET = 8'h d4; // Reset values for hwext registers and their fields parameter logic [0:0] CLUSTER_ICACHE_CTRL_FLUSH_RESVAL = 1'h 0; @@ -210,11 +214,13 @@ package cluster_icache_ctrl_reg_pkg; CLUSTER_ICACHE_CTRL_COUNTERS_40, CLUSTER_ICACHE_CTRL_COUNTERS_41, CLUSTER_ICACHE_CTRL_COUNTERS_42, - CLUSTER_ICACHE_CTRL_COUNTERS_43 + CLUSTER_ICACHE_CTRL_COUNTERS_43, + CLUSTER_ICACHE_CTRL_COUNTERS_44, + CLUSTER_ICACHE_CTRL_COUNTERS_45 } cluster_icache_ctrl_id_e; // Register width information to check illegal writes - parameter logic [3:0] CLUSTER_ICACHE_CTRL_PERMIT [51] = '{ + parameter logic [3:0] CLUSTER_ICACHE_CTRL_PERMIT [53] = '{ 4'b 0001, // index[ 0] CLUSTER_ICACHE_CTRL_ENABLE 4'b 0001, // index[ 1] CLUSTER_ICACHE_CTRL_FLUSH 4'b 0001, // index[ 2] CLUSTER_ICACHE_CTRL_FLUSH_L1_ONLY @@ -265,7 +271,9 @@ package cluster_icache_ctrl_reg_pkg; 4'b 1111, // index[47] CLUSTER_ICACHE_CTRL_COUNTERS_40 4'b 1111, // index[48] CLUSTER_ICACHE_CTRL_COUNTERS_41 4'b 1111, // index[49] CLUSTER_ICACHE_CTRL_COUNTERS_42 - 4'b 1111 // index[50] CLUSTER_ICACHE_CTRL_COUNTERS_43 + 4'b 1111, // index[50] CLUSTER_ICACHE_CTRL_COUNTERS_43 + 4'b 1111, // index[51] CLUSTER_ICACHE_CTRL_COUNTERS_44 + 4'b 1111 // index[52] CLUSTER_ICACHE_CTRL_COUNTERS_45 }; endpackage diff --git a/src/ctrl_unit/cluster_icache_ctrl_reg_top.sv b/src/ctrl_unit/cluster_icache_ctrl_reg_top.sv index 9f9d0ca..305ac0b 100644 --- a/src/ctrl_unit/cluster_icache_ctrl_reg_top.sv +++ b/src/ctrl_unit/cluster_icache_ctrl_reg_top.sv @@ -225,6 +225,12 @@ module cluster_icache_ctrl_reg_top #( logic [31:0] counters_43_qs; logic [31:0] counters_43_wd; logic counters_43_we; + logic [31:0] counters_44_qs; + logic [31:0] counters_44_wd; + logic counters_44_we; + logic [31:0] counters_45_qs; + logic [31:0] counters_45_wd; + logic counters_45_we; // Register instances // R[enable]: V(False) @@ -1561,10 +1567,64 @@ module cluster_icache_ctrl_reg_top #( .qs (counters_43_qs) ); + // Subregister 44 of Multireg counters + // R[counters_44]: V(False) + prim_subreg #( + .DW (32), + .SWACCESS("W0C"), + .RESVAL (32'h0) + ) u_counters_44 ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (counters_44_we), + .wd (counters_44_wd), + + // from internal hardware + .de (hw2reg.counters[44].de), + .d (hw2reg.counters[44].d ), + + // to internal hardware + .qe (), + .q (reg2hw.counters[44].q ), + + // to register interface (read) + .qs (counters_44_qs) + ); + + // Subregister 45 of Multireg counters + // R[counters_45]: V(False) + + prim_subreg #( + .DW (32), + .SWACCESS("W0C"), + .RESVAL (32'h0) + ) u_counters_45 ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + // from register interface + .we (counters_45_we), + .wd (counters_45_wd), + + // from internal hardware + .de (hw2reg.counters[45].de), + .d (hw2reg.counters[45].d ), - logic [50:0] addr_hit; + // to internal hardware + .qe (), + .q (reg2hw.counters[45].q ), + + // to register interface (read) + .qs (counters_45_qs) + ); + + + + + logic [52:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[ 0] = (reg_addr == CLUSTER_ICACHE_CTRL_ENABLE_OFFSET); @@ -1618,6 +1678,8 @@ module cluster_icache_ctrl_reg_top #( addr_hit[48] = (reg_addr == CLUSTER_ICACHE_CTRL_COUNTERS_41_OFFSET); addr_hit[49] = (reg_addr == CLUSTER_ICACHE_CTRL_COUNTERS_42_OFFSET); addr_hit[50] = (reg_addr == CLUSTER_ICACHE_CTRL_COUNTERS_43_OFFSET); + addr_hit[51] = (reg_addr == CLUSTER_ICACHE_CTRL_COUNTERS_44_OFFSET); + addr_hit[52] = (reg_addr == CLUSTER_ICACHE_CTRL_COUNTERS_45_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -1675,7 +1737,9 @@ module cluster_icache_ctrl_reg_top #( (addr_hit[47] & (|(CLUSTER_ICACHE_CTRL_PERMIT[47] & ~reg_be))) | (addr_hit[48] & (|(CLUSTER_ICACHE_CTRL_PERMIT[48] & ~reg_be))) | (addr_hit[49] & (|(CLUSTER_ICACHE_CTRL_PERMIT[49] & ~reg_be))) | - (addr_hit[50] & (|(CLUSTER_ICACHE_CTRL_PERMIT[50] & ~reg_be))))); + (addr_hit[50] & (|(CLUSTER_ICACHE_CTRL_PERMIT[50] & ~reg_be))) | + (addr_hit[51] & (|(CLUSTER_ICACHE_CTRL_PERMIT[51] & ~reg_be))) | + (addr_hit[52] & (|(CLUSTER_ICACHE_CTRL_PERMIT[52] & ~reg_be))))); end assign enable_we = addr_hit[0] & reg_we & !reg_error; @@ -1835,6 +1899,12 @@ module cluster_icache_ctrl_reg_top #( assign counters_43_we = addr_hit[50] & reg_we & !reg_error; assign counters_43_wd = reg_wdata[31:0]; + assign counters_44_we = addr_hit[51] & reg_we & !reg_error; + assign counters_44_wd = reg_wdata[31:0]; + + assign counters_45_we = addr_hit[52] & reg_we & !reg_error; + assign counters_45_wd = reg_wdata[31:0]; + // Read data return always_comb begin reg_rdata_next = '0; @@ -2043,6 +2113,14 @@ module cluster_icache_ctrl_reg_top #( reg_rdata_next[31:0] = counters_43_qs; end + addr_hit[51]: begin + reg_rdata_next[31:0] = counters_44_qs; + end + + addr_hit[52]: begin + reg_rdata_next[31:0] = counters_45_qs; + end + default: begin reg_rdata_next = '1; end diff --git a/src/ctrl_unit/cluster_icache_ctrl_unit.sv b/src/ctrl_unit/cluster_icache_ctrl_unit.sv index 8456a43..847ff34 100644 --- a/src/ctrl_unit/cluster_icache_ctrl_unit.sv +++ b/src/ctrl_unit/cluster_icache_ctrl_unit.sv @@ -26,9 +26,9 @@ module cluster_icache_ctrl_unit import snitch_icache_pkg::*; #( import cluster_icache_ctrl_reg_pkg::*; initial begin - assert(5 == $bits(icache_l0_events_t)); - assert(4 == $bits(icache_l1_events_t)); - assert(NumAvailableCounters >= 4 + NR_FETCH_PORTS*5); + 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 @@ -63,13 +63,15 @@ module cluster_icache_ctrl_unit import snitch_icache_pkg::*; #( 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[4 + i*5 + 0].de = reg2hw.enable_counters.q & l0_events_i[i].l0_miss; - counters_reg[4 + i*5 + 1].de = reg2hw.enable_counters.q & l0_events_i[i].l0_hit; - counters_reg[4 + i*5 + 2].de = reg2hw.enable_counters.q & l0_events_i[i].l0_prefetch; - counters_reg[4 + i*5 + 3].de = reg2hw.enable_counters.q & l0_events_i[i].l0_double_hit; - counters_reg[4 + i*5 + 4].de = reg2hw.enable_counters.q & l0_events_i[i].l0_stall; + 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 diff --git a/src/snitch_icache_lookup_parallel.sv b/src/snitch_icache_lookup_parallel.sv index 4a8fa46..1a2eb11 100644 --- a/src/snitch_icache_lookup_parallel.sv +++ b/src/snitch_icache_lookup_parallel.sv @@ -260,6 +260,8 @@ module snitch_icache_lookup_parallel import snitch_icache_pkg::*; #( icache_events_o.l1_hit = valid_q & data_d.hit; icache_events_o.l1_stall = in_valid_i & ~in_ready_o; icache_events_o.l1_handler_stall = out_valid_o & ~out_ready_i; + icache_events_o.l1_tag_parity_error = '0; + icache_events_o.l1_data_parity_error = '0; end // Assertions diff --git a/src/snitch_icache_lookup_serial.sv b/src/snitch_icache_lookup_serial.sv index 459b773..a58c879 100644 --- a/src/snitch_icache_lookup_serial.sv +++ b/src/snitch_icache_lookup_serial.sv @@ -457,6 +457,8 @@ module snitch_icache_lookup_serial import snitch_icache_pkg::*; #( icache_events_o.l1_hit = req_handshake & tag_rsp_s.hit; icache_events_o.l1_stall = in_valid_i & ~in_ready_o; icache_events_o.l1_handler_stall = out_valid_o & ~out_ready_i; + icache_events_o.l1_tag_parity_error = req_handshake & faulty_hit_d; + icache_events_o.l1_data_parity_error = tag_handshake & data_parity_inv_d.parity_error; end endmodule diff --git a/src/snitch_icache_pkg.sv b/src/snitch_icache_pkg.sv index 8623300..0c090a5 100644 --- a/src/snitch_icache_pkg.sv +++ b/src/snitch_icache_pkg.sv @@ -19,6 +19,8 @@ package snitch_icache_pkg; logic l1_hit; logic l1_stall; logic l1_handler_stall; + logic l1_tag_parity_error; + logic l1_data_parity_error; } icache_l1_events_t; typedef struct packed {