|
@@ -2,7 +2,7 @@
|
|
|
// sysclock.sv
|
|
|
//
|
|
|
// Very simple unit that keeps track of time in "human" format based
|
|
|
-// on 32 kHz signal from the RTC. The registers have to be set from
|
|
|
+// on 32.768 kHz signal from the RTC. The registers have to be set from
|
|
|
// software, presumably from reading the RTC.
|
|
|
//
|
|
|
// Register 0 contains the 2 s granular date and time in FAT filesystem format.
|
|
@@ -12,20 +12,24 @@
|
|
|
// to in adcance, will write the counter when register 0 is written.
|
|
|
|
|
|
module sysclock (
|
|
|
- input rst_n,
|
|
|
- input sys_clk,
|
|
|
- input rtc_clk,
|
|
|
-
|
|
|
- input valid,
|
|
|
- input addr,
|
|
|
- output reg [31:0] rdata,
|
|
|
- input [31:0] wdata,
|
|
|
- input [3:0] wstrb
|
|
|
+ input rst_n,
|
|
|
+ input sys_clk,
|
|
|
+ input rtc_clk,
|
|
|
+
|
|
|
+ input valid,
|
|
|
+ input addr,
|
|
|
+ output reg [31:0] rdata,
|
|
|
+ input [31:0] wdata,
|
|
|
+ input [3:0] wstrb,
|
|
|
+
|
|
|
+ output periodic
|
|
|
);
|
|
|
|
|
|
+ parameter PERIODIC_HZ_LG2 = 5;
|
|
|
+
|
|
|
wire rtc_clk_sync;
|
|
|
- reg rtc_clk_q;
|
|
|
- reg rtc_clk_stb;
|
|
|
+ reg rtc_clk_q;
|
|
|
+ reg rtc_clk_stb;
|
|
|
|
|
|
synchronizer rtc_sync (
|
|
|
.rst_n ( 1'b1 ),
|
|
@@ -63,16 +67,16 @@ module sysclock (
|
|
|
|
|
|
function logic [7:0] tick(input [7:0] me,
|
|
|
input [7:0] start,
|
|
|
- input wrap_pre,
|
|
|
- input wrap_me);
|
|
|
-
|
|
|
+ input wrap_pre,
|
|
|
+ input wrap_me);
|
|
|
+
|
|
|
tick = wrap_me ? start : me + wrap_pre;
|
|
|
endfunction // tick
|
|
|
|
|
|
// Counter read/writes holding register
|
|
|
reg [15:0] tm_hold;
|
|
|
reg [ 1:0] tm_whold; // Byte enables for hold register
|
|
|
-
|
|
|
+
|
|
|
reg [15:0] tm_tick;
|
|
|
reg [31:0] tm_dt; // Day and time in FAT filesystem format
|
|
|
|
|
@@ -83,7 +87,7 @@ module sysclock (
|
|
|
wire [4:0] tm_mday = tm_dt[20:16];
|
|
|
wire [3:0] tm_mon = tm_dt[24:21];
|
|
|
wire [6:0] tm_year = tm_dt[31:25];
|
|
|
-
|
|
|
+
|
|
|
wire wrap_tick = rtc_clk_stb & |tm_tick;
|
|
|
wire wrap_sec = wrap_tick & (tm_2sec >= 5'd29);
|
|
|
wire wrap_min = wrap_sec & (tm_min >= 6'd59);
|
|
@@ -91,6 +95,9 @@ module sysclock (
|
|
|
wire wrap_mday = wrap_hour & (tm_mday >= maxday(tm_mon, tm_year));
|
|
|
wire wrap_mon = wrap_mday & (tm_mon >= 4'd12);
|
|
|
|
|
|
+ // Yes, it may jump if the counter is written...
|
|
|
+ assign periodic = tm_tick[14 - PERIODIC_HZ_LG2];
|
|
|
+
|
|
|
always @(posedge sys_clk)
|
|
|
begin
|
|
|
tm_tick <= tm_tick + rtc_clk_stb;
|
|
@@ -114,7 +121,7 @@ module sysclock (
|
|
|
if (wstrb[1]) tm_dt[15:8] <= wdata[15:8];
|
|
|
if (wstrb[2]) tm_dt[23:16] <= wdata[23:16];
|
|
|
if (wstrb[3]) tm_dt[31:24] <= wdata[31:24];
|
|
|
-
|
|
|
+
|
|
|
if (tm_whold[0]) tm_tick[7:0] <= tm_hold[7:0];
|
|
|
if (tm_whold[1]) tm_tick[15:8] <= tm_hold[15:8];
|
|
|
tm_hold <= tm_tick;
|
|
@@ -137,5 +144,5 @@ module sysclock (
|
|
|
1'b0: rdata = tm_dt;
|
|
|
1'b1: rdata = { tm_tick, tm_hold };
|
|
|
endcase // case (addr)
|
|
|
-
|
|
|
+
|
|
|
endmodule // sysclock
|