190 lines
4.1 KiB
Coq
190 lines
4.1 KiB
Coq
|
module VGA_Pattern_Generator(
|
||
|
input i_Clk,
|
||
|
input [3:0] i_Pattern,
|
||
|
input i_HSync,
|
||
|
input i_VSync,
|
||
|
|
||
|
output reg o_HSync = 0,
|
||
|
output reg o_VSync = 0,
|
||
|
output reg [VIDEO_WIDTH-1:0] o_Red,
|
||
|
output reg [VIDEO_WIDTH-1:0] o_Green,
|
||
|
output reg [VIDEO_WIDTH-1:0] o_Blue
|
||
|
);
|
||
|
// Go Board only supports 3 bits per channel. That's even less than the
|
||
|
// Amiga!
|
||
|
parameter VIDEO_WIDTH = 3;
|
||
|
|
||
|
parameter TOTAL_COLUMNS = 800;
|
||
|
parameter TOTAL_ROWS = 525;
|
||
|
|
||
|
parameter ACTIVE_COLUMNS = 640;
|
||
|
parameter ACTIVE_ROWS = 480;
|
||
|
|
||
|
localparam COLOR_BAR_WIDTH = ACTIVE_COLUMNS / 8;
|
||
|
|
||
|
wire w_HSync, w_VSync;
|
||
|
|
||
|
wire [VIDEO_WIDTH-1:0] w_Red[0:15];
|
||
|
wire [VIDEO_WIDTH-1:0] w_Green[0:15];
|
||
|
wire [VIDEO_WIDTH-1:0] w_Blue[0:15];
|
||
|
|
||
|
wire [$clog2(TOTAL_COLUMNS)-1:0] w_X;
|
||
|
wire [$clog2(TOTAL_ROWS)-1:0] w_Y;
|
||
|
|
||
|
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)
|
||
|
);
|
||
|
|
||
|
// all these pattern operations take one clock tick
|
||
|
// so delay sync signals by that much
|
||
|
always @(posedge i_Clk) begin
|
||
|
o_HSync <= w_HSync;
|
||
|
o_VSync <= w_VSync;
|
||
|
end
|
||
|
|
||
|
// none more black
|
||
|
assign w_Red[0] = 0;
|
||
|
assign w_Green[0] = 0;
|
||
|
assign w_Blue[0] = 0;
|
||
|
|
||
|
// red
|
||
|
assign w_Red[1] = (
|
||
|
(w_X < ACTIVE_COLUMNS && w_Y < ACTIVE_ROWS) ?
|
||
|
{VIDEO_WIDTH{1'b1}} :
|
||
|
0
|
||
|
);
|
||
|
assign w_Green[1] = 0;
|
||
|
assign w_Blue[1] = 0;
|
||
|
|
||
|
// green
|
||
|
assign w_Red[2] = 0;
|
||
|
assign w_Green[2] = (
|
||
|
(w_X < ACTIVE_COLUMNS && w_Y < ACTIVE_ROWS) ?
|
||
|
{VIDEO_WIDTH{1'b1}} :
|
||
|
0
|
||
|
);
|
||
|
assign w_Blue[2] = 0;
|
||
|
|
||
|
// blue
|
||
|
assign w_Red[3] = 0;
|
||
|
assign w_Green[3] = 0;
|
||
|
assign w_Blue[3] = (
|
||
|
(w_X < ACTIVE_COLUMNS && w_Y < ACTIVE_ROWS) ?
|
||
|
{VIDEO_WIDTH{1'b1}} :
|
||
|
0
|
||
|
);
|
||
|
|
||
|
// checkerboard
|
||
|
// cell size is 32 pixels
|
||
|
assign w_Red[4] = (w_X[5] ^ w_Y[5]) ? {VIDEO_WIDTH{1'b1}} : 0;
|
||
|
assign w_Green[4] = w_Red[4];
|
||
|
assign w_Blue[4] = w_Red[4];
|
||
|
|
||
|
wire [2:0] w_colorBarSelect;
|
||
|
|
||
|
// color bars
|
||
|
// yes this is the hardware way to do this b/c multi/div
|
||
|
assign w_colorBarSelect =
|
||
|
w_X < COLOR_BAR_WIDTH ? 0 :
|
||
|
w_X < COLOR_BAR_WIDTH * 2 ? 1 :
|
||
|
w_X < COLOR_BAR_WIDTH * 3 ? 2 :
|
||
|
w_X < COLOR_BAR_WIDTH * 4 ? 3 :
|
||
|
w_X < COLOR_BAR_WIDTH * 5 ? 4 :
|
||
|
w_X < COLOR_BAR_WIDTH * 6 ? 5 :
|
||
|
w_X < COLOR_BAR_WIDTH * 7 ? 6 :7;
|
||
|
|
||
|
assign w_Red[5] = (
|
||
|
w_colorBarSelect == 4 ||
|
||
|
w_colorBarSelect == 5 ||
|
||
|
w_colorBarSelect == 6 ||
|
||
|
w_colorBarSelect == 7
|
||
|
) ? {VIDEO_WIDTH{1'b1}} : 0;
|
||
|
|
||
|
assign w_Green[5] = (
|
||
|
w_colorBarSelect == 2 ||
|
||
|
w_colorBarSelect == 3 ||
|
||
|
w_colorBarSelect == 6 ||
|
||
|
w_colorBarSelect == 7
|
||
|
) ? {VIDEO_WIDTH{1'b1}} : 0;
|
||
|
|
||
|
assign w_Blue[5] = (
|
||
|
w_colorBarSelect == 1 ||
|
||
|
w_colorBarSelect == 3 ||
|
||
|
w_colorBarSelect == 5 ||
|
||
|
w_colorBarSelect == 7
|
||
|
) ? {VIDEO_WIDTH{1'b1}} : 0;
|
||
|
|
||
|
// border
|
||
|
|
||
|
localparam BORDER_WIDTH = 2;
|
||
|
|
||
|
assign w_Red[6] = (
|
||
|
w_X < BORDER_WIDTH || w_X >= ACTIVE_COLUMNS - BORDER_WIDTH ||
|
||
|
w_Y < BORDER_WIDTH || w_Y >= ACTIVE_ROWS - BORDER_WIDTH
|
||
|
) ? {VIDEO_WIDTH{1'b1}} : 0;
|
||
|
assign w_Green[6] = 0;
|
||
|
assign w_Blue[6] = 0;
|
||
|
|
||
|
always @(posedge i_Clk) begin
|
||
|
case (i_Pattern)
|
||
|
0:
|
||
|
begin
|
||
|
o_Red <= w_Red[0];
|
||
|
o_Green <= w_Green[0];
|
||
|
o_Blue <= w_Blue[0];
|
||
|
end
|
||
|
1:
|
||
|
begin
|
||
|
o_Red <= w_Red[1];
|
||
|
o_Green <= w_Green[1];
|
||
|
o_Blue <= w_Blue[1];
|
||
|
end
|
||
|
2:
|
||
|
begin
|
||
|
o_Red <= w_Red[2];
|
||
|
o_Green <= w_Green[2];
|
||
|
o_Blue <= w_Blue[2];
|
||
|
end
|
||
|
3:
|
||
|
begin
|
||
|
o_Red <= w_Red[3];
|
||
|
o_Green <= w_Green[3];
|
||
|
o_Blue <= w_Blue[3];
|
||
|
end
|
||
|
4:
|
||
|
begin
|
||
|
o_Red <= w_Red[4];
|
||
|
o_Green <= w_Green[4];
|
||
|
o_Blue <= w_Blue[4];
|
||
|
end
|
||
|
5:
|
||
|
begin
|
||
|
o_Red <= w_Red[5];
|
||
|
o_Green <= w_Green[5];
|
||
|
o_Blue <= w_Blue[5];
|
||
|
end
|
||
|
6:
|
||
|
begin
|
||
|
o_Red <= w_Red[6];
|
||
|
o_Green <= w_Green[6];
|
||
|
o_Blue <= w_Blue[6];
|
||
|
end
|
||
|
default:
|
||
|
begin
|
||
|
o_Red <= w_Red[0];
|
||
|
o_Green <= w_Green[0];
|
||
|
o_Blue <= w_Blue[0];
|
||
|
end
|
||
|
endcase
|
||
|
end
|
||
|
endmodule
|