Agnus Internal Timing - nonarkitten/amiga_replacement_project GitHub Wiki

Internal Clocks

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.

Internal Clock "States"

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