1 /* Mac Plus real time clock
3 * Doesn't do much yet ... eventually needs a backbus interface
4 * to save/restore PRAM to the PIC. Not much I can do about the
10 * The HW ref manual seems to indicate that the RTC chip latches
11 * on raising clock but SW should latch on falling clock. However
12 * that isn't what the ROM does.
14 * The actual transfer done by the ROM looks like:
17 * - Direction set to output, value 111 (disabled, clock & data high)
18 * - Set enabled and clock to 0
19 * 8 times: - Set value bit and clock to 0
22 * So the transfer "completes" with clock high after sending the last bit,
23 * the next transfer is then either a read or a write. In the later case,
24 * the ROM goes back to the same routine above, which means it continues
25 * clocking bits without a significant "hickup".
27 * For a read however, what happens next is:
29 * - Set direction to input (at this point clock is still high)
30 * - Clear data (no effect as direction is input) and clock
31 * 8 times: - Set clock to 0
34 * - Set direction to output
36 * Finally disable chip.
38 * You will notice that this is quite bogus since there's no way
39 * for the RTC chip to know after a read when to stop driving the
40 * data line before the Mac sets the direction back to output,
41 * so there -will- be some contention... oops. This isn't a problem
42 * for us though as we use separate signals.
45 module rtc(input sysclk,
53 parameter divider = 23'h7a1200;
55 /* Sysclk is 16Mhz, to generate a 1-sec pulse, we need
69 localparam rtc_state_cmd = 0;
70 localparam rtc_state_read = 1;
71 localparam rtc_state_write = 2;
72 localparam rtc_state_cmd2 = 3;
75 /* Generate one second tick */
76 always@(posedge sysclk or posedge reset) begin
89 /* Data clock edge detect buffer */
90 always@(posedge sysclk or posedge reset) begin
97 assign dstrobe = data_clock & ~oldclk & ~_data_enable;
100 /* Shift bit counter */
101 always@(posedge sysclk or posedge reset) begin
108 bitcnt <= bitcnt - 1;
111 assign gotbyte = (bitcnt == 0) && dstrobe;
114 always@(posedge sysclk or posedge reset) begin
120 else if (dstrobe) begin
121 if (state == rtc_state_read && bitcnt == 3'b111)
124 shift <= { shift[6:0], data_in };
128 assign data_out = shift[7];
130 /* Latch/decode command byte into address, ckaddr and dir */
131 always@(posedge sysclk or posedge reset) begin
136 end else if (gotbyte) begin
137 if (state == rtc_state_cmd) begin
140 end else if (state == rtc_state_cmd2)
141 addr <= { addr[2:0], shift[6:2] };
146 always@(posedge sysclk or posedge reset) begin
148 state <= rtc_state_cmd;
151 state <= rtc_state_cmd;
152 else if (gotbyte) begin
153 if (state == rtc_state_cmd) begin
154 if (shift[6:3] == 4'b1111)
155 state <= rtc_state_cmd2;
157 state <= rtc_state_read;
159 state <= rtc_state_write;
160 end else if (state == rtc_state_cmd2) begin
162 state <= rtc_state_read;
164 state <= rtc_state_write;
166 state <= rtc_state_cmd;
172 always@(posedge sysclk or posedge reset) begin