| 1 |
131 |
jt_eaton |
|
| 2 |
|
|
//---------------------------------------------------
|
| 3 |
|
|
|
| 4 |
|
|
module `VARIANT`SVGA_TIMING_GENERATION
|
| 5 |
|
|
#(parameter CHARACTER_DECODE_DELAY=4,
|
| 6 |
|
|
parameter H_ACTIVE=640,
|
| 7 |
|
|
parameter H_FRONT_PORCH=16,
|
| 8 |
|
|
parameter H_SYNCH=96,
|
| 9 |
|
|
parameter H_BACK_PORCH=48,
|
| 10 |
|
|
parameter H_TOTAL=800,
|
| 11 |
|
|
parameter V_ACTIVE=480,
|
| 12 |
|
|
parameter V_FRONT_PORCH=11,
|
| 13 |
|
|
parameter V_SYNCH=2,
|
| 14 |
|
|
parameter V_BACK_PORCH=31,
|
| 15 |
|
|
parameter V_TOTAL=524
|
| 16 |
|
|
)
|
| 17 |
|
|
(
|
| 18 |
|
|
|
| 19 |
|
|
input clk, // pixel clock
|
| 20 |
|
|
input reset, // reset
|
| 21 |
|
|
output reg h_synch, // horizontal synch for VGA connector
|
| 22 |
|
|
output reg v_synch, // vertical synch for VGA connector
|
| 23 |
|
|
output reg blank, // composite blanking
|
| 24 |
|
|
output reg [10:0] pixel_count, // counts the pixels in a line
|
| 25 |
|
|
output reg [9:0] line_count, // counts the display lines
|
| 26 |
|
|
output reg [2:0] subchar_pixel,// pixel position within the character
|
| 27 |
|
|
output reg [2:0] subchar_line, // identifies the line number within a character block
|
| 28 |
|
|
output reg [6:0] char_column, // character number on the current line
|
| 29 |
|
|
output reg [6:0] char_line // line number on the screen
|
| 30 |
|
|
);
|
| 31 |
|
|
|
| 32 |
|
|
|
| 33 |
|
|
|
| 34 |
|
|
|
| 35 |
|
|
reg h_blank; // horizontal blanking
|
| 36 |
|
|
reg v_blank; // vertical blanking
|
| 37 |
|
|
|
| 38 |
|
|
|
| 39 |
|
|
|
| 40 |
|
|
reg [9:0] char_column_count; // a counter used to define the character column number
|
| 41 |
|
|
reg [9:0] char_line_count; // a counter used to define the character line number
|
| 42 |
|
|
reg reset_char_line; // flag to reset the character line during VBI
|
| 43 |
|
|
reg reset_char_column; // flag to reset the character column during HBI
|
| 44 |
|
|
|
| 45 |
|
|
|
| 46 |
|
|
|
| 47 |
|
|
// CREATE THE HORIZONTAL LINE PIXEL COUNTER
|
| 48 |
|
|
always @ (posedge clk) begin
|
| 49 |
|
|
if (reset)
|
| 50 |
|
|
// on reset set pixel counter to 0
|
| 51 |
|
|
pixel_count <= 11'd0;
|
| 52 |
|
|
|
| 53 |
|
|
else if (pixel_count == (H_TOTAL - 1))
|
| 54 |
|
|
// last pixel in the line, so reset pixel counter
|
| 55 |
|
|
pixel_count <= 11'd0;
|
| 56 |
|
|
|
| 57 |
|
|
else
|
| 58 |
|
|
pixel_count <= pixel_count + 1;
|
| 59 |
|
|
end
|
| 60 |
|
|
|
| 61 |
|
|
// CREATE THE HORIZONTAL SYNCH PULSE
|
| 62 |
|
|
always @ (posedge clk ) begin
|
| 63 |
|
|
if (reset)
|
| 64 |
|
|
// on reset remove h_synch
|
| 65 |
|
|
h_synch <= 1'b0;
|
| 66 |
|
|
|
| 67 |
|
|
else if (pixel_count == (H_ACTIVE + H_FRONT_PORCH - 1))
|
| 68 |
|
|
// start of h_synch
|
| 69 |
|
|
h_synch <= 1'b1;
|
| 70 |
|
|
|
| 71 |
|
|
else if (pixel_count == (H_TOTAL - H_BACK_PORCH - 1))
|
| 72 |
|
|
// end of h_synch
|
| 73 |
|
|
h_synch <= 1'b0;
|
| 74 |
|
|
end
|
| 75 |
|
|
|
| 76 |
|
|
// CREATE THE VERTICAL FRAME LINE COUNTER
|
| 77 |
|
|
always @ (posedge clk ) begin
|
| 78 |
|
|
if (reset)
|
| 79 |
|
|
// on reset set line counter to 0
|
| 80 |
|
|
line_count <= 10'd0;
|
| 81 |
|
|
|
| 82 |
|
|
else if ((line_count == (V_TOTAL - 1)) & (pixel_count == (H_TOTAL - 1)))
|
| 83 |
|
|
// last pixel in last line of frame, so reset line counter
|
| 84 |
|
|
line_count <= 10'd0;
|
| 85 |
|
|
|
| 86 |
|
|
else if ((pixel_count == (H_TOTAL - 1)))
|
| 87 |
|
|
// last pixel but not last line, so increment line counter
|
| 88 |
|
|
line_count <= line_count + 1;
|
| 89 |
|
|
end
|
| 90 |
|
|
|
| 91 |
|
|
// CREATE THE VERTICAL SYNCH PULSE
|
| 92 |
|
|
always @ (posedge clk ) begin
|
| 93 |
|
|
if (reset)
|
| 94 |
|
|
// on reset remove v_synch
|
| 95 |
|
|
v_synch <= 1'b0;
|
| 96 |
|
|
|
| 97 |
|
|
else if ((line_count == (V_ACTIVE + V_FRONT_PORCH - 1) &
|
| 98 |
|
|
(pixel_count == H_TOTAL - 1)))
|
| 99 |
|
|
// start of v_synch
|
| 100 |
|
|
v_synch <= 1'b1;
|
| 101 |
|
|
|
| 102 |
|
|
else if ((line_count == (V_TOTAL - V_BACK_PORCH - 1)) &
|
| 103 |
|
|
(pixel_count == (H_TOTAL - 1)))
|
| 104 |
|
|
// end of v_synch
|
| 105 |
|
|
v_synch <= 1'b0;
|
| 106 |
|
|
end
|
| 107 |
|
|
|
| 108 |
|
|
|
| 109 |
|
|
// CREATE THE HORIZONTAL BLANKING SIGNAL
|
| 110 |
|
|
// the "-2" is used instead of "-1" because of the extra register delay
|
| 111 |
|
|
// for the composite blanking signal
|
| 112 |
|
|
always @ (posedge clk ) begin
|
| 113 |
|
|
if (reset)
|
| 114 |
|
|
// on reset remove the h_blank
|
| 115 |
|
|
h_blank <= 1'b0;
|
| 116 |
|
|
|
| 117 |
|
|
else if (pixel_count == (H_ACTIVE -2))
|
| 118 |
|
|
// start of HBI
|
| 119 |
|
|
h_blank <= 1'b1;
|
| 120 |
|
|
|
| 121 |
|
|
else if (pixel_count == (H_TOTAL -2))
|
| 122 |
|
|
// end of HBI
|
| 123 |
|
|
h_blank <= 1'b0;
|
| 124 |
|
|
end
|
| 125 |
|
|
|
| 126 |
|
|
|
| 127 |
|
|
// CREATE THE VERTICAL BLANKING SIGNAL
|
| 128 |
|
|
// the "-2" is used instead of "-1" in the horizontal factor because of the extra
|
| 129 |
|
|
// register delay for the composite blanking signal
|
| 130 |
|
|
always @ (posedge clk ) begin
|
| 131 |
|
|
if (reset)
|
| 132 |
|
|
// on reset remove v_blank
|
| 133 |
|
|
v_blank <= 1'b0;
|
| 134 |
|
|
|
| 135 |
|
|
else if ((line_count == (V_ACTIVE - 1) &
|
| 136 |
|
|
(pixel_count == H_TOTAL - 2)))
|
| 137 |
|
|
// start of VBI
|
| 138 |
|
|
v_blank <= 1'b1;
|
| 139 |
|
|
|
| 140 |
|
|
else if ((line_count == (V_TOTAL - 1)) &
|
| 141 |
|
|
(pixel_count == (H_TOTAL - 2)))
|
| 142 |
|
|
// end of VBI
|
| 143 |
|
|
v_blank <= 1'b0;
|
| 144 |
|
|
end
|
| 145 |
|
|
|
| 146 |
|
|
|
| 147 |
|
|
// CREATE THE COMPOSITE BANKING SIGNAL
|
| 148 |
|
|
always @ (posedge clk ) begin
|
| 149 |
|
|
if (reset)
|
| 150 |
|
|
// on reset remove blank
|
| 151 |
|
|
blank <= 1'b0;
|
| 152 |
|
|
|
| 153 |
|
|
// blank during HBI or VBI
|
| 154 |
|
|
else if (h_blank || v_blank)
|
| 155 |
|
|
blank <= 1'b1;
|
| 156 |
|
|
|
| 157 |
|
|
else
|
| 158 |
|
|
// active video do not blank
|
| 159 |
|
|
blank <= 1'b0;
|
| 160 |
|
|
end
|
| 161 |
|
|
|
| 162 |
|
|
|
| 163 |
|
|
/*
|
| 164 |
|
|
CREATE THE CHARACTER COUNTER.
|
| 165 |
|
|
CHARACTERS ARE DEFINED WITHIN AN 8 x 8 PIXEL BLOCK.
|
| 166 |
|
|
|
| 167 |
|
|
A 640 x 480 video mode will display 80 characters on 60 lines.
|
| 168 |
|
|
A 800 x 600 video mode will display 100 characters on 75 lines.
|
| 169 |
|
|
A 1024 x 768 video mode will display 128 characters on 96 lines.
|
| 170 |
|
|
|
| 171 |
|
|
"subchar_line" identifies the row in the 8 x 8 block.
|
| 172 |
|
|
"subchar_pixel" identifies the column in the 8 x 8 block.
|
| 173 |
|
|
*/
|
| 174 |
|
|
|
| 175 |
|
|
// CREATE THE VERTICAL FRAME LINE COUNTER
|
| 176 |
|
|
always @ (posedge clk ) begin
|
| 177 |
|
|
if (reset)
|
| 178 |
|
|
// on reset set line counter to 0
|
| 179 |
|
|
subchar_line <= 3'b000;
|
| 180 |
|
|
|
| 181 |
|
|
else if ((line_count == (V_TOTAL - 1)) & (pixel_count == (H_TOTAL - 1) - CHARACTER_DECODE_DELAY))
|
| 182 |
|
|
// reset line counter
|
| 183 |
|
|
subchar_line <= 3'b000;
|
| 184 |
|
|
|
| 185 |
|
|
else if (pixel_count == (H_TOTAL - 1) - CHARACTER_DECODE_DELAY)
|
| 186 |
|
|
// increment line counter
|
| 187 |
|
|
subchar_line <= line_count[2:0] + 3'b001;
|
| 188 |
|
|
end
|
| 189 |
|
|
|
| 190 |
|
|
// subchar_pixel defines the pixel within the character line
|
| 191 |
|
|
always @ (posedge clk ) begin
|
| 192 |
|
|
if (reset)
|
| 193 |
|
|
// reset to 5 so that the first character data can be latched
|
| 194 |
|
|
subchar_pixel <= 3'b101;
|
| 195 |
|
|
|
| 196 |
|
|
else if (pixel_count == ((H_TOTAL - 1) - CHARACTER_DECODE_DELAY))
|
| 197 |
|
|
// reset to 5 so that the first character data can be latched
|
| 198 |
|
|
subchar_pixel <= 3'b101;
|
| 199 |
|
|
|
| 200 |
|
|
else
|
| 201 |
|
|
subchar_pixel <= subchar_pixel + 1;
|
| 202 |
|
|
end
|
| 203 |
|
|
|
| 204 |
|
|
|
| 205 |
|
|
wire [9:0] char_column_count_iter = char_column_count + 1;
|
| 206 |
|
|
|
| 207 |
|
|
always @ (posedge clk ) begin
|
| 208 |
|
|
if (reset) begin
|
| 209 |
|
|
char_column_count <= 10'd0;
|
| 210 |
|
|
char_column <= 7'd0;
|
| 211 |
|
|
end
|
| 212 |
|
|
|
| 213 |
|
|
else if (reset_char_column) begin
|
| 214 |
|
|
// reset the char column count during the HBI
|
| 215 |
|
|
char_column_count <= 10'd0;
|
| 216 |
|
|
char_column <= 7'd0;
|
| 217 |
|
|
end
|
| 218 |
|
|
|
| 219 |
|
|
else begin
|
| 220 |
|
|
char_column_count <= char_column_count_iter;
|
| 221 |
|
|
char_column <= char_column_count_iter[9:3];
|
| 222 |
|
|
end
|
| 223 |
|
|
end
|
| 224 |
|
|
|
| 225 |
|
|
wire [9:0] char_line_count_iter = char_line_count + 1;
|
| 226 |
|
|
|
| 227 |
|
|
always @ (posedge clk ) begin
|
| 228 |
|
|
if (reset) begin
|
| 229 |
|
|
char_line_count <= 10'd0;
|
| 230 |
|
|
char_line <= 7'd0;
|
| 231 |
|
|
end
|
| 232 |
|
|
|
| 233 |
|
|
else if (reset_char_line) begin
|
| 234 |
|
|
// reset the char line count during the VBI
|
| 235 |
|
|
char_line_count <= 10'd0;
|
| 236 |
|
|
char_line <= 7'd0;
|
| 237 |
|
|
end
|
| 238 |
|
|
|
| 239 |
|
|
else if (pixel_count == ((H_TOTAL - 1) - CHARACTER_DECODE_DELAY)) begin
|
| 240 |
|
|
// last pixel but not last line, so increment line counter
|
| 241 |
|
|
char_line_count <= char_line_count_iter;
|
| 242 |
|
|
char_line <= char_line_count_iter[9:3];
|
| 243 |
|
|
end
|
| 244 |
|
|
end
|
| 245 |
|
|
|
| 246 |
|
|
// CREATE THE CONTROL SIGNALS FOR THE CHARACTER ADDRESS COUNTERS
|
| 247 |
|
|
/*
|
| 248 |
|
|
The HOLD and RESET signals are advanced from the beginning and end
|
| 249 |
|
|
of HBI and VBI to compensate for the internal character generation
|
| 250 |
|
|
pipeline.
|
| 251 |
|
|
*/
|
| 252 |
|
|
always @ (posedge clk ) begin
|
| 253 |
|
|
if (reset)
|
| 254 |
|
|
reset_char_column <= 1'b0;
|
| 255 |
|
|
|
| 256 |
|
|
else if (pixel_count == ((H_ACTIVE - 2) - CHARACTER_DECODE_DELAY))
|
| 257 |
|
|
// start of HBI
|
| 258 |
|
|
reset_char_column <= 1'b1;
|
| 259 |
|
|
|
| 260 |
|
|
else if (pixel_count == ((H_TOTAL - 1) - CHARACTER_DECODE_DELAY))
|
| 261 |
|
|
// end of HBI
|
| 262 |
|
|
reset_char_column <= 1'b0;
|
| 263 |
|
|
end
|
| 264 |
|
|
|
| 265 |
|
|
always @ (posedge clk ) begin
|
| 266 |
|
|
if (reset)
|
| 267 |
|
|
reset_char_line <= 1'b0;
|
| 268 |
|
|
|
| 269 |
|
|
else if ((line_count == (V_ACTIVE - 1)) &
|
| 270 |
|
|
(pixel_count == ((H_ACTIVE - 1) - CHARACTER_DECODE_DELAY)))
|
| 271 |
|
|
// start of VBI
|
| 272 |
|
|
reset_char_line <= 1'b1;
|
| 273 |
|
|
|
| 274 |
|
|
else if ((line_count == (V_TOTAL - 1)) &
|
| 275 |
|
|
(pixel_count == ((H_TOTAL - 1) - CHARACTER_DECODE_DELAY)))
|
| 276 |
|
|
// end of VBI
|
| 277 |
|
|
reset_char_line <= 1'b0;
|
| 278 |
|
|
end
|
| 279 |
|
|
endmodule //SVGA_TIMING_GENERATION
|
| 280 |
|
|
|