千兆以太网的双向图像传输和显示系统(1)

  1. 实现目标:上位机通过串口发送图片到FPGA中,FPGA接收图片并保存在DDR2中,保存在 DDR2中的图片分为两路,一路经过VGA时序输出到RGB触摸屏上,另一路按照以太网帧格式进 行编码, 将以太网帧发送到PC端后,可用上位机软件实时显示视频图像。
  2. 主要工作:1.FPGA串口图像接收。2.DDR2读写。3.千兆以太网发送。4.VGA视频图像显示。
  3. 使用工具:Quartus ii、Modelsim、Wireshark、小梅哥UDP摄像头、串口传图工具。
    一、串口接收模块(串口接收子模块用来接收上位机发送的图像数据)
//(串口接收子模块用来接收上位机发送的图像数据)
//波特率1562500
module uart_byte_rx(
	clk50M,
	rst_n,
	Rs232_rx,
	baud_set,

	Data_Byte,
	Rx_Done
);

	input clk50M;
	input rst_n;
	input Rs232_rx;
	input [2:0]baud_set;

	output reg [7:0]Data_Byte;
	output reg Rx_Done;
	
	reg s0_Rs232_rx, s1_Rs232_rx;    //同步寄存器
	reg tmp0_Rs232_rx, tmp1_Rs232_rx;//数据寄存器
	
	reg [15:0]bps_DR; //分频计数器计数最大值
	reg [15:0]div_cnt;//分频计数器计数
	reg bps_clk50M;      //采样的频率,所选波特率的16倍
	reg [7:0]bps_cnt; //采样次数计数器
	reg uart_state;   //串口传输状态,1为忙,0为空闲	
	
	wire ndge;
	wire error_start;  //错误开始的标志位
	
	//同步寄存器
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)begin
		s0_Rs232_rx <= 1'b0;
		s1_Rs232_rx <= 1'b0;
	end
	else begin
		s0_Rs232_rx <= Rs232_rx;
		s1_Rs232_rx <= s0_Rs232_rx;
	end
	
	//数据寄存器
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)begin
		tmp0_Rs232_rx <= 1'b0;
		tmp1_Rs232_rx <= 1'b0;
	end
	else begin
		tmp0_Rs232_rx <= s1_Rs232_rx;
		tmp1_Rs232_rx <= tmp0_Rs232_rx;
	end
	
	assign ndge = !tmp0_Rs232_rx & tmp1_Rs232_rx;
	
	//波特率查找表
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		bps_DR = 16'd324;
	else begin
		case(baud_set)
			3'd0:bps_DR = 16'd324; //波特率9600*16
			3'd1:bps_DR = 16'd162; //波特率19200*16
			3'd2:bps_DR = 16'd80;  //波特率38400*16
			3'd3:bps_DR = 16'd53;  //波特率57600*16
			3'd4:bps_DR = 16'd26;  //波特率115200*16
			3'd5:bps_DR = 16'd1;   //波特率1562500*16
			default:bps_DR = 16'd324;	
		endcase
	end
	
	//分频计数器的实现
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		div_cnt <= 16'd0;
	else if(!uart_state)
		div_cnt <= 16'd0;
	else if(div_cnt == bps_DR)
		div_cnt <= 16'd0;
	else	
		div_cnt <= div_cnt + 16'b1;		
	
	//波特率的产生
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		bps_clk50M <= 1'b0;
	else if(div_cnt == 16'b1)
		bps_clk50M <= 1'b1;
	else	
		bps_clk50M <= 1'b0;
		
	//数据传输状态的判断
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		uart_state <= 1'b0;
	else if(ndge)
		uart_state <= 1'b1;
	else if(Rx_Done || error_start)
		uart_state <= 1'b0;
	else
		uart_state <= uart_state;	
	
	//数据传输计数器bps_cnt
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		bps_cnt <= 8'b0;
	else if(bps_cnt == 8'd159 || error_start)
		bps_cnt <= 8'b0;
	else if(bps_clk50M)	
		bps_cnt <= bps_cnt + 8'b1;
	else
		bps_cnt <= bps_cnt;
		
	//一次数据传送完成输出位Rx_Done
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		Rx_Done <= 1'b0;
	else if(bps_cnt == 8'd159)
		Rx_Done <= 1'b1;
	else 
		Rx_Done <= 1'b0;	
		
	reg [2:0]r_Data_Byte[7:0];
	reg [7:0]tmp_Data_Byte;
	reg [2:0]START_BIT;
	reg [2:0]STOP_BIT;
	
	//数据采样, 每个波特率中采集16次,但只记录中间的6次,并将6次记录的数据累加
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)begin
		START_BIT <= 3'd0;
		r_Data_Byte[0] <= 3'd0;
		r_Data_Byte[1] <= 3'd0;
		r_Data_Byte[2] <= 3'd0;
		r_Data_Byte[3] <= 3'd0;
		r_Data_Byte[4] <= 3'd0;
		r_Data_Byte[5] <= 3'd0;
		r_Data_Byte[6] <= 3'd0;
		r_Data_Byte[7] <= 3'd0;	
		STOP_BIT <= 3'd0;
	end
	else if(bps_clk50M)begin
		case(bps_cnt)
		0:begin
			START_BIT <= 3'd0;
			r_Data_Byte[0] <= 3'd0;
			r_Data_Byte[1] <= 3'd0;
			r_Data_Byte[2] <= 3'd0;
			r_Data_Byte[3] <= 3'd0;
			r_Data_Byte[4] <= 3'd0;
			r_Data_Byte[5] <= 3'd0;
			r_Data_Byte[6] <= 3'd0;
			r_Data_Byte[7] <= 3'd0;
			STOP_BIT <= 3'd0;
		end
		5,  6,  7,  8,  9,  10: START_BIT <= START_BIT + s1_Rs232_rx;
		21, 22, 23, 24, 25, 26: r_Data_Byte[0] <= r_Data_Byte[0] + s1_Rs232_rx;
		37, 38, 39, 40, 41, 42: r_Data_Byte[1] <= r_Data_Byte[1] + s1_Rs232_rx;
		53, 54, 55, 56, 57, 58: r_Data_Byte[2] <= r_Data_Byte[2] + s1_Rs232_rx;
		69, 70, 71, 72, 73, 74: r_Data_Byte[3] <= r_Data_Byte[3] + s1_Rs232_rx;
		85, 86, 87, 88, 89, 90: r_Data_Byte[4] <= r_Data_Byte[4] + s1_Rs232_rx;
		101,102,103,104,105,106:r_Data_Byte[5] <= r_Data_Byte[5] + s1_Rs232_rx;
		117,118,119,120,121,122:r_Data_Byte[6] <= r_Data_Byte[6] + s1_Rs232_rx;
		133,134,135,136,137,138:r_Data_Byte[7] <= r_Data_Byte[7] + s1_Rs232_rx;
		149,150,151,152,153,154:STOP_BIT <= STOP_BIT + s1_Rs232_rx;
		default:begin
			START_BIT <= START_BIT;
			r_Data_Byte[0] <= r_Data_Byte[0];
			r_Data_Byte[1] <= r_Data_Byte[1];
			r_Data_Byte[2] <= r_Data_Byte[2];
			r_Data_Byte[3] <= r_Data_Byte[3];
			r_Data_Byte[4] <= r_Data_Byte[4];
			r_Data_Byte[5] <= r_Data_Byte[5];
			r_Data_Byte[6] <= r_Data_Byte[6];
			r_Data_Byte[7] <= r_Data_Byte[7];
			STOP_BIT <= STOP_BIT;
		end
		endcase
	end
	
	//当检测的开始信号不是低电平时,错误开始标志置1
	assign error_start = ((bps_cnt == 8'd12) && (START_BIT > 2))?1'b1:1'b0;	
	
	//判断所传输的数据,通过比较采样的高低电平的概率来判断
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		tmp_Data_Byte <= 8'b0000_0000;
	else if(bps_cnt == 8'd159)begin
		tmp_Data_Byte[0] <= (r_Data_Byte[0]>3);
		tmp_Data_Byte[1] <= (r_Data_Byte[1]>3);
		tmp_Data_Byte[2] <= (r_Data_Byte[2]>3);
		tmp_Data_Byte[3] <= (r_Data_Byte[3]>3);
		tmp_Data_Byte[4] <= (r_Data_Byte[4]>3);
		tmp_Data_Byte[5] <= (r_Data_Byte[5]>3);
		tmp_Data_Byte[6] <= (r_Data_Byte[6]>3);
		tmp_Data_Byte[7] <= (r_Data_Byte[7]>3);	
	end
	
	//数据传输完成将数据输出
	always@(posedge clk50M or negedge rst_n)
	if(!rst_n)
		Data_Byte <= 8'd0;
	else if(Rx_Done)
		Data_Byte <= tmp_Data_Byte;
	else
		Data_Byte <= Data_Byte;
		
endmodule ```
参考资料:【学习教材】FPGA系统设计与验证实战指南_V3.0(小梅哥)
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值