Created
December 8, 2022 20:42
-
-
Save yupferris/f50e270b4bdb398e2a1ce39d214755bc to your computer and use it in GitHub Desktop.
video stuffz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// video generation | |
// ~12,288,000 hz pixel clock | |
// | |
// we want our video mode of 320x240 @ 60hz, this results in 204800 clocks per frame | |
// we need to add hblank and vblank times to this, so there will be a nondisplay area. | |
// it can be thought of as a border around the visible area. | |
// to make numbers simple, we can have 400 total clocks per line, and 320 visible. | |
// dividing 204800 by 400 results in 512 total lines per frame, and 240 visible. | |
// this pixel clock is fairly high for the relatively low resolution, but that's fine. | |
// PLL output has a minimum output frequency anyway. | |
assign video_rgb_clock = clk_core_12288; | |
assign video_rgb_clock_90 = clk_core_12288_90deg; | |
assign video_rgb = vidout_rgb; | |
assign video_de = vidout_de; | |
assign video_skip = vidout_skip; | |
assign video_vs = vidout_vs; | |
assign video_hs = vidout_hs; | |
localparam VID_V_BPORCH = 'd10; | |
localparam VID_V_ACTIVE = 'd240; | |
localparam VID_V_TOTAL = 'd512; | |
localparam VID_H_BPORCH = 'd10; | |
localparam VID_H_ACTIVE = 'd320; | |
localparam VID_H_TOTAL = 'd400; | |
reg [15:0] frame_count; | |
reg [9:0] x_count; | |
reg [9:0] y_count; | |
reg [23:0] vidout_rgb; | |
reg vidout_de; | |
reg vidout_skip; | |
reg vidout_vs; | |
reg vidout_hs; | |
always @(posedge clk_core_12288 or negedge reset_n) begin | |
if(~reset_n) begin | |
x_count <= 0; | |
y_count <= 0; | |
end else begin | |
vidout_de <= 0; | |
vidout_skip <= 0; | |
vidout_vs <= 0; | |
vidout_hs <= 0; | |
// x and y counters | |
x_count <= x_count + 1'b1; | |
if(x_count == VID_H_TOTAL-1) begin | |
x_count <= 0; | |
y_count <= y_count + 1'b1; | |
if(y_count == VID_V_TOTAL-1) begin | |
y_count <= 0; | |
end | |
end | |
// generate sync | |
if(x_count == 0 && y_count == 0) begin | |
// sync signal in back porch | |
// new frame | |
vidout_vs <= 1; | |
frame_count <= frame_count + 1'b1; | |
end | |
// we want HS to occur a bit after VS, not on the same cycle | |
if(x_count == 3) begin | |
// sync signal in back porch | |
// new line | |
vidout_hs <= 1; | |
end | |
// inactive screen areas are black | |
vidout_rgb <= 24'h0; | |
// generate active video | |
if(x_count >= VID_H_BPORCH && x_count < VID_H_ACTIVE+VID_H_BPORCH) begin | |
if(y_count >= VID_V_BPORCH && y_count < VID_V_ACTIVE+VID_V_BPORCH) begin | |
// data enable. this is the active region of the line | |
vidout_de <= 1; | |
vidout_rgb[23:16] <= test_pattern_r; | |
vidout_rgb[15:8] <= test_pattern_g; | |
vidout_rgb[7:0] <= test_pattern_b; | |
end | |
end | |
end | |
end | |
// video test pattern generator | |
// currently on the output pixel clock, but should ideally happen in another domain with line buffer fifo(s) in between | |
reg [8:0] test_pattern_x; | |
reg [7:0] test_pattern_y; | |
always @(posedge clk_core_12288 or negedge reset_n) begin | |
if (~reset_n) begin | |
test_pattern_x <= 9'd0; | |
test_pattern_y <= 8'd0; | |
end | |
else begin | |
if (vidout_vs) begin | |
test_pattern_x <= 9'd0; | |
test_pattern_y <= 8'd0; | |
end | |
else if (x_count >= VID_H_BPORCH && x_count < VID_H_ACTIVE + VID_H_BPORCH - 1) begin | |
test_pattern_x <= test_pattern_x + 9'd1; | |
end | |
else if (x_count == VID_H_ACTIVE + VID_H_BPORCH - 1) begin | |
test_pattern_x <= 9'd0; | |
test_pattern_y <= test_pattern_y + 8'd1; | |
end | |
end | |
end | |
wire [7:0] test_pattern_r = test_pattern_x[7:0]; | |
wire [7:0] test_pattern_g = test_pattern_y; | |
wire [7:0] test_pattern_b = 8'd64; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment