็่งฃVGAๆถๅบ็็งๅฏโโๅ็ด ๆถ้ใๅๆญฅ่ๅฒใๆถ้ๅบ
๐ ๆๅฐฑ๏ผไฟกๅท็ๆ โ Verilator้ช่ฏ
VGAๅชๆ5ๆ น็บฟ๏ผR/G/Bไธ่ฒๆจกๆไฟกๅท + HSYNCๆฐดๅนณๅๆญฅ + VSYNCๅ็ดๅๆญฅใๆพ็คบๅจไปๅทฆไธ่ง้ๅ็ด ๆซๆ๏ผ็ปๅฎไธ่กๆขไธไธ่ก๏ผ็ปๅฎไธๅธงๅๅฐๅทฆไธ่ง้ๆฐๅผๅงใ
| ๅๆฐ | ๆฐดๅนณ๏ผ่ก๏ผ | ๅ็ด๏ผๅธง๏ผ |
|---|---|---|
| ๅฏ่งๅ็ด /่ก | 640 | 480 |
| ๅๆญฅ่ๅฒ | 96 | 2 |
| ๅ่ฉ | 48 | 33 |
| ๅ่ฉ | 16 | 10 |
| ๆป่ฎก | 800 | 525 |
ๅธง็้ช่ฏ๏ผ25MHz รท (800 ร 525) โ 59.52Hz โ 60Hz โ
module vga_sync (
input wire clk, // 25MHzๅ็ด ๆถ้
input wire rst_n,
output reg hsync, vsync,
output reg [9:0] hcount, vcount,
output wire video_on
);
localparam H_TOTAL=800, H_VISIBLE=640, H_FRONT=16, H_SYNC=96, H_BACK=48;
localparam V_TOTAL=525, V_VISIBLE=480, V_FRONT=10, V_SYNC=2, V_BACK=33;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) hcount <= 0;
else if (hcount == H_TOTAL-1) hcount <= 0;
else hcount <= hcount + 1;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) vcount <= 0;
else if (hcount == H_TOTAL-1) begin
if (vcount == V_TOTAL-1) vcount <= 0;
else vcount <= vcount + 1;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) hsync <= 1;
else hsync <= ~((hcount >= H_VISIBLE+H_FRONT) &&
(hcount < H_VISIBLE+H_FRONT+H_SYNC));
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) vsync <= 1;
else vsync <= ~((vcount >= V_VISIBLE+V_FRONT) &&
(vcount < V_VISIBLE+V_FRONT+V_SYNC));
end
assign video_on = (hcount < H_VISIBLE) && (vcount < V_VISIBLE);
endmoduleโ
VGAๆๅช5ๆ นไฟกๅท็บฟ๏ผ
โ
ไธบไปไน640ร480้่ฆ800ร525็ๆถๅบ๏ผ
โ
HSYNCๅVSYNCๆฏ้ซๆๆ่ฟๆฏไฝๆๆ๏ผ
โ
ๅธง็ๅฆไฝ่ฎก็ฎ๏ผ
module vga_sync_tb;
logic clk,rst_n; logic hsync,vsync,video_on;
logic [9:0] hcount,vcount;
vga_sync uut(.*);
initial clk=0; always #20 clk=~clk; // 25MHz
// HSYNCไฝ่ๅฒๅฎฝๅบฆ็ป่ฎก
int hsync_low, hsync_edges;
logic hsync_prev;
always @(posedge clk) begin
hsync_prev<=hsync;
if(!hsync) hsync_low++;
else if(hsync&&!hsync_prev&&hsync_low>0) begin
if(hsync_low!=96) $display("FAIL:HSYNC=%0d",hsync_low);
else $display(" HSYNC่ๅฒ=%0dๅ็ด โ",hsync_low);
hsync_low<=0; hsync_edges++;
end
end
// VSYNCไฝ่ๅฒ็ป่ฎก
int vsync_low;
logic vsync_prev;
always @(posedge clk) begin
vsync_prev<=vsync;
if(!vsync) vsync_low++;
else if(vsync&&!vsync_prev&&vsync_low>0) begin
if(vsync_low!=1600) $display("FAIL:VSYNC=%0d",vsync_low);
else $display(" VSYNC่ๅฒ=%0dๅ็ด ๆถ้(2่ก) โ",vsync_low);
vsync_low<=0;
end
end
// ๅธง่ฎกๆฐๅๆๆๅ็ด ็ป่ฎก
int frame_count=0, video_on_count;
logic vsync_fell;
always @(posedge clk) begin
vsync_fell<=!vsync&&vsync_prev;
if(video_on) video_on_count++;
if(vsync_fell) begin
if(frame_count>0) begin
if(video_on_count==640*480)
$display(" ๅธง%0d: ๆๆๅ็ด =%0d โ",frame_count,video_on_count);
else
$display(" FAIL: ๅธง%0dๅ็ด =%0d",frame_count,video_on_count);
end
video_on_count<=0; frame_count++;
end
end
initial begin
$dumpfile("vga_sync.vcd");$dumpvars(0,vga_sync_tb);
rst_n=0;#100;rst_n=1;
$display("========== VGAๆถๅบ้ช่ฏ ==========");
wait(frame_count==4);
$display("==================================");
$display(" VGAๆถๅบ้ช่ฏๅฎๆ๏ผ");
$display(" - HSYNC: 96ๅ็ด โ");
$display(" - VSYNC: 2่ก โ");
$display(" - ๆๆ: 640ร480 โ");
$display("==================================");
$finish;
end
initial #200_000_000 $finish;
endmodule| ๆจกๅผ | ๅ่พจ็ | ๅ็ด ๆถ้ | ๅทๆฐ็ | H_TOTAL | V_TOTAL |
|---|---|---|---|---|---|
| VGA | 640ร480 | 25.175MHz | 60Hz | 800 | 525 |
| SVGA | 800ร600 | 40MHz | 60Hz | 1056 | 628 |
| XGA | 1024ร768 | 65MHz | 60Hz | 1344 | 806 |
| 720p | 1280ร720 | 74.25MHz | 60Hz | 1650 | 750 |
| 1080p | 1920ร1080 | 148.5MHz | 60Hz | 2200 | 1125 |
| ๆจกๅผ | ๅ่พจ็ | ๅ็ด ๆถ้ | ๅทๆฐ็ | H_TOTAL | V_TOTAL |
|---|---|---|---|---|---|
| VGA | 640ร480 | 25.175MHz | 60Hz | 800 | 525 |
| SVGA | 800ร600 | 40MHz | 60Hz | 1056 | 628 |
| XGA | 1024ร768 | 65MHz | 60Hz | 1344 | 806 |
| 720p | 1280ร720 | 74.25MHz | 60Hz | 1650 | 750 |
| 1080p | 1920ร1080 | 148.5MHz | 60Hz | 2200 | 1125 |
module vga_sync_tb;
logic clk,rst_n; logic hsync,vsync,video_on;
logic [9:0] hcount,vcount;
vga_sync uut(.*);
initial clk=0; always #20 clk=~clk; // 25MHz
// ๆฃๆตHSYNCไฝ่ๅฒๅฎฝๅบฆ(ๅบไธบ96)
int hsync_low;
always @(posedge clk) begin
if(!hsync) hsync_low++;
else if(hsync_low>0 && hsync_low!=96)
$display("FAIL: HSYNC=%0d",hsync_low);
else if(hsync_low==96) $display("HSYNC=96 โ");
end
initial begin rst_n=0; #100; rst_n=1; #200_000_000; $finish; end
endmoduleVerilatorไปฟ็VGAไธๅธง้่ฆ420,000ไธชๆถ้ๅจๆใๅฏไปฅๅ ๆH_TOTAL/V_TOTAL็ผฉๅฐ้ช่ฏ้ป่พ๏ผ็กฎ่ฎคๅๅ็จๆ ๅๅๆฐใ
CRTๆถไปฃ็ตๅญๆชไปไธ่กๆซๅฐพ่ทณๅฐไธไธ่กๅผๅคด้่ฆๆถ้ด๏ผไปๅบ้จ่ทณๅ้กถ้จไน้่ฆๆถ้ดใๆถ้ๅบๅฐฑๆฏ็ป็ตๅญๆช"็งปๅจๆถ้ด"ใ่ฝ็ถLCDไธ้่ฆ็ตๅญๆช๏ผไฝไธบๅ ผๅฎนไฟ็่ณไปใ
ๆถ้ๅบไธๆฏ"ๆตช่ดน"โโๆไปฌๅฏไปฅๅฉ็จๅฎ๏ผๆฏๅฆVGAๆถ้ๅบๅฏไปฅ็จๆฅๆดๆฐๅ็ผๅฒใๆง่กๆธธๆ้ป่พ็ญ๏ผไธๅฝฑๅ็ป้ขๆพ็คบใ