見出し画像

Tang Nano 9K で Apple II を再現する(14)ビデオディスプレイ

第八章 The Video Display

回路図 C-16 と C-20 を video_generator.sv として実装します。

`default_nettype none

module a2_video_generator (
    input wire clk_14m,
    input wire clk_7m,
    input wire clk_7m_n,
    input wire ldps_n,
    input wire ld194,
    input wire color_ref_n,
    input wire h0,
    input wire h2,
    input wire h3,
    input wire h4,
    input wire h5,
    input wire va,
    input wire vb,
    input wire vc,
    input wire v0,
    input wire v1,
    input wire v2,
    input wire v3,
    input wire v4,
    input wire v5,
    input wire [7:0] dl,
    input wire hires_mode,
    input wire text_mode,
    input wire mix_mode,
    input wire ras_n,
    output wire hires,
    output wire color_burst,
    output wire hbl,
    output wire sync,
    output wire blanking,
    output wire [2:0] composite_video
);

logic video_data;

// A5:2316B
logic [8:1] a5_o;
logic [10:0] a5_a;

Gowin_ROM16 cg_rom(
    .dout(a5_o), //output [7:0] dout
    .ad(a5_a) //input [10:0] ad
);

assign a5_a[0] = va;
assign a5_a[1] = vb;
assign a5_a[2] = vc;
assign a5_a[3] = dl[0];
assign a5_a[4] = dl[1];
assign a5_a[5] = dl[2];
assign a5_a[6] = dl[3];
assign a5_a[7] = dl[4];
assign a5_a[8] = dl[5];
assign a5_a[9] = dl[6];
assign a5_a[10] = dl[7];

// B11:74Ls08;
logic b11_11;
assign b11_11 = a5_o[8] & b3_out;

// B13:74LS02
logic b13_4;
assign b13_4 = ~(b11_11 | dl[7]);

// A3:74166
logic a3_cl1;
logic a3_qh;
logic [7:0] a3_q;
assign a3_cl1 = clk_7m;
always_ff@(posedge clk_14m) begin
    if (clk_7m) begin 
        if (ldps_n) begin
            a3_q = {a3_q[6:0], a10_q3};
        end else begin
            a3_q = {a5_o[7:1], b13_4};
        end
    end
end
assign a3_qh = a3_q[7];

// B3:555
logic b3_out;
logic [22:0] b3_cnt;
assign b3_out = b3_cnt[22];
always_ff@(posedge clk_14m) begin
    b3_cnt <= b3_cnt + 23'b1;
end

// B2:74S86
logic b2_11;
assign b2_11 = a3_qh ^ a10_q3;

// A8:74LS257
logic a8_za;
logic a8_zb;
logic a8_zc;
logic a8_zd;
assign a8_za = a11_q_n ? b9_q0 : b4_q0;
assign a8_zb = a11_q_n ? b5_q0 : vc;
assign a8_zc = a11_q_n ? clk_7m_n : 1'b1;
assign a8_zd = a11_q_n ? dl[7] : h0;

// A10:74LS194
logic a10_q0;
logic a10_q1;
logic a10_q2;
logic a10_q3;
always_ff@(posedge clk_14m) begin
    if (ld194) begin
        a10_q0 <= a8_zb;
        a10_q1 <= a8_zd;
        a10_q2 <= blanking;
        a10_q3 <= b13_4;
    end
end

// B4:74LS194
logic b4_q0;
logic b4_q1;
logic b4_q2;
logic b4_q3;
always_ff@(posedge clk_14m) begin
    if (ld194 & a8_zc) begin
        b4_q0 <= dl[0];
        b4_q1 <= dl[1];
        b4_q2 <= dl[2];
        b4_q3 <= dl[3];
    end else if (ld194 & !a8_zc) begin
        b4_q0 <= 1'b1;
        b4_q1 <= b4_q0;
        b4_q2 <= b4_q1;
        b4_q3 <= b4_q2;
    end else if (!ld194 & a8_zc) begin
        b4_q0 <= b4_q1;
        b4_q1 <= b4_q2;
        b4_q2 <= b4_q3;
        b4_q3 <= a8_za;
    end
end

// B9:74LS194
logic b9_q0;
logic b9_q1;
logic b9_q2;
logic b9_q3;
always_ff@(posedge clk_14m) begin
    if (ld194 & a8_zc) begin
        b9_q0 <= dl[4];
        b9_q1 <= dl[5];
        b9_q2 <= dl[6];
        b9_q3 <= dl[7];
    end else if (ld194 & !a8_zc) begin
        b9_q0 <= 1'b1;
        b9_q1 <= b9_q0;
        b9_q2 <= b9_q1;
        b9_q3 <= b9_q2;
    end else if (!ld194 & a8_zc) begin
        b9_q0 <= b9_q1;
        b9_q1 <= b9_q2;
        b9_q2 <= b9_q3;
        b9_q3 <= b9_q0;
    end
end

// A11:74LS74
logic a11_q;
always_ff@(posedge clk_14m) begin
    a11_q <= b4_q0;
end

// A9:74LS151
logic a9_y;
assign a9_y = a10_q2 ? 1'b0
    : (!a10_q1 & !a10_q0 & !a12_13) ? b2_11 // D0
    : (a10_q1 & !a10_q0 & !a12_13) ? b2_11  // D1
    : (!a10_q1 & a10_q0 & !a12_13) ? b4_q0  // D2
    : (a10_q1 & a10_q0 & !a12_13) ? a11_q   // D3
    : (!a10_q1 & !a10_q0 & a12_13) ? b4_q0  // D4
    : (a10_q1 & !a10_q0 & a12_13) ? b4_q2   // D5
    : (!a10_q1 & a10_q0 & a12_13) ? b9_q0   // D6
    : b9_q2; // (a10_q1 & a10_q0 & a12_13)     D7

// B10:74LS74
logic b10_q;
always_ff@(posedge clk_14m) begin
    b10_q <= a9_y;
end

assign video_data = b10_q;

// A11:74LS74
logic a11_q_n;
assign a11_q_n = ~a12_13;

// A12:74LS74
logic a12_13;
assign a12_13 = ~(hires_mode | ~(b8_q0 | b8_q0));

// B12:74LS11
logic b12_6;
assign b12_6 = mix_mode & v2 & v4;

// B13:74LS02
logic b13_13;
assign b13_13 = ~(text_mode | b12_6);

// B5:74LS74
logic b5_q0;
always_ff@(posedge ras_n) begin
    b5_q0 <= b13_13;
end

// B8:74LS74
logic b8_q5;
logic b8_q0;
always_ff@(posedge ras_n) begin
    b8_q5 <= b5_q0;
    b8_q0 <= b8_q5;
end

// B11:74LS08
logic b11_6;
assign b11_6 = hires_mode & b8_q0;

assign hires = b11_6;


logic a14_1;
logic a14_13;
logic c13_a;
logic c13_b;
logic c13_6;
logic b12_12;
logic b13_1;
logic b14_4;
logic a14_4;
logic a14_10;
logic b14_1;
logic b14_10;
logic a12_4;
logic b14_13;
logic b11_8;
logic c13_c;
logic c13_d;
logic c13_8;
logic c14_6;

assign a14_1 = ~(text_mode | color_ref_n);  // A14:74LS02
assign a14_13 = ~(h2 | h2);                 // A14:74LS02
assign b13_1 = ~(a14_1 | a14_13);           // B13:74LS02
assign c13_b = h5 & h5;                     // C13:74Ls51
assign c13_a = h4 & h3;                     // C13:74LS51
assign c13_6 = ~(c13_b | c13_a);            // C13:74LS51
assign b12_12 = b13_1 & h3 & c13_6;         // B12:74LS11
assign b14_4 = ~(h5 | h4);                  // B14:74LS02
assign a14_4 = ~(b14_4 | b14_4);            // B14:74LS02
assign a14_10 = ~(a14_4 | h3);              // A14:74LS02
assign b14_1 = ~(a14_10 | ~v2);             // B14:74LS02
assign b14_10 = ~(vc | v0);                 // B14:74LS02
assign a12_4 = ~(b14_10 | b14_10);          // A12:74LS02
assign b14_13 = ~(a12_4 | v1);              // B14:74LS02
assign b11_8 = v3 & v4;                     // B11:74LS08
assign c13_d = c13_6 & a14_13 & h3;         // C13:74LS51
assign c13_c = b14_1 & b14_13 & b11_8;      // C13:74LS51
assign c13_8 = ~(c13_d | c13_c);            // C13:74LS51
assign c14_6 = c13_6 | b11_8;               // C14:74LS32

assign color_burst = b12_12;
assign hbl = c13_6;
assign sync = c13_8;
assign blanking = c14_6;

assign composite_video = ~sync ? 0
        : (h2 & h3 & hbl) ? {1'b0, color_burst, !text_mode}
        : {video_data, 1'b1, video_data};

endmodule

`default_nettype wire

コンポジット出力は、3 ビットの信号を抵抗で合成し、1V p-p のビデオ信号に変換します。

On-board I/O

参考文献


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