URL
https://opencores.org/ocsvn/axi_vga/axi_vga/trunk
Subversion Repositories axi_vga
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 3 to Rev 4
- ↔ Reverse comparison
Rev 3 → Rev 4
/axi_vga/trunk/rtl/vga_out.v
0,0 → 1,446
|
/****************************8********** |
Date: 20191111 |
Designer: HugoLiu |
AXI to VGA frame buffer xr8g8b8 To use the DRAM |
To use AUO LCD A070vW05V2 and Xilinx Zynq7020 |
(c) HugoLiu 2019 |
*****************************8**********/ |
`define Hsync_len 1055 //799 |
`define Hsync_low 840 //656 |
`define Hsync_high 968 //752 |
`define Hsync_act 799 //639 |
|
`define Vsync_len 504 //524 |
`define Vsync_low 480 //490 |
`define Vsync_high 483 //492 |
`define Vsync_act 479 //399 |
|
`define Hsync_act_d 800 //640 |
`define Vsync_act_d 480 //400 |
|
module vga_out( |
S_AXI_ARESETN, S_AXI_ACLK, |
//write address signal |
M_AXI_AWADDR, //care |
M_AXI_AWVALID, //care |
M_AXI_AWREADY, //care |
M_AXI_AWID, //care |
M_AXI_AWBURST, |
M_AXI_AWCACHE, |
M_AXI_AWLEN, |
M_AXI_AWLOCK, |
M_AXI_AWPROT, |
M_AXI_AWQOS, |
M_AXI_AWSIZE, |
//write data |
M_AXI_WDATA, |
M_AXI_WSTRB, |
M_AXI_WVALID, |
M_AXI_WREADY, |
M_AXI_WID, |
M_AXI_WLAST, |
//write response |
M_AXI_BID, |
M_AXI_BREADY, |
M_AXI_BRESP, |
M_AXI_BVALID, |
//read address signal |
M_AXI_ARADDR, |
M_AXI_ARVALID, |
M_AXI_ARREADY, |
M_AXI_ARID, |
M_AXI_ARBURST, |
M_AXI_ARCACHE, |
M_AXI_ARLEN, |
M_AXI_ARLOCK, |
M_AXI_ARPROT, |
M_AXI_ARQOS, |
M_AXI_ARSIZE, |
//read data |
M_AXI_RDATA, |
M_AXI_RID, |
M_AXI_RLAST, |
M_AXI_RREADY, |
M_AXI_RRESP, |
M_AXI_RVALID, |
//setting |
/* |
video_first_addr , |
vga_en , |
Total_Burst_Per_Frame, |
*/ |
r8 , |
g8 , |
b8 , |
hsync , |
vsync , |
de , |
pixel_clk |
|
); |
//TFT interface |
// input [31:0] video_first_addr; |
// input vga_en; |
// input [23:0] Total_Burst_Per_Frame; |
output [7:0] r8, g8, b8; |
output hsync, vsync, de; |
input pixel_clk; |
|
/////////////////////////////////////////////// |
|
input S_AXI_ARESETN, S_AXI_ACLK; |
//waddr |
output [31:0] M_AXI_AWADDR; |
output [1:0] M_AXI_AWBURST; |
output [3:0] M_AXI_AWCACHE; |
output [5:0] M_AXI_AWID; |
output [3:0] M_AXI_AWLEN; |
output [1:0] M_AXI_AWLOCK; |
output [2:0] M_AXI_AWPROT; |
output [3:0] M_AXI_AWQOS; |
input M_AXI_AWREADY; |
output [2:0] M_AXI_AWSIZE; |
output M_AXI_AWVALID; |
//wdata |
output [63:0] M_AXI_WDATA; |
output [5:0] M_AXI_WID; |
output M_AXI_WLAST; |
input M_AXI_WREADY; |
output [7:0] M_AXI_WSTRB; |
output M_AXI_WVALID; |
//w response |
input [5:0] M_AXI_BID; |
output M_AXI_BREADY; |
input [1:0] M_AXI_BRESP; |
input M_AXI_BVALID; |
//read addr |
output [31:0] M_AXI_ARADDR; |
output [1:0] M_AXI_ARBURST; |
output [3:0] M_AXI_ARCACHE; |
output [5:0] M_AXI_ARID; |
output [3:0] M_AXI_ARLEN; |
output [1:0] M_AXI_ARLOCK; |
output [2:0] M_AXI_ARPROT; |
output [3:0] M_AXI_ARQOS; |
input M_AXI_ARREADY; |
output [2:0] M_AXI_ARSIZE; |
output M_AXI_ARVALID; |
//read data |
input [63:0] M_AXI_RDATA; |
input [5:0] M_AXI_RID; |
input M_AXI_RLAST; |
output M_AXI_RREADY; |
input [1:0] M_AXI_RRESP; |
input M_AXI_RVALID; |
// |
// |
|
////////////////////////////////////////////////////////////////////// |
|
//master 0 |
(*mark_debug = "true"*) reg [31:0] M_AXI_ARADDR; |
reg [31:0] M_AXI_AWADDR; |
//master0 |
//waddr |
reg [5:0] M_AXI_AWID; |
reg M_AXI_AWVALID; |
wire M_AXI_AWREADY; |
wire [1:0] M_AXI_AWBURST = 2'b01; |
wire [3:0] M_AXI_AWCACHE = 4'b0; |
wire [3:0] M_AXI_AWLEN = 4'b1111; |
wire [1:0] M_AXI_AWLOCK = 2'b0; |
wire [2:0] M_AXI_AWPROT = 3'b1; |
wire [3:0] M_AXI_AWQOS = 4'b0; |
wire [2:0] M_AXI_AWSIZE = 3'b011; |
wire [7:0] M_AXI_WSTRB = 8'hff; |
//read |
(*mark_debug = "true"*) wire M_AXI_ARREADY; |
wire [1:0] M_AXI_ARBURST = 2'b01; |
wire [3:0] M_AXI_ARCACHE = 4'b0; |
wire [3:0] M_AXI_ARLEN = 4'b1111; |
wire [1:0] M_AXI_ARLOCK = 2'b0; |
wire [2:0] M_AXI_ARPROT = 3'b1; |
wire [3:0] M_AXI_ARQOS = 4'b0; |
wire [2:0] M_AXI_ARSIZE = 3'b011; |
// |
(*mark_debug = "true"*) reg M_AXI_RREADY; |
(*mark_debug = "true"*) wire [63:0] M_AXI_RDATA; |
(*mark_debug = "true"*) reg M_AXI_ARVALID; |
(*mark_debug = "true"*) wire M_AXI_RLAST; |
(*mark_debug = "true"*) wire M_AXI_RVALID; |
wire [5:0] M_AXI_RID; |
wire [1:0] M_AXI_RRESP; |
|
|
//fifo write data count |
// |
// |
reg M_AXI_BREADY; |
(*mark_debug = "true"*) wire [31:0] video_first_addr = 32'h30000000; |
// input [31:0] video_first_addr; |
// input vga_en; |
// input [23:0] Total_Burst_Per_Frame; |
wire vga_en = 1; |
wire [23:0] axi_master_read_len = 24'h2EE0; //Total_Burst_Per_Frame; |
wire read_addr_over; |
(*mark_debug = "true"*)reg [23:0] burst_r_count; |
|
wire frame_axi_addr_over = (burst_r_count == (axi_master_read_len -1)); |
reg axi_master_go_read_d; |
reg vga_en_d; |
reg vsync, hsync; |
reg vsync_syncd1, vsync_syncd2; |
|
always @(posedge S_AXI_ACLK) vsync_syncd1 <= vsync; |
always @(posedge S_AXI_ACLK) vsync_syncd2 <= vsync_syncd1; |
(* keep = "true" *)wire vsync_axi = vsync_syncd1 & vsync_syncd2; |
reg vsync_axi_d; |
always @(posedge S_AXI_ACLK) vsync_axi_d <= vsync_axi; |
(*mark_debug = "true"*)wire raddr_puls = vsync_axi & !vsync_axi_d; |
(*mark_debug = "true"*)reg axi_master_active_read; |
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) axi_master_active_read <= 0; |
else if (!vsync_axi) axi_master_active_read <= vga_en; |
end |
|
assign read_addr_over = (M_AXI_ARVALID & M_AXI_ARREADY); |
|
////////////////////////////////////////////////////////// |
|
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) M_AXI_ARADDR <= 32'h3000_0000; |
else if (!vsync_axi) M_AXI_ARADDR <= video_first_addr; |
else if (read_addr_over) M_AXI_ARADDR <= M_AXI_ARADDR + 32'h80; |
end |
////////////////////////////////////////////////////////////////////////////////////////////////// |
(*mark_debug = "true"*) reg full_0, full_1; |
|
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) burst_r_count <= 0; |
else if (!axi_master_active_read) burst_r_count <= 0; |
else if (frame_axi_addr_over & read_addr_over) burst_r_count <= 0; |
else if (read_addr_over) burst_r_count <= burst_r_count + 1; |
end |
|
reg video_read_ready; |
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) video_read_ready <= 1'b0; |
else if (frame_axi_addr_over & read_addr_over) video_read_ready <= 1'b0; |
else if (M_AXI_ARVALID) video_read_ready <= 1'b0; |
else if (raddr_puls) video_read_ready <= 1'b1; |
end |
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) M_AXI_ARVALID <= 1'b0; |
else if (!axi_master_active_read) M_AXI_ARVALID <= 1'b0; |
else if (frame_axi_addr_over & read_addr_over) M_AXI_ARVALID <= 1'b0; |
else if (video_read_ready) M_AXI_ARVALID <= 1'b1; |
end |
reg [5:0] M_AXI_ARID; |
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) M_AXI_ARID <= 6'h1; |
else if (!axi_master_active_read | raddr_puls) M_AXI_ARID <= 6'h1; |
else if (read_addr_over) M_AXI_ARID <= M_AXI_ARID + 1; |
end |
|
//read data |
|
(*mark_debug = "true"*) reg [23:0] burst_r_count_data; |
reg [8:0] r_len; |
wire rdata_vaild = (M_AXI_RREADY & M_AXI_RVALID); |
wire R_last = rdata_vaild & M_AXI_RLAST; |
(* keep = "true" *) wire burst_read_finish = (burst_r_count_data == (axi_master_read_len - 1)) & R_last ; |
//(* keep = "true" *) wire real_finish_read_finish = real_finish_data_count_over & R_last ; |
|
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) burst_r_count_data <= 0; |
else if (!axi_master_active_read) burst_r_count_data <= 0; |
else if (raddr_puls) burst_r_count_data <= 0; |
else if (burst_read_finish) burst_r_count_data <= 0; |
else if (R_last) burst_r_count_data <= burst_r_count_data + 1; |
end |
|
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) r_len <= 0; |
else if (raddr_puls) r_len <= 0; |
else if (R_last) r_len <= 0; |
else if (rdata_vaild) r_len <= r_len + 1; |
end |
|
(*mark_debug = "true"*) reg axi_rdata_act; |
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) axi_rdata_act <= 0; |
else if (!axi_master_active_read) axi_rdata_act <= 0; |
else if (burst_read_finish) axi_rdata_act <= 0; |
else if (M_AXI_ARREADY & M_AXI_ARVALID) axi_rdata_act <= 1; |
end |
|
|
wire [4:0] thrould; |
wire full_0_high = (rdata_vaild & (r_len == 4'hf) & (thrould[4:0] == 5'hf)); |
wire full_1_high = (rdata_vaild & (r_len == 4'hf) & (thrould[4:0] == 5'h1f)); |
|
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK ) begin |
if (!S_AXI_ARESETN) M_AXI_RREADY <= 1'b0; |
else if (!axi_master_active_read) M_AXI_RREADY <= 1'b0; |
else if (raddr_puls) M_AXI_RREADY <= 1'b0; |
else if (full_0 & full_1) M_AXI_RREADY <= 1'b0; |
else if (full_0 & full_1_high) M_AXI_RREADY <= 1'b0; |
else if (full_1 & full_0_high) M_AXI_RREADY <= 1'b0; |
else if (burst_read_finish) M_AXI_RREADY <= 1'b0; |
else if (axi_rdata_act) M_AXI_RREADY <= 1'b1; |
end |
|
/////////////////////////////////////////////////////////////////////////// |
// The VGA Controller |
////////////////////////////////////////////////////////////////////////// |
(*mark_debug = "true"*)reg [15:0] counX, counY; |
reg vga_en_video, vga_en_video_syncd1, vga_en_video_syncd2; |
|
always @(posedge pixel_clk) vga_en_video_syncd1 <= axi_master_active_read; |
always @(posedge pixel_clk) vga_en_video_syncd2 <= vga_en_video_syncd1; |
|
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) vga_en_video <= 1; |
else vga_en_video <= vga_en_video_syncd1 & vga_en_video_syncd2; |
end |
|
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) counX <= `Hsync_high; |
else if (!vga_en_video) counX <= `Hsync_high; |
else if (counX==`Hsync_len) counX <=0; |
else counX <= counX+1; |
end |
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) counY <= `Vsync_low; |
else if(counX==`Hsync_len) begin |
if (counY==`Vsync_len) counY <= 0; |
else counY <= counY + 1'b1; |
end |
end |
reg vsync_pre, hsync_pre; |
|
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) hsync_pre <=0; |
else hsync_pre <= (counX>=`Hsync_low) && (counX<`Hsync_high); |
end |
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) vsync_pre <=0; |
else vsync_pre <= (counY>=`Vsync_low) && (counY<`Vsync_high); |
end |
reg [9:0] gadd; |
|
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) gadd <= 0; |
else if (vsync_pre) gadd <= 0; |
else if ((counY < `Vsync_act_d) && (counX < `Hsync_act_d)) gadd <= gadd + 1; |
//counX[10:1]+{counY[10:1],8'b0}+{counY[10:1],7'b0}+{counY[10:1],4'b0}; //800/2=400=190H |
end |
// dac |
wire [31:0] vga_data; |
reg [7:0] r8, g8, b8; |
always @(negedge S_AXI_ARESETN or negedge pixel_clk) begin |
if (!S_AXI_ARESETN) r8 <= 0; |
else if ((counX>`Hsync_act) | (counY>`Vsync_act)) r8 <= 0; |
else r8 <= vga_data[23:16]; |
end |
always @(negedge S_AXI_ARESETN or negedge pixel_clk) begin |
if (!S_AXI_ARESETN) g8 <= 0; |
else if ((counX>`Hsync_act) | (counY>`Vsync_act)) g8 <= 0; |
else g8 <= vga_data[15:8]; |
end |
always @(negedge S_AXI_ARESETN or negedge pixel_clk) begin |
if (!S_AXI_ARESETN) b8 <= 0; |
else if ((counX>`Hsync_act) | (counY>`Vsync_act)) b8 <= 0; |
else b8 <= vga_data[7:0]; |
end |
|
/* |
assign r8 = (counX>`Hsync_act) ? 0 : (counY>`Vsync_act) ? 0 : |
vga_data[23:16]; |
|
assign g8 = (counX>`Hsync_act) ? 0 : (counY>`Vsync_act) ? 0 : |
vga_data[15:8]; |
|
assign b8 = (counX>`Hsync_act) ? 0 : (counY>`Vsync_act) ? 0 : |
vga_data[ 7: 0]; |
*/ |
always @(negedge S_AXI_ARESETN or negedge pixel_clk) begin |
if (!S_AXI_ARESETN) hsync <= 0; |
else hsync <= ~hsync_pre; |
end |
always @(negedge S_AXI_ARESETN or negedge pixel_clk) begin |
if (!S_AXI_ARESETN) vsync <= 0; |
else if (hsync_pre) vsync <= ~vsync_pre; |
end |
|
reg de_pre; // = !vt & (counX < `Hsync_act_d) & hz; |
always @(negedge S_AXI_ARESETN or negedge pixel_clk) begin |
if (~S_AXI_ARESETN) de_pre <=0; |
else if ((counY < `Vsync_act_d) & (counX < `Hsync_act_d)) de_pre <= 1; |
else de_pre <= 0; |
end |
reg de; |
always @(negedge pixel_clk) de <= de_pre; |
|
|
assign thrould = burst_r_count_data[4:0]; |
reg full_0_low, full_1_low; |
reg full_0_low_pre, full_1_low_pre; |
reg full_0_sync_d1, full_1_sync_d1; |
reg full_0_sync_d2, full_1_sync_d2; |
always @(posedge pixel_clk) full_0_sync_d1 <= full_0; |
always @(posedge pixel_clk) full_0_sync_d2 <= full_0_sync_d1; |
always @(posedge pixel_clk) full_1_sync_d1 <= full_1; |
always @(posedge pixel_clk) full_1_sync_d2 <= full_1_sync_d1; |
|
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) full_0_low_pre <= 0; |
else if (!(full_0_sync_d1 | full_0_sync_d2)) full_0_low_pre <= 0; |
else if (gadd[9:0] == 10'h1ff) full_0_low_pre <= 1; |
end |
always @(negedge S_AXI_ARESETN or posedge pixel_clk) begin |
if (!S_AXI_ARESETN) full_1_low_pre <= 0; |
else if (!(full_1_sync_d1 | full_1_sync_d2)) full_1_low_pre <= 0; |
else if (gadd[9:0] == 10'h3ff) full_1_low_pre <= 1; |
end |
always @(posedge S_AXI_ACLK) full_0_low <= full_0_low_pre; |
always @(posedge S_AXI_ACLK) full_1_low <= full_1_low_pre; |
|
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK) begin |
if (!S_AXI_ARESETN) full_0 <= 0; |
else if (raddr_puls) full_0 <= 0; |
else if (full_0_high) full_0 <= 1; |
else if (full_0_low) full_0 <= 0; |
end |
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK) begin |
if (!S_AXI_ARESETN) full_1 <= 0; |
else if (raddr_puls) full_1 <= 0; |
else if (full_1_high) full_1 <= 1; |
else if (full_1_low) full_1 <= 0; |
end |
|
(* keep = "true" *)wire [8:0] vga_write_count = {burst_r_count_data[4:0], r_len[3:0]}; |
reg [31:0] Rdata_tmp; |
always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK) begin |
if (!S_AXI_ARESETN) Rdata_tmp <= 0; |
else Rdata_tmp <= {M_AXI_RDATA[59:52], M_AXI_RDATA[43:36], M_AXI_RDATA[27:20], M_AXI_RDATA[11:4]}; |
end |
|
// |
//wire [63:0] Rdata = M_AXI_RDATA; |
blk_mem_gen_vga U_VGAMem( |
.clka (S_AXI_ACLK), |
.wea (rdata_vaild), |
.addra (vga_write_count), //{burst_r_count_data[4:0], r_len[3:0]}), |
.dina (M_AXI_RDATA), |
.douta (), |
.clkb (pixel_clk), |
.web (1'b0), |
.addrb (gadd[9:0]), |
.dinb (32'h0), |
.doutb (vga_data) |
); |
|
|
endmodule |