見出し画像

Tang Nano 9K で Apple II を再現する(1)クロック生成

FPGA での Apple II の実装はいくつかありますが、自分でもやってみます。
Apple II の回路を、SystemVerilog で愚直に書き下すことにします。
参考文献として、The Apple II Circuit Description を使います。

第三章 Clock Generator and Horizontal Timing

14.31818 MHz のマスタークロックから、以下のクロックを生成します。

  • COLOR REF (3.58MHz)

  • 7M (7.2MHz)

  • 14M (14.3MHz)

  • /RAS (2MHz)

  • AX (2MHz)

  • /CAS (2MHz)

  • Q3 (2MHz)

  • φ0 (1MHz)

  • φ1 (1MHz)

  • LD194 (1MHz)

  • /LDPS (1MHz)

回路図 C-2 を clocks.sv として実装します。

`default_nettype none

module a2_clocks (
    input wire  mclk,
    input wire  hpe_n,
    output wire color_ref,
    output wire color_ref_n,
    output wire clk_7m,
    output wire clk_7m_n,
    output wire clk_14m,
    output wire ras_n,
    output wire ax,
    output wire cas_n,
    output wire q3,
    output wire ph0,
    output wire ph1,
    output reg  ld194,
    output reg  ldps_n
);

// B1:74S175
logic b1_d0;
logic b1_q0;
logic b1_q0n;
logic b1_d1;
logic b1_q1;
logic b1_q1n;
logic b1_d2;
logic b1_q2;
logic b1_d3;
logic b1_q3;
logic b1_q3n;

always_ff@(posedge mclk) begin
    b1_q0 <= b1_d0;
    b1_q0n <= ~b1_d0;
    b1_q1 <= b1_d1;
    b1_q1n <= !b1_d1;
    b1_q2 <= b1_d2;
    b1_q3 <= b1_d3;
    b1_q3n <= ~b1_d3;
end

assign b1_d0 = b1_q0n;
assign b1_d1 = b1_q0 ^ b1_q1;   // B2:74S86
assign b1_d2 = c1_zb;
assign b1_d3 = b1_q2;

// C2:74S195
logic c2_p0;
logic c2_p1;
logic c2_p2;
logic c2_p3;
logic c2_q0;
logic c2_q1;
logic c2_q2;
logic c2_q3;
logic c2_q3n;
logic c2_pen;

always_ff@(posedge mclk) begin
    if (!c2_pen) begin
        c2_q0 <= c2_p0;
        c2_q1 <= c2_p1;
        c2_q2 <= c2_p2;
        c2_q3 <= c2_p3;
        c2_q3n <= ~c2_p3;
    end else begin
        c2_q0 <= 0;
        c2_q1 <= c2_q0;
        c2_q2 <= c2_q1;
        c2_q3 <= c2_q2;
        c2_q3n <= ~c2_q2;
    end
end

logic b13_10;
logic b2_6;

assign c2_p0 = c2_q1;
assign b13_10 = ~(c2_q1 | c2_q2);                   // B13:74LS02
assign b2_6 = (hpe_n ^ 1'b1);                       // B2:74S86
assign c2_p1 = ~(b13_10 & b1_q3 & b1_q1 & b2_6);    // D2:74LS20
assign c2_p2 = c2_q1;
assign c2_p3 = c2_q0;
assign c2_pen = c2_q3;

// C1:74LS153
logic c1_s0;
logic c1_s1;
logic c1_0b;
logic c1_1b;
logic c1_2b;
logic c1_3b;
logic c1_zb;

always_comb begin
    if (!c1_s1) begin
        if (!c1_s0) begin
            c1_zb = c1_0b;
        end else begin
            c1_zb = c1_1b;
        end
    end else begin
        if (!c1_s0) begin
            c1_zb = c1_2b;
        end else begin
            c1_zb = c1_3b;
        end
    end
end

assign c1_s0 = c2_q1;
assign c1_s1 = b1_q3;
assign c1_0b = b1_q2;
assign c1_1b = c2_q3n;
assign c1_2b = b1_q2;
assign c1_3b = c2_q3;

// Apple II Clocks
assign color_ref    = b1_q1n;
assign color_ref_n  = b1_q1;
assign clk_7m       = b1_q0;
assign clk_7m_n     = b1_q0n;
assign clk_14m      = mclk;
assign ras_n        = c2_q0;
assign ax           = c2_q1;
assign cas_n        = c2_q2;
assign q3           = c2_q3;
assign ph0          = b1_q3;
assign ph1          = b1_q3n;
assign ld194        = b1_q0n & b1_q3 & b13_10;  // B12:74LS11
assign ldps_n       = ~(b13_10 & b1_q3);        // A1:74LS00

endmodule

`default_nettype wire

クロックの生成ができました。

Simplified system timing.

この記事が気に入ったらサポートをしてみませんか?