Skip to content

Commit

Permalink
[rtl, aon_timer] Reset core.prescale_count on wkup_ctrl write
Browse files Browse the repository at this point in the history
The AON timer core has an internal counter `prescale_count_q` which is
not reset upon each write to wkup_ctrl.
This causes issues if the WKUP timer is re-configured to a lower
prescaler value than it was before, and the `prescale_count_q` variable
is greater than the new prescaler value, forcing the
`prescale_count_q` counter to overflow itself causing a non-spec
compliant behavior.

In order to mitigate the above, the internal `prescale_count_q` is
reset after wkup_ctrl write. Thus, the aon timer is forced to count
from scratch the new intended prescaler value.

Signed-off-by: Antonio Martinez Zambrana <[email protected]>
  • Loading branch information
antmarzam committed Jan 16, 2025
1 parent ee42e18 commit 1f75cdf
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 4 deletions.
1 change: 1 addition & 0 deletions hw/ip/aon_timer/data/aon_timer.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
{ bits: "12:1",
name: "prescaler",
desc: "Pre-scaler value for wakeup timer count",
hwqe: "true",
}
],
},
Expand Down
2 changes: 2 additions & 0 deletions hw/ip/aon_timer/rtl/aon_timer_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ module aon_timer_core import aon_timer_reg_pkg::*; (
always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin
if (!rst_aon_ni) begin
prescale_count_q <= 12'h000;
end else if (reg2hw_i.wkup_ctrl.prescaler.qe) begin
prescale_count_q <= 12'h000;
end else if (prescale_en) begin
prescale_count_q <= prescale_count_d;
end
Expand Down
5 changes: 3 additions & 2 deletions hw/ip/aon_timer/rtl/aon_timer_reg_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package aon_timer_reg_pkg;
typedef struct packed {
struct packed {
logic [11:0] q;
logic qe;
} prescaler;
struct packed {
logic q;
Expand Down Expand Up @@ -124,8 +125,8 @@ package aon_timer_reg_pkg;

// Register -> HW type
typedef struct packed {
aon_timer_reg2hw_alert_test_reg_t alert_test; // [247:246]
aon_timer_reg2hw_wkup_ctrl_reg_t wkup_ctrl; // [245:233]
aon_timer_reg2hw_alert_test_reg_t alert_test; // [248:247]
aon_timer_reg2hw_wkup_ctrl_reg_t wkup_ctrl; // [246:233]
aon_timer_reg2hw_wkup_thold_hi_reg_t wkup_thold_hi; // [232:201]
aon_timer_reg2hw_wkup_thold_lo_reg_t wkup_thold_lo; // [200:169]
aon_timer_reg2hw_wkup_count_hi_reg_t wkup_count_hi; // [168:137]
Expand Down
16 changes: 14 additions & 2 deletions hw/ip/aon_timer/rtl/aon_timer_reg_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,17 @@ module aon_timer_reg_top (


// R[wkup_ctrl]: V(False)
logic wkup_ctrl_qe;
logic [1:0] wkup_ctrl_flds_we;
prim_flop #(
.Width(1),
.ResetValue(0)
) u_wkup_ctrl0_qe (
.clk_i(clk_aon_i),
.rst_ni(rst_aon_ni),
.d_i(&wkup_ctrl_flds_we),
.q_o(wkup_ctrl_qe)
);
// F[enable]: 0:0
prim_subreg #(
.DW (1),
Expand All @@ -617,7 +628,7 @@ module aon_timer_reg_top (
.d ('0),

// to internal hardware
.qe (),
.qe (wkup_ctrl_flds_we[0]),
.q (reg2hw.wkup_ctrl.enable.q),
.ds (),

Expand All @@ -644,13 +655,14 @@ module aon_timer_reg_top (
.d ('0),

// to internal hardware
.qe (),
.qe (wkup_ctrl_flds_we[1]),
.q (reg2hw.wkup_ctrl.prescaler.q),
.ds (),

// to register interface (read)
.qs (aon_wkup_ctrl_prescaler_qs_int)
);
assign reg2hw.wkup_ctrl.prescaler.qe = wkup_ctrl_qe;


// R[wkup_thold_hi]: V(False)
Expand Down

0 comments on commit 1f75cdf

Please sign in to comment.