§ Видеоразрешение

Параметры: 640 x 400 x 60 Hz, 25 Mhz опорная частота
Вывод текстового экрана.
Код модуля.
1module vga
2(
3    input   wire        clock,
4    output  reg [3:0]   R,
5    output  reg [3:0]   G,
6    output  reg [3:0]   B,
7    output              HS,
8    output              VS,
9
10    // Доступ к памяти
11    output  reg  [11:0] A,      // Видеоданные [0000..0FFF]
12    input        [ 7:0] D,      // Знакоместо
13    input        [ 7:0] F,      // Шрифт
14
15    // Внешний интерфейс
16    input        [10:0] cursor  // Положение курсора от 0 до 2047
17);
18
19// ---------------------------------------------------------------------
20// Тайминги для горизонтальной|вертикальной развертки (640x400)
21// ---------------------------------------------------------------------
22parameter
23    hz_visible = 640, vt_visible = 400,
24    hz_front   = 16,  vt_front   = 12,
25    hz_sync    = 96,  vt_sync    = 2,
26    hz_back    = 48,  vt_back    = 35,
27    hz_whole   = 800, vt_whole   = 449;
28// ---------------------------------------------------------------------
29assign HS = x  < (hz_back + hz_visible + hz_front); // NEG.
30assign VS = y >= (vt_back + vt_visible + vt_front); // POS.
31// ---------------------------------------------------------------------
32wire        xmax = (x == hz_whole - 1);
33wire        ymax = (y == vt_whole - 1);
34reg  [10:0] x    = 0;
35reg  [10:0] y    = 0;
36wire [10:0] X    = x - hz_back + 8; // X=[0..639]
37wire [ 9:0] Y    = y - vt_back;     // Y=[0..399]
38// ---------------------------------------------------------------------
39// Текстовый видеоадаптер
40// ---------------------------------------------------------------------
41reg         flash;
42reg  [23:0] timer;
43reg  [ 7:0] char, attr, temp;
44// ---------------------------------------------------------------------
45wire [10:0] id = X[9:3] + (Y[8:4] * 80);
46wire        maskbit = (char[~X[2:0]]) | (flash && (id == cursor+1) && Y[3:0] >= 14);
47wire [ 3:0] color = maskbit ? (attr[7] & flash ? attr[6:4] : attr[3:0]) : attr[6:4];
48wire [15:0] dst =
49    color == 4'h0 ? 12'h111 : color == 4'h8 ? 12'h888 :
50    color == 4'h1 ? 12'h008 : color == 4'h9 ? 12'h00f :
51    color == 4'h2 ? 12'h080 : color == 4'hA ? 12'h0f0 :
52    color == 4'h3 ? 12'h088 : color == 4'hB ? 12'h0ff :
53    color == 4'h4 ? 12'h800 : color == 4'hC ? 12'hf00 :
54    color == 4'h5 ? 12'h808 : color == 4'hD ? 12'hf0f :
55    color == 4'h6 ? 12'h880 : color == 4'hE ? 12'hff0 :
56    color == 4'h7 ? 12'hccc :                 12'hfff;
57
58// Вывод видеосигнала
59always @(posedge clock) begin
60
61    {R, G, B} <= 12'h000;
62
63    // Кадровая развертка
64    x <= xmax ?         0 : x + 1;
65    y <= xmax ? (ymax ? 0 : y + 1) : y;
66
67    case (X[2:0])
68    0: begin A    <= {id[10:0], 1'b0}; end
69    1: begin temp <= D; A[0] <= 1'b1; end
70    2: begin temp <= D; A    <= {temp[7:0], Y[3:0]}; end
71    7: begin attr <= temp; char <= F; end
72    endcase
73
74    // Таймер для мигания курсора
75    if (timer == 12500000) begin flash <= ~flash; timer <= 0; end else timer <= timer + 1;
76
77    // Вывод окна видеоадаптера
78    if (x >= hz_back && x < hz_visible + hz_back && y >= vt_back && y < vt_visible + vt_back)
79        {R, G, B} <= dst;
80end
81
82endmodule