-
Notifications
You must be signed in to change notification settings - Fork 23
Agnus Internal Timing
There are two critical internal clocks used by Agnus/Alice, PH2 and PH1. These two clocks appear to be used almost exclusively. PH2 goes low approximately 15ns after CCK goes high and returns high approximately 30ns after CCKQ goes high. PH1 is an inverse of PH2 with another 15ns of padding and is a very narrow signal.
____ _______________
|_______________| |_______ CCK (3.58MHz Color Clock)
____________ _______________
|_______________| CCKQ (3.58MHz Color Clock Quadrature)
______________________ ___________
|_________| PH2 (85ns negative pulse)
_____
________________________| |_____________ PH1 (55ns positive pulse)
These timings are based on average-case performance of HCMOS gates of the era and could be tighter on a cold system and slower on a very hot system. I would say these are +/-8ns, or about 7-23ns per gate.
To simply the clock logic and avoid clock domain issues in FPGA we'll operate on a common ~57MHz clock (clock doubled from the input 28MHz). This represents about 17.5ns steps which should be close enough to meet the above timing.
Cyc CCK CCKQ PH2 PH1
0 0 1 1 0
1 0 1 1 0
2 0 1 1 0
3 0 1 1 0
4 0 0 1 0
5 0 0 1 0
6 0 0 1 0
7 0 0 1 0
8 1 0 1 0
9 1 0 0 0
10 1 0 0 1
11 1 0 0 1
12 1 1 0 1
13 1 1 0 0
14 1 1 1 0
15 1 1 1 0
I believe this can be represented by the following Verilog:
module cck_gen (
input clk, // clk should be a PLL input that's double the ~28MHz input clock
input nrst, // nRESET pin signal
output cck, // 3.58MHz main clock
output cckq, // 3.58MHz quadrature clock
output ph2, // internal phase-2 clock
output ph1 // internal phase-1 clock
);
reg [15:0] shift; // 16 state clock:
// FEDCBA9876543210
assign cck = ~|shift[7:0]; // 1111111100000000
assign cckq = ~|shift[11:4]; // 1111000000001111
assign ph2 = ~|shift[13:9]; // 1100000111111111
assign ph1 = |shift[12:10]; // 0001110000000000
always @ (posedge clk) begin // rotate left each ~57MHz tick
if(!nrst)
shift <= 1; // 0000000000000001 <- reset state
else
shift <= { shift[14:0], shift[15] };
end
endmodule