概述
FPGA发送图片到PC机并用MATLAB显示
- 项目简述
- UDP组包时序及实现
- UDP组包时序
- UDP组包代码设计
- 校验码模块的设计及实现
- 检验码模块时序图的设计
- 检验码模块的代码设计
- CRC模块的设计及代码实现
- 整个项目工程代码
- 实验结果
- 总结
项目简述
本次实验我们将利用我们千兆网的第一个项目继续学习,在千兆网接收的基础上再加上千兆网发送模块。为了方便大家的学习,在前面我们已经讲解了UDP与IP包的检验码、CRC检验码、MATLAB读取txt文件显示图片。通过本次实验我们可以学习到:USB3.0、千兆网接收、千兆网发送、DDR3缓存数据。本次实验所用到的软硬件环境如下:
1、VIVADO 2019.1软件开发环境
2、米联客MA7035FA(100T)开发板
3、V3学院千兆网发送软件
4、MATLAB
5、米联客USB视频显示上位机
最终图片接收出现了一点瑕疵,但是我们认为是上位机的原因,并不是FPGA方面的原因。因为博主不会编写新的上位机,所以这里就忽略了这些瑕疵。整个项目的流程图如下:
UDP组包时序及实现
UDP组包时序
我们前面已经讲解了UDP协议的数据流中每一位所代表的意义,我们只需要按照UDP协议的要求进行组包即可,但是这里由于UDP的校验与UDP的数据有关,所以我们先将IP与UDP的检验码赋值为0,然后在后面的模块中专门计算检验码,再添加到数据流中,并且由单独的CRC模块进行计算。所以这里我们首先给出UDP协议组包模块的时序图,如下:
UDP组包代码设计
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : tx_gen_frame.v
// Create Time : 2020-04-01 12:48:28
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module tx_geb_frame(
input sclk ,
input rst_n ,
input Tx_start_en ,
input [10:0] fifo3_rd_count ,
input [127:0]fifo3_read_data ,
output reg read_fifo3_rd_en ,
output reg tx_end_flag ,
output reg [15:0] UDP_len ,
output reg [ 7:0] po_gen_data ,
output reg po_gen_data_en
);
//========================================================================================
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter IMG_W_DATA = 16'H03FF ;
parameter IMG_H_DTAT = 16'H02FF ;
parameter MAC_S0 = 8'H00 ;
parameter MAC_S1 = 8'H0a ;
parameter MAC_S2 = 8'H35 ;
parameter MAC_S3 = 8'H00 ;
parameter MAC_S4 = 8'H01 ;
parameter MAC_S5 = 8'H02 ;
parameter H_IP_LEN = 16'H011C ;
parameter rgb1_IP_LEN = 16'h04d6 ;
parameter rgb3_IP_LEN = 16'h02c6 ;
parameter H_UDP_LEN = 16'H0108 ;
parameter rgb1_UDP_LEN = 16'H04c2 ;
parameter rgb3_UDP_LEN = 16'H02b2 ;
parameter IP_S0 = 8'Hc0 ;
parameter IP_S1 = 8'Ha8 ;
parameter IP_S2 = 8'H00 ;
parameter IP_S3 = 8'H01 ;
parameter IP_D0 = 8'Hc0 ;
parameter IP_D1 = 8'Ha8 ;
parameter IP_D2 = 8'H00 ;
parameter IP_D3 = 8'H02 ;
parameter P_S0 = 8'Hf0 ;
parameter P_S1 = 8'H00 ;
parameter P_D0 = 8'Hf0 ;
parameter P_D1 = 8'H01 ;
parameter WAIT_MAX = 16 ;
reg [15:0] IP_len ;
reg shift_en ;
reg [ 3:0] shift_cnt ;
reg Head_cnt_en ;
reg [ 8:0] head_cnt ;
reg [ 7:0] Head_data ;
reg Head_en ;
reg [16:0] wait_cnt ;
reg wait_en ;
reg [ 7:0] PR ;
reg Gen_image_cnt_en ;
reg [10:0] Gen_image_cnt ;
reg [ 7:0] Gen_image_data ;
reg Gen_image__en ;
reg [ 1:0] Pik_gen_cnt ;
reg [15:0] img_row_cnt ;
//========================================================================================
//************** Main Code **********************************
//========================================================================================/
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Head_cnt_en <= 1'b0;
else if(head_cnt == 305)
Head_cnt_en <= 1'b0;
else if(Tx_start_en == 1'b1 && fifo3_rd_count >= 256 && head_cnt == 10'd0)
Head_cnt_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
head_cnt <= 0;
else if(Head_cnt_en == 1'b1)
head_cnt <= head_cnt + 1'b1;
else if(tx_end_flag==1)
head_cnt <= 0;
//ip_len
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
IP_len <= 16'h0;
else if(Head_cnt_en == 1'b1)
IP_len <= H_IP_LEN;
else if(Pik_gen_cnt < 2)
IP_len <= rgb1_IP_LEN;
else if(Pik_gen_cnt == 2)
IP_len <= rgb3_IP_LEN;
//udp_len
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
UDP_len <= 16'h0;
else if(Head_cnt_en == 1'b1)
UDP_len <= H_UDP_LEN;
else if(Pik_gen_cnt < 2)
UDP_len <= rgb1_UDP_LEN;
else if(Pik_gen_cnt==2)
UDP_len <= rgb3_UDP_LEN ;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Head_data <= 8'hdd;
else case (head_cnt)
0,1,2,3,4,5,6 : Head_data <= 8'h55;
7 : Head_data <= 8'hd5;
8,9,10,11,12,13 : Head_data <= 8'hff;
14 : Head_data <= MAC_S0;
15 : Head_data <= MAC_S1;
16 : Head_data <= MAC_S2;
17 : Head_data <= MAC_S3;
18 : Head_data <= MAC_S4;
19 : Head_data <= MAC_S5;
20 : Head_data <= 8'h08;
21 : Head_data <= 8'h00;
22 : Head_data <= 8'h45;
23 : Head_data <= 8'h00;
24 : Head_data <= IP_len[15:8] ;
25 : Head_data <= IP_len[7:0] ;
26,27 : Head_data <= 8'h00;
28 : Head_data <= 8'h40;
29 : Head_data <= 8'h00;
30 : Head_data <= 8'h80;
31 : Head_data <= 8'h11;
32,33 : Head_data <= 8'h00;
34 : Head_data <= IP_S0;
35 : Head_data <= IP_S1;
36 : Head_data <= IP_S2;
37 : Head_data <= IP_S3;
38 : Head_data <= 8'hff;//IP_D0;
39 : Head_data <= 8'hff;//IP_D1;
40 : Head_data <= 8'hff;//IP_D2;
41 : Head_data <= 8'hff;//IP_D3;
42 : Head_data <= P_S0;
43 : Head_data <= P_S1;
44 : Head_data <= P_D0;
45 : Head_data <= P_D1;
46 : Head_data <= UDP_len[15:8];
47 : Head_data <= UDP_len[7:0];
48,49 : Head_data <= 8'h00;
50,51,52,53,54,55,56: Head_data <= 8'hAA;
57 : Head_data <= 8'hfa;
58 : Head_data <= IMG_W_DATA[15:8];
59 : Head_data <= IMG_W_DATA[7:0] ;
60 : Head_data <= IMG_H_DTAT[15:8];
61 : Head_data <= IMG_H_DTAT[7:0] ;
304 : Head_data <= 8'h02;
305 : Head_data <= 8'h03;
default : Head_data <= 8'h00;
endcase
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Head_en <= 1'b0;
else
Head_en <= Head_cnt_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
wait_en <= 1'b0;
else if(wait_cnt[WAIT_MAX]== 1'b1)
wait_en <= 1'b0;
else if(head_cnt == 305 || Gen_image_cnt == 1259 || (Gen_image_cnt == 731&& Pik_gen_cnt == 2'd2 && img_row_cnt != 10'd767))
wait_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
wait_cnt <= 0;
else if(wait_en == 1'b1)
wait_cnt <= wait_cnt + 1'b1;
else
wait_cnt <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image_cnt_en <= 1'b0;
else if(Gen_image_cnt == 1259 || (Gen_image_cnt == 731 && Pik_gen_cnt == 2'd2))
Gen_image_cnt_en <= 1'b0;
else if(wait_cnt[WAIT_MAX] == 1'b1)
Gen_image_cnt_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image_cnt <= 0;
else if(Gen_image_cnt_en == 1)
Gen_image_cnt <= Gen_image_cnt + 1'b1;
else
Gen_image_cnt <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Pik_gen_cnt <= 2'b0;
else if(Pik_gen_cnt == 2'd2 && Gen_image_cnt == 731)
Pik_gen_cnt <= 2'd0;
else if(Gen_image_cnt == 1259)
Pik_gen_cnt <= Pik_gen_cnt + 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
img_row_cnt <= 16'd0;
else if(img_row_cnt == 16'd768)
img_row_cnt <= 16'd0;
else if(Pik_gen_cnt == 2'd2 && Gen_image_cnt == 731)
img_row_cnt <= img_row_cnt + 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
PR <= 8'd0;
else if(img_row_cnt == 16'd767 )
PR <= 8'hf6;
else
PR <= 8'hf5;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
tx_end_flag <= 1'b0;
else if(img_row_cnt == 768 )
tx_end_flag <= 1'b1;
else
tx_end_flag <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_en <= 1'b0;
else if(Gen_image_cnt == 1259 || (Pik_gen_cnt == 2'd2 && Gen_image_cnt == 731))
shift_en <= 1'b0;
else if(Gen_image_cnt == 59)
shift_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_cnt <= 'b0;
else if(shift_en == 0)
shift_cnt <= 'b0;
else if(shift_cnt == 11)
shift_cnt <= 'b0;
else if(shift_en == 1)
shift_cnt <= shift_cnt + 1'b1 ;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
read_fifo3_rd_en <= 1'b0;
else if(shift_cnt == 11)
read_fifo3_rd_en <= 1'b1;
else
read_fifo3_rd_en <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image_data <= 8'hdd;
else if(shift_en == 1)begin
case(shift_cnt)
0: Gen_image_data <= fifo3_read_data[119:112];
1: Gen_image_data <= fifo3_read_data[127:120];
2: Gen_image_data <= fifo3_read_data[103:96];
3: Gen_image_data <= fifo3_read_data[87:80];
4: Gen_image_data <= fifo3_read_data[95:88];
5: Gen_image_data <= fifo3_read_data[71:64];
6: Gen_image_data <= fifo3_read_data[55:48];
7: Gen_image_data <= fifo3_read_data[63:56];
8: Gen_image_data <= fifo3_read_data[39:32];
9: Gen_image_data <= fifo3_read_data[23:16];
10: Gen_image_data <= fifo3_read_data[31:24];
11: Gen_image_data <= fifo3_read_data[7:0];
default:;
endcase
end
else case (Gen_image_cnt)
0,1,2,3,4,5,6 : Gen_image_data <= 8'h55;
7 : Gen_image_data <= 8'hd5;
8,9,10,11,12,13 : Gen_image_data <= 8'hff;
14 : Gen_image_data <= MAC_S0;
15 : Gen_image_data <= MAC_S1;
16 : Gen_image_data <= MAC_S2;
17 : Gen_image_data <= MAC_S3;
18 : Gen_image_data <= MAC_S4;
19 : Gen_image_data <= MAC_S5;
20 : Gen_image_data <= 8'h08;
21 : Gen_image_data <= 8'h00;
22 : Gen_image_data <= 8'h45;
23 : Gen_image_data <= 8'h00;
24 : Gen_image_data <= IP_len[15:8];
25 : Gen_image_data <= IP_len[7:0];
26,27,28,29 : Gen_image_data <= 8'h00;
30 : Gen_image_data <= 8'h80;
31 : Gen_image_data <= 8'h11;
32,33 : Gen_image_data <= 8'h00;
34 : Gen_image_data <= IP_S0;
35 : Gen_image_data <= IP_S1;
36 : Gen_image_data <= IP_S2;
37 : Gen_image_data <= IP_S3;
38,39,40,41 : Gen_image_data <= 8'hff;
42 : Gen_image_data <= P_S0;
43 : Gen_image_data <= P_S1;
44 : Gen_image_data <= P_D0;
45 : Gen_image_data <= P_D1;
46 : Gen_image_data <= UDP_len[15:8];
47 : Gen_image_data <= UDP_len[7:0];
48,49 : Gen_image_data <= 8'h00;
50,51,52,53,54,55,56 : Gen_image_data <= 8'hAA;
57 : Gen_image_data <= PR;
58 : Gen_image_data <= img_row_cnt[15:8];
59 : Gen_image_data <= img_row_cnt[7:0];
default:;
endcase
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image__en <= 1'b0;
else
Gen_image__en <= Gen_image_cnt_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
po_gen_data <= 8'b0;
else if(Head_en == 1)
po_gen_data <= Head_data;
else if(Gen_image__en == 1)
po_gen_data <= Gen_image_data;
else
po_gen_data <= 8'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
po_gen_data_en <= 1'b0;
else if(Head_en==1||Gen_image__en==1)
po_gen_data_en <= 1'b1;
else
po_gen_data_en <= 1'b0;
//========================================================================================
//******************************* Debug **********************************
//========================================================================================/
ila_1 ila_1_inst (
.clk (sclk ), // input wire clk
.probe0 (Tx_start_en ), // input wire [0:0] probe0
.probe1 (fifo3_rd_count ), // input wire [9:0] probe1
.probe2 (fifo3_read_data ), // input wire [127:0] probe2
.probe3 (read_fifo3_rd_en ), // input wire [0:0] probe3
.probe4 (tx_end_flag ), // input wire [0:0] probe4
.probe5 (po_gen_data ), // input wire [7:0] probe5
.probe6 (po_gen_data_en ) // input wire [0:0] probe6
);
endmodule
相信同学们经过时序图与程序相结合可以很容易明白上面的原理与代码的书写
校验码模块的设计及实现
检验码模块时序图的设计
在我们千兆网的第一篇博客我们已经讲解了UDP协议中两个检验码的计算方法。我们按照博客中的计算方法进行如下的时序设计:
检验码模块的代码设计
经过上面的时序设计,我们可以很容易实现上面的代码,如下:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : add_checksum.v
// Create Time : 2020-04-01 14:18:57
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module add_checksum(
input sclk ,
input rst_n ,
input [15:0] UDP_len ,
input tx_gen_data_en ,
input [ 7:0] tx_gen_data ,
output reg [ 7:0] tx_check_sum_data ,
output reg tx_check_sum_en ,
output reg pre_flag
);
//========================================================================================
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [ 7:0] tx_gen_data_dly ;
reg tx_gen_data_en_dly ;
reg clc_flag ;
reg [10:0] data_cnt ;
reg shift_ip_en ;
reg shift_ip_en_dly ;
reg shift_ip_flag ;
reg [15:0] shift_ip_data ;
reg [31:0] ip_sum ;
reg [31:0] ip_checksum ;
reg [10:0] latch__max ;
reg latch__flag ;
reg shift_udp_en ;
reg shift_udp_en_dly ;
reg shift_udp_flag ;
reg [15:0] shift_udp_data ;
reg [31:0] udp_sum ;
reg [31:0] udp_checksum ;
reg add_pse_flag ;
reg [15:0] latch_UDP_len ;
wire [31:0] ip_head_pseudo ;
reg rd_en ;
reg rd_dout_en ;
reg [10:0] rd_addr ;
wire [ 7:0] rd_dout ;
//========================================================================================
//************** Main Code **********************************
//========================================================================================/
assign ip_head_pseudo = 16'hc0a8 + 16'h0001 + 16'hffff + 16'hffff + 16'h0011 + latch_UDP_len;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)begin
tx_gen_data_en_dly <= 1'b0;
tx_gen_data_dly <= 8'b0;
end else begin
tx_gen_data_en_dly <= tx_gen_data_en;
tx_gen_data_dly <= tx_gen_data;
end
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
clc_flag <= 1'd0;
else if(tx_gen_data_en_dly == 1'b0 && tx_gen_data_en == 1)
clc_flag <= 1'b1;
else
clc_flag <= 1'd0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
data_cnt <= 11'd0;
else if(tx_gen_data_en_dly== 1'b0)
data_cnt <= 11'b0;
else
data_cnt <= data_cnt + 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
latch__flag <= 1'b0;
else if(tx_gen_data_en_dly == 1 && tx_gen_data_en == 0)
latch__flag <= 1'b1;
else
latch__flag <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
latch__max <= 1'b0;
else if(latch__flag == 1)
latch__max <= data_cnt - 1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_en <= 1'd0;
else if(data_cnt == 21)
shift_ip_en <= 1'b1;
else if(data_cnt == 41)
shift_ip_en <= 1'd0;
//Shift_ip_en_dly
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_en_dly <= 1'd0;
else
shift_ip_en_dly <= shift_ip_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_data <= 16'd0;
else if(shift_ip_en == 1'b1 )
shift_ip_data <= {shift_ip_data[7:0],tx_gen_data_dly};
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_flag <= 1'b0;
else if(shift_ip_en_dly == 1'b1)
shift_ip_flag <= ~shift_ip_flag;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
ip_sum <= 32'd0;
else if(shift_ip_flag == 1'b1)
ip_sum <= ip_sum + shift_ip_data;
else if(clc_flag == 1'b1 )
ip_sum <= 32'd0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
ip_checksum <= 32'd0;
else if(data_cnt == 43)
ip_checksum <= ip_sum;
else if(ip_checksum >16'hffff)
ip_checksum <= ip_checksum[31:16] + ip_checksum[15:0];
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
latch_UDP_len <= 'd0 ;
else if(tx_gen_data_en_dly == 1'b0 && tx_gen_data_en == 1)
latch_UDP_len <= UDP_len;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_en <= 1'd0;
else if(data_cnt == 41 && shift_ip_en == 1)
shift_udp_en <= 1'b1;
else if(tx_gen_data_en == 0 && tx_gen_data_en_dly == 1)
shift_udp_en <= 1'd0;
//Shift_ip_en_dly
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_en_dly <= 1'd0;
else
shift_udp_en_dly <= shift_udp_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_data <= 16'd0;
else if(shift_udp_en == 1'b1)
shift_udp_data <= {shift_udp_data[7:0],tx_gen_data_dly};
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_flag <= 1'b0;
else if(shift_udp_en_dly == 1'b1)
shift_udp_flag <= ~shift_udp_flag;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
udp_sum <= 32'd0;
else if(shift_udp_flag == 1'b1)
udp_sum <= udp_sum + shift_udp_data;
else if(clc_flag == 1'b1 )
udp_sum <= 32'd0;
always@(posedge sclk or negedge rst_n)
if(!rst_n)
add_pse_flag <= 1'b0;
else
add_pse_flag <= latch__flag;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
udp_checksum <= 32'd0;
else if(add_pse_flag == 1)
udp_checksum <= udp_sum + ip_head_pseudo;
else if(udp_checksum > 16'hffff)
udp_checksum <= udp_checksum[31:16] + udp_checksum[15:0] ;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
rd_en <= 1'b0;
else if(add_pse_flag == 1)
rd_en <= 1'b1;
else if(rd_addr == latch__max)
rd_en <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
rd_dout_en <= 1'b0;
else
rd_dout_en <= rd_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
rd_addr <= 11'h0;
else if(rd_en == 1)
rd_addr <= rd_addr + 1'b1;
else
rd_addr <= 11'h0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
tx_check_sum_data <= 'h0;
else case(rd_addr)
11'd33: tx_check_sum_data <= ~ip_checksum[15:8] ;
11'd34: tx_check_sum_data <= ~ip_checksum[7:0] ;
11'd49: tx_check_sum_data <= ~udp_checksum[15:8] ;
11'd50: tx_check_sum_data <= ~udp_checksum[7:0] ;
default: tx_check_sum_data <= rd_dout ;
endcase
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
tx_check_sum_en <= 1'b0;
else
tx_check_sum_en <= rd_dout_en;
ram_2048x8 ram_2048x8_inst (
.clka (sclk ),
.wea (tx_gen_data_en_dly ),
.addra (data_cnt ),
.dina (tx_gen_data_dly ),
.clkb (sclk ),
.addrb (rd_addr ),
.doutb (rd_dout )
);
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
pre_flag <= 1'b0;
else if(rd_addr >= 9)
pre_flag <= 1'b0;
else
pre_flag <= 1'b1;
endmodule
经过时序图与代码相结合再加上前面检验码的理论讲解,同学们应该可以学会检验码的设计。
CRC模块的设计及代码实现
关于CRC模块的设计原理与实现在我们千兆网的第三篇博客进行了详细的讲解,可以学习第三篇博客进行设计。当然,我们在上一篇博客中也给出了相应的代码。
整个项目工程代码
经过上面的讲解,大家可以学会千兆网发送模块的设计。那么我们这里给出整个模块的设计代码,如下:
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 Interfaces
input 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 Interfaces
output wire phy_rst_n ,
input [ 3:0] rx_data ,
input rx_ctrl ,
input rx_clk ,
output wire tx_clk ,
output wire [ 3:0] tx_dat ,
output wire tx_dv ,
//USB3 Interfaces
output 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 ;
wire c3_p2_cmd_clk ;
wire c3_p2_cmd_en ;
wire [ 2:0] c3_p2_cmd_instr ;
wire [27:0] c3_p2_cmd_byte_addr ;
wire [ 6:0] c3_p2_cmd_bl ;
wire c3_p2_rd_clk ;
wire c3_p2_rd_en ;
wire [255:0] c3_p2_rd_data ;
wire [10:0] c3_p2_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 ;
//top_GBET_tx_inst
wire Rx_end_flag ;//DDR3写结束标志位
wire [127:0] fifo3_read_data ;//从DDR3 P3口读fifo的数据
wire read_fifo3_rd_en ;
wire clk_125m_90 ;
//========================================================================================
//************** 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 ),
.clk_out4 (clk_125m_90 ),
// Status and control signals
.reset (~rst_n ), // input reset
.locked (locked ), // output locked
// Clock in ports
.clk_in1 (sclk )
); // input clk_in1
ddr3_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 (c3_p2_cmd_clk ),
.c3_p3_cmd_en (c3_p2_cmd_en ),
.c3_p3_cmd_bl (c3_p2_cmd_bl ),
.c3_p3_cmd_byte_addr (c3_p2_cmd_byte_addr ),
.c3_p3_cmd_empty ( ),
.c3_p3_cmd_full ( ),
.c3_p3_rd_clk (c3_p2_rd_clk ),
.c3_p3_rd_en (c3_p2_rd_en ),
.c3_p3_rd_data (c3_p2_rd_data ),
.c3_p3_rd_full ( ),
.c3_p3_rd_empty ( ),
.c3_p3_rd_count (c3_p2_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 ),
.c3_p2_cmd_clk (c3_p2_cmd_clk ),
.c3_p2_cmd_en (c3_p2_cmd_en ),
.c3_p2_cmd_instr (c3_p2_cmd_instr ),
.c3_p2_cmd_byte_addr (c3_p2_cmd_byte_addr ),
.c3_p2_cmd_bl (c3_p2_cmd_bl ),
.c3_p2_rd_clk (c3_p2_rd_clk ),
.c3_p2_rd_en (c3_p2_rd_en ),
.c3_p2_rd_data (c3_p2_rd_data ),
.c3_p2_rd_count (c3_p2_rd_count ),
//Write DDR3
.clk_24m (clk_125m ),
.data_wr_en (data_wr_en ),
.data_wr (data_wr ),
//Gigbit Interfaces
.tx_clk (clk_125m ),
.tx_data_en (read_fifo3_rd_en ),
.tx_data (fifo3_read_data ),
.ddr_wr_end (Rx_end_flag ),
Read DDR3
.USB_clk (USB_clk ),
.wr_n (data_req ),
.data_in (data_in )
);
top_GBET_tx top_GBET_tx_inst(
.sclk (clk_125m ),//输入的125M的时钟
.clk_50m_90 (clk_125m_90 ),
.rst_n (locked ),
.Rx_end_flag (Rx_end_flag ),//DDR3写结束标志位
.fifo3_rd_count (c3_p2_rd_count ),//DDR3 P3口读fifo计数器
.fifo3_read_data (fifo3_read_data ),//从DDR3 P3口读fifo的数据
.read_fifo3_rd_en (read_fifo3_rd_en ),//从DDR3 P3口读fifo的使能信号
.tx_clk (tx_clk ),
.tx_dat (tx_dat ),
.tx_dv (tx_dv )
);
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 )
);
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 )
);
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 Interfaces
input 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 Interfaces
output 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 Interfaces
input 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;
else
rand_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;
else
state <= state;
WR1 : if(a7_wr_end_wr1 == 1'b1)
state <= ARBIT;
else
state <= state;
WR2 : if(a7_wr_end_wr2 == 1'b1)
state <= ARBIT;
else
state <= state;
RD1 : if(a7_rd_end_rd1 == 1'b1)
state <= ARBIT;
else
state <= state;
RD2 : if(a7_rd_end_rd2 == 1'b1)
state <= ARBIT;
else
state <= state;
default : state <= IDLE;
endcase
always @(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;
else
a7_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;
else
a7_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;
else
a7_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;
else
a7_rd_start_rd2 <= 1'b0;
always @(*)
case(state)
WR1 : begin
app_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;
end
RD2 : begin
app_addr = app_addr_rd2;
app_cmd = app_cmd_rd2;
app_en = app_en_rd2;
app_rd_data_valid_rd2 = app_rd_data_valid;
end
default : begin
app_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
endcase
endmodule
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 Interfaces
input rst_n ,
//DDR3 Interfaces
input 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 Interfaces
input 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;
else
wr_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;
else
app_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;
else
bl_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;
else
a7_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 Interfaces
input 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 Interfaces
input 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;
else
rd_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;
else
app_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;
else
cmd_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;
else
rd_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;
else
app_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;
else
a7_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;
else
data_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 Interfaces
input rst_n ,
//Write DDR3
input clk_24m ,
input data_wr_en ,
input [31:0] data_wr ,
//Gigbit Interfaces
input tx_clk ,
input tx_data_en ,
output reg [127:0] tx_data ,
//Read DDR3
input USB_clk ,
input wr_n ,
output wire [15:0] data_in ,
//DDR3 Interfaces
output 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 ,
output c3_p2_cmd_clk ,
output reg c3_p2_cmd_en ,
output wire [ 2:0] c3_p2_cmd_instr ,
output reg [27:0] c3_p2_cmd_byte_addr ,
output wire [ 6:0] c3_p2_cmd_bl ,
output c3_p2_rd_clk ,
output reg c3_p2_rd_en ,
input [255:0] c3_p2_rd_data ,
input [10:0] c3_p2_rd_count ,
//Communication
output wire ddr_wr_end
);
//========================================================================================
//**************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 ;
reg ddr3_wr_flag ;
reg [15:0] bl_cnt_r2 ;
reg data_cnt_rd2 ;
reg ddr_wr_end_r ;
reg ddr_wr_end_r1 ;
reg ddr_wr_end_r2 ;
reg ddr_wr_end_r3 ;
reg ddr_wr_end_r4 ;
reg ddr_wr_end_r5 ;
reg ddr_wr_end_r6 ;
reg ddr_wr_end_r7 ;
reg ddr_wr_end_r8 ;
reg [19:0] cnt_flag ;
//========================================================================================
//************** 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;
assign c3_p2_cmd_clk = tx_clk;
assign c3_p2_rd_clk = tx_clk;
assign c3_p2_cmd_instr = 3'd1;
assign c3_p2_cmd_bl = BURST_LENFTH;
assign ddr_wr_end = ddr_wr_end_r8;
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;
else
data_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};
else
c3_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;
else
c3_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;
else
wr_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;
else
c3_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;
else
bl_cnt <= bl_cnt;
always @(posedge clk_24m or negedge rst_n)
if(rst_n == 1'b0)
ddr_wr_end_r <= 1'b0;
else if(bl_cnt == BURST_NUM - 1'b1 && c3_p0_cmd_en == 1'b1)
ddr_wr_end_r <= 1'b1;
else
ddr_wr_end_r <= 1'b0;
always @(posedge tx_clk)begin
ddr_wr_end_r1 <= ddr_wr_end_r;
ddr_wr_end_r2 <= ddr_wr_end_r1;
ddr_wr_end_r3 <= ddr_wr_end_r2;
ddr_wr_end_r4 <= ddr_wr_end_r3;
ddr_wr_end_r5 <= ddr_wr_end_r4;
ddr_wr_end_r6 <= ddr_wr_end_r5;
ddr_wr_end_r7 <= ddr_wr_end_r6;
ddr_wr_end_r8 <= ddr_wr_end_r7;
end
always @(posedge clk_24m or negedge rst_n)
if(rst_n == 1'b0)
ddr3_wr_flag <= 1'b0;
else if(bl_cnt == BURST_NUM - 1'b1 && c3_p0_cmd_en == 1'b1)
ddr3_wr_flag <= 1'b1;
else if(c3_p0_cmd_en == 1'b1)
ddr3_wr_flag <= 1'b0;
else
ddr3_wr_flag <= ddr3_wr_flag;
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;
else
wr_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;
else
data_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;
else
rd_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;
else
c3_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;
else
c3_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;
else
c3_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;
else
bl_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;
else
c3_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;
endcase
always @(posedge tx_clk or negedge rst_n)
if(rst_n == 1'b0)
c3_p2_cmd_en <= 1'b0;
else if(c3_p2_rd_count <= BURST_LENFTH/2 && ddr3_wr_flag == 1'b1)
c3_p2_cmd_en <= 1'b1;
else
c3_p2_cmd_en <= 1'b0;
always @(posedge tx_clk or negedge rst_n)
if(rst_n == 1'b0)
c3_p2_cmd_byte_addr <= 28'd0;
else if(bl_cnt_r2 == BURST_NUM - 1'b1 && c3_p2_cmd_en == 1'b1)
c3_p2_cmd_byte_addr <= 28'd0;
else if(c3_p2_cmd_en == 1'b1)
c3_p2_cmd_byte_addr <= c3_p2_cmd_byte_addr + 128;
else
c3_p2_cmd_byte_addr <= c3_p2_cmd_byte_addr;
always @(posedge tx_clk or negedge rst_n)
if(rst_n == 1'b0)
bl_cnt_r2 <= 16'd0;
else if(bl_cnt_r2 == BURST_NUM - 1'b1 && c3_p2_cmd_en == 1'b1)
bl_cnt_r2 <= 16'd0;
else if(c3_p2_cmd_en == 1'b1)
bl_cnt_r2 <= bl_cnt_r2 + 1'b1;
else
bl_cnt_r2 <= bl_cnt_r2;
always @(posedge tx_clk or negedge rst_n)
if(rst_n == 1'b0)
data_cnt_rd2 <= 1'd0;
else if(tx_data_en == 1'b1)
data_cnt_rd2 <= data_cnt_rd2 + 1'b1;
else
data_cnt_rd2 <= data_cnt_rd2;
always @(posedge tx_clk or negedge rst_n)
if(rst_n == 1'b0)
c3_p2_rd_en <= 1'b0;
else if(data_cnt_rd2 == 1'b1 && tx_data_en == 1'b1)
c3_p2_rd_en <= 1'b1;
else
c3_p2_rd_en <= 1'b0;
always @(posedge tx_clk or negedge rst_n)
if(rst_n == 1'b0)
cnt_flag <= 20'd0;
else if(c3_p2_rd_en == 1'b1)
cnt_flag <= cnt_flag + 1'b1;
else
cnt_flag <= cnt_flag;
always @(*)
if(data_cnt_rd2 == 1'b0)
tx_data <= c3_p2_rd_data[255:128];
else
tx_data <= c3_p2_rd_data[127:0];
//========================================================================================
//******************************* Debug **********************************
//========================================================================================/
//ila_3 ila_3_inst (
// .clk (tx_clk ), // input wire clk
//
// .probe0 (ddr_wr_end ), // input wire [0:0] probe0
// .probe1 (c3_p2_cmd_en ), // input wire [0:0] probe1
// .probe2 (c3_p2_cmd_byte_addr ), // input wire [27:0] probe2
// .probe3 (bl_cnt_r2 ), // input wire [15:0] probe3
// .probe4 (data_cnt_rd2 ), // input wire [0:0] probe4
// .probe5 (c3_p2_rd_en ), // input wire [0:0] probe5
// .probe6 (1'b1 ), // input wire [127:0] probe6
// .probe7 (1'b1 ), // input wire [255:0] probe7
// .probe8 (ddr3_wr_flag ), // input wire [0:0] probe8
// .probe9 (c3_p2_rd_count ), // input wire [10:0] probe9
// .probe10 (bl_cnt_r2 ), // input wire [15:0] probe9
// .probe11 (cnt_flag )
//);
ila_0 your_instance_name (
.clk (tx_clk), // input wire clk
.probe0 (ddr_wr_end ), // input wire [0:0] probe0
.probe1 (c3_p2_cmd_en ), // input wire [0:0] probe1
.probe2 (c3_p2_cmd_byte_addr ), // input wire [27:0] probe2
.probe3 (bl_cnt_r2 ), // input wire [15:0] probe3
.probe4 (ddr3_wr_flag ), // input wire [0:0] probe4
.probe5 (cnt_flag ) // input wire [10:0] probe5
);
endmodule
top_GBET_tx模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : top_GBET_tx.v
// Create Time : 2020-04-01 12:32:27
// 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_GBET_tx(
input sclk ,
input clk_50m_90 ,
input rst_n ,
input Rx_end_flag ,
input [10:0] fifo3_rd_count ,
input [127:0] fifo3_read_data ,
output wire read_fifo3_rd_en ,
output wire tx_clk ,
output wire [ 3:0] tx_dat ,
output wire tx_dv
);
//========================================================================================
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg Tx_start_en ;
reg Rx_end_flag_dly ;
wire tx_end_flag ;
wire [ 7:0] po_gen_data ;
wire po_gen_data_en ;
wire [15:0] UDP_len ;
wire [ 7:0] tx_check_sum_data ;
wire tx_check_sum_en ;
wire frame_head_flag ;
wire [ 7:0] tx_data_crc ;
wire tx_data_crc_en ;
//========================================================================================
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Rx_end_flag_dly <= 0;
else
Rx_end_flag_dly <= Rx_end_flag;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Tx_start_en <= 0;
else if(Rx_end_flag == 1 && Rx_end_flag_dly == 0)
Tx_start_en <= 1;
else if(tx_end_flag==1)
Tx_start_en <= 0;
tx_geb_frame tx_geb_frame(
.sclk (sclk ),
.rst_n (rst_n ),
.Tx_start_en (Tx_start_en ),
.fifo3_read_data (fifo3_read_data ),
.fifo3_rd_count (fifo3_rd_count ),
.UDP_len (UDP_len ),
.read_fifo3_rd_en (read_fifo3_rd_en ),
.tx_end_flag (tx_end_flag ),
.po_gen_data (po_gen_data ),
.po_gen_data_en (po_gen_data_en )
);
add_checksum add_checksum_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.UDP_len (UDP_len ),
.tx_gen_data (po_gen_data ),
.tx_gen_data_en (po_gen_data_en ),
.tx_check_sum_data (tx_check_sum_data ),
.tx_check_sum_en (tx_check_sum_en ),
.pre_flag (frame_head_flag )
);
crc32_d8_send_02 crc32_d8_send_02_inst (
.resetb (rst_n ),
.sclk (sclk ),
.dsin (tx_check_sum_en ),
.din (tx_check_sum_data ),
.pre_flag (frame_head_flag ),
.crc_err_en (0 ),
.dsout (tx_data_crc_en ),
.dout (tx_data_crc )
);
rgmii_tx rgmii_tx (
.sclk (sclk ),
.clk_50m_90 (clk_50m_90 ),
.rst_n (rst_n ),
.tx_dat (tx_data_crc ),
.tx_en (tx_data_crc_en ),
.tx_data (tx_dat ),
.tx_dv (tx_dv ),
.tx_clk (tx_clk )
);
endmodule
tx_geb_frame模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : tx_gen_frame.v
// Create Time : 2020-04-01 12:48:28
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module tx_geb_frame(
input sclk ,
input rst_n ,
input Tx_start_en ,
input [10:0] fifo3_rd_count ,
input [127:0]fifo3_read_data ,
output reg read_fifo3_rd_en ,
output reg tx_end_flag ,
output reg [15:0] UDP_len ,
output reg [ 7:0] po_gen_data ,
output reg po_gen_data_en
);
//========================================================================================
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter IMG_W_DATA = 16'H03FF ;
parameter IMG_H_DTAT = 16'H02FF ;
parameter MAC_S0 = 8'H00 ;
parameter MAC_S1 = 8'H0a ;
parameter MAC_S2 = 8'H35 ;
parameter MAC_S3 = 8'H00 ;
parameter MAC_S4 = 8'H01 ;
parameter MAC_S5 = 8'H02 ;
parameter H_IP_LEN = 16'H011C ;
parameter rgb1_IP_LEN = 16'h04d6 ;
parameter rgb3_IP_LEN = 16'h02c6 ;
parameter H_UDP_LEN = 16'H0108 ;
parameter rgb1_UDP_LEN = 16'H04c2 ;
parameter rgb3_UDP_LEN = 16'H02b2 ;
parameter IP_S0 = 8'Hc0 ;
parameter IP_S1 = 8'Ha8 ;
parameter IP_S2 = 8'H00 ;
parameter IP_S3 = 8'H01 ;
parameter IP_D0 = 8'Hc0 ;
parameter IP_D1 = 8'Ha8 ;
parameter IP_D2 = 8'H00 ;
parameter IP_D3 = 8'H02 ;
parameter P_S0 = 8'Hf0 ;
parameter P_S1 = 8'H00 ;
parameter P_D0 = 8'Hf0 ;
parameter P_D1 = 8'H01 ;
parameter WAIT_MAX = 16 ;
reg [15:0] IP_len ;
reg shift_en ;
reg [ 3:0] shift_cnt ;
reg Head_cnt_en ;
reg [ 8:0] head_cnt ;
reg [ 7:0] Head_data ;
reg Head_en ;
reg [16:0] wait_cnt ;
reg wait_en ;
reg [ 7:0] PR ;
reg Gen_image_cnt_en ;
reg [10:0] Gen_image_cnt ;
reg [ 7:0] Gen_image_data ;
reg Gen_image__en ;
reg [ 1:0] Pik_gen_cnt ;
reg [15:0] img_row_cnt ;
//========================================================================================
//************** Main Code **********************************
//========================================================================================/
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Head_cnt_en <= 1'b0;
else if(head_cnt == 305)
Head_cnt_en <= 1'b0;
else if(Tx_start_en == 1'b1 && fifo3_rd_count >= 256 && head_cnt == 10'd0)
Head_cnt_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
head_cnt <= 0;
else if(Head_cnt_en == 1'b1)
head_cnt <= head_cnt + 1'b1;
else if(tx_end_flag==1)
head_cnt <= 0;
//ip_len
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
IP_len <= 16'h0;
else if(Head_cnt_en == 1'b1)
IP_len <= H_IP_LEN;
else if(Pik_gen_cnt < 2)
IP_len <= rgb1_IP_LEN;
else if(Pik_gen_cnt == 2)
IP_len <= rgb3_IP_LEN;
//udp_len
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
UDP_len <= 16'h0;
else if(Head_cnt_en == 1'b1)
UDP_len <= H_UDP_LEN;
else if(Pik_gen_cnt < 2)
UDP_len <= rgb1_UDP_LEN;
else if(Pik_gen_cnt==2)
UDP_len <= rgb3_UDP_LEN ;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Head_data <= 8'hdd;
else case (head_cnt)
0,1,2,3,4,5,6 : Head_data <= 8'h55;
7 : Head_data <= 8'hd5;
8,9,10,11,12,13 : Head_data <= 8'hff;
14 : Head_data <= MAC_S0;
15 : Head_data <= MAC_S1;
16 : Head_data <= MAC_S2;
17 : Head_data <= MAC_S3;
18 : Head_data <= MAC_S4;
19 : Head_data <= MAC_S5;
20 : Head_data <= 8'h08;
21 : Head_data <= 8'h00;
22 : Head_data <= 8'h45;
23 : Head_data <= 8'h00;
24 : Head_data <= IP_len[15:8] ;
25 : Head_data <= IP_len[7:0] ;
26,27 : Head_data <= 8'h00;
28 : Head_data <= 8'h40;
29 : Head_data <= 8'h00;
30 : Head_data <= 8'h80;
31 : Head_data <= 8'h11;
32,33 : Head_data <= 8'h00;
34 : Head_data <= IP_S0;
35 : Head_data <= IP_S1;
36 : Head_data <= IP_S2;
37 : Head_data <= IP_S3;
38 : Head_data <= 8'hff;//IP_D0;
39 : Head_data <= 8'hff;//IP_D1;
40 : Head_data <= 8'hff;//IP_D2;
41 : Head_data <= 8'hff;//IP_D3;
42 : Head_data <= P_S0;
43 : Head_data <= P_S1;
44 : Head_data <= P_D0;
45 : Head_data <= P_D1;
46 : Head_data <= UDP_len[15:8];
47 : Head_data <= UDP_len[7:0];
48,49 : Head_data <= 8'h00;
50,51,52,53,54,55,56: Head_data <= 8'hAA;
57 : Head_data <= 8'hfa;
58 : Head_data <= IMG_W_DATA[15:8];
59 : Head_data <= IMG_W_DATA[7:0] ;
60 : Head_data <= IMG_H_DTAT[15:8];
61 : Head_data <= IMG_H_DTAT[7:0] ;
304 : Head_data <= 8'h02;
305 : Head_data <= 8'h03;
default : Head_data <= 8'h00;
endcase
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Head_en <= 1'b0;
else
Head_en <= Head_cnt_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
wait_en <= 1'b0;
else if(wait_cnt[WAIT_MAX]== 1'b1)
wait_en <= 1'b0;
else if(head_cnt == 305 || Gen_image_cnt == 1259 || (Gen_image_cnt == 731&& Pik_gen_cnt == 2'd2 && img_row_cnt != 10'd767))
wait_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
wait_cnt <= 0;
else if(wait_en == 1'b1)
wait_cnt <= wait_cnt + 1'b1;
else
wait_cnt <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image_cnt_en <= 1'b0;
else if(Gen_image_cnt == 1259 || (Gen_image_cnt == 731 && Pik_gen_cnt == 2'd2))
Gen_image_cnt_en <= 1'b0;
else if(wait_cnt[WAIT_MAX] == 1'b1)
Gen_image_cnt_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image_cnt <= 0;
else if(Gen_image_cnt_en == 1)
Gen_image_cnt <= Gen_image_cnt + 1'b1;
else
Gen_image_cnt <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Pik_gen_cnt <= 2'b0;
else if(Pik_gen_cnt == 2'd2 && Gen_image_cnt == 731)
Pik_gen_cnt <= 2'd0;
else if(Gen_image_cnt == 1259)
Pik_gen_cnt <= Pik_gen_cnt + 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
img_row_cnt <= 16'd0;
else if(img_row_cnt == 16'd768)
img_row_cnt <= 16'd0;
else if(Pik_gen_cnt == 2'd2 && Gen_image_cnt == 731)
img_row_cnt <= img_row_cnt + 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
PR <= 8'd0;
else if(img_row_cnt == 16'd767 )
PR <= 8'hf6;
else
PR <= 8'hf5;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
tx_end_flag <= 1'b0;
else if(img_row_cnt == 768 )
tx_end_flag <= 1'b1;
else
tx_end_flag <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_en <= 1'b0;
else if(Gen_image_cnt == 1259 || (Pik_gen_cnt == 2'd2 && Gen_image_cnt == 731))
shift_en <= 1'b0;
else if(Gen_image_cnt == 59)
shift_en <= 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_cnt <= 'b0;
else if(shift_en == 0)
shift_cnt <= 'b0;
else if(shift_cnt == 11)
shift_cnt <= 'b0;
else if(shift_en == 1)
shift_cnt <= shift_cnt + 1'b1 ;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
read_fifo3_rd_en <= 1'b0;
else if(shift_cnt == 11)
read_fifo3_rd_en <= 1'b1;
else
read_fifo3_rd_en <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image_data <= 8'hdd;
else if(shift_en == 1)begin
case(shift_cnt)
0: Gen_image_data <= fifo3_read_data[119:112];
1: Gen_image_data <= fifo3_read_data[127:120];
2: Gen_image_data <= fifo3_read_data[103:96];
3: Gen_image_data <= fifo3_read_data[87:80];
4: Gen_image_data <= fifo3_read_data[95:88];
5: Gen_image_data <= fifo3_read_data[71:64];
6: Gen_image_data <= fifo3_read_data[55:48];
7: Gen_image_data <= fifo3_read_data[63:56];
8: Gen_image_data <= fifo3_read_data[39:32];
9: Gen_image_data <= fifo3_read_data[23:16];
10: Gen_image_data <= fifo3_read_data[31:24];
11: Gen_image_data <= fifo3_read_data[7:0];
default:;
endcase
end
else case (Gen_image_cnt)
0,1,2,3,4,5,6 : Gen_image_data <= 8'h55;
7 : Gen_image_data <= 8'hd5;
8,9,10,11,12,13 : Gen_image_data <= 8'hff;
14 : Gen_image_data <= MAC_S0;
15 : Gen_image_data <= MAC_S1;
16 : Gen_image_data <= MAC_S2;
17 : Gen_image_data <= MAC_S3;
18 : Gen_image_data <= MAC_S4;
19 : Gen_image_data <= MAC_S5;
20 : Gen_image_data <= 8'h08;
21 : Gen_image_data <= 8'h00;
22 : Gen_image_data <= 8'h45;
23 : Gen_image_data <= 8'h00;
24 : Gen_image_data <= IP_len[15:8];
25 : Gen_image_data <= IP_len[7:0];
26,27,28,29 : Gen_image_data <= 8'h00;
30 : Gen_image_data <= 8'h80;
31 : Gen_image_data <= 8'h11;
32,33 : Gen_image_data <= 8'h00;
34 : Gen_image_data <= IP_S0;
35 : Gen_image_data <= IP_S1;
36 : Gen_image_data <= IP_S2;
37 : Gen_image_data <= IP_S3;
38,39,40,41 : Gen_image_data <= 8'hff;
42 : Gen_image_data <= P_S0;
43 : Gen_image_data <= P_S1;
44 : Gen_image_data <= P_D0;
45 : Gen_image_data <= P_D1;
46 : Gen_image_data <= UDP_len[15:8];
47 : Gen_image_data <= UDP_len[7:0];
48,49 : Gen_image_data <= 8'h00;
50,51,52,53,54,55,56 : Gen_image_data <= 8'hAA;
57 : Gen_image_data <= PR;
58 : Gen_image_data <= img_row_cnt[15:8];
59 : Gen_image_data <= img_row_cnt[7:0];
default:;
endcase
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
Gen_image__en <= 1'b0;
else
Gen_image__en <= Gen_image_cnt_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
po_gen_data <= 8'b0;
else if(Head_en == 1)
po_gen_data <= Head_data;
else if(Gen_image__en == 1)
po_gen_data <= Gen_image_data;
else
po_gen_data <= 8'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
po_gen_data_en <= 1'b0;
else if(Head_en==1||Gen_image__en==1)
po_gen_data_en <= 1'b1;
else
po_gen_data_en <= 1'b0;
//========================================================================================
//******************************* Debug **********************************
//========================================================================================/
ila_1 ila_1_inst (
.clk (sclk ), // input wire clk
.probe0 (Tx_start_en ), // input wire [0:0] probe0
.probe1 (fifo3_rd_count ), // input wire [9:0] probe1
.probe2 (fifo3_read_data ), // input wire [127:0] probe2
.probe3 (read_fifo3_rd_en ), // input wire [0:0] probe3
.probe4 (tx_end_flag ), // input wire [0:0] probe4
.probe5 (po_gen_data ), // input wire [7:0] probe5
.probe6 (po_gen_data_en ) // input wire [0:0] probe6
);
endmodule
add_checksum模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : add_checksum.v
// Create Time : 2020-04-01 14:18:57
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module add_checksum(
input sclk ,
input rst_n ,
input [15:0] UDP_len ,
input tx_gen_data_en ,
input [ 7:0] tx_gen_data ,
output reg [ 7:0] tx_check_sum_data ,
output reg tx_check_sum_en ,
output reg pre_flag
);
//========================================================================================
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg [ 7:0] tx_gen_data_dly ;
reg tx_gen_data_en_dly ;
reg clc_flag ;
reg [10:0] data_cnt ;
reg shift_ip_en ;
reg shift_ip_en_dly ;
reg shift_ip_flag ;
reg [15:0] shift_ip_data ;
reg [31:0] ip_sum ;
reg [31:0] ip_checksum ;
reg [10:0] latch__max ;
reg latch__flag ;
reg shift_udp_en ;
reg shift_udp_en_dly ;
reg shift_udp_flag ;
reg [15:0] shift_udp_data ;
reg [31:0] udp_sum ;
reg [31:0] udp_checksum ;
reg add_pse_flag ;
reg [15:0] latch_UDP_len ;
wire [31:0] ip_head_pseudo ;
reg rd_en ;
reg rd_dout_en ;
reg [10:0] rd_addr ;
wire [ 7:0] rd_dout ;
//========================================================================================
//************** Main Code **********************************
//========================================================================================/
assign ip_head_pseudo = 16'hc0a8 + 16'h0001 + 16'hffff + 16'hffff + 16'h0011 + latch_UDP_len;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)begin
tx_gen_data_en_dly <= 1'b0;
tx_gen_data_dly <= 8'b0;
end else begin
tx_gen_data_en_dly <= tx_gen_data_en;
tx_gen_data_dly <= tx_gen_data;
end
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
clc_flag <= 1'd0;
else if(tx_gen_data_en_dly == 1'b0 && tx_gen_data_en == 1)
clc_flag <= 1'b1;
else
clc_flag <= 1'd0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
data_cnt <= 11'd0;
else if(tx_gen_data_en_dly== 1'b0)
data_cnt <= 11'b0;
else
data_cnt <= data_cnt + 1'b1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
latch__flag <= 1'b0;
else if(tx_gen_data_en_dly == 1 && tx_gen_data_en == 0)
latch__flag <= 1'b1;
else
latch__flag <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
latch__max <= 1'b0;
else if(latch__flag == 1)
latch__max <= data_cnt - 1;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_en <= 1'd0;
else if(data_cnt == 21)
shift_ip_en <= 1'b1;
else if(data_cnt == 41)
shift_ip_en <= 1'd0;
//Shift_ip_en_dly
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_en_dly <= 1'd0;
else
shift_ip_en_dly <= shift_ip_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_data <= 16'd0;
else if(shift_ip_en == 1'b1 )
shift_ip_data <= {shift_ip_data[7:0],tx_gen_data_dly};
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_ip_flag <= 1'b0;
else if(shift_ip_en_dly == 1'b1)
shift_ip_flag <= ~shift_ip_flag;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
ip_sum <= 32'd0;
else if(shift_ip_flag == 1'b1)
ip_sum <= ip_sum + shift_ip_data;
else if(clc_flag == 1'b1 )
ip_sum <= 32'd0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
ip_checksum <= 32'd0;
else if(data_cnt == 43)
ip_checksum <= ip_sum;
else if(ip_checksum >16'hffff)
ip_checksum <= ip_checksum[31:16] + ip_checksum[15:0];
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
latch_UDP_len <= 'd0 ;
else if(tx_gen_data_en_dly == 1'b0 && tx_gen_data_en == 1)
latch_UDP_len <= UDP_len;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_en <= 1'd0;
else if(data_cnt == 41 && shift_ip_en == 1)
shift_udp_en <= 1'b1;
else if(tx_gen_data_en == 0 && tx_gen_data_en_dly == 1)
shift_udp_en <= 1'd0;
//Shift_ip_en_dly
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_en_dly <= 1'd0;
else
shift_udp_en_dly <= shift_udp_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_data <= 16'd0;
else if(shift_udp_en == 1'b1)
shift_udp_data <= {shift_udp_data[7:0],tx_gen_data_dly};
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
shift_udp_flag <= 1'b0;
else if(shift_udp_en_dly == 1'b1)
shift_udp_flag <= ~shift_udp_flag;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
udp_sum <= 32'd0;
else if(shift_udp_flag == 1'b1)
udp_sum <= udp_sum + shift_udp_data;
else if(clc_flag == 1'b1 )
udp_sum <= 32'd0;
always@(posedge sclk or negedge rst_n)
if(!rst_n)
add_pse_flag <= 1'b0;
else
add_pse_flag <= latch__flag;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
udp_checksum <= 32'd0;
else if(add_pse_flag == 1)
udp_checksum <= udp_sum + ip_head_pseudo;
else if(udp_checksum > 16'hffff)
udp_checksum <= udp_checksum[31:16] + udp_checksum[15:0] ;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
rd_en <= 1'b0;
else if(add_pse_flag == 1)
rd_en <= 1'b1;
else if(rd_addr == latch__max)
rd_en <= 1'b0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
rd_dout_en <= 1'b0;
else
rd_dout_en <= rd_en;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
rd_addr <= 11'h0;
else if(rd_en == 1)
rd_addr <= rd_addr + 1'b1;
else
rd_addr <= 11'h0;
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
tx_check_sum_data <= 'h0;
else case(rd_addr)
11'd33: tx_check_sum_data <= ~ip_checksum[15:8] ;
11'd34: tx_check_sum_data <= ~ip_checksum[7:0] ;
11'd49: tx_check_sum_data <= ~udp_checksum[15:8] ;
11'd50: tx_check_sum_data <= ~udp_checksum[7:0] ;
default: tx_check_sum_data <= rd_dout ;
endcase
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
tx_check_sum_en <= 1'b0;
else
tx_check_sum_en <= rd_dout_en;
ram_2048x8 ram_2048x8_inst (
.clka (sclk ),
.wea (tx_gen_data_en_dly ),
.addra (data_cnt ),
.dina (tx_gen_data_dly ),
.clkb (sclk ),
.addrb (rd_addr ),
.doutb (rd_dout )
);
always@(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
pre_flag <= 1'b0;
else if(rd_addr >= 9)
pre_flag <= 1'b0;
else
pre_flag <= 1'b1;
endmodule
crc32_d8_send_02模块:
module crc32_d8_send_02(
input resetb ,
input sclk ,
input dsin ,
input [ 7:0] din ,
input pre_flag ,
input crc_err_en ,
output reg dsout ,
output reg [ 7:0] dout
);
//========================================================================================
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg crc_ds,crc_en ;
reg [ 4:0] crc_ds_t ;
reg dsin_t ;
reg [ 7:0] din_t ;
reg [ 2:0] d_count ;
reg [ 7:0] d ;
wire [31:0] c ;
reg [31:0] crc32_value ;
reg crc_en_t ;
reg [ 2:0] d_cnt ;
//========================================================================================
//************** Main Code **********************************
//========================================================================================/
assign c = crc32_value;
always @(dsin or pre_flag)
if (dsin == 1 && pre_flag == 0)
crc_ds <= 1;
else
crc_ds <= 0;
always @(posedge sclk or negedge resetb)
if (resetb == 0)
crc_ds_t <= 0;
else
crc_ds_t <= {crc_ds_t[3:0],crc_ds};
always@(posedge sclk)
if (crc_ds == 1)//crc_ds_t[3]==1)
crc_en <= 1;
else
crc_en <= 0;
always@(posedge sclk)
if (crc_ds == 0)
d_count <= 0;
else if (d_count[2] == 0)
d_count <= d_count + 1;
always@(posedge sclk)
if (crc_ds == 'd0)
d <= 'd0;
else if(d_count[2] == 0)
d <= din;
else
d <= din;
always @(posedge sclk or negedge resetb)
if (resetb==0)
crc32_value <= 32'hFFFFFFFF;
else if(crc_en == 1)
begin
crc32_value[0] <= c[24]^c[30]^d[1]^d[7];
crc32_value[1] <= c[25]^c[31]^d[0]^d[6]^c[24]^c[30]^d[1]^d[7];
crc32_value[2] <= c[26]^d[5]^c[25]^c[31]^d[0]^d[6]^c[24]^c[30]^d[1]^d[7];
crc32_value[3] <= c[27]^d[4]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
crc32_value[4] <= c[28]^d[3]^c[27]^d[4]^c[26]^d[5]^c[24]^c[30]^d[1]^d[7];
crc32_value[5] <= c[29]^d[2]^c[28]^d[3]^c[27]^d[4]^c[25]^c[31]^d[0]^d[6]^c[24]^c[30]^d[1]^d[7];
crc32_value[6] <= c[30]^d[1]^c[29]^d[2]^c[28]^d[3]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
crc32_value[7] <= c[31]^d[0]^c[29]^d[2]^c[27]^d[4]^c[26]^d[5]^c[24]^d[7];
crc32_value[8] <= c[0]^c[28]^d[3]^c[27]^d[4]^c[25]^d[6]^c[24]^d[7];
crc32_value[9] <= c[1]^c[29]^d[2]^c[28]^d[3]^c[26]^d[5]^c[25]^d[6];
crc32_value[10] <= c[2]^c[29]^d[2]^c[27]^d[4]^c[26]^d[5]^c[24]^d[7];
crc32_value[11] <= c[3]^c[28]^d[3]^c[27]^d[4]^c[25]^d[6]^c[24]^d[7];
crc32_value[12] <= c[4]^c[29]^d[2]^c[28]^d[3]^c[26]^d[5]^c[25]^d[6]^c[24]^c[30]^d[1]^d[7];
crc32_value[13] <= c[5]^c[30]^d[1]^c[29]^d[2]^c[27]^d[4]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
crc32_value[14] <= c[6]^c[31]^d[0]^c[30]^d[1]^c[28]^d[3]^c[27]^d[4]^c[26]^d[5];
crc32_value[15] <= c[7]^c[31]^d[0]^c[29]^d[2]^c[28]^d[3]^c[27]^d[4];
crc32_value[16] <= c[8]^c[29]^d[2]^c[28]^d[3]^c[24]^d[7];
crc32_value[17] <= c[9]^c[30]^d[1]^c[29]^d[2]^c[25]^d[6];
crc32_value[18] <= c[10]^c[31]^d[0]^c[30]^d[1]^c[26]^d[5];
crc32_value[19] <= c[11]^c[31]^d[0]^c[27]^d[4];
crc32_value[20] <= c[12]^c[28]^d[3];
crc32_value[21] <= c[13]^c[29]^d[2];
crc32_value[22] <= c[14]^c[24]^d[7];
crc32_value[23] <= c[15]^c[25]^d[6]^c[24]^c[30]^d[1]^d[7];
crc32_value[24] <= c[16]^c[26]^d[5]^c[25]^c[31]^d[0]^d[6];
crc32_value[25] <= c[17]^c[27]^d[4]^c[26]^d[5];
crc32_value[26] <= c[18]^c[28]^d[3]^c[27]^d[4]^c[24]^c[30]^d[1]^d[7];
crc32_value[27] <= c[19]^c[29]^d[2]^c[28]^d[3]^c[25]^c[31]^d[0]^d[6];
crc32_value[28] <= c[20]^c[30]^d[1]^c[29]^d[2]^c[26]^d[5];
crc32_value[29] <= c[21]^c[31]^d[0]^c[30]^d[1]^c[27]^d[4];
crc32_value[30] <= c[22]^c[31]^d[0]^c[28]^d[3];
crc32_value[31] <= c[23]^c[29]^d[2];
end
else
crc32_value <= {crc32_value[23:0],8'hff};
always @(posedge sclk)
crc_en_t <= crc_en;
always @ (posedge sclk)
if(!resetb)
d_cnt <= 0;
else if(!crc_en && crc_en_t)
d_cnt <= d_cnt + 1'd1;
else if(d_cnt>3'd0 && d_cnt<3'd4)
d_cnt <= d_cnt+1'd1;
else
d_cnt <= 3'd0;
//dsin_t
always @(posedge sclk)
dsin_t <= dsin;
always @ (posedge sclk)
din_t <= din;
always@(posedge sclk)
if (dsin_t == 'd0 && d_cnt == 'd0 && crc_en_t == 'd0)
dout <= 'd0;
else if (dsin_t == 1'b1)
dout <= din_t;
else if (d_cnt == 'd4)
dout <= 'd0;
else if (crc_err_en == 0)
dout <= ~{crc32_value[24], crc32_value[25], crc32_value[26], crc32_value[27], crc32_value[28], crc32_value[29], crc32_value[30], crc32_value[31]};
else
dout <= {crc32_value[24], crc32_value[25], crc32_value[26], crc32_value[27], crc32_value[28], crc32_value[29], crc32_value[30], crc32_value[31]};
//dsout
always @(posedge sclk)
if(!resetb)
dsout <= 'd0;
else if(dsin_t)
dsout <= 'd1;
else if(d_cnt == 'd4)
dsout <= 'd0;
endmodule
rgmii_tx模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : rgmii_tx..v
// Create Time : 2020-04-01 14:57:14
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module rgmii_tx(
input sclk ,
input rst_n ,
input [ 7:0] tx_dat ,
input tx_en ,
input tx_c ,//相移时钟
input clk_50m_90 ,
output wire [ 3:0] tx_data ,
output wire tx_dv ,
output wire tx_clk
);
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE" ), // "OPPOSITE_EDGE" or "SAME_EDGE"
.INIT (1'b0 ), // Initial value of Q: 1'b0 or 1'b1
.SRTYPE ("ASYNC" ) // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_DV_inst (
.Q (tx_dv ), // 1-bit DDR output
.C (sclk ), // 1-bit clock input
.CE (1'b1 ), // 1-bit clock enable input
.D1 (tx_en ), // 1-bit data input (positive edge)
.D2 (tx_en ), // 1-bit data input (negative edge)
.R (1'b0 ), // 1-bit reset
.S (~rst_n ) // 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 ("ASYNC" ) // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_CLK_inst (
.Q (tx_clk ), // 1-bit DDR output
.C (clk_50m_90 ), // 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 (1'b0 ), // 1-bit reset
.S (~rst_n ) // 1-bit set
);
genvar j;
generate
for(j = 0;j < 4;j = j+1)begin
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE" ),
.INIT (1'b0 ),
.SRTYPE ("ASYNC" )
) ODDR_DATA_inst (
.Q (tx_data[j] ),
.C (sclk ),
.CE (1'b1 ),
.D1 (tx_dat[j] ),
.D2 (tx_dat[j+4] ),
.R (1'b0 ),
.S (~rst_n )
);
end
endgenerate
endmodule
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 Interfaces
input clk_50m ,
input clk_125m ,
input rst_n ,
//Gigbit Interfaces
output reg phy_rst_n ,
input [ 3:0] rx_data ,
input rx_ctrl ,
input rx_clk ,
//Communication Interfaces
output 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;
else
phy_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;
else
phy_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 Interfaces
input rst_n ,
//Gigabit Interfaces
input [ 3:0] rx_data ,
input rx_ctrl ,
input rx_clk ,
//Communication Interfaces
output 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;
generate
for (i = 0; i < 4; i = i+1) begin
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[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
);
end
endgenerate
always @(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;
else
gb_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 Interfaces
input sclk ,
input rst_n ,
//Gigbit Interfaces
input [ 7:0] rx_data ,
input rx_en ,
input rx_clk ,
//Communication Interfaces
output 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;
else
rx_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;
else
rx_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;
else
latch_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;
else
latch_max <= latch_max;
always @(posedge sclk)begin
mac_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;
end
always @(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;
else
rd_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;
else
rd_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;
else
rd_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 Interfaces
input sclk ,
input rst_n ,
//Gigbit Interfaces
input [ 7:0] dout_o ,
input dout_en ,
//Communication Interfaces
input [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;
else
rd_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;
else
cnt_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;
else
width_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;
else
height_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};
else
width_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};
else
height_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;
else
rlst_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;
else
start_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;
else
image_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;
else
image_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
);
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 Interfaces
input sclk ,
input rst_n ,
//Gigbit Interfaces
input [ 7:0] image_data ,
input image_data_en ,
//Communication Interfaces
output 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;
else
image_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};
else
data <= 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;
else
rgb_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 Interfaces
input [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;
else
state <= JUDGE;
WRITE : if(txf_n == 1'b1)
state <= JUDGE;
else
state <= WRITE;
READ : if(rxf_n == 1'b1)
state <= JUDGE;
else
state <= READ;
default : state <= IDLE;
endcase
always @(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;
else
oe_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;
else
rd_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;
else
wr_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
经过上面的代码我们可以实现相应的功能。
实验结果
上位机发送图片:
USB上位机接收的图片:
千兆网发送到上位机经MATLAB显示的图像:
经过上面的实验结果可以验证我们的实验基本正确。
总结
创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
最后
以上就是碧蓝秋天为你收集整理的基于FPGA的千兆以太网的实现(4)项目简述UDP组包时序及实现校验码模块的设计及实现CRC模块的设计及代码实现整个项目工程代码实验结果总结的全部内容,希望文章能够帮你解决基于FPGA的千兆以太网的实现(4)项目简述UDP组包时序及实现校验码模块的设计及实现CRC模块的设计及代码实现整个项目工程代码实验结果总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复