Verilog CPLD上VGA控制器的故障

Verilog CPLD上VGA控制器的故障,verilog,fpga,vga,Verilog,Fpga,Vga,我试图做的是从Verilog中的Lattice MachXO CPLD创建一个VGA控制器 问题 我试图使用CPLD内部的25.175 MHz时钟,以640x480@60Hz的分辨率显示红色;然而,当我把CPLD插入显示器时,我得到一条“超出范围”的信息;我尝试的监视器都无法理解我想要的分辨率 我尝试过的 我在ModelSim(包括图片)中模拟了代码,除了一个问题外,一切看起来都很好。当我计算在V-Sync显示区域(当H-Sync绘制时)期间从发生的时间步数并将其除以H-Sync的频率时,我得到

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

问题

我试图使用CPLD内部的25.175 MHz时钟,以640x480@60Hz的分辨率显示红色;然而,当我把CPLD插入显示器时,我得到一条“超出范围”的信息;我尝试的监视器都无法理解我想要的分辨率

我尝试过的

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

我用来生成计时数字的数字来自Tiny VGA:

下面是我的代码和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_同步、V_同步、红色);
输入线复位;
输出线H_同步;
输出线V_同步;
输出线为红色;
导线rgb_en;
/***试验台代码***/
//注册osc_时钟,复位;
//初始开始
//#0重置=0;
//#0 osc_clk=0;
//#2复位=1;
//结束
//始终#1 osc#U clk=~osc#U clk;
OSCC OSCC_1(.OSC(OSC_clk));/**/
控制器CNTRL(.NRST(重置),.CLK(osc_-CLK),.H_-SYNC(H_-SYNC),.V_-SYNC(V_-SYNC),.RGB_-EN(RGB_-EN));
分配红色=(rgb_en?1:1'bz);
端模
模块控制器(时钟、NRST、H_同步、V_同步、RGB_EN);
输入线CLK;/*<来自顶部模块的时钟输入>*/
输入线NRST;/*<从顶部模块重置输入>*/
输出寄存器H_SYNC;/*<转到VGA水平同步>*/
输出寄存器V_SYNC;/*<转到VGA Verical Sync>*/
输出寄存器RGB_EN;/*<在H_SYNC>*/
reg[10:0]h_计数器;/*<跟踪来自时钟的脉冲量>*/
reg[19:0]v_计数器;/*<跟踪来自H_SYNC>*/
`定义同步脉冲11'd96/*<同步脉冲长度>*/
`定义后走廊末端11'd144/**/
`定义前廊标准11'd784/*<前廊长度-最大值>*/
`定义H_计数\u最大值11'd799/*<分辨率的最大线脉冲>*/
`定义V_同步脉冲19'd1600
`定义V_后廊_端19'd28000
`定义V_前廊标准19'd412000
`定义V_计数最大值19'D41999
/***H_同步的状态机***/
始终@(*)开始
/*如果垂直同步线不在显示区,请将H_同步保持在低位*/
如果(!(v_计数器>`v_后走廊末端和&v_计数器<`v_前走廊末端))开始
H_SYNC=0;
RGB_EN=0;
结束
/*如果垂直同步线位于显示区,请允许H_sync完成其过程*/
否则开始
如果(h_计数器<`h_同步_脉冲)开始
H_SYNC=0;
RGB_EN=0;
结束
/*如果H_Sync在显示区域中,请启用RGB*/
否则,如果(h_计数器>h_后廊&h_计数器=`h_计数_最大值| | |!NRST)开始
h_计数器/

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


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

与@expeated_engy response相关(试图对此发表评论,但不知道该在何处发表):许多视频dac都有dac_blank和dac_sync的管脚,正是为了这个目的

你是怎么计算出这场比赛的分数的?不是说他们错了,但也许在你的帖子中添加一些数学知识会有所帮助。例如,如果我查看V_COUNT_MAX*您的频率,我得到16.55ms(60.4Hz),而在VGA链接中,您提供的帧时间应为16.68ms(60Hz)。另外,你前后门廊之间的时间(408800-28000)/800我想只有476行,不是480行。谢谢蒂姆。我一定是忘了在回家后发帖子的时候把我的代码推到回购协议上了,因为这些都是旧号码。V_COUNT_MAX的值应该是419999,V_FRONT_roach_STRT应该等于412000,这给了我59.94Hz的值。我编辑了这篇文章,以反映正确的数字,这是我在实验室和在家的副本之间唯一的区别。不幸的是,这个问题仍然存在。这确实是一个时间问题。问题在于CPLD,在我的教授的带领下,以及糟糕的文档,我认为内部时钟是可编程的,而事实上我在读取误差范围。如果其他人偶然发现,Lattice MachXO 2280C CPLD不能用于