`timescale 1ns / 1ps
module vga_controller(
input clk,
input rst,
input [3:0]num,
output hs,
output vs,
output reg R,
output reg G,
output reg B
);
parameter HS_CNT=96;
parameter H_FP_CNT=16;
parameter H_BP_CNT=48;
parameter HDISP_CNT=640;
parameter VS_CNT=2;
parameter V_FP_CNT=10;
parameter V_BP_CNT=29;
parameter VDISP_CNT=480;
reg [11:0]h_cnt;
reg [11:0]v_cnt;
reg disp,disp_ff1,disp_ff2,disp_ff3;
reg hsync,hsync_ff1,hsync_ff2,hsync_ff3,hsync_ff4;
reg vsync,vsync_ff1,vsync_ff2,vsync_ff3,vsync_ff4;
reg [13:0]addr;
wire [2:0]dout;
wire [9:0]pix_row;
wire [9:0]pix_col;
reg [9:0]pix_row_ff1;
reg [9:0]pix_row_ff2;
reg [9:0]pix_row_ff3;
reg [9:0]pix_row_ff4;
reg [9:0]pix_col_ff1;
reg [9:0]pix_col_ff2;
reg [9:0]pix_col_ff3;
reg [9:0]pix_col_ff4;
always@(posedge clk,posedge rst)
if(rst)
begin
{pix_row_ff1,pix_row_ff2,pix_row_ff3,pix_row_ff4}<=40'd0;
{pix_col_ff1,pix_col_ff2,pix_col_ff3,pix_col_ff4}<=40'd0;
end
else
begin
{pix_row_ff1,pix_row_ff2,pix_row_ff3,pix_row_ff4}<={pix_row,pix_row_ff1,pix_row_ff2,pix_row_ff3};
{pix_col_ff1,pix_col_ff2,pix_col_ff3,pix_col_ff4}<={pix_col,pix_col_ff1,pix_col_ff2,pix_col_ff3};
end
assign hs=hsync_ff4;
assign vs=vsync_ff4;
always@(posedge clk,posedge rst)
if(rst)
h_cnt<=12'd0;
else if(h_cnt==HS_CNT+H_BP_CNT+H_FP_CNT+HDISP_CNT-1)
h_cnt<=12'd0;
else
h_cnt<=h_cnt+12'd1;
always@(posedge clk,posedge rst)
if(rst)
v_cnt<=12'd0;
else if(h_cnt==HS_CNT+H_BP_CNT+H_FP_CNT+HDISP_CNT-1)
if(v_cnt==VS_CNT+V_BP_CNT+V_FP_CNT+VDISP_CNT-1)
v_cnt<=12'd0;
else
v_cnt<=v_cnt+12'd1;
always@(posedge clk,posedge rst)
if(rst)
hsync<=1'b1;
else if(h_cnt>=0&&h_cnt<HS_CNT)
hsync<=1'b0;
else
hsync<=1'b1;
always@(posedge clk,posedge rst)
if(rst)
vsync<=1'b1;
else if(v_cnt>=0&&v_cnt<VS_CNT)
vsync<=1'b0;
else
vsync<=1'b1;
always@(posedge clk,posedge rst)
if(rst)
disp<=1'b0;
else if(h_cnt>=HS_CNT+H_BP_CNT&&h_cnt<HS_CNT+H_BP_CNT+HDISP_CNT
&&v_cnt>=VS_CNT+V_BP_CNT&&v_cnt<VS_CNT+V_BP_CNT+VDISP_CNT)
disp<=1'b1;
else
disp<=1'b0;
assign pix_col=h_cnt-HS_CNT-H_BP_CNT;
assign pix_row=v_cnt-VS_CNT-V_BP_CNT;
always@(posedge clk,posedge rst)
if(rst)
begin
addr<=14'd0;
end
else if(disp)
begin
if(pix_row_ff1<32&&pix_col_ff1<32)
addr<={num,10'b0}+{pix_row_ff1,5'b0}+pix_col_ff1;
else
addr<=14'd0;
end
always@(posedge clk,posedge rst)
if(rst)
{R,G,B}<=3'b000;
else if(disp_ff3)
if(pix_row_ff4<32&&pix_col_ff4<32)
{R,G,B}<=dout;
else
{R,G,B}<=3'b000;
else
{R,G,B}<=3'b000;
BRAM number (
.clka(clk),
.ena(1'b1),
.wea(1'b0),
.addra(addr),
.dina(),
.douta(dout)
);
always@(posedge clk,posedge rst)
if(rst)
begin
disp_ff1<=1'b0;
disp_ff2<=1'b0;
disp_ff3<=1'b0;
end
else
begin
disp_ff1<=disp;
disp_ff2<=disp_ff1;
disp_ff3<=disp_ff2;
end
always@(posedge clk,posedge rst)
if(rst)
begin
{hsync_ff1,hsync_ff2,hsync_ff3,hsync_ff4}<=4'b0000;
{vsync_ff1,vsync_ff2,vsync_ff3,vsync_ff4}<=4'b0000;
end
else
begin
{hsync_ff1,hsync_ff2,hsync_ff3,hsync_ff4}<={hsync,hsync_ff1,hsync_ff2,hsync_ff3};
{vsync_ff1,vsync_ff2,vsync_ff3,vsync_ff4}<={vsync,vsync_ff1,vsync_ff2,vsync_ff3};
end
endmodule