대사는 다 똑같고 타이밍의 길이만 다를 뿐
다음 지침은 640 * 480 해상도를 기준으로 합니다.
라인에서 동기화
- 라인 카운터가 a-96으로 카운트되면 라인 인에이블 출력이 높게 풀링됩니다.
- 그런 다음 라인 수는 계속해서 800까지 카운트되고 0에 도달하면 라인 활성화를 낮출 수 있습니다.
- 이때 필드 카운터는 0에서 1씩 증가하여 1이 됩니다.
- 800 라인 카운터의 또 다른 라운드 후 필드 카운터는 자동으로 2로 증가하고 조건이 충족되고 필드 활성화 출력이 높게 풀링됩니다.
- 데이터 전송을 시작하기 전에 필드 카운터가 35에 추가될 때까지 기다리십시오.
- 그러나 필드 카운트가 35에 도달하는 즉시 전송되지 않습니다. 라인 카운터가 표시 지연에 도달할 때까지 기다려야 합니다.
전체: 세그먼트로 나누기
- 필드 인에이블은 low 에 의해 높게 풀링된 다음 출력: 사용된 타이밍: 800 * 2 = 1600
- 라인 필드의 디스플레이 지연, 버퍼 단계: 시간 순서 동안: 800 * 33 = 26400
- 디스플레이 단계에서 클록 주기는 480 * 640 = 입니다. . . .
- 디스플레이 지연 ,
VGA 드라이버 코드:
module vga_driver(
input vga_clk, //VGA驱动时钟
input sys_rst_n, //复位信号
//VGA接口
output vga_hs, //行同步信号
output vga_vs, //场同步信号
output [15:0] vga_rgb, //红绿蓝三原色输出
input [15:0] pixel_data, //像素点数据
output [ 9:0] pixel_xpos, //像素点横坐标
output [ 9:0] pixel_ypos //像素点纵坐标
);
//parameter define
parameter H_SYNC = 10'd96; //行同步
parameter H_BACK = 10'd48; //行显示后沿
parameter H_DISP = 10'd640; //行有效数据
parameter H_FRONT = 10'd16; //行显示前沿
parameter H_TOTAL = 10'd800; //行扫描周期
parameter V_SYNC = 10'd2; //场同步
parameter V_BACK = 10'd33; //场显示后沿
parameter V_DISP = 10'd480; //场有效数据
parameter V_FRONT = 10'd10; //场显示前沿
parameter V_TOTAL = 10'd525; //场扫描周期
//reg define
reg [9:0] cnt_h;
reg [9:0] cnt_v;
//wire define
wire vga_en;
wire data_req;
//*****************************************************
//** main code
//*****************************************************
//VGA行场同步信号
assign vga_hs = (cnt_h <= H_SYNC - 1'b1) ? 1'b0 : 1'b1;
assign vga_vs = (cnt_v <= V_SYNC - 1'b1) ? 1'b0 : 1'b1;
//使能RGB565数据输出,颜色输出的开关
assign vga_en = (((cnt_h >= H_SYNC+H_BACK) && (cnt_h < H_SYNC+H_BACK+H_DISP)) // 判断行信号在有效数据段内
&&((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP))) // 判断场信号在有效数据段内
? 1'b1 : 1'b0;
//RGB565数据输出
assign vga_rgb = vga_en ? pixel_data : 16'd0; // 如果满足要求则能输出颜色信号
//请求像素点颜色数据输入,颜色位置的开关
assign data_req = (((cnt_h >= H_SYNC+H_BACK-1'b1) && (cnt_h < H_SYNC+H_BACK+H_DISP-1'b1))
&& ((cnt_v >= V_SYNC+V_BACK) && (cnt_v < V_SYNC+V_BACK+V_DISP)))
? 1'b1 : 1'b0;
//像素点坐标
assign pixel_xpos = data_req ? (cnt_h - (H_SYNC + H_BACK - 1'b1)) : 10'd0; // 如果满足条件则输出像素对应的位置
assign pixel_ypos = data_req ? (cnt_v - (V_SYNC + V_BACK - 1'b1)) : 10'd0; // 如果满足条件则输出像素对应的位置
/*
上述是设计两个开关来控制输出信号
*/
//行计数器对像素时钟计数
always @(posedge vga_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
cnt_h <= 10'd0;
else begin
if(cnt_h < H_TOTAL - 1'b1)
cnt_h <= cnt_h + 1'b1;
else
cnt_h <= 10'd0;
end
end
//场计数器对行计数
always @(posedge vga_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
cnt_v <= 10'd0;
else if(cnt_h == H_TOTAL - 1'b1) begin
if(cnt_v < V_TOTAL - 1'b1)
cnt_v <= cnt_v + 1'b1;
else
cnt_v <= 10'd0;
end
end
endmodule
드라이브 테스트 코드:
`timescale 1ns/1ps
`define clock_period 20
module VGA_driver_tb;
reg sys_clk ;
reg sys_rst_n ;
reg [15:0] pixel_data ;
wire vga_hs ;
wire vga_vs ;
wire [15:0] vga_rgb ;
wire [ 9:0] xpos ;
wire [ 9:0] ypos ;
vga_driver a1(
.vga_clk (sys_clk), //VGA驱动时钟
.sys_rst_n (sys_rst_n), //复位信号
.vga_hs (vga_hs), //行同步信号
.vga_vs (vga_vs), //场同步信号
.vga_rgb (vga_rgb), //红绿蓝三原色输出
.pixel_data(pixel_data), //像素点数据
.pixel_xpos (xpos), //像素点横坐标
.pixel_ypos (ypos) //像素点纵坐标
);
initial sys_clk = 1;
always #(`clock_period / 2) sys_clk = ~sys_clk;
initial begin
sys_rst_n = 0 ;
pixel_data = 0;
#(`clock_period * 20 +1);
sys_rst_n = 1 ;
pixel_data = 16'h1234;
#(`clock_period * 500_000);
#20;
$stop;
end
endmodule
요약하다:
VGA 드라이버 모듈의 기능은 다음과 같습니다.
1. 16픽셀 데이터 수신
2. 동작, 라인+필드 동기화 타이밍
2.1 라인 + 필드, 픽셀 데이터 전송 타이밍, 전송
2.2 행 + 필드의 전송 타이밍에서 현재 수평 및 수직 좌표를 전송합니다.
아마 그럴거야