verilog - Trouble with VGA Controller on CPLD -
what attempting create vga controller lattice machxo cpld in verilog.
the problem
i attempting display color red resolution of 640x480 @ 60hz using 25.175 mhz clock internal cpld; however, when plug cpld monitor "out of range" message; no monitor try can understand resolution like.
what i've tried
i have simulated code in modelsim (pictures included), , appears save 1 issue. when count amount of time steps have occurred during v-sync display zone (when h-sync drawing) , divided frequency of h-sync, 479 pulses -- 1 short of 480 lines should drawing. don't understand coming i've check timings many times, , suspect may symptom of problem, i'm not sure.
the numbers i'm using generate numbers timings tiny vga: tinyvga.com/vga-timing/640x480@60hz
below code, , pictures of timings modelsim, thanks.
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 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 top module >*/ input wire nrst; /*< reset input top module >*/ output reg h_sync; /*< goes vga horizontal sync >*/ output reg v_sync; /*< goes 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 clk >*/ reg [19:0] v_counter; /*< tracks amount of pulses 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 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 h_sync ***/ @(*) begin /* if vertical sync line not in 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 vertical sync line in display zone, allow h_sync go through procedure */ else begin if (h_counter < `h_sync_pulse) begin h_sync = 0; rgb_en = 0; end /* if h_sync in 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 front porch period, disable rgb */ else begin h_sync = 1; rgb_en = 0; end end end /*** state machine v_sync ***/ @(*) begin if (v_counter < `v_sync_pulse) begin v_sync = 0; end else begin v_sync = 1; end end /*** counter logic ***/ @(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 @(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
every vga monitor i've worked requires red, green, , blue signals 0 during blanking periods (hsync | vsync)
. instead of assigning z (high impedance) try assign red = (rgb_en ? 1'b1 : 1'b0);
. have green , blue (or assign them 0 permanently).
if it's not that, timing issue. try use oscilloscope measure frequency of vsync signals - should nicely line 60hz.
Comments
Post a Comment