Trouble with VGA controller on CPLD

Status
Not open for further replies.

OctalByte

Newbie level 1
Joined
Apr 8, 2013
Messages
1
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,313
Hello,

my apologize if this question has been asked before; I searched these forums and none of the older posts were able to help me. What I am attempting to do is create a VGA controller from a Lattice MachXO CPLD in Verilog.

The Problem
I am attempting to display the color red with a resolution of 640x480 using a 25.175 MHz clock internal to the CPLD; however, when I plug the CPLD into a monitor I get an "Out of Range" message.

What I've tried
I have simulated the code in ModelSim, and everything appears to look good save for one issue. When I count the amount of time steps that have occurred from the during the V-Sync display zone (when H-Sync is drawing) and divided it by the frequency of H-Sync, I get 479 pulses -- one short of the 480 lines I should be drawing. I don't understand where this could be coming from as I've check my timings many times, and I suspect that this may be a symptom of the problem, but I'm not sure. Below is my code, and pictures of the timings from ModelSim. I have exhausted all of my other resources trying to figure this problem out, and I would greatly appreciate any help. Thanks.


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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



Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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'd408800
    `define V_COUNT_MAX         19'd416799
    
    /*** 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

 

Attachments

  • h-sync-timing-diagram.png
    22.3 KB · Views: 130
  • h-sync-timing-diagram2.png
    26.6 KB · Views: 114
  • h-sync-timing-diagram3.png
    30.7 KB · Views: 103
  • v-sync-timing-diagram.png
    28.6 KB · Views: 115
  • v-sync-timing-diagram2.png
    27.5 KB · Views: 108
Last edited:

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…