以太网传输图片实验

(以下内容是在学习完正点原子视频后的总结,代码均是来自正点原子)
1.实验内容
本节的实验任务是网口接收上位机传输的图片(分辨率为640*480),然后将图片存储在SDRAM中并通过VGA接口在显示器屏幕上显示。
2.实验系统框图
在这里插入图片描述
3.代码部分
顶层模块;
module eth_sdram_vga(
input clk, //FPGA外部时钟,50MHz
input rst_n, //按键复位,低电平有效
//以太网接口
input eth_rx_clk, //MII接收数据时钟
input eth_rxdv, //MII输入数据有效信号
input [ 3:0] eth_rx_data, //MII输入数据
output eth_tx_en, //MII输出数据有效信号
output eth_rst_n, //以太网芯片复位信号,低电平有效
//SDRAM接口
output sdram_clk, //SDRAM 芯片时钟
output sdram_cke, //SDRAM 时钟有效
output sdram_cs_n, //SDRAM 片选
output sdram_ras_n, //SDRAM 行有效
output sdram_cas_n, //SDRAM 列有效
output sdram_we_n, //SDRAM 写有效
output [ 1:0] sdram_ba, //SDRAM Bank地址
output [12:0] sdram_addr, //SDRAM 行/列地址
inout [15:0] sdram_data, //SDRAM 数据
output [ 1:0] sdram_dqm, //SDRAM 数据掩码
//VGA接口
output vga_hs, //行同步信号
output vga_vs, //场同步信号
output [15:0] vga_rgb //红绿蓝三原色输出
);

//parameter define
//开发板MAC地址 00-11-22-33-44-55
parameter BOARD_MAC = 48’h00_11_22_33_44_55;
//开发板IP地址 192.168.1.123
parameter BOARD_IP = {8’d192,8’d168,8’d1,8’d123};
//目的MAC地址 ff_ff_ff_ff_ff_ff
parameter DES_MAC = 48’hff_ff_ff_ff_ff_ff;
//目的IP地址 192.168.1.102
parameter DES_IP = {8’d192,8’d168,8’d1,8’d102};

//wire define
wire vga_clk; //VGA驱动时钟,25MHz
wire clk_100m; //SDRAM 控制器时钟
wire clk_100m_shift; //相位偏移时钟

wire locked; //PLL输出有效标志
wire sys_rst_n; //系统复位信号
wire sdram_init_done; //SDRAM 初始化完成标志

wire udp_rec_en; //以太网接收的数据有效信号
wire [31:0] udp_rec_data; //以太网接收的数据

wire wr_en; //SDRAM 写端口:写使能
wire [15:0] wr_data; //SDRAM 写端口:写入的数据
wire rd_en; //SDRAM 读端口:读使能
wire [15:0] rd_data; //SDRAM 读端口:读出的数据

//*****************************************************
//** main code
//*****************************************************

//待PLL输出稳定之后,停止系统复位
assign sys_rst_n = rst_n & locked;

//例化PLL, 产生各模块所需要的时钟
pll_clk u_pll_clk(
.inclk0 (clk),
.areset (~rst_n),

.c0                 (vga_clk),
.c1                 (clk_100m),
.c2                 (clk_100m_shift),
.locked             (locked)
);

//UDP模块接收网口数据
udp #(
.BOARD_MAC (BOARD_MAC), //开发板MAC地址
.BOARD_IP (BOARD_IP), //开发板IP地址
.DES_MAC (DES_MAC), //目的MAC地址
.DES_IP (DES_IP) //目的IP地址
)
u_udp(
.rst_n (sys_rst_n),

.eth_rx_clk         (eth_rx_clk),       //MII接收数据时钟
.eth_rxdv           (eth_rxdv),         //MII输入数据有效信号
.eth_rx_data        (eth_rx_data),      //MII输入数据
.eth_rst_n          (eth_rst_n),        //以太网芯片复位信号,低电平有效 
.rec_en             (udp_rec_en),       //以太网接收的数据有效信号
.rec_data           (udp_rec_data),     //以太网接收的数据
.rec_pkt_done       (),                 //以太网单包数据接收完成信号
.rec_byte_num       (),                 //以太网接收的有效字节数 单位:byte

.eth_tx_clk         (),           
.eth_tx_en          (eth_tx_en),        //MII输出数据有效信号
.tx_start_en        (),        
.tx_data            (),         
.tx_byte_num        (),    
.tx_done            (),        
.tx_req             (),                           
.eth_tx_data        ()
); 

//将UDP模块接收到的32bit数据转换成16bit数据
udp_32_to_16bit(
.eth_rx_clk (eth_rx_clk),
.rst_n (sys_rst_n),

.udp_rec_en         (udp_rec_en),
.udp_rec_data       (udp_rec_data),    
.udp_rec_en_16      (wr_en),
.udp_rec_data_16    (wr_data)
);

//SDRAM 控制器顶层模块,封装成FIFO接口
//SDRAM 控制器地址组成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]}
sdram_top u_sdram_top(
.ref_clk (clk_100m), //sdram 控制器参考时钟
.out_clk (clk_100m_shift), //用于输出的相位偏移时钟
.rst_n (sys_rst_n), //系统复位

//用户写端口
.wr_clk 			(eth_rx_clk),	    //写端口FIFO: 写时钟
.wr_en				(wr_en),			//写端口FIFO: 写使能
.wr_data		    (wr_data),		    //写端口FIFO: 写数据
.wr_min_addr		(24'd0),			//写SDRAM的起始地址
.wr_max_addr		(24'd640*24'd480),	//写SDRAM的结束地址
.wr_len			    (10'd512),			//写SDRAM时的数据突发长度
.wr_load			(~sys_rst_n),		//写端口复位: 复位写地址,清空写FIFO

//用户读端口
.rd_clk 			(vga_clk),			//读端口FIFO: 读时钟
.rd_en				(rd_en),			//读端口FIFO: 读使能
.rd_data	    	(rd_data),		    //读端口FIFO: 读数据
.rd_min_addr		(24'd0),			//读SDRAM的起始地址
.rd_max_addr		(24'd640*24'd480),	//读SDRAM的结束地址
.rd_len 			(10'd512),			//从SDRAM中读数据时的突发长度
.rd_load			(~sys_rst_n),		//读端口复位: 复位读地址,清空读FIFO
   
 //用户控制端口  
.sdram_read_valid	(1'b1),             //SDRAM 读使能
.sdram_init_done	(sdram_init_done),	//SDRAM 初始化完成标志

//SDRAM 芯片接口
.sdram_clk			(sdram_clk),        //SDRAM 芯片时钟
.sdram_cke			(sdram_cke),        //SDRAM 时钟有效
.sdram_cs_n			(sdram_cs_n),       //SDRAM 片选
.sdram_ras_n		(sdram_ras_n),      //SDRAM 行有效
.sdram_cas_n		(sdram_cas_n),      //SDRAM 列有效
.sdram_we_n			(sdram_we_n),       //SDRAM 写有效
.sdram_ba			(sdram_ba),         //SDRAM Bank地址
.sdram_addr			(sdram_addr),       //SDRAM 行/列地址
.sdram_data			(sdram_data),       //SDRAM 数据
.sdram_dqm			(sdram_dqm)         //SDRAM 数据掩码
);

//VGA驱动模块
vga_driver u_vga_driver(
.vga_clk (vga_clk),
.sys_rst_n (sdram_init_done),

.vga_hs             (vga_hs),       
.vga_vs             (vga_vs),       
.vga_rgb            (vga_rgb),      

.data_req           (rd_en),
.pixel_data         (rd_data),
.pixel_xpos         (), 
.pixel_ypos         ()
); 

endmodule
UDP模块
module udp
#(
//开发板MAC地址 00-11-22-33-44-55
parameter BOARD_MAC = 48’h00_11_22_33_44_55,
//开发板IP地址 192.168.1.123
parameter BOARD_IP = {8’d192,8’d168,8’d1,8’d123},
//目的MAC地址 ff_ff_ff_ff_ff_ff
parameter DES_MAC = 48’hff_ff_ff_ff_ff_ff,
//目的IP地址 192.168.1.102
parameter DES_IP = {8’d192,8’d168,8’d1,8’d102}
)
(
input eth_rx_clk , //MII接收数据时钟
input rst_n , //复位信号,低电平有效
input eth_rxdv , //MII输入数据有效信号
input [3:0] eth_rx_data , //MII输入数据
input eth_tx_clk , //MII发送数据时钟

input                  tx_start_en ,  //以太网开始发送信号
input        [31:0]    tx_data     ,  //以太网待发送数据  
input        [15:0]    tx_byte_num ,  //以太网发送的有效字节数 单位:byte                  
output                 tx_done     ,  //以太网发送完成信号
output                 tx_req      ,  //读数据请求信号   
output                 rec_pkt_done,  //以太网单包数据接收完成信号
output                 rec_en      ,  //以太网接收的数据使能信号
output       [31:0]    rec_data    ,  //以太网接收的数据
output       [15:0]    rec_byte_num,  //以太网接收的有效字节数 单位:byte  

output                 eth_tx_en   ,  //MII输出数据有效信号
output       [3:0]     eth_tx_data ,  //MII输出数据
output                 eth_rst_n      //以太网芯片复位信号,低电平有效       
);

32bit转换为16bit模块
module udp_32_to_16bit(
input eth_rx_clk,
input rst_n,

input             udp_rec_en,
input      [31:0] udp_rec_data,

output reg        udp_rec_en_16,
output reg [15:0] udp_rec_data_16
);

//reg define
reg rec_en_flag;

//*****************************************************
//** main code
//*****************************************************

//将UDP模块的接收数据有效信号延时一个时钟周期
always @(posedge eth_rx_clk or negedge rst_n)begin
if(!rst_n)
rec_en_flag <=0;
else
rec_en_flag <= udp_rec_en;
end

//分两个时钟周期输出UPP模块接收数据的高十六位和低十六位
always @(posedge eth_rx_clk or negedge rst_n)begin
if(!rst_n) begin
udp_rec_en_16 <= 1’b0;
udp_rec_data_16 <= 1’b0;
end
else if(udp_rec_en)begin
udp_rec_en_16 <= 1’b1;
udp_rec_data_16 <= udp_rec_data[31:16];
end
else if(rec_en_flag)begin
udp_rec_en_16 <= 1’b1;
udp_rec_data_16 <= udp_rec_data[15:0];
end
else begin
udp_rec_en_16 <= 0;
udp_rec_data_16 <= udp_rec_data_16;
end
end
endmodule

SDRAM模块:
module sdram_top(
input ref_clk, //sdram 控制器参考时钟
input out_clk, //用于输出的相位偏移时钟
input rst_n, //系统复位

//用户写端口			
input         wr_clk,                   //写端口FIFO: 写时钟
input         wr_en,                    //写端口FIFO: 写使能
input  [15:0] wr_data,                  //写端口FIFO: 写数据
input  [23:0] wr_min_addr,              //写SDRAM的起始地址
input  [23:0] wr_max_addr,              //写SDRAM的结束地址
input  [ 9:0] wr_len,                   //写SDRAM时的数据突发长度
input         wr_load,                  //写端口复位: 复位写地址,清空写FIFO

//用户读端口
input         rd_clk,                   //读端口FIFO: 读时钟
input         rd_en,                    //读端口FIFO: 读使能
output [15:0] rd_data,                  //读端口FIFO: 读数据
input  [23:0] rd_min_addr,              //读SDRAM的起始地址
input  [23:0] rd_max_addr,              //读SDRAM的结束地址
input  [ 9:0] rd_len,                   //从SDRAM中读数据时的突发长度
input         rd_load,                  //读端口复位: 复位读地址,清空读FIFO

//用户控制端口  
input         sdram_read_valid,         //SDRAM 读使能
output        sdram_init_done,          //SDRAM 初始化完成标志

//SDRAM 芯片接口
output        sdram_clk,                //SDRAM 芯片时钟
output        sdram_cke,                //SDRAM 时钟有效
output        sdram_cs_n,               //SDRAM 片选
output        sdram_ras_n,              //SDRAM 行有效
output        sdram_cas_n,              //SDRAM 列有效
output        sdram_we_n,               //SDRAM 写有效
output [ 1:0] sdram_ba,                 //SDRAM Bank地址
output [12:0] sdram_addr,               //SDRAM 行/列地址
inout  [15:0] sdram_data,               //SDRAM 数据
output [ 1:0] sdram_dqm                 //SDRAM 数据掩码
);

VGA模块:
module vga_driver(
input           vga_clk,      //VGA驱动时钟
input           sys_rst_n,    //复位信号
//VGA接口                          
output          vga_hs,       //行同步信号
output          vga_vs,       //场同步信号
output  [15:0]  vga_rgb,      //红绿蓝三原色输出

output          data_req,     //像素点数据请求
input   [15:0]  pixel_data,   //像素点数据
output  [ 9:0]  pixel_xpos,   //像素点横坐标
output  [ 9:0]  pixel_ypos    //像素点纵坐标    
);  
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值