其他分享
首页 > 其他分享> > FPGA实现720P图像的左右翻转

FPGA实现720P图像的左右翻转

作者:互联网

使用两片BRAM,进行缓存,一片写入,一片读取,交替进行,通过地址的加减实现左右翻转。
所以图像会有一行的延时,通过自己生成时钟来解决,但是发现在列还有5个像素的延时,所以在生成H信号的时候延时了5个时钟周期。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    20:22:03 11/11/2021 
// Design Name: 
// Module Name:    top 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module top(
	input CLK50M,
	input CLK27M,
	
	input[19:0] GS2971_DI,
	input[2:0] GS2971_STAT, // H V DE
	input GS2971_CLKI,
	output GS2971_RESET,
	output GS2971_XTALL1,
	
	output[19:0] GS2972_DO,
	output GS2972_PCLK,
	output GS2972_FDE,
	output GS2972_HSVNC,
	output GS2972_VSYNC,
	output GS2972_RESET,
	output GS2972_RATESEL0,
	output GS2972_RATESEL1,
	output GS2972_SDOEN
    );
	
	/***1280x720***/
	parameter LinePeriod = 1650;//总的周期
	parameter H_SyncPluse = 40;//HSYNC的时钟数
	parameter H_BackPorch = 220;//前消隐
	parameter H_ActivePix = 1280;//有效像素值
	parameter H_FrontPorch = 110;//后消隐
	parameter Hde_start = 260;//开始的时钟
	parameter Hde_end = 1540;//结束的时钟

	parameter FramePeriod = 750;//总的周期
	parameter V_SyncPluse = 5;//VSYNC的时钟数
	parameter V_BackPorch = 20;//
	parameter V_ActivePix = 720;
	parameter V_FrontPorch = 5;
	parameter Vde_start = 25;
	parameter Vde_end = 745;
	
	reg GS2972_VSYNC_creat;
	reg GS2972_HSVNC_creat;
	reg GS2972_FDE_creat;
	
	reg vsync_de;
	reg hsync_de;
	
	reg GS2971_H = 0;
	reg GS2971_V = 0;
	reg GS2971_DE = 0;
	
	reg GS2971_H_delay = 0;
	reg GS2971_V_delay = 0;
	reg BRAM_EN_delay = 0;
	
	reg[10:0] x_cnt = 0;
	reg[10:0] y_cnt = 0;
	reg BRAM_EN = 0;
//	reg BRAM_START = 0;
	
	reg[19:0] GS2972_DO_reg = 0;
	
//	reg[10:0] ADDR_WR1, ADDR_WR2;
	reg[10:0] ADDR_RE1 = 1280;
	reg[10:0] ADDR_RE2 = 0;
	
	reg[15:0] DATA_WR1, DATA_WR2;
	wire[15:0] DATA_RE1, DATA_RE2;
	
	reg BRAM1_READ = 0;
	reg BRAM2_READ = 1;
	
//	reg BRAM1_READ_past = 1;
//	reg BRAM2_READ_past = 0;
	
	reg BRAM1_WR = 1;
	reg BRAM2_WR = 0;

	wire fPowerUp_Rst; // 得到复位波形 刚开始低,后面高
	sSystemReset # (.MAX_COUNT(500000))
	SystemReset
	(
	.iClk(CLK50M),
	.iRst(1'b1),
	.oRst(fPowerUp_Rst)
	);
	
	BRAM sBRAM1(
	  .clka(GS2971_CLKI), // input clka
	  .wea((~BRAM1_READ) & BRAM_EN), // input [0 : 0] wea
	  .addra(ADDR_RE1), // input [10 : 0] addra
	  .dina(DATA_WR1), // input [15 : 0] dina
	  .clkb(GS2971_CLKI), // input clkb
	  .addrb(ADDR_RE1), // input [10 : 0] addrb
	  .doutb(DATA_RE1) // output [15 : 0] doutb
	);
	
	BRAM sBRAM2(
	  .clka(GS2971_CLKI), // input clka
	  .wea((~BRAM2_READ) & BRAM_EN), // input [0 : 0] wea
	  .addra(ADDR_RE2), // input [10 : 0] addra
	  .dina(DATA_WR2), // input [15 : 0] dina
	  .clkb(GS2971_CLKI), // input clkb
	  .addrb(ADDR_RE2), // input [10 : 0] addrb
	  .doutb(DATA_RE2) // output [15 : 0] doutb
	);


	always @(posedge GS2971_CLKI)
	 begin
		GS2971_H_delay <= GS2971_H;
	 end
	 
	 always @(posedge GS2971_CLKI)
	 begin
		GS2971_V_delay <= GS2971_V;
	 end
	 
	 always @(posedge GS2971_CLKI)
	 begin
		BRAM_EN_delay <= BRAM_EN;
	 end

	//水平扫描计数
	always @(posedge GS2971_CLKI)
		if(!fPowerUp_Rst) x_cnt <= 1; // 0还是 1
		else if((~GS2971_H_delay) & (GS2971_H)) x_cnt <= 1;
//		else if(x_cnt == LinePeriod) x_cnt <= 1;
		else x_cnt <= x_cnt + 1;
	
	//垂直扫描计数
	always @(posedge GS2971_CLKI)
		if(!fPowerUp_Rst) y_cnt <= 1;
		else if((~GS2971_V_delay) & (GS2971_V)) y_cnt <= 1;
//		else if(y_cnt == FramePeriod) y_cnt <= 1;
		else if(x_cnt == LinePeriod) y_cnt <= y_cnt + 1;
	
	//垂直扫描信号产生
	always @(posedge GS2971_CLKI)
		begin
			if(x_cnt == 6) GS2972_HSVNC_creat <= 1'b1; //延时1650个时钟周期
			else if(x_cnt == (H_SyncPluse + 5)) GS2972_HSVNC_creat <=1'b0;
		
			if(y_cnt == 2) GS2972_VSYNC_creat <= 1'b1;
			else if(y_cnt == (V_SyncPluse + 1)) GS2972_VSYNC_creat <= 1'b0;
			
			if(y_cnt == (Vde_start + 1)) vsync_de <= 1'b1;
			else if(y_cnt == (Vde_end + 1)) vsync_de <= 1'b0;
			
			if(x_cnt == (Hde_start + 5)) hsync_de <= 1'b1;//延时5个时钟周期
			else if(x_cnt == (Hde_end + 5)) hsync_de <= 1'b0;
		end
	
	
	//存储使能
	always @(posedge GS2971_CLKI)
		begin
		GS2971_H <= GS2971_STAT[0];
		GS2971_V <= GS2971_STAT[1];
		GS2971_DE <= GS2971_STAT[2];
		if((x_cnt >= Hde_start) & (x_cnt <= Hde_end))
			begin
			if((y_cnt >= Vde_start) & (y_cnt <= Vde_end))
				begin
					BRAM_EN <= 1;
					DATA_WR1[15:8] <= GS2971_DI[19:12];
					DATA_WR1[7:0]  <= GS2971_DI[9:2];
					
					DATA_WR2[15:8] <= GS2971_DI[19:12];
					DATA_WR2[7:0]  <= GS2971_DI[9:2];
				end
			else
				BRAM_EN <= 0;
			end
		else
			BRAM_EN <= 0;
		end


	always @(posedge BRAM_EN)
		begin
			BRAM1_READ <= 1 - BRAM1_READ;
			BRAM2_READ <= 1 - BRAM2_READ;
		end
	// 写入
	always @(posedge GS2971_CLKI)
		begin
		if(BRAM_EN)
		begin
			if(BRAM1_READ)
				ADDR_RE1 <= ADDR_RE1 - 1;
			else
				ADDR_RE1 <= ADDR_RE1 + 1;
				
			if(BRAM2_READ)
				ADDR_RE2 <= ADDR_RE2 - 1;
			else
				ADDR_RE2 <= ADDR_RE2 + 1;
		end
		
		if(BRAM_EN)
		begin
			if(BRAM1_READ)
			begin
				GS2972_DO_reg[19:12] <= DATA_RE1[15:8];
				GS2972_DO_reg[9:2]   <= DATA_RE1[7:0];
			end
			if(BRAM2_READ)
			begin
				GS2972_DO_reg[19:12] <= DATA_RE2[15:8];
				GS2972_DO_reg[9:2]   <= DATA_RE2[7:0];
			end
		end
		
		end

	assign GS2971_RESET 	= fPowerUp_Rst;
	assign GS2971_XTALL1    = CLK27M;
	assign GS2972_RESET 	= fPowerUp_Rst;
	assign GS2972_RATESEL0 	= 0;
	assign GS2972_RATESEL1 	= 0;
	assign GS2972_SDOEN 	= 1;
	assign GS2972_PCLK 		= GS2971_CLKI;
	assign GS2972_HSVNC 	= GS2972_HSVNC_creat;
	assign GS2972_VSYNC 	= GS2972_VSYNC_creat;
//	assign GS2972_FDE 		= GS2971_DE;
	assign GS2972_FDE 		= (hsync_de & vsync_de)? 1 : 0;
	assign GS2972_DO 		= GS2972_DO_reg;
	
endmodule

最终效果:
在这里插入图片描述

标签:GS2972,GS2971,FPGA,720P,output,input,parameter,reg,翻转
来源: https://blog.csdn.net/qq_40608730/article/details/121309902