go-board-code/vga_add_porches_to_output.v

104 lines
2.6 KiB
Verilog

/**
* The output is buffered as the front/back porches are added, so watch your
* timing for other stuff.
*
* Side effects:
* * Blanks o_<color> if within HSync/VSync
*/
module VGA_Add_Porches_To_Output(
input i_Clk,
input i_HSync,
input i_VSync,
input [VIDEO_WIDTH-1:0] i_Red,
input [VIDEO_WIDTH-1:0] i_Green,
input [VIDEO_WIDTH-1:0] i_Blue,
output reg o_HSync,
output reg o_VSync,
output reg [VIDEO_WIDTH-1:0] o_Red,
output reg [VIDEO_WIDTH-1:0] o_Green,
output reg [VIDEO_WIDTH-1:0] o_Blue
);
parameter VIDEO_WIDTH = 3;
parameter TOTAL_COLUMNS = 800;
parameter TOTAL_ROWS = 525;
parameter ACTIVE_COLUMNS = 640;
parameter ACTIVE_ROWS = 480;
//parameter FRONT_PORCH_COUNT_X = 18;
parameter FRONT_PORCH_COUNT_X = 15;
//parameter FRONT_PORCH_COUNT_Y = 10;
parameter FRONT_PORCH_COUNT_Y = 10;
//parameter BACK_PORCH_COUNT_X = 50;
parameter BACK_PORCH_COUNT_X = 53;
//parameter BACK_PORCH_COUNT_Y = 33;
parameter BACK_PORCH_COUNT_Y = 33;
wire w_HSync, w_VSync;
wire [$clog2(TOTAL_COLUMNS)-1:0] w_X;
wire [$clog2(TOTAL_ROWS)-1:0] w_Y;
reg [VIDEO_WIDTH-1:0] r_Red = 0;
reg [VIDEO_WIDTH-1:0] r_Green = 0;
reg [VIDEO_WIDTH-1:0] r_Blue = 0;
VGA_Current_Beam_Position #(
.TOTAL_COLUMNS(TOTAL_COLUMNS),
.TOTAL_ROWS(TOTAL_ROWS)
) CurrentPosition (
.i_Clk(i_Clk),
.i_HSync(i_HSync),
.i_VSync(i_VSync),
.o_HSync(w_HSync),
.o_VSync(w_VSync),
.o_X(w_X),
.o_Y(w_Y)
);
wire w_withinHPorch, w_withinVPorch, w_withinSync;
assign w_withinHPorch = (w_X < FRONT_PORCH_COUNT_X + ACTIVE_COLUMNS) ||
(w_X > TOTAL_COLUMNS - BACK_PORCH_COUNT_X - 1);
assign w_withinVPorch = (w_Y < FRONT_PORCH_COUNT_Y + ACTIVE_ROWS) ||
(w_Y > TOTAL_ROWS - BACK_PORCH_COUNT_Y - 1);
assign w_withinSync = (w_X > ACTIVE_COLUMNS) || (w_Y > ACTIVE_COLUMNS);
// https://web.mit.edu/6.111/www/s2004/NEWKIT/vga.shtml
always @(posedge i_Clk) begin
if (w_withinHPorch) begin
o_HSync <= 1;
end else begin
o_HSync <= w_HSync;
end
if (w_withinVPorch) begin
o_VSync <= 1;
end else begin
o_VSync <= w_VSync;
end
end
// The process of going through Current Beam Position and then
// the porch alignment above delays the video signal by two clock ticks.
// Do the same input -> wire -> output as above.
always @(posedge i_Clk) begin
r_Red <= i_Red;
r_Green <= i_Green;
r_Blue <= i_Blue;
// Ensure we never deliver color data during hsync/vsync
if (w_withinSync) begin
o_Red <= 0;
o_Green <= 0;
o_Blue <= 0;
end else begin
o_Red <= r_Red;
o_Green <= r_Green;
o_Blue <= r_Blue;
end
end
endmodule