基于FPGA的千兆以太网的实现(1)
基于FPGA的以太网图片接收
- 项目简述
- UDP协议讲解
- V3学院的上位机传送图像数据的数据流
- 项目的实验框图
- 跨时钟域处理时序图
- Image_ctrl时序图
- 工程代码
- 测试模块的代码
- 测试结果
- 总结
项目简述
本次实验我们将完成千兆以太网接收模块的设计。上位机利用千兆以太网发送图片到FPGA开发板,并且经过DDR3缓存,最后经由USB3.0接口传输到上位机。本次实验是基于我们前面DDR3模块的基础上做的,只需要把相应的数据产生模块换成以太网接收模块即可。本次实验用到的软硬件工具如下:
1、VIVADO2019.1开发软件
2、米联客MA7035(100T)开发板
3、V3学院上位机发送软件
4、米联客上位机接收软件
上面两个上位机软件稍微有点不兼容,所以最终的实验效果有点小瑕疵,但是经过ila的抓包可以判断FPGA程序没有问题。毕竟现在在家硬件不充足,只能这样做,大家相互理解。但是经过这篇文章,大家确确实实可以学会千兆网接收的时序设计。
UDP协议讲解
因为米联客开发板上面的千兆网是RGMII接口,所以我们得使用前篇文章中设计的iddr来进行数据从双沿到单沿的转变。
常见UDP协议的数据流每一位所占据的意义如下:
从上面我们可以学习到UDP协议的数据流含义。而且,我们可以看出以太网传输主要分为三层,即MAC层、IP层、UDP层,如下图:
IP头部checksum 算法1
把IP头部20byte 按2byte 即16bit 分开分别相加后,如果大于FFFF那么把高位与低16位相加,直到最终结果为16bit数。最后把结果取反作为ip_checksum。
例如,抓个IP数据包,取IP数据报报头部分(20B),数据如下:
45 00 00 30 80 4c 40 00 80 06 b5 2e d3 43 11 7b cb 51 15 3d
下面我来计算一下校验和:
(1)将校验和字段置为0:
将b5 2e置为00 00,即变成:
45 00 00 30 80 4c 40 00 80 06 00 00 d3 43 11 7b cb 51 15 3d
(2)反码求和
4500+0030+804c+4000+8006+0000+d343+117b+cb51+153d=34ace
将将进位(3)加到低16位(4ace)上:0003+4ace=4ad1
(3)取反码
将4ad1取反得ip_checksum=b52e
2.接收IP数据报检验IP校验和
(1)对首部中每个16 bit进行二进制反码求和;
(2)将(1)中得到的和再取反码 ,看是否为0.
接收到的IP数据报首部:
45 00 00 30 80 4c 40 00 80 06 b5 2e d3 43 11 7b cb 51 15 3d
下面来验证下:
(1)反码求和
4500+0030+804c+4000+8006+b52e+d343+117b+cb51+153d=3fffc
0003+fffc=ffff
(2)取反码:~ffff=0 正确
UDP checksum 计算方法
UDP _sum=(Ip伪头部+(UDP首部+数据 每两个字节拼接分别相加的和))
头包:ip伪头部=c0a8+0001+ffff+ffff+0011+0108
数据包1:ip伪头部=c0a8+0001+ffff+ffff+0011+04c2
数据包2:ip伪头部=c0a8+0001+ffff+ffff+0011+04c2
数据包3:ip伪头部=c0a8+0001+ffff+ffff+0011+02b2
以太网(IEEE 802.3)帧格式:
1、前导码:7字节0x55,一串1、0间隔,用于信号同步 有的说是AA
2、帧起始定界符:1字节0xD5(10101011),表示一帧开始 有的说是AB
3、DA(目的MAC):6字节 如果设置为全1 为广播包
4、SA(源MAC):6字节
5、类型/长度:2字节,0~1500保留为长度域值,1536~65535保留为类型域值(0x0600~0xFFFF)
6、数据:46~1500字节
7、帧校验序列(FCS):4字节,使用CRC计算从目的MAC到数据域这部分内容而得到的校验和。
以CSMA/CD作为MAC算法的一类LAN称为以太网。CSMA/CD冲突避免的方法:先听后发、边听边发、随机延迟后重发。一旦发生冲突,必须让每台主机都能检测到。关于最小发送间隙和最小帧长的规定也是为了避免冲突。
考虑如下极限的情况,主机发送的帧很小,而两台冲突主机相距很远。 在主机A发送的帧传输到B的前一刻,B开始发送帧。这样,当A的帧到达B时,B检测到冲突,于是发送冲突信号。假如在B的冲突信号传输到A之前,A的帧已 经发送完毕,那么A将检测不到冲突而误认为已发送成功。由于信号传播是有时延的,因此检测冲突也需要一定的时间。这也是为什么必须有个最小帧长的限制。
按照标准,10Mbps以太网采用中继器时,连接的最大长度是 2500米,最多经过4个中继器,因此规定对10Mbps以太网一帧的最小发送时间为51.2微秒。这段时间所能传输的数据为512位,因此也称该时间为 512位时。这个时间定义为以太网时隙,或冲突时槽。512位=64字节,这就是以太网帧最小64字节的原因。
512位时是主机捕获信道的时间。如果某主机发送一个帧的64字节仍无冲突,以后也就不会再发生冲突了,称此主机捕获了信道。由于信道是所有主机共享的,为避免单一主机占用信道时间过长,规定了以太网帧的最大帧长为1500。
100Mbps以太网的时隙仍为512位时,以太网规定一帧的最小发送时间必须为5.12μs。
1000Mbps以太网的时隙增至512字节,即4096位时,4.096μs。
V3学院的上位机传送图像数据的数据流
图像数据在千兆以太网数据流中所在的位置是在上面50~1073里面,主要分为图像的数据头包与图像的数据包。这里说明一下,下面的数据协议都是自己定义的,可以根据不同的需求编写不同的协议,同时编写相应的上位机。数据头包是指在发送第一行图像数据前发送的帧头数据,标志着下一包图像数据即将到来。
注:check sum 计算是把一帧内第8字节到第253字节之和的低16位作为check_sum,为了给软件提供校验帧数据的作用,校验方法判断接收端计算的check_sum和接收到的check_sum是否一致。03+FF+02+FF=104+FF=’h203
图像行数据帧
跟在数据头包之后的图像行数据包,一次发送一行图像数据。
如果RGB图像一行超过400pixel需要把一行像素分包发送,由于每个UDP包不能超过1.5k长度。
限定最大发送图像宽度为1200pixel
小于等于400pixel 发送一个udp包
大于400小于等于800pixel分两个udp包发送
大于800小于等于1200pixel分三个udp包发送
这里也讲解一下对图像数据进行上面编码的作用:因为电脑随机会产生一些冗余的以太网包,那么如何去除相应的废包,一个方法就是进行编码,当然也可以通过使用指定phy芯片的MAC地址的方法。但是在本次实验中,我们使用的是广播包的形式,所以只有通过编码进行相应冗余包的处理。
项目的实验框图
接下来为了让同学们方便理解这个项目的流程,我们给出相应的系统框图如下:
这里简述一下几个模块的功能:
1、Iddr_ctrl模块:使用RGMII相移90度的时钟将双沿数据转化成单沿数据,注意这里使用相移90度的原因是为了采集数据的稳定性。
2、Run_clk_ctrl:这个模块的设计思想特别重要,是处理跨时钟域最常见的处理方法,将RGMII的时钟域转换到系统时钟域,特别特别重要
3、Image_ctrl模块:将上面用户进行编码的图像数据进行相应的译码,然后放到DDR3中进行缓存。4、4、Ddr3_ctrl模块:DDR3的驱动模块,进行数据的读取与写出。
5、USB3.0模块:将图像数据经由USB3.0传输到上位机中去。
跨时钟域处理时序图
这里的跨时钟域处理特别重要,主要包括上面的run_clk_ctrl、pll、iddr_ctrl模块,其中pll就是调用pll的IP实现移位90度,iddr_ctrl前面的博客我们已经讲解过,那么接下来我们主要讲解run_clk_ctrl模块的时序图。
时序图如下:
从上面的原理我们可以看出这次的跨时钟域处理主要是利用FIFO来实现的,其中上面mac_en_dly移位了8拍是为了同步同时是为了让后面进行处理时,latch_max已经有效供我们去除CRC校验位。
Image_ctrl时序图
该模块是为了解码出相应图像数据,具体的时序图如下:
经过上面的时序图,相信大家可以很简单写出时序图。接下来,我们给出相应的代码。
工程代码
top模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : top.v
// Create Time : 2020-03-01 20:33:42
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module top(//System Interfacesinput sclk ,input rst_n ,//DDR3 Interfaces output wire [13:0] ddr3_addr ,output wire [ 2:0] ddr3_ba ,output wire ddr3_cas_n ,output wire ddr3_ck_n ,output wire ddr3_ck_p ,output wire ddr3_cke ,output wire ddr3_ras_n ,output wire ddr3_reset_n ,output wire ddr3_we_n ,inout [31:0] ddr3_dq ,inout [ 3:0] ddr3_dqs_n ,inout [ 3:0] ddr3_dqs_p ,output wire [ 0:0] ddr3_cs_n ,output wire [ 3:0] ddr3_dm ,output wire [ 0:0] ddr3_odt ,//Gigbit Interfacesoutput wire phy_rst_n ,input [ 3:0] rx_data ,input rx_ctrl ,input rx_clk ,//USB3 Interfacesoutput wire USBSS_EN ,input USB_clk ,inout [15:0] data ,inout [ 1:0] be ,input rxf_n ,input txf_n ,output wire oe_n ,output wire wr_n ,output wire siwu_n ,output wire rd_n ,output wire wakeup ,output wire [ 1:0] gpio );//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
//clk_wiz_0_inst
wire clk_200m ;
wire locked ;
wire clk_125m ;
//ddr3_drive_inst
wire init_calib_complete ;
wire c3_p0_cmd_clk ;
wire c3_p0_cmd_en ;
wire [ 2:0] c3_p0_cmd_instr ;
wire [27:0] c3_p0_cmd_byte_addr ;
wire [ 6:0] c3_p0_cmd_bl ;
wire c3_p0_wr_clk ;
wire c3_p0_wr_en ;
wire [31:0] c3_p0_wr_mask ;
wire [255:0] c3_p0_wr_data ;
wire [10:0] c3_p0_wr_count ; wire c3_p1_cmd_clk ;
wire c3_p1_cmd_en ;
wire [ 2:0] c3_p1_cmd_instr ;
wire [27:0] c3_p1_cmd_byte_addr ;
wire [ 6:0] c3_p1_cmd_bl ;
wire c3_p1_rd_clk ;
wire c3_p1_rd_en ;
wire [255:0] c3_p1_rd_data ;
wire [10:0] c3_p1_rd_count ;//sensor_data_gen_inst
wire clk_24m ;
wire data_wr_en ;
wire [31:0] data_wr ;//usb3_drive_inst
wire [15:0] data_in ;
wire data_req ;wire [ 7:0] image_data ;
wire image_data_en ;
wire [31:0] rlst ;
wire rlst_flag ; //========================================================================================\
//************** Main Code **********************************
//========================================================================================/
clk_wiz_0 clk_wiz_0_inst(// Clock out ports.clk_out1 (clk_200m ), // output clk_out1.clk_out2 (clk_125m ),.clk_out3 (clk_50m ),// Status and control signals.reset (~rst_n ), // input reset.locked (locked ), // output locked// Clock in ports.clk_in1 (sclk )
); // input clk_in1ddr3_top ddr3_top_inst(//System Interfaces.rst_n (rst_n ),.locked (locked ),.clk_200m (clk_200m ), //DDR3 Interfaces .ddr3_addr (ddr3_addr ),.ddr3_ba (ddr3_ba ),.ddr3_cas_n (ddr3_cas_n ),.ddr3_ck_n (ddr3_ck_n ),.ddr3_ck_p (ddr3_ck_p ),.ddr3_cke (ddr3_cke ),.ddr3_ras_n (ddr3_ras_n ),.ddr3_reset_n (ddr3_reset_n ),.ddr3_we_n (ddr3_we_n ),.ddr3_dq (ddr3_dq ),.ddr3_dqs_n (ddr3_dqs_n ),.ddr3_dqs_p (ddr3_dqs_p ),.ddr3_cs_n (ddr3_cs_n ),.ddr3_dm (ddr3_dm ),.ddr3_odt (ddr3_odt ),//User Interfaces.init_calib_complete (init_calib_complete ),.c3_p0_cmd_clk (c3_p0_cmd_clk ),.c3_p0_cmd_en (c3_p0_cmd_en ),.c3_p0_cmd_bl (c3_p0_cmd_bl ),.c3_p0_cmd_byte_addr (c3_p0_cmd_byte_addr ),.c3_p0_cmd_empty ( ),.c3_p0_cmd_full ( ),.c3_p0_wr_clk (c3_p0_wr_clk ),.c3_p0_wr_en (c3_p0_wr_en ),.c3_p0_wr_mask (c3_p0_wr_mask ),.c3_p0_wr_data (c3_p0_wr_data ),.c3_p0_wr_full ( ),.c3_p0_wr_empty ( ),.c3_p0_wr_count (c3_p0_wr_count ),.c3_p1_cmd_clk ('d0 ),.c3_p1_cmd_en ('d0 ),.c3_p1_cmd_bl ('d0 ),.c3_p1_cmd_byte_addr ('d0 ),.c3_p1_cmd_empty ( ),.c3_p1_cmd_full ( ),.c3_p1_wr_clk ('d0 ),.c3_p1_wr_en ('d0 ),.c3_p1_wr_mask ('d0 ),.c3_p1_wr_data ('d0 ),.c3_p1_wr_full ( ),.c3_p1_wr_empty ( ),.c3_p1_wr_count ( ),.c3_p2_cmd_clk (c3_p1_cmd_clk ),.c3_p2_cmd_en (c3_p1_cmd_en ),.c3_p2_cmd_bl (c3_p1_cmd_bl ),.c3_p2_cmd_byte_addr (c3_p1_cmd_byte_addr ),.c3_p2_cmd_empty ( ),.c3_p2_cmd_full ( ),.c3_p2_rd_clk (c3_p1_rd_clk ),.c3_p2_rd_en (c3_p1_rd_en ),.c3_p2_rd_data (c3_p1_rd_data ),.c3_p2_rd_full ( ),.c3_p2_rd_empty ( ),.c3_p2_rd_count (c3_p1_rd_count ),.c3_p3_cmd_clk ('d0 ),.c3_p3_cmd_en ('d0 ),.c3_p3_cmd_bl ('d0 ),.c3_p3_cmd_byte_addr ('d0 ),.c3_p3_cmd_empty ( ),.c3_p3_cmd_full ( ),.c3_p3_rd_clk ('d0 ),.c3_p3_rd_en ('d0 ),.c3_p3_rd_data ( ),.c3_p3_rd_full ( ),.c3_p3_rd_empty ( ),.c3_p3_rd_count ( ));ddr3_drive ddr3_drive_inst(//System Interfaces.rst_n (init_calib_complete ),//DDR3 Interfaces .c3_p0_cmd_clk (c3_p0_cmd_clk ),.c3_p0_cmd_en (c3_p0_cmd_en ),.c3_p0_cmd_instr (c3_p0_cmd_instr ),.c3_p0_cmd_byte_addr (c3_p0_cmd_byte_addr ),.c3_p0_cmd_bl (c3_p0_cmd_bl ),.c3_p0_wr_clk (c3_p0_wr_clk ),.c3_p0_wr_en (c3_p0_wr_en ),.c3_p0_wr_mask (c3_p0_wr_mask ),.c3_p0_wr_data (c3_p0_wr_data ),.c3_p0_wr_count (c3_p0_wr_count ),.c3_p1_cmd_clk (c3_p1_cmd_clk ),.c3_p1_cmd_en (c3_p1_cmd_en ),.c3_p1_cmd_instr (c3_p1_cmd_instr ),.c3_p1_cmd_byte_addr (c3_p1_cmd_byte_addr ),.c3_p1_cmd_bl (c3_p1_cmd_bl ),.c3_p1_rd_clk (c3_p1_rd_clk ),.c3_p1_rd_en (c3_p1_rd_en ),.c3_p1_rd_data (c3_p1_rd_data ),.c3_p1_rd_count (c3_p1_rd_count ),//Write DDR3.clk_24m (clk_125m ),.data_wr_en (data_wr_en ),.data_wr (data_wr ),Read DDR3.USB_clk (USB_clk ),.wr_n (data_req ),.data_in (data_in )
);gbit_top gbit_top_inst(//System Interfaces.clk_50m (clk_50m ),.clk_125m (clk_125m ),.rst_n (locked ),//Gigbit Interfaces.phy_rst_n (phy_rst_n ),.rx_data (rx_data ),.rx_ctrl (rx_ctrl ),.rx_clk (rx_clk ),//Communication Interfaces.image_data (image_data ),.image_data_en (image_data_en ),.rlst (rlst ),.rlst_flag (rlst_flag )
);conver_bit conver_bit_inst(//System Interfaces.sclk (clk_125m ),.rst_n (locked ),//Gigbit Interfaces.image_data (image_data ),.image_data_en (image_data_en ),//Communication Interfaces.rgb_data ({data_wr[15:8],data_wr[23:16],data_wr[31:24],data_wr[7:0]} ),.rgb_data_en (data_wr_en )
);
//sensor_data_gen sensor_data_gen_inst(
// .clk (clk_24m ),
// .rst_n (init_calib_complete ),
// .rgb ({data_wr[15:0],data_wr[31:16]} ),
// .de (data_wr_en ),
// .vsync ( ),
// .hsync ( )
//);
//lways @(posedge clk_24m)
// if(init_calib_complete == 1'b0)
// data_wr_en <= 1'b0;
// else
// data_wr_en <= 1'b1;//lways @(posedge clk_24m)
// if(init_calib_complete == 1'b0)
// data_wr <= 32'd0;
// else if(data_wr_en == 1'b1)
// data_wr <= data_wr + 1'b1;usb3_drive usb3_drive_inst(//System Interfaces.rst_n (init_calib_complete ),//USB3 Interfaces.USBSS_EN (USBSS_EN ),.sclk (USB_clk ),.data (data ),.be (be ),.rxf_n (rxf_n ),.txf_n (txf_n ),.oe_n (oe_n ),.wr_n (wr_n ),.siwu_n (siwu_n ),.rd_n (rd_n ),.wakeup (wakeup ),.gpio (gpio ),//Communication Interfaces.data_in (data_in ),.data_req (data_req )
);//========================================================================================\
//******************************* Debug **********************************
//========================================================================================/ila_3 ila_3_inst (.clk (clk_125m ), // input wire clk.probe0 (image_data ), // input wire [7:0] probe0 .probe1 (image_data_en ), // input wire [0:0] probe1 .probe2 (data_wr ), // input wire [31:0] probe2 .probe3 (data_wr_en ) // input wire [0:0] probe3
);endmodule
ddr3_top模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : ddr3_top.v
// Create Time : 2020-02-27 23:16:16
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module ddr3_top(//System Interfacesinput rst_n ,input locked ,input clk_200m , //DDR3 Interfaces output wire [13:0] ddr3_addr ,output wire [ 2:0] ddr3_ba ,output wire ddr3_cas_n ,output wire ddr3_ck_n ,output wire ddr3_ck_p ,output wire ddr3_cke ,output wire ddr3_ras_n ,output wire ddr3_reset_n ,output wire ddr3_we_n ,inout [31:0] ddr3_dq ,inout [ 3:0] ddr3_dqs_n ,inout [ 3:0] ddr3_dqs_p ,output wire [ 0:0] ddr3_cs_n ,output wire [ 3:0] ddr3_dm ,output wire [ 0:0] ddr3_odt ,//User Interfacesoutput wire init_calib_complete , input c3_p0_cmd_clk ,input c3_p0_cmd_en ,input [ 6:0] c3_p0_cmd_bl ,input [27:0] c3_p0_cmd_byte_addr ,output wire c3_p0_cmd_empty ,output wire c3_p0_cmd_full ,input c3_p0_wr_clk ,input c3_p0_wr_en ,input [31:0] c3_p0_wr_mask ,input [255:0] c3_p0_wr_data ,output wire c3_p0_wr_full ,output wire c3_p0_wr_empty ,output wire [10:0] c3_p0_wr_count ,input c3_p1_cmd_clk ,input c3_p1_cmd_en ,input [ 6:0] c3_p1_cmd_bl ,input [27:0] c3_p1_cmd_byte_addr ,output wire c3_p1_cmd_empty ,output wire c3_p1_cmd_full ,input c3_p1_wr_clk ,input c3_p1_wr_en ,input [31:0] c3_p1_wr_mask ,input [255:0] c3_p1_wr_data ,output wire c3_p1_wr_full ,output wire c3_p1_wr_empty ,output wire [10:0] c3_p1_wr_count ,input c3_p2_cmd_clk ,input c3_p2_cmd_en ,input [ 6:0] c3_p2_cmd_bl ,input [27:0] c3_p2_cmd_byte_addr ,output wire c3_p2_cmd_empty ,output wire c3_p2_cmd_full ,input c3_p2_rd_clk ,input c3_p2_rd_en ,output wire [255:0] c3_p2_rd_data ,output wire c3_p2_rd_full ,output wire c3_p2_rd_empty ,output wire [10:0] c3_p2_rd_count ,input c3_p3_cmd_clk ,input c3_p3_cmd_en ,input [ 6:0] c3_p3_cmd_bl ,input [27:0] c3_p3_cmd_byte_addr ,output wire c3_p3_cmd_empty ,output wire c3_p3_cmd_full ,input c3_p3_rd_clk ,input c3_p3_rd_en ,output wire [255:0] c3_p3_rd_data ,output wire c3_p3_rd_full ,output wire c3_p3_rd_empty ,output wire [10:0] c3_p3_rd_count );//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
//mig_7series_0_inst
wire [27:0] app_addr ;
wire [ 2:0] app_cmd ;
wire app_en ;
wire [255:0] app_wdf_data ;
wire app_wdf_end ;
wire app_wdf_wren ;
wire [255:0] app_rd_data ;
wire app_rd_data_end ;
wire app_rd_data_valid ;
wire app_rdy ;
wire app_wdf_rdy ;
wire [31:0] app_wdf_mask ;
wire ui_clk ;
wire ui_clk_sync_rst ;
//a7_wr_ctrl_inst1
wire app_en_wr1 ;
wire [ 3:0] app_cmd_wr1 ;
wire [27:0] app_addr_wr1 ;
wire app_wdf_wren_wr1 ;
wire [255:0] app_wdf_data_wr1 ;
wire [31:0] app_wdf_mask_wr1 ;
wire app_wdf_end_wr1 ;
wire a7_wr_start_wr1 ;
wire [ 6:0] a7_wr_bl_wr1 ;
wire [27:0] a7_wr_init_addr_wr1 ;
wire [255:0] a7_wr_data_wr1 ;
wire [31:0] a7_wr_mask_wr1 ;
wire a7_wr_end_wr1 ;
wire a7_wr_req_wr1 ;
//a7_wr_ctrl_inst2
wire app_en_wr2 ;
wire [ 3:0] app_cmd_wr2 ;
wire [27:0] app_addr_wr2 ;
wire app_wdf_wren_wr2 ;
wire [255:0] app_wdf_data_wr2 ;
wire [31:0] app_wdf_mask_wr2 ;
wire app_wdf_end_wr2 ;
wire a7_wr_start_wr2 ;
wire [ 6:0] a7_wr_bl_wr2 ;
wire [27:0] a7_wr_init_addr_wr2 ;
wire [255:0] a7_wr_data_wr2 ;
wire [31:0] a7_wr_mask_wr2 ;
wire a7_wr_end_wr2 ;
wire a7_wr_req_wr2 ;
//a7_rd_ctrl_inst1
wire app_en_rd1 ;
wire [ 3:0] app_cmd_rd1 ;
wire [27:0] app_addr_rd1 ;
wire app_rd_data_valid_rd1 ;
wire a7_rd_start_rd1 ;
wire [ 6:0] a7_rd_bl_rd1 ;
wire [27:0] a7_rd_init_addr_rd1 ;
wire [255:0] a7_rd_data_rd1 ;
wire a7_rd_data_valid_rd1 ;
wire a7_rd_end_rd1 ;
//a7_rd_ctrl_inst2
wire app_en_rd2 ;
wire [ 3:0] app_cmd_rd2 ;
wire [27:0] app_addr_rd2 ;
wire app_rd_data_valid_rd2 ;
wire a7_rd_start_rd2 ;
wire [ 6:0] a7_rd_bl_rd2 ;
wire [27:0] a7_rd_init_addr_rd2 ;
wire [255:0] a7_rd_data_rd2 ;
wire a7_rd_data_valid_rd2 ;
wire a7_rd_end_rd2 ;
//arbit_inst
//wire c3_p0_cmd_empty ;
//wire c3_p1_cmd_empty ;
//wire c3_p2_cmd_empty ;
//wire c3_p3_cmd_empty ;//rst delay
reg [ 5:0] rst_cnt ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/always @(posedge clk_200m or negedge rst_n)if(rst_n == 1'b0)rst_cnt <= 6'b0;else if(locked == 1'b0) rst_cnt <= 6'b0;else if(rst_cnt[5] == 1'b0)rst_cnt <= rst_cnt + 1'b1;mig_7series_0 mig_7series_0_inst (// Memory interface ports.ddr3_addr (ddr3_addr ), // output [13:0] ddr3_addr.ddr3_ba (ddr3_ba ), // output [2:0] ddr3_ba.ddr3_cas_n (ddr3_cas_n ), // output ddr3_cas_n.ddr3_ck_n (ddr3_ck_n ), // output [0:0] ddr3_ck_n.ddr3_ck_p (ddr3_ck_p ), // output [0:0] ddr3_ck_p.ddr3_cke (ddr3_cke ), // output [0:0] ddr3_cke.ddr3_ras_n (ddr3_ras_n ), // output ddr3_ras_n.ddr3_reset_n (ddr3_reset_n ), // output ddr3_reset_n.ddr3_we_n (ddr3_we_n ), // output ddr3_we_n.ddr3_dq (ddr3_dq ), // inout [31:0] ddr3_dq.ddr3_dqs_n (ddr3_dqs_n ), // inout [3:0] ddr3_dqs_n.ddr3_dqs_p (ddr3_dqs_p ), // inout [3:0] ddr3_dqs_p.init_calib_complete (init_calib_complete ), // output init_calib_complete.ddr3_cs_n (ddr3_cs_n ), // output [0:0] ddr3_cs_n.ddr3_dm (ddr3_dm ), // output [3:0] ddr3_dm.ddr3_odt (ddr3_odt ), // output [0:0] ddr3_odt// Application interface ports.app_addr (app_addr ), // input [27:0] app_addr.app_cmd (app_cmd ), // input [2:0] app_cmd.app_en (app_en ), // input app_en.app_wdf_data (app_wdf_data ), // input [255:0] app_wdf_data.app_wdf_end (app_wdf_end ), // input app_wdf_end.app_wdf_wren (app_wdf_wren ), // input app_wdf_wren.app_rd_data (app_rd_data ), // output [255:0] app_rd_data.app_rd_data_end (app_rd_data_end ), // output app_rd_data_end.app_rd_data_valid (app_rd_data_valid ), // output app_rd_data_valid.app_rdy (app_rdy ), // output app_rdy.app_wdf_rdy (app_wdf_rdy ), // output app_wdf_rdy.app_sr_req (1'b0 ), // input app_sr_req.app_ref_req (1'b0 ), // input app_ref_req.app_zq_req (1'b0 ), // input app_zq_req.app_sr_active ( ), // output app_sr_active.app_ref_ack ( ), // output app_ref_ack.app_zq_ack ( ), // output app_zq_ack.ui_clk (ui_clk ), // output ui_clk.ui_clk_sync_rst (ui_clk_sync_rst ), // output ui_clk_sync_rst.app_wdf_mask (app_wdf_mask ), // input [31:0] app_wdf_mask// System Clock Ports.sys_clk_i (clk_200m ),.sys_rst (locked ) // input sys_rst
);
arbit arbit_inst(//System Interfaces.rst_n (init_calib_complete ),//DDR3 Interfaces .ui_clk (ui_clk ),.app_addr (app_addr ),.app_cmd (app_cmd ),.app_en (app_en ),.app_wdf_data (app_wdf_data ),.app_wdf_end (app_wdf_end ),.app_wdf_wren (app_wdf_wren ),.app_rd_data_valid (app_rd_data_valid ),.app_wdf_mask (app_wdf_mask ),//a7_wr_ctrl_inst1 .app_en_wr1 (app_en_wr1 ),.app_cmd_wr1 (app_cmd_wr1 ),.app_addr_wr1 (app_addr_wr1 ),.app_wdf_wren_wr1 (app_wdf_wren_wr1 ),.app_wdf_data_wr1 (app_wdf_data_wr1 ),.app_wdf_mask_wr1 (app_wdf_mask_wr1 ),.app_wdf_end_wr1 (app_wdf_end_wr1 ),.a7_wr_start_w1 (a7_wr_start_wr1 ),.a7_wr_end_wr1 (a7_wr_end_wr1 ),.c3_p0_cmd_empty (c3_p0_cmd_empty ),//a7_wr_ctrl_inst1 .app_en_wr2 (app_en_wr2 ),.app_cmd_wr2 (app_cmd_wr2 ),.app_addr_wr2 (app_addr_wr2 ),.app_wdf_wren_wr2 (app_wdf_wren_wr2 ),.app_wdf_data_wr2 (app_wdf_data_wr2 ),.app_wdf_mask_wr2 (app_wdf_mask_wr2 ),.app_wdf_end_wr2 (app_wdf_end_wr2 ),.a7_wr_start_w2 (a7_wr_start_wr2 ),.a7_wr_end_wr2 (a7_wr_end_wr2 ),.c3_p1_cmd_empty (c3_p1_cmd_empty ),//a7_rd_ctrl_inst1 .app_en_rd1 (app_en_rd1 ),.app_cmd_rd1 (app_cmd_rd1 ),.app_addr_rd1 (app_addr_rd1 ),.app_rd_data_valid_rd1 (app_rd_data_valid_rd1 ), .a7_rd_start_rd1 (a7_rd_start_rd1 ),.a7_rd_end_rd1 (a7_rd_end_rd1 ), .c3_p2_cmd_empty (c3_p2_cmd_empty ), //a7_rd_ctrl_inst2 .app_en_rd2 (app_en_rd2 ),.app_cmd_rd2 (app_cmd_rd2 ),.app_addr_rd2 (app_addr_rd2 ),.app_rd_data_valid_rd2 (app_rd_data_valid_rd2 ), .a7_rd_start_rd2 (a7_rd_start_rd2 ),.a7_rd_end_rd2 (a7_rd_end_rd2 ),.c3_p3_cmd_empty (c3_p3_cmd_empty )
);a7_wr_ctrl a7_wr_ctrl_inst1(//System Interfaces.rst_n (init_calib_complete ),//DDR3 Interfaces.ui_clk (ui_clk ),.app_rdy (app_rdy ),.app_wdf_rdy (app_wdf_rdy ),.app_en (app_en_wr1 ),.app_cmd (app_cmd_wr1 ),.app_addr (app_addr_wr1 ),.app_wdf_wren (app_wdf_wren_wr1 ),.app_wdf_data (app_wdf_data_wr1 ),.app_wdf_mask (app_wdf_mask_wr1 ),.app_wdf_end (app_wdf_end_wr1 ),//Communication Interfaces.a7_wr_start (a7_wr_start_wr1 ),.a7_wr_bl (a7_wr_bl_wr1 ),.a7_wr_init_addr (a7_wr_init_addr_wr1 ),.a7_wr_data (a7_wr_data_wr1 ),.a7_wr_mask (a7_wr_mask_wr1 ),.a7_wr_end (a7_wr_end_wr1 ),.a7_wr_req (a7_wr_req_wr1 )
);fifo_generator_0 cmd_wr1_fifo (.rst (~init_calib_complete ), // input wire rst.wr_clk (c3_p0_cmd_clk ), // input wire wr_clk.rd_clk (ui_clk ), // input wire rd_clk.din ({c3_p0_cmd_bl,c3_p0_cmd_byte_addr}), // input wire [38 : 0] din.wr_en (c3_p0_cmd_en ), // input wire wr_en.rd_en (a7_wr_start_wr1 ), // input wire rd_en.dout ({a7_wr_bl_wr1,a7_wr_init_addr_wr1}), // output wire [38 : 0] dout.full (c3_p0_cmd_full ), // output wire full.empty (c3_p0_cmd_empty )
); fifo_generator_1 data_wr1_fifo (.rst (~init_calib_complete ), // input wire rst.wr_clk (c3_p0_wr_clk ), // input wire wr_clk.rd_clk (ui_clk ), // input wire rd_clk.din ({c3_p0_wr_mask,c3_p0_wr_data} ), // input wire [287 : 0] din.wr_en (c3_p0_wr_en ), // input wire wr_en.rd_en (a7_wr_req_wr1 ), // input wire rd_en.dout ({a7_wr_mask_wr1,a7_wr_data_wr1}), // output wire [287 : 0] dout.full (c3_p0_wr_full ), // output wire full.empty (c3_p0_wr_empty ), // output wire empty.wr_data_count (c3_p0_wr_count ) // output wire [10 : 0] wr_data_count
); a7_wr_ctrl a7_wr_ctrl_inst2(//System Interfaces.rst_n (init_calib_complete ),//DDR3 Interfaces.ui_clk (ui_clk ),.app_rdy (app_rdy ),.app_wdf_rdy (app_wdf_rdy ),.app_en (app_en_wr2 ),.app_cmd (app_cmd_wr2 ),.app_addr (app_addr_wr2 ),.app_wdf_wren (app_wdf_wren_wr2 ),.app_wdf_data (app_wdf_data_wr2 ),.app_wdf_mask (app_wdf_mask_wr2 ),.app_wdf_end (app_wdf_end_wr2 ),//Communication Interfaces.a7_wr_start (a7_wr_start_wr2 ),.a7_wr_bl (a7_wr_bl_wr2 ),.a7_wr_init_addr (a7_wr_init_addr_wr2 ),.a7_wr_data (a7_wr_data_wr2 ),.a7_wr_mask (a7_wr_mask_wr2 ),.a7_wr_end (a7_wr_end_wr2 ),.a7_wr_req (a7_wr_req_wr2 )
);fifo_generator_0 cmd_wr2_fifo (.rst (~init_calib_complete ), // input wire rst.wr_clk (c3_p1_cmd_clk ), // input wire wr_clk.rd_clk (ui_clk ), // input wire rd_clk.din ({c3_p1_cmd_bl,c3_p1_cmd_byte_addr}), // input wire [38 : 0] din.wr_en (c3_p1_cmd_en ), // input wire wr_en.rd_en (a7_wr_start_wr2 ), // input wire rd_en.dout ({a7_wr_bl_wr2,a7_wr_init_addr_wr2}), // output wire [38 : 0] dout.full (c3_p1_cmd_full ), // output wire full.empty (c3_p1_cmd_empty )
);fifo_generator_1 data_wr2_fifo (.rst (~init_calib_complete ), // input wire rst.wr_clk (c3_p1_wr_clk ), // input wire wr_clk.rd_clk (ui_clk ), // input wire rd_clk.din ({c3_p1_wr_mask,c3_p1_wr_data} ), // input wire [287 : 0] din.wr_en (c3_p1_wr_en ), // input wire wr_en.rd_en (a7_wr_req_wr2 ), // input wire rd_en.dout ({a7_wr_mask_wr2,a7_wr_data_wr2}), // output wire [287 : 0] dout.full (c3_p1_wr_full ), // output wire full.empty (c3_p1_wr_empty ), // output wire empty.wr_data_count (c3_p1_wr_count ) // output wire [10 : 0] wr_data_count
);a7_rd_ctrl a7_rd_ctrl_inst1(//System Interfaces.rst_n (init_calib_complete ),//DDR3 Interfaces .ui_clk (ui_clk ),.app_en (app_en_rd1 ),.app_cmd (app_cmd_rd1 ),.app_addr (app_addr_rd1 ),.app_rd_data (app_rd_data ),.app_rd_data_valid (app_rd_data_valid_rd1 ),.app_rdy (app_rdy ),//Communication Interfaces.a7_rd_start (a7_rd_start_rd1 ),.a7_rd_bl (a7_rd_bl_rd1 ),.a7_rd_init_addr (a7_rd_init_addr_rd1 ),.a7_rd_data (a7_rd_data_rd1 ),.a7_rd_data_valid (a7_rd_data_valid_rd1 ),.a7_rd_end (a7_rd_end_rd1 )
);fifo_generator_0 cmd_rd1_fifo (.rst (~rst_cnt[5] ), // input wire rst.wr_clk (c3_p2_cmd_clk ), // input wire wr_clk.rd_clk (ui_clk ), // input wire rd_clk.din ({c3_p2_cmd_bl,c3_p2_cmd_byte_addr}), // input wire [38 : 0] din.wr_en (c3_p2_cmd_en ), // input wire wr_en.rd_en (a7_rd_start_rd1 ), // input wire rd_en.dout ({a7_rd_bl_rd1,a7_rd_init_addr_rd1}), // output wire [38 : 0] dout.full (c3_p2_cmd_full ), // output wire full.empty (c3_p2_cmd_empty )
);fifo_generator_2 data_rd1_fifo (.rst (~rst_cnt[5] ), // input wire rst.wr_clk (ui_clk ), // input wire wr_clk.rd_clk (c3_p2_rd_clk ), // input wire rd_clk.din (a7_rd_data_rd1 ), // input wire [255 : 0] din.wr_en (a7_rd_data_valid_rd1 ), // input wire wr_en.rd_en (c3_p2_rd_en ), // input wire rd_en.dout (c3_p2_rd_data ), // output wire [255 : 0] dout.full (c3_p2_rd_full ), // output wire full.empty (c3_p2_rd_empty ), // output wire empty.rd_data_count (c3_p2_rd_count ) // output wire [10 : 0] rd_data_count
);a7_rd_ctrl a7_rd_ctrl_inst2(//System Interfaces.rst_n (init_calib_complete ),//DDR3 Interfaces .ui_clk (ui_clk ),.app_en (app_en_rd2 ),.app_cmd (app_cmd_rd2 ),.app_addr (app_addr_rd2 ),.app_rd_data (app_rd_data ),.app_rd_data_valid (app_rd_data_valid_rd2 ),.app_rdy (app_rdy ),//Communication Interfaces.a7_rd_start (a7_rd_start_rd2 ),.a7_rd_bl (a7_rd_bl_rd2 ),.a7_rd_init_addr (a7_rd_init_addr_rd2 ),.a7_rd_data (a7_rd_data_rd2 ),.a7_rd_data_valid (a7_rd_data_valid_rd2 ),.a7_rd_end (a7_rd_end_rd2 )
);fifo_generator_0 cmd_rd2_fifo (.rst (~rst_cnt[5] ), // input wire rst.wr_clk (c3_p3_cmd_clk ), // input wire wr_clk.rd_clk (ui_clk ), // input wire rd_clk.din ({c3_p3_cmd_bl,c3_p3_cmd_byte_addr}), // input wire [38 : 0] din.wr_en (c3_p3_cmd_en ), // input wire wr_en.rd_en (a7_rd_start_rd2 ), // input wire rd_en.dout ({a7_rd_bl_rd2,a7_rd_init_addr_rd2}), // output wire [38 : 0] dout.full (c3_p3_cmd_full ), // output wire full.empty (c3_p3_cmd_empty )
);fifo_generator_2 data_rd2_fifo (.rst (~rst_cnt[5] ), // input wire rst.wr_clk (ui_clk ), // input wire wr_clk.rd_clk (c3_p3_rd_clk ), // input wire rd_clk.din (a7_rd_data_rd2 ), // input wire [255 : 0] din.wr_en (a7_rd_data_valid_rd2 ), // input wire wr_en.rd_en (c3_p3_rd_en ), // input wire rd_en.dout (c3_p3_rd_data ), // output wire [255 : 0] dout.full (c3_p3_rd_full ), // output wire full.empty (c3_p3_rd_empty ), // output wire empty.rd_data_count (c3_p3_rd_count ) // output wire [10 : 0] rd_data_count
);endmodule
arbit模块:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/03/01 15:17:14
// Design Name:
// Module Name: arbit
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module arbit(//System Interfacesinput rst_n ,//DDR3 Interfaces input ui_clk ,output reg [27:0] app_addr ,output reg [ 2:0] app_cmd ,output reg app_en ,output reg [255:0] app_wdf_data ,output reg app_wdf_end ,output reg app_wdf_wren ,input app_rd_data_valid ,output reg [31:0] app_wdf_mask ,//a7_wr_ctrl_inst1 input app_en_wr1 ,input [ 3:0] app_cmd_wr1 ,input [27:0] app_addr_wr1 ,input app_wdf_wren_wr1 ,input [255:0] app_wdf_data_wr1 ,input [31:0] app_wdf_mask_wr1 ,input app_wdf_end_wr1 ,output reg a7_wr_start_w1 ,input a7_wr_end_wr1 ,input c3_p0_cmd_empty ,//a7_wr_ctrl_inst1 input app_en_wr2 ,input [ 3:0] app_cmd_wr2 ,input [27:0] app_addr_wr2 ,input app_wdf_wren_wr2 ,input [255:0] app_wdf_data_wr2 ,input [31:0] app_wdf_mask_wr2 ,input app_wdf_end_wr2 ,output reg a7_wr_start_w2 ,input a7_wr_end_wr2 ,input c3_p1_cmd_empty ,//a7_rd_ctrl_inst1 input app_en_rd1 ,input [ 3:0] app_cmd_rd1 ,input [27:0] app_addr_rd1 ,output reg app_rd_data_valid_rd1 , output reg a7_rd_start_rd1 ,input a7_rd_end_rd1 , input c3_p2_cmd_empty , //a7_rd_ctrl_inst2 input app_en_rd2 ,input [ 3:0] app_cmd_rd2 ,input [27:0] app_addr_rd2 ,output reg app_rd_data_valid_rd2 , output reg a7_rd_start_rd2 ,input a7_rd_end_rd2 ,input c3_p3_cmd_empty
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter IDLE = 6'b000001 ;
parameter ARBIT = 6'b000010 ;
parameter WR1 = 6'b000100 ;
parameter WR2 = 6'b001000 ;
parameter RD1 = 6'b010000 ;
parameter RD2 = 6'b100000 ;reg [ 5:0] state ;
reg [ 2:0] rand_cnt ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)rand_cnt <= 3'd0; else if(rand_cnt == 3'd3)rand_cnt <= 3'd0;elserand_cnt <= rand_cnt + 1'b1;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)state <= IDLE;else case(state)IDLE : state <= ARBIT;ARBIT : if(c3_p0_cmd_empty == 1'b0 && rand_cnt == 3'd0)state <= WR1;else if(c3_p1_cmd_empty == 1'b0 && rand_cnt == 3'd1)state <= WR2;else if(c3_p2_cmd_empty == 1'b0 && rand_cnt == 3'd2)state <= RD1;else if(c3_p3_cmd_empty == 1'b0 && rand_cnt == 3'd3)state <= RD2;elsestate <= state; WR1 : if(a7_wr_end_wr1 == 1'b1)state <= ARBIT;elsestate <= state; WR2 : if(a7_wr_end_wr2 == 1'b1)state <= ARBIT;elsestate <= state; RD1 : if(a7_rd_end_rd1 == 1'b1)state <= ARBIT;elsestate <= state; RD2 : if(a7_rd_end_rd2 == 1'b1)state <= ARBIT;elsestate <= state; default : state <= IDLE;endcasealways @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)a7_wr_start_w1 <= 1'b0; else if(state == ARBIT && c3_p0_cmd_empty == 1'b0 && rand_cnt == 3'd0) a7_wr_start_w1 <= 1'b1;elsea7_wr_start_w1 <= 1'b0; always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)a7_wr_start_w2 <= 1'b0; else if(state == ARBIT && c3_p1_cmd_empty == 1'b0 && rand_cnt == 3'd1) a7_wr_start_w2 <= 1'b1;elsea7_wr_start_w2 <= 1'b0; always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)a7_rd_start_rd1 <= 1'b0; else if(state == ARBIT && c3_p2_cmd_empty == 1'b0 && rand_cnt == 3'd2) a7_rd_start_rd1 <= 1'b1; elsea7_rd_start_rd1 <= 1'b0; always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)a7_rd_start_rd2 <= 1'b0; else if(state == ARBIT && c3_p3_cmd_empty == 1'b0 && rand_cnt == 3'd3) a7_rd_start_rd2 <= 1'b1; elsea7_rd_start_rd2 <= 1'b0; always @(*)case(state)WR1 : beginapp_addr = app_addr_wr1; app_cmd = app_cmd_wr1; app_en = app_en_wr1; app_wdf_data = app_wdf_data_wr1;app_wdf_end = app_wdf_end_wr1;app_wdf_wren = app_wdf_wren_wr1;app_wdf_mask = app_wdf_mask_wr1;end WR2 : begin app_addr = app_addr_wr2; app_cmd = app_cmd_wr2; app_en = app_en_wr2; app_wdf_data = app_wdf_data_wr2;app_wdf_end = app_wdf_end_wr2;app_wdf_wren = app_wdf_wren_wr2;app_wdf_mask = app_wdf_mask_wr2;end RD1 : begin app_addr = app_addr_rd1;app_cmd = app_cmd_rd1;app_en = app_en_rd1;app_rd_data_valid_rd1 = app_rd_data_valid;endRD2 : beginapp_addr = app_addr_rd2;app_cmd = app_cmd_rd2;app_en = app_en_rd2;app_rd_data_valid_rd2 = app_rd_data_valid;enddefault : beginapp_addr = 28'd0; app_cmd = 3'd0; app_en = 1'b0; app_wdf_data = 256'd0;app_wdf_end = 1'b0;app_wdf_wren = 1'b0;app_rd_data_valid_rd1 = 1'b0;app_rd_data_valid_rd2 = 1'b0;app_wdf_mask = 32'd0;end endcaseendmodule
a7_wr_ctrl模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : a7_wr_ctrl.v
// Create Time : 2020-02-29 22:19:50
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module a7_wr_ctrl(//System Interfacesinput rst_n ,//DDR3 Interfacesinput ui_clk ,input app_rdy ,input app_wdf_rdy ,output wire app_en ,output wire [ 3:0] app_cmd ,output reg [27:0] app_addr ,output wire app_wdf_wren ,output wire [255:0] app_wdf_data ,output wire [31:0] app_wdf_mask ,output wire app_wdf_end ,//Communication Interfacesinput a7_wr_start ,input [ 6:0] a7_wr_bl ,input [27:0] a7_wr_init_addr ,input [255:0] a7_wr_data ,input [31:0] a7_wr_mask ,output reg a7_wr_end ,output wire a7_wr_req
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [ 6:0] wr_bl ;
reg wr_flag ;
reg [ 6:0] bl_cnt ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign app_en = wr_flag && app_rdy && app_wdf_rdy;
assign app_wdf_end = app_en;
assign app_wdf_wren = app_en;
assign app_wdf_data = a7_wr_data;
assign a7_wr_req = app_en;
assign app_wdf_mask = a7_wr_mask;
assign app_cmd = 3'd0;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)wr_flag <= 1'b0;else if(bl_cnt == wr_bl && app_en == 1'b1)wr_flag <= 1'b0; else if(a7_wr_start == 1'b1)wr_flag <= 1'b1; always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)wr_bl <= 7'd0; else if(a7_wr_start == 1'b1)wr_bl <= a7_wr_bl;elsewr_bl <= wr_bl;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)app_addr <= 28'd0;else if(a7_wr_start == 1'b1)app_addr <= a7_wr_init_addr;else if(app_en == 1'b1)app_addr <= app_addr + 8;elseapp_addr <= app_addr;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)bl_cnt <= 7'd0;else if(bl_cnt == wr_bl && app_en == 1'b1 && wr_flag == 1'b1)bl_cnt <= 7'd0;else if(wr_flag == 1'b1 && app_en == 1'b1)bl_cnt <= bl_cnt + 1'b1;elsebl_cnt <= bl_cnt;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)a7_wr_end <= 1'b0; else if(bl_cnt == wr_bl && app_en == 1'b1) a7_wr_end <= 1'b1;elsea7_wr_end <= 1'b0;endmodule
a7_rd_ctrl模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : a7_rd_ctrl.v
// Create Time : 2020-03-01 14:32:05
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module a7_rd_ctrl(//System Interfacesinput rst_n ,//DDR3 Interfaces input ui_clk ,output reg app_en ,output wire [ 3:0] app_cmd ,output reg [27:0] app_addr ,input [255:0] app_rd_data ,input app_rd_data_valid ,input app_rdy ,//Communication Interfacesinput a7_rd_start ,input [ 6:0] a7_rd_bl ,input [27:0] a7_rd_init_addr ,output reg [255:0] a7_rd_data ,output reg a7_rd_data_valid ,output reg a7_rd_end
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [ 6:0] rd_bl ;
reg [ 6:0] cmd_cnt ;
reg rd_flag ;
reg [ 6:0] data_cnt ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign app_cmd = 3'd1;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)rd_bl <= 7'd0;else if(a7_rd_start == 1'b1)rd_bl <= a7_rd_bl;elserd_bl <= a7_rd_bl;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)app_en <= 1'b0;else if(a7_rd_start == 1'b1)app_en <= 1'b1;else if(cmd_cnt == rd_bl && app_rdy == 1'b1)app_en <= 1'b0;elseapp_en <= app_en;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)cmd_cnt <= 7'd0; else if(rd_flag == 1'b1 && cmd_cnt == rd_bl && app_rdy == 1'b1)cmd_cnt <= 7'd0;else if(rd_flag == 1'b1 && app_rdy == 1'b1 && app_en == 1'b1)cmd_cnt <= cmd_cnt + 1'b1;elsecmd_cnt <= cmd_cnt;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)rd_flag <= 1'b0;else if(a7_rd_start == 1'b1)rd_flag <= 1'b1;else if(data_cnt == rd_bl && app_rd_data_valid == 1'b1)rd_flag <= 1'b0;elserd_flag <= rd_flag;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)app_addr <= 28'd0;else if(a7_rd_start == 1'b1)app_addr <= a7_rd_init_addr;else if(app_en == 1'b1 && app_rdy == 1'b1)app_addr <= app_addr + 8;elseapp_addr <= app_addr;always @(posedge ui_clk)a7_rd_data <= app_rd_data;always @(posedge ui_clk) a7_rd_data_valid <= app_rd_data_valid;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0)a7_rd_end <= 1'b0;else if(data_cnt == rd_bl && app_rd_data_valid == 1'b1)a7_rd_end <= 1'b1;elsea7_rd_end <= 1'b0;always @(posedge ui_clk or negedge rst_n)if(rst_n == 1'b0) data_cnt <= 7'd0;else if(data_cnt == rd_bl && rd_flag == 1'b1 && app_rd_data_valid == 1'b1)data_cnt <= 7'd0;else if(rd_flag == 1'b1 && app_rd_data_valid == 1'b1)data_cnt <= data_cnt + 1'b1;elsedata_cnt <= data_cnt;endmodule
ddr3_drive模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : ddr3_drive.v
// Create Time : 2020-02-22 11:41:08
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module ddr3_drive(//System Interfacesinput rst_n ,//Write DDR3input clk_24m ,input data_wr_en ,input [31:0] data_wr ,//Read DDR3input USB_clk ,input wr_n ,output wire [15:0] data_in ,//DDR3 Interfacesoutput c3_p0_cmd_clk ,output reg c3_p0_cmd_en ,output wire [ 2:0] c3_p0_cmd_instr ,output reg [27:0] c3_p0_cmd_byte_addr ,output wire [10:0] c3_p0_cmd_bl ,output c3_p0_wr_clk ,output reg c3_p0_wr_en ,output wire [31:0] c3_p0_wr_mask ,output reg [255:0] c3_p0_wr_data ,input [ 6:0] c3_p0_wr_count ,output c3_p1_cmd_clk ,output reg c3_p1_cmd_en ,output wire [ 2:0] c3_p1_cmd_instr ,output reg [27:0] c3_p1_cmd_byte_addr ,output wire [ 6:0] c3_p1_cmd_bl ,output c3_p1_rd_clk ,output reg c3_p1_rd_en ,input [255:0] c3_p1_rd_data ,input [10:0] c3_p1_rd_count
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
//parameter BURST_NUM = 1048576 ;
parameter BURST_NUM = 6144 ;
parameter BURST_LENFTH = 7'd15 ;reg [ 3:0] data_cnt ;
reg [ 6:0] wr_data_cnt ;
reg [15:0] bl_cnt ;
reg wr_n_flag ;
reg [31:0] usb_data ;
reg [ 3:0] data_cnt_rd ;
reg [15:0] bl_cnt_r ;
reg rd_first ;
reg [255:0] c3_p1_rd_data_r ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign c3_p0_cmd_clk = clk_24m;
assign c3_p0_wr_clk = clk_24m;
assign c3_p0_cmd_instr = 3'd0;
assign c3_p0_cmd_bl = BURST_LENFTH;
assign c3_p0_wr_mask = 32'd0;
assign data_in = wr_n_flag == 1'b0 ? usb_data[31:16] : usb_data[15:0];
assign c3_p1_cmd_clk = USB_clk;
assign c3_p1_rd_clk = USB_clk;
assign c3_p1_cmd_instr = 3'd1;
assign c3_p1_cmd_bl = BURST_LENFTH;always @(posedge clk_24m or negedge rst_n)if(rst_n == 1'b0)data_cnt <= 4'd0;else if(data_cnt == 4'd7 && data_wr_en == 1'b1)data_cnt <= 4'd0;else if(data_wr_en == 1'b1)data_cnt <= data_cnt + 1'b1;elsedata_cnt <= data_cnt;always @(posedge clk_24m or negedge rst_n)if(rst_n == 1'b0)c3_p0_wr_data <= 256'd0; else if(data_wr_en == 1'b1)c3_p0_wr_data <= {c3_p0_wr_data[223:0],data_wr};elsec3_p0_wr_data <= c3_p0_wr_data;always @(posedge clk_24m or negedge rst_n)if(rst_n == 1'b0)c3_p0_wr_en <= 1'b0; else if(data_cnt == 4'd7 && data_wr_en == 1'b1)c3_p0_wr_en <= 1'b1;elsec3_p0_wr_en <= 1'b0;always @(posedge clk_24m or negedge rst_n)if(rst_n == 1'b0)wr_data_cnt <= 7'd0;else if(wr_data_cnt == BURST_LENFTH && c3_p0_wr_en == 1'b1)wr_data_cnt <= 7'd0;else if(c3_p0_wr_en == 1'b1)wr_data_cnt <= wr_data_cnt + 1'b1;elsewr_data_cnt <= wr_data_cnt;always @(posedge clk_24m or negedge rst_n)if(rst_n == 1'b0)c3_p0_cmd_en <= 1'b0;else if(wr_data_cnt == BURST_LENFTH && c3_p0_wr_en == 1'b1)c3_p0_cmd_en <= 1'b1;elsec3_p0_cmd_en <= 1'b0;always @(posedge clk_24m or negedge rst_n)if(rst_n == 1'b0)c3_p0_cmd_byte_addr <= 28'd0; else if(bl_cnt == BURST_NUM - 1'b1 && c3_p0_cmd_en == 1'b1) c3_p0_cmd_byte_addr <= 28'd0;else if(c3_p0_cmd_en == 1'b1)c3_p0_cmd_byte_addr <= c3_p0_cmd_byte_addr + 'd128; always @(posedge clk_24m or negedge rst_n)if(rst_n == 1'b0)bl_cnt <= 16'd0;else if(bl_cnt == BURST_NUM - 1'b1 && c3_p0_cmd_en == 1'b1)bl_cnt <= 16'd0;else if(c3_p0_cmd_en == 1'b1) bl_cnt <= bl_cnt + 1'b1;elsebl_cnt <= bl_cnt;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)wr_n_flag <= 1'b0; else if(wr_n == 1'b0)wr_n_flag <= wr_n_flag + 1'b1;elsewr_n_flag <= wr_n_flag;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)data_cnt_rd <= 4'd0;else if(data_cnt_rd == 4'd7 && wr_n_flag == 1'b1 && wr_n == 1'b0)data_cnt_rd <= 4'd0;else if(wr_n_flag == 1'b1 && wr_n == 1'b0)data_cnt_rd <= data_cnt_rd + 1'b1;elsedata_cnt_rd <= data_cnt_rd;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)rd_first <= 1'b0;else if(c3_p1_rd_count >= BURST_LENFTH/2 && rd_first == 1'b0) rd_first <= 1'b1;elserd_first <= rd_first; always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)c3_p1_rd_en <= 1'b0;else if(c3_p1_rd_count >= BURST_LENFTH/2 && rd_first == 1'b0)c3_p1_rd_en <= 1'b1;else if(data_cnt_rd == 4'd7 && wr_n_flag == 1'b1 && wr_n == 1'b0) c3_p1_rd_en <= 1'b1;elsec3_p1_rd_en <= 1'b0;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)c3_p1_cmd_en <= 1'b0; else if(c3_p1_rd_count <= BURST_LENFTH/2)c3_p1_cmd_en <= 1'b1;elsec3_p1_cmd_en <= 1'b0;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)c3_p1_cmd_byte_addr <= 28'd0;else if(bl_cnt_r == BURST_NUM - 1'b1 && c3_p1_cmd_en == 1'b1) c3_p1_cmd_byte_addr <= 28'd0;else if(c3_p1_cmd_en == 1'b1)c3_p1_cmd_byte_addr <= c3_p1_cmd_byte_addr + 128;elsec3_p1_cmd_byte_addr <= c3_p1_cmd_byte_addr;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)bl_cnt_r <= 16'd0;else if(bl_cnt_r == BURST_NUM - 1'b1 && c3_p1_cmd_en == 1'b1)bl_cnt_r <= 16'd0;else if(c3_p1_cmd_en == 1'b1)bl_cnt_r <= bl_cnt_r + 1'b1;elsebl_cnt_r <= bl_cnt_r; always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)c3_p1_rd_data_r <= 256'd0;else if(c3_p1_rd_en == 1'b1) c3_p1_rd_data_r <= c3_p1_rd_data;elsec3_p1_rd_data_r <= c3_p1_rd_data_r;always @(*)if(c3_p1_rd_en == 1'b1)usb_data <= c3_p1_rd_data[255:224];else case(data_cnt_rd)0 : usb_data <= c3_p1_rd_data_r[255:224]; 1 : usb_data <= c3_p1_rd_data_r[223:192]; 2 : usb_data <= c3_p1_rd_data_r[191:160]; 3 : usb_data <= c3_p1_rd_data_r[159:128]; 4 : usb_data <= c3_p1_rd_data_r[127:96]; 5 : usb_data <= c3_p1_rd_data_r[95:64]; 6 : usb_data <= c3_p1_rd_data_r[63:32]; 7 : usb_data <= c3_p1_rd_data_r[31:0]; default : usb_data <= 32'd0;endcaseendmodule
gbit_top模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : gbit_top.v
// Create Time : 2020-03-17 09:43:00
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module gbit_top(//System Interfacesinput clk_50m ,input clk_125m ,input rst_n ,//Gigbit Interfacesoutput reg phy_rst_n ,input [ 3:0] rx_data ,input rx_ctrl ,input rx_clk ,//Communication Interfacesoutput wire [ 7:0] image_data ,output wire image_data_en ,output wire [31:0] rlst ,output wire rlst_flag
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/reg [20:0] phy_rst_cnt ;
wire rx_clk_90 ;
//iddr_ctrl_inst
wire [ 7:0] gb_rx_data ;
wire gb_rx_data_en ;
wire gb_rx_data_err ;
//run_clk_ctrl_inst
wire [ 7:0] dout_o ;
wire dout_en ;
wire [12:0] latch_max ;
//image_ctrl_inst//========================================================================================\
//************** Main Code **********************************
//========================================================================================/always @(posedge clk_50m or negedge rst_n)if(rst_n == 1'b0)phy_rst_cnt <= 21'd0;else if(phy_rst_cnt[20] == 1'b0)phy_rst_cnt <= phy_rst_cnt + 1'b1;elsephy_rst_cnt <= phy_rst_cnt;always @(posedge clk_50m or negedge rst_n)if(rst_n == 1'b0)phy_rst_n <= 1'b0;else if(phy_rst_cnt[20] == 1'b1)phy_rst_n <= 1'b1;elsephy_rst_n <= phy_rst_n;clk_wiz_1 clk_wiz_1_inst(// Clock out ports.clk_out1 (rx_clk_90 ), // output clk_out1// Clock in ports.clk_in1 (rx_clk )
); //clk_wiz_1 clk_wiz_1_inst(
// // Clock out ports
// .clk_out1 (clk_50m ), // output clk_out1
// .clk_out2 (clk_125m ), // output clk_out2
// // Status and control signals
// .reset (~rst_n ), // input reset
// .locked (locked ), // output locked
// // Clock in ports
// .clk_in1 (sclk )
//); iddr_ctrl iddr_ctrl_inst(//System Interfaces.rst_n (rst_n ),//Gigabit Interfaces.rx_data (rx_data ),.rx_ctrl (rx_ctrl ),.rx_clk (rx_clk_90 ),//Communication Interfaces.gb_rx_data (gb_rx_data ),.gb_rx_data_en (gb_rx_data_en ), .gb_rx_data_err (gb_rx_data_err )
);run_clk_ctrl run_clk_ctrl_inst(//System Interfaces.sclk (clk_125m ),.rst_n (rst_n ),//Gigbit Interfaces.rx_data (gb_rx_data ),.rx_en (gb_rx_data_en ),.rx_clk (rx_clk_90 ),//Communication Interfaces.latch_max (latch_max ),.dout_o (dout_o ),.dout_en (dout_en )
);image_ctrl image_ctrl_inst(//System Interfaces.sclk (clk_125m ),.rst_n (rst_n ),//Gigbit Interfaces.dout_o (dout_o ),.dout_en (dout_en ),//Communication Interfaces.latch_max (latch_max ),.image_data (image_data ),.image_data_en (image_data_en ),.rlst (rlst ),.rlst_flag (rlst_flag )
);//========================================================================================\
//******************************* Debug **********************************
//========================================================================================/
ila_2 ila_2_inst (.clk (clk_125m ), // input wire clk.probe0 (gb_rx_data ), // input wire [7:0] probe0 .probe1 (gb_rx_data_en ), // input wire [0:0] probe1 .probe2 (gb_rx_data_err ), // input wire [0:0] probe2 .probe3 (image_data ), // input wire [7:0] probe3 .probe4 (image_data_en ), // input wire [0:0] probe4 .probe5 (rlst ), // input wire [31:0] probe5 .probe6 (rlst_flag ) // input wire [0:0] probe6
);endmodule
iddr_ctrl模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : iddr_ctrl.v
// Create Time : 2020-03-17 09:21:20
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module iddr_ctrl(//System Interfacesinput rst_n ,//Gigabit Interfacesinput [ 3:0] rx_data ,input rx_ctrl ,input rx_clk ,//Communication Interfacesoutput reg [ 7:0] gb_rx_data ,output reg gb_rx_data_en , output reg gb_rx_data_err
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
wire [ 7:0] data ;
wire data_en ;
wire data_err ; //========================================================================================\
//************** Main Code **********************************
//========================================================================================/
IDDR #(.DDR_CLK_EDGE ("OPPOSITE_EDGE" ), // "OPPOSITE_EDGE", "SAME_EDGE" // or "SAME_EDGE_PIPELINED" .INIT_Q1 (1'b0 ), // Initial value of Q1: 1'b0 or 1'b1.INIT_Q2 (1'b0 ), // Initial value of Q2: 1'b0 or 1'b1.SRTYPE ("SYNC" ) // Set/Reset type: "SYNC" or "ASYNC"
) IDDR_ctrl (.Q1 (data_en ), // 1-bit output for positive edge of clock.Q2 (data_err ), // 1-bit output for negative edge of clock.C (rx_clk ), // 1-bit clock input.CE (1'b1 ), // 1-bit clock enable input.D (rx_ctrl ), // 1-bit DDR data input.R (~rst_n ), // 1-bit reset.S (1'b0 ) // 1-bit set);genvar i;generatefor (i = 0; i < 4; i = i+1) beginIDDR #(.DDR_CLK_EDGE ("OPPOSITE_EDGE" ), // "OPPOSITE_EDGE", "SAME_EDGE" // or "SAME_EDGE_PIPELINED" .INIT_Q1 (1'b0 ), // Initial value of Q1: 1'b0 or 1'b1.INIT_Q2 (1'b0 ), // Initial value of Q2: 1'b0 or 1'b1.SRTYPE ("SYNC" ) // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_ctrl (.Q1 (data[i] ), // 1-bit output for positive edge of clock.Q2 (data[4+i] ), // 1-bit output for negative edge of clock.C (rx_clk ), // 1-bit clock input.CE (1'b1 ), // 1-bit clock enable input.D (rx_data[i] ), // 1-bit DDR data input.R (~rst_n ), // 1-bit reset.S (1'b0 ) // 1-bit set);endendgeneratealways @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)gb_rx_data <= 8'd0;else gb_rx_data <= data;always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)gb_rx_data_err <= 1'b0;else gb_rx_data_err <= data_err;always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)gb_rx_data_en <= 1'b0;elsegb_rx_data_en <= data_en;endmodule
run_clk_ctrl模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : run_clk_ctrl.v
// Create Time : 2020-03-17 21:57:11
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module run_clk_ctrl(//System Interfacesinput sclk ,input rst_n ,//Gigbit Interfacesinput [ 7:0] rx_data ,input rx_en ,input rx_clk ,//Communication Interfacesoutput reg [12:0] latch_max ,output wire [ 7:0] dout_o ,output reg dout_en
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [ 2:0] cnt_55 ;
reg mac_en ;
reg mac_en_dly ;
reg [ 7:0] rx_data_dly ;
reg [12:0] rx_cnt ;
reg latch_flag ;
wire rx_clr_flag ;reg mac_en_r1 ;
reg mac_en_r2 ;
reg mac_en_r3 ;
reg mac_en_r4 ;
reg mac_en_r5 ;
reg mac_en_r6 ;
reg mac_en_r7 ;
reg rd_start ;
reg rd_en ;
reg [12:0] rd_cnt ;wire full ;
wire empty ;
wire [ 9:0] rd_data_count ;
wire [ 9:0] wr_data_count ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign rx_clr_flag = mac_en && ~mac_en_dly;
always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)cnt_55 <= 3'd0;else if(mac_en == 1'b0 && rx_data == 8'h55 && rx_en == 1'b1)cnt_55 <= cnt_55 + 1'b1;else if(mac_en == 1'b0 && rx_data == 8'hd5 && rx_en == 1'b1) cnt_55 <= 3'd0;else cnt_55 <= 3'd0;always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)mac_en <= 1'b0;else if(cnt_55 == 3'd7 && rx_data == 8'hd5 && rx_en == 1'b1) mac_en <= 1'b1;else if(rx_en == 1'b0)mac_en <= 1'b0;always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)mac_en_dly <= 1'b0;else if(rx_en == 1'b0)mac_en_dly <= 1'b0;else if(mac_en == 1'b1)mac_en_dly <= 1'b1; else mac_en_dly <= mac_en_dly;always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)rx_data_dly <= 8'd0;elserx_data_dly <= rx_data;always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)rx_cnt <= 13'd0; else if(rx_clr_flag == 1'b1)rx_cnt <= 13'd0;else if(mac_en_dly == 1'b1)rx_cnt <= rx_cnt + 1'b1;elserx_cnt <= 13'd0;always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)latch_flag <= 1'b0; else if(mac_en_dly == 1'b1 && rx_en == 1'b0)latch_flag <= 1'b1;elselatch_flag <= 1'b0; always @(posedge rx_clk or negedge rst_n)if(rst_n == 1'b0)latch_max <= 13'h1fff;else if(rx_clr_flag == 1'b1)latch_max <= 13'h1fff;else if(latch_flag == 1'b1)latch_max <= rx_cnt - 1'b1;elselatch_max <= latch_max;always @(posedge sclk)beginmac_en_r1 <= mac_en_dly;mac_en_r2 <= mac_en_r1;mac_en_r3 <= mac_en_r2;mac_en_r4 <= mac_en_r3;mac_en_r5 <= mac_en_r4;mac_en_r6 <= mac_en_r5;mac_en_r7 <= mac_en_r6;
endalways @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rd_start <= 1'b0;else if(mac_en_r7 == 1'b0 && mac_en_r6 == 1'b1)rd_start <= 1'b1;elserd_start <= 1'b0;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rd_en <= 1'b0;else if(rd_start == 1'b1)rd_en <= 1'b1;else if(mac_en_r5 == 1'b0 && rd_cnt == latch_max) rd_en <= 1'b0;elserd_en <= rd_en;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rd_cnt <= 13'd0;else if(mac_en_r5 == 1'b0 && rd_cnt == latch_max)rd_cnt <= 13'd0;else if(rd_en == 1'b1)rd_cnt <= rd_cnt + 1'b1;elserd_cnt <= rd_cnt;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)dout_en <= 1'b0;else dout_en <= rd_en;fifo_generator_3 fifo_generator_3_inst(.rst (1'b0 ), // input wire rst.wr_clk (rx_clk ), // input wire wr_clk.rd_clk (sclk ), // input wire rd_clk.din (rx_data_dly ), // input wire [7 : 0] din.wr_en (mac_en_dly ), // input wire wr_en.rd_en (rd_en ), // input wire rd_en.dout (dout_o ), // output wire [7 : 0] dout.full (full ), // output wire full.empty (empty ), // output wire empty.rd_data_count (rd_data_count ), // output wire [9 : 0] rd_data_count.wr_data_count (wr_data_count ) // output wire [9 : 0] wr_data_count
); //========================================================================================\
//******************************* Debug **********************************
//========================================================================================/endmodule
image_ctrl模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : image_ctrl.v
// Create Time : 2020-03-18 10:51:41
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module image_ctrl(//System Interfacesinput sclk ,input rst_n ,//Gigbit Interfacesinput [ 7:0] dout_o ,input dout_en ,//Communication Interfacesinput [12:0] latch_max ,output reg [ 7:0] image_data ,output reg image_data_en ,output wire [31:0] rlst ,output reg rlst_flag
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [12:0] rd_cnt ;
reg [ 2:0] cnt_aa ;
reg width_en ;
reg height_en ;
reg height_en_r ;
reg [15:0] width_data ;
reg [15:0] height_data ;
reg start_image_en ;
reg image_en ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rd_cnt <= 13'd0;else if(dout_en == 1'b1 && rd_cnt == latch_max) rd_cnt <= 13'd0;else if(dout_en == 1'b1)rd_cnt <= rd_cnt + 1'b1;elserd_cnt <= rd_cnt;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)cnt_aa <= 3'd0;else if(rd_cnt == 'd49 && (dout_o == 8'hfa || dout_o == 8'hf5 || dout_o == 8'hf6))cnt_aa <= 3'd0;else if(rd_cnt >= 'd42 && rd_cnt <= 'd48 && dout_o == 8'haa)cnt_aa <= cnt_aa + 1'b1;elsecnt_aa <= 3'd0;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)width_en <= 1'b0; else if(rd_cnt == 'd49 && dout_o == 8'hfa)width_en <= 1'b1;else if(rd_cnt == 'd51)width_en <= 1'b0;elsewidth_en <= width_en;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)height_en <= 1'b0;else if(rd_cnt == 'd51 && width_en == 1'b1)height_en <= 1'b1;else if(rd_cnt == 'd53)height_en <= 1'b0;elseheight_en <= height_en;always @(posedge sclk)height_en_r <= height_en;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)width_data <= 16'd0;else if(width_en == 1'b1)width_data <= {width_data[7:0],dout_o};elsewidth_data <= width_data;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)height_data <= 16'd0;else if(height_en == 1'b1)height_data <= {height_data[7:0],dout_o};elseheight_data <= height_data;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rlst_flag <= 1'b0;else if(height_en_r == 1'b1 && rd_cnt == 'd54)rlst_flag <= 1'b1;elserlst_flag <= 1'b0;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)start_image_en <= 1'b0;else if(rd_cnt == 'd49 && (dout_o == 8'hf5 || dout_o == 8'hf6)) start_image_en <= 1'b1;else if(rd_cnt == 'd51)start_image_en <= 1'b0;elsestart_image_en <= start_image_en;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)image_en <= 1'b0;else if(rd_cnt == 'd51 && start_image_en == 1'b1)image_en <= 1'b1;else if(rd_cnt == latch_max - 4)image_en <= 1'b0;elseimage_en <= image_en;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)image_data <= 8'd0;else if(image_en == 1'b1)image_data <= dout_o;elseimage_data <= 8'd0;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)image_data_en <= 1'b0;else image_data_en <= image_en; mult_gen_0 mult_gen_0_inst (.CLK (sclk ), // input wire CLK.A (width_data ), // input wire [7 : 0] A.B (height_data ), // input wire [7 : 0] B.P (rlst ) // output wire [15 : 0] P
); //========================================================================================\
//******************************* Debug **********************************
//========================================================================================/ila_1 ila_1_inst (.clk (sclk ), // input wire clk.probe0 (dout_o ), // input wire [7:0] probe0 .probe1 (dout_en ), // input wire [0:0] probe1 .probe2 (rd_cnt ), // input wire [12:0] probe2 .probe3 (cnt_aa ), // input wire [2:0] probe3 .probe4 (width_en ), // input wire [0:0] probe4 .probe5 (height_en ), // input wire [0:0] probe5 .probe6 (height_en_r ), // input wire [0:0] probe6 .probe7 (start_image_en ), // input wire [0:0] probe7 .probe8 (image_en ), // input wire [0:0] probe8 .probe9 (image_data ), // input wire [7:0] probe9 .probe10 (image_data_en ) // input wire [0:0] probe10
);endmodule
conver_bit模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : conver_bit.v
// Create Time : 2020-03-18 17:39:59
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module conver_bit(//System Interfacesinput sclk ,input rst_n ,//Gigbit Interfacesinput [ 7:0] image_data ,input image_data_en ,//Communication Interfacesoutput wire [31:0] rgb_data ,output reg rgb_data_en
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [ 1:0] image_cnt ;
reg [23:0] data ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign rgb_data = {8'h00,data};always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)image_cnt <= 2'b0;else if(image_cnt == 2'd2 && image_data_en == 1'b1)image_cnt <= 2'd0;else if(image_data_en == 1'b1)image_cnt <= image_cnt + 1'b1;elseimage_cnt <= image_cnt;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)data <= 24'd0;else if(image_data_en == 1'b1)data <= {data[15:0],image_data};elsedata <= data;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rgb_data_en <= 1'b0;else if(image_cnt == 2'd2 && image_data_en == 1'b1)rgb_data_en <= 1'b1;elsergb_data_en <= 1'b0;endmodule
usb3_drive模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : usb3_drive.v
// Create Time : 2020-03-03 10:36:21
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module usb3_drive(input rst_n ,output wire USBSS_EN ,input sclk ,inout [15:0] data ,inout [ 1:0] be ,input rxf_n ,input txf_n ,output reg oe_n ,output reg wr_n ,output wire siwu_n ,output reg rd_n ,output wire wakeup ,output wire [ 1:0] gpio ,//Communication Interfacesinput [15:0] data_in ,output wire data_req
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter IDLE = 4'b0001 ;
parameter JUDGE = 4'b0010 ;
parameter READ = 4'b0100 ;
parameter WRITE = 4'b1000 ;reg [ 3:0] state ;
wire fifo_wr ;
wire [15:0] data_wr ;//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign USBSS_EN = 1'b1;
assign wakeup = 1'b1;
assign siwu_n = 1'b0;
assign gpio = 2'b00;
assign fifo_wr = (rd_n == 1'b0) && (rxf_n == 1'b0);
assign data_wr = (state == READ) ? data : 16'hzzzz;
assign data_req = ~((wr_n == 1'b0) && (txf_n == 1'b0));
assign data = (data_req == 1'b0) ? data_in : 16'hzzzz;
assign be = (state == WRITE) ? 2'b11 : 2'bzz;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)state <= IDLE;else case(state)IDLE : state <= JUDGE;JUDGE : if(rxf_n == 1'b0)state <= READ;else if(txf_n == 1'b0)state <= WRITE;elsestate <= JUDGE; WRITE : if(txf_n == 1'b1)state <= JUDGE;elsestate <= WRITE; READ : if(rxf_n == 1'b1)state <= JUDGE;elsestate <= READ;default : state <= IDLE;endcasealways @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)oe_n <= 1'b1; else if(state == READ && rxf_n == 1'b1)oe_n <= 1'b1;else if(state == READ)oe_n <= 1'b0;elseoe_n <= oe_n;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)rd_n <= 1'b1;else if(state == READ && rxf_n == 1'b1)rd_n <= 1'b1;else if(state == READ && oe_n == 1'b0)rd_n <= 1'b0;elserd_n <= rd_n;always @(posedge sclk or negedge rst_n)if(rst_n == 1'b0)wr_n <= 1'b1;else if(state == WRITE && txf_n == 1'b1)wr_n <= 1'b1;else if(state == WRITE)wr_n <= 1'b0;elsewr_n <= wr_n;//========================================================================================\
//******************************* Debug **********************************
//========================================================================================/ila_0 ila_0_inst (.clk (sclk ), // input wire clk.probe0 (USBSS_EN ), // input wire [0:0] probe0 .probe1 (data_in ), // input wire [15:0] probe1 .probe2 (2'd1 ), // input wire [1:0] probe2 .probe3 (rxf_n ), // input wire [0:0] probe3 .probe4 (txf_n ), // input wire [0:0] probe4 .probe5 (oe_n ), // input wire [0:0] probe5 .probe6 (wr_n ), // input wire [0:0] probe6 .probe7 (siwu_n ), // input wire [0:0] probe7 .probe8 (rd_n ), // input wire [0:0] probe8 .probe9 (wakeup ), // input wire [0:0] probe9 .probe10 (gpio ) // input wire [1:0] probe10
);endmodule
oddr_ctrl模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : oddr_ctrl.v
// Create Time : 2020-03-17 09:56:53
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module oddr_ctrl(//System Interfacesinput rst_n ,//Gigbit Interfacesoutput wire [ 3:0] tx_data ,output wire tx_data_ctrl ,output wire tx_clk ,//Communication Interfacesinput [ 7:0] gb_tx_data ,input gb_tx_data_en ,input gb_tx_data_err ,input gb_tx_clk
);//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================///========================================================================================\
//************** Main Code **********************************
//========================================================================================/ODDR #(.DDR_CLK_EDGE ("SAME_EDGE" ), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT (1'b0 ), // Initial value of Q: 1'b0 or 1'b1.SRTYPE ("SYNC" ) // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_ctrl (.Q (tx_data_ctrl ), // 1-bit DDR output.C (gb_tx_clk ), // 1-bit clock input.CE (1'b1 ), // 1-bit clock enable input.D1 (gb_tx_data_en ), // 1-bit data input (positive edge).D2 (gb_tx_data_err ), // 1-bit data input (negative edge).R (~rst_n ), // 1-bit reset.S (1'b0 ) // 1-bit set
);ODDR #(.DDR_CLK_EDGE ("SAME_EDGE" ), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT (1'b0 ), // Initial value of Q: 1'b0 or 1'b1.SRTYPE ("SYNC" ) // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_clk (.Q (tx_clk ), // 1-bit DDR output.C (gb_tx_clk ), // 1-bit clock input.CE (1'b1 ), // 1-bit clock enable input.D1 (1'b1 ), // 1-bit data input (positive edge).D2 (1'b0 ), // 1-bit data input (negative edge).R (~rst_n ), // 1-bit reset.S (1'b0 ) // 1-bit set
);genvar i;generatefor (i = 0; i < 4; i = i+1) beginODDR #(.DDR_CLK_EDGE ("SAME_EDGE" ), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT (1'b0 ), // Initial value of Q: 1'b0 or 1'b1.SRTYPE ("SYNC" ) // Set/Reset type: "SYNC" or "ASYNC" ) ODDR_data (.Q (tx_data[i] ), // 1-bit DDR output.C (gb_tx_clk ), // 1-bit clock input.CE (1'b1 ), // 1-bit clock enable input.D1 (gb_tx_data[i] ), // 1-bit data input (positive edge).D2 (gb_tx_data[4+i] ), // 1-bit data input (negative edge).R (~rst_n ), // 1-bit reset.S (1'b0 ) // 1-bit set);endendgenerate
endmodule
测试模块的代码
`timescale 1ns / 1ps
`define CLOCK 20// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : tb_ddr3.v
// Create Time : 2020-02-27 23:36:46
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************module tb_ddr3;parameter DQ_WIDTH = 32;
localparam MEMORY_WIDTH = 16;
localparam NUM_COMP = DQ_WIDTH/MEMORY_WIDTH ;reg sclk ;
reg rst_n ;wire [13:0] ddr3_addr ;
wire [ 2:0] ddr3_ba ;
wire ddr3_cas_n ;
wire ddr3_ck_n ;
wire ddr3_ck_p ;
wire ddr3_cke ;
wire ddr3_ras_n ;
wire ddr3_reset_n ;
wire ddr3_we_n ;
wire [31:0] ddr3_dq ;
wire [ 3:0] ddr3_dqs_n ;
wire [ 3:0] ddr3_dqs_p ;
wire init_calib_complete ;
wire [ 0:0] ddr3_cs_n ;
wire [ 3:0] ddr3_dm ;
wire [ 0:0] ddr3_odt ;reg USB_clk ;
reg txf_n ;
wire [15:0] data ;wire phy_rst_n ;
wire [ 3:0] tx_data ;
wire tx_ctrl ;
wire tx_clk ;reg [ 7:0] gb_tx_data ;
reg gb_tx_data_en ;
reg gb_tx_clk ;
reg [ 7:0] send_data = 0 ;
reg err_flag ;
reg cnt ;initial beginsclk = 1'b0;rst_n <= 1'b0;#(100*`CLOCK);rst_n <= 1'b1;
end
always #(`CLOCK/2) sclk = ~sclk;
initial begingb_tx_clk = 1'b0;
end
always #(4) gb_tx_clk = ~gb_tx_clk;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)cnt <= 2'd0;else if(top_inst.data_req == 1'b0)cnt <= cnt + 1'b1;elsecnt <= cnt;always @(posedge USB_clk or negedge rst_n)if(rst_n == 1'b0)err_flag <= 1'b0;else if(top_inst.data_req == 1'b0 && data[15:8] != data[7:0] + 1 && cnt == 1'b0)err_flag <= 1'b1;elseerr_flag <= 1'b0;initial beginUSB_clk = 1'b0;
end
always #(10/2) USB_clk = ~USB_clk;initial begintxf_n <= 1'b1;#(500000);txf_n <= 1'b0;
endinitial begin#(200000);image_top();repeat(10000) beginimage_data();#(80);end
endtask image_top;integer i ;begin i = 0;for(i = 0;i < 1000;i = i+1)begin@(posedge gb_tx_clk);gb_tx_data_en <= 1'b1;if(i < 7)gb_tx_data <= 8'h55;else if(i == 7)gb_tx_data <= 8'hd5;else if(i >= 50 && i<= 56)gb_tx_data <= 8'haa;else if(i == 57)gb_tx_data <= 8'hfa;else if(i == 58)gb_tx_data <= 8'h03;else if(i == 58)gb_tx_data <= 8'hff;else if(i == 58)gb_tx_data <= 8'h02;else if(i == 58)gb_tx_data <= 8'hff;else gb_tx_data <= i; end@(posedge gb_tx_clk);gb_tx_data <= 8'h0;gb_tx_data_en <= 1'b0;end
endtasktask image_data;integer i ;begin i = 0;for(i = 0;i < 900;i = i+1)begin@(posedge gb_tx_clk);gb_tx_data_en <= 1'b1;if(i < 7)gb_tx_data <= 8'h55;else if(i == 7)gb_tx_data <= 8'hd5;else if(i >= 50 && i<= 56)gb_tx_data <= 8'haa;else if(i == 57)gb_tx_data <= 8'hf5;else if (i >= 60 ) begingb_tx_data <= send_data;send_data <= send_data + 1'b1;if(send_data == 180)send_data <= 0;end end@(posedge gb_tx_clk);gb_tx_data <= 8'h0;gb_tx_data_en <= 1'b0;end
endtaskoddr_ctrl oddr_ctrl_inst(//System Interfaces.rst_n (rst_n ),//Gigbit Interfaces.tx_data (tx_data ),.tx_data_ctrl (tx_ctrl ),.tx_clk (tx_clk ),//Communication Interfaces.gb_tx_data (gb_tx_data ),.gb_tx_data_en (gb_tx_data_en ),.gb_tx_data_err (1'b0 ),.gb_tx_clk (gb_tx_clk )
);top top_inst(//System Interfaces.sclk (sclk ),.rst_n (rst_n ),//DDR3 Interfaces .ddr3_addr (ddr3_addr ),.ddr3_ba (ddr3_ba ),.ddr3_cas_n (ddr3_cas_n ),.ddr3_ck_n (ddr3_ck_n ),.ddr3_ck_p (ddr3_ck_p ),.ddr3_cke (ddr3_cke ),.ddr3_ras_n (ddr3_ras_n ),.ddr3_reset_n (ddr3_reset_n ),.ddr3_we_n (ddr3_we_n ),.ddr3_dq (ddr3_dq ),.ddr3_dqs_n (ddr3_dqs_n ),.ddr3_dqs_p (ddr3_dqs_p ),.ddr3_cs_n (ddr3_cs_n ),.ddr3_dm (ddr3_dm ),.ddr3_odt (ddr3_odt ),//Gigbit Interfaces.phy_rst_n (phy_rst_n ),.rx_data (tx_data ),.rx_ctrl (tx_ctrl ),.rx_clk (tx_clk ),.USBSS_EN ( ),.USB_clk (USB_clk ),.data (data ),.be ( ),.rxf_n (1'b1 ),.txf_n (txf_n ),.oe_n ( ),.wr_n ( ),.siwu_n ( ),.rd_n ( ),.wakeup ( ),.gpio ( ) );genvar i;for (i = 0; i < NUM_COMP; i = i + 1) begin: gen_memddr3_model u_comp_ddr3(.rst_n (ddr3_reset_n ),.ck (ddr3_ck_p ),.ck_n (ddr3_ck_n ),.cke (ddr3_cke ),.cs_n (ddr3_cs_n ),.ras_n (ddr3_ras_n ),.cas_n (ddr3_cas_n ),.we_n (ddr3_we_n ),.dm_tdqs (ddr3_dm[(2*(i+1)-1):(2*i)] ),.ba (ddr3_ba ),.addr (ddr3_addr ),.dq (ddr3_dq[16*(i+1)-1:16*(i)] ),.dqs (ddr3_dqs_p[(2*(i+1)-1):(2*i)] ),.dqs_n (ddr3_dqs_n[(2*(i+1)-1):(2*i)] ),.tdqs_n ( ),.odt (ddr3_odt ));endendmodule
DDR3仿真模型的代码我们这里不在给出,需要的进群自取或者从生成的IP中获得。
测试结果
从上面上位机显示的图形可以看出我们的设计是正确的。
总结
创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
基于FPGA的千兆以太网的实现(1)相关推荐
- 基于FPGA的千兆以太网设计
今天给大侠带来基于FPGA的千兆以太网设计,话不多说,上货. 一.设计概述 由于设计比较复杂,本篇带来设计流程以及设计思路,仅供各位大侠参考. 本篇通过管理数据输入输出MDIO配置PHY寄存器,使其工 ...
- 简谈基于FPGA的千兆以太网设计
简谈基于FPGA的千兆以太网设计 今天给大侠带来简谈基于FPGA的千兆以太网设计,话不多说,上货. 今天我们来简单的聊一聊以太网,以太网在FPGA学习中属于比较高级的内容了,有些大侠肯定会感觉以太网学 ...
- 【转】简谈基于FPGA的千兆以太网
原文地址: http://blog.chinaaet.com/luhui/p/5100052903 大家好,又到了学习时间了,学习使人快乐.今天我们来简单的聊一聊以太网,以太网在FPGA学习中属于比较 ...
- 简谈基于FPGA的千兆以太网
当今,随着互联网技术的迅速发展,采用以太网实现数据采集和控制方面的应用,成为了电子系统设计的热点.以太网具有价格低廉.稳定可靠.传输速度快.传输距离远等特点,以太网技术发展成熟,具有很高的性价比.采用 ...
- 【千兆以太网】基于FPGA的千兆以太网MIMO通信系统开发
1.千兆以太网技术 千兆以太网技术简介 以太网技术是当今应用广泛的网络技术,千兆以太网技术继承了以往以太网技术的许多优点,同时又具有许多新的特性,例如传输介质包括光纤和铜缆,使用8B/10B的编解码方 ...
- 基于FPGA的万兆以太网UDP/IP协议栈讲解
基于FPGA的UDP/IP协议栈 1 udp协议分析 1.1 udp介绍 UDP即User Datagram Protocol,用户数据报协议,还有一个耳熟能详的叫做TCP(Transmission ...
- 基于FPGA的数据采集、通讯和存储系统设计(即FPGA+RTL8211千兆以太网+SD卡存储+RTC+Uart+AD7606数模转换+电流放大采集等硬件设计及程序验证)
本文主要介绍了学生期间自己做的一个小项目,便于学习初期对fpga的整体把握,涉及了很多常见.常用.常考和面试常问的知识点. 可以作为入门后的拓展学习和应对一些找工作的项目面试. 下面对硬件及软件代码进 ...
- 一个udp用户数据报的数据字段为8192_基于FPGA的千兆网UDP通信分析
千兆网UDP通信 以太网帧格式 图8‑12 以太网帧格式 表8‑5 以太网帧格式说明 UDP协议分析 为什么UDP协议在FPGA实现时很受欢迎,最主要一个原因就是简单,简答到什么地步呢?UDP协议只是 ...
- 基于zynq的千兆网udp项目_基于FPGA的千兆网UDP通信分析
千兆网UDP通信 以太网帧格式 图8‑12 以太网帧格式 表8‑5 以太网帧格式说明 UDP协议分析 为什么UDP协议在FPGA实现时很受欢迎,最主要一个原因就是简单,简答到什么地步呢?UDP协议只是 ...
最新文章
- 如何从异步调用返回响应?
- 这么说线程生命周期是不是简单了点?
- 翻译:Google大表(BigTable)
- Day_03-函数和模块的使用
- oracle命令行登录sy,oracle里常用命令
- 想创业怕失败就不要轻易选择去创业
- 织物印花疵点专用术语大全
- OpenCV-膨胀cv::dilate
- Linux: kill
- 包级别的 TCP/UDP 负载均衡和NAT(Network Address Translate)
- 窥探PTAM之模板搜索
- 什么是电子商务——百科
- WPS文档如何删除空白页
- 暑假D16 T3 密道(数位DP? 打表找规律)
- 房屋安全鉴定现场检测主要检测哪些内容
- WebApp最佳实践用户体验篇之如何针对多种屏幕尺寸设计合理的移动应用
- springboot中使用poi-tl导出word(包含表格合并单元格)实例
- 终端运行npm install @tinymce/tinymce-vue -S报错的解决办法
- 自媒体怎么赚钱?自媒体的5大变现方式!
- 学习C语言常用的几个网站
热门文章
- 论文阅读笔记:Deep Chain HDRI: Reconstructing a HDR Image from a Single LDR Image
- 2023年甘肃省职业院校技能大赛高职组“信息安全管理与评估”赛项样卷D
- 【2022刷题】心理阴影面积
- 收藏:PPT素材网站等大全
- SpringMvc方法获取和返回参数源码探究
- android水果界面设计,一组色彩鲜艳的水果电商APP界面设计鉴赏
- 制作ESX6.0 U盘启动器
- C++ 反反调试(PEB)
- UI高级 一一 画板
- gotoprint函数在c语言,C语言之goto浅析