3

我试图做的是从 Verilog 中的 Lattice MachXO CPLD 创建一个 VGA 控制器。

问题

我正在尝试使用 CPLD 内部的 25.175 MHz 时钟以 640x480 @ 60Hz 的分辨率显示红色;但是,当我将 CPLD 插入显示器时,我会收到“超出范围”消息;我尝试的任何显示器都无法理解我想要的分辨率。

我试过的

我已经在 ModelSim 中模拟了代码(包括图片),除了一个问题,一切看起来都不错。当我计算从 V-Sync 显示区域(绘制 H-Sync 时)发生的时间步长并将其除以 H-Sync 的频率时,我得到 479 个脉冲 - 比 480 个少一个我应该画的线条。我不明白这可能来自哪里,因为我已经多次检查了我的时间,我怀疑这可能是问题的征兆,但我不确定。

我用来生成计时数字的数字来自 Tiny VGA: tinyvga.com/vga-timing/640x480@60Hz

下面是我的代码,以及来自 ModelSim 的时序图片,谢谢。

module Top(RESET, H_SYNC, V_SYNC, RED);
    input  wire RESET;
    output wire H_SYNC;
    output wire V_SYNC;
    output wire RED;

    wire rgb_en;

    /*** Test Bench Code ***/
     //reg osc_clk, reset;
     //initial begin
         //#0 reset     = 0;
         //#0 osc_clk = 0;
         //#2 reset     = 1;
     //end

     //always #1 osc_clk = ~osc_clk;

    OSCC        OSCC_1 (.OSC(osc_clk)); /*< IP clock module for Lattice CPLD    >*/
    Controller  CNTRL(.NRST(RESET), .CLK(osc_clk), .H_SYNC(H_SYNC), .V_SYNC(V_SYNC), .RGB_EN(rgb_en));

    assign RED = (rgb_en ? 1:1'bz); 

endmodule

module Controller(CLK, NRST, H_SYNC, V_SYNC, RGB_EN);
    input  wire CLK;        /*< CLK input from Top module   >*/
    input  wire NRST;       /*< Reset input from Top module >*/
    output reg  H_SYNC;     /*< Goes to VGA Horizontal Sync >*/
    output reg  V_SYNC;     /*< Goes to VGA Verical Sync    >*/
    output reg  RGB_EN  ;   /*< Enables RGB values durning display time on H_SYNC   >*/

    reg [10:0] h_counter;   /*< Tracks amount of pulses from CLK                    >*/
    reg [19:0] v_counter;   /*< Tracks amount of pulses from H_SYNC                 >*/

    `define H_SYNC_PULSE        11'd96      /*< Length of Sync Pulse            >*/
    `define H_BACK_PORCH_END    11'd144     /*< Pulse len + Porch Len           >*/
    `define H_FRONT_PORCH_STRT  11'd784     /*< Front Porch Len - Max           >*/
    `define H_COUNT_MAX         11'd799     /*< Max line pulses for resolution          >*/

    `define V_SYNC_PULSE        19'd1600
    `define V_BACK_PORCH_END    19'd28000
    `define V_FRONT_PORCH_STRT  19'd412000
    `define V_COUNT_MAX         19'd419999

    /*** State Machine for H_SYNC ***/
    always @(*) begin
        /* If the vertical sync line is not in the display zone, keep H_Sync low */
        if(!(v_counter > `V_BACK_PORCH_END && v_counter < `V_FRONT_PORCH_STRT)) begin
            H_SYNC = 0;
            RGB_EN = 0;
        end
        /* If the vertical sync line is in display zone, allow H_Sync to go through its procedure */
        else begin
            if (h_counter < `H_SYNC_PULSE) begin
                H_SYNC = 0;
                RGB_EN = 0;
            end
            /* If H_Sync is in the display zone, enable RGB */
            else if (h_counter > `H_BACK_PORCH_END && h_counter < `H_FRONT_PORCH_STRT) begin
                H_SYNC = 1;
                RGB_EN = 1;
            end
            /* During the Front Porch period, disable RGB */
            else begin
                H_SYNC = 1;
                RGB_EN = 0;
            end
        end
    end

    /*** State Machine for V_SYNC ***/
    always @(*) begin
        if (v_counter < `V_SYNC_PULSE) begin
            V_SYNC = 0;
        end
        else begin
            V_SYNC = 1;
        end
    end

    /*** Counter logic ***/
    always @(posedge CLK) begin
        if (h_counter >= `H_COUNT_MAX || !NRST) begin
            h_counter <= 11'b00;
        end
        else begin
            h_counter <= h_counter + 1;
        end
    end

    always @(posedge CLK) begin
        if (v_counter >= `V_COUNT_MAX || !NRST) begin
            v_counter <= 11'b00;
        end
        else begin
            v_counter <= v_counter + 1;
        end
    end

endmodule

/ < 后廊 h_counter > /

/ < 计数器翻转和 V_SYNC > /

4

2 回答 2

2

我使用过的每台 VGA 显示器都要求在消隐期间红色、绿色和蓝色信号都为零(HSYNC | VSYNC)。而不是分配给 z (高阻抗) try assign RED = (rgb_en ? 1'b1 : 1'b0);。您还必须对 GREEN 和 BLUE 执行此操作(或者将它们永久分配为 0)。

如果不是这样,那很可能是时间问题。尝试使用示波器来测量 VSYNC 信号的频率——它应该很好地达到 60Hz。

于 2013-06-01T07:51:28.803 回答
0

与@exhausted_engy 响应相关(试图对此发表评论,但不知道在哪里这样做):很多视频 DAC 都有用于 dac_blank 和 dac_sync 的引脚,正是为了这个目的。

于 2013-06-03T19:18:26.603 回答