合起来 dat_recv_blocks
c
复制代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
// Create Date:
// Design Name:
// Module Name: dat_recv_blocks
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// Dependencies:
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module dat_recv_blocks(
clk ,//系统时钟,110M
rst ,//系统复位,高有效
din ,//接收到的数据,第一个数据为总帧长[8],其余数据均为8比特数据
din_clk_p ,//接收到的数据时钟,脉冲型
dout ,//链路数据,16比特
real_clk_p ,//接收到有效数据时钟,脉冲型
dout_clk_p , //链路数据时钟,脉冲型
LENGTH_REAL ,
LENGTH_THIMBLE ,
LENGTH_DIV4 ,
thimble_valid
);
//
input clk ;//系统时钟,110M
input rst ;//系统复位,高有效
input [7:0] din ;//接收到的数据,第一个数据为总帧长[16],其余数据均为8比特数据
input din_clk_p ;//接收到的数据时钟,脉冲型
output [15:0] dout;//链路数据,16比特
output real_clk_p ;//接收到有效数据时钟,脉冲型
output dout_clk_p ;//链路数据时钟,脉冲型
// 给传输上位机网口模块的
output [15:0] LENGTH_REAL ;
output [23:0] LENGTH_THIMBLE ;
output [15:0] LENGTH_DIV4 ;
output thimble_valid ;
//
reg delay_din_clk_p;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_din_clk_p<=1'b0;
end
else
begin
delay_din_clk_p<=din_clk_p;
end
end
//
reg select_0_1 ;
always @ (posedge clk or posedge rst)//提取帧计数,将前后两包区分开,避免两帧不是同一包的情况
begin
if(rst)
begin
select_0_1<=1'b0;
end
else if((din_clk_p==1'b1)&&(delay_din_clk_p==1'b0))//posedge
begin
select_0_1<=din[0];
end
else
begin
select_0_1<=select_0_1;
end
end
//
reg pack_check_pulse;// 检测到一包数据
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
pack_check_pulse<=1'b0;
end
else if((din_clk_p==1'b1)&&(delay_din_clk_p==1'b0))//posedge
begin
pack_check_pulse<=1'b1;
end
else
begin
pack_check_pulse<=1'b0;
end
end
//
reg pack_check;//接收到的包指示是否正确判决
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
pack_check<=1'b0;
end
else if(pack_check_pulse==1'b1)//pulse
begin
if((din[7:4]<=din[3:0])&&(din[7:4]>=4'd1)&&(din[7:4]<=4'd7))//区间正确
begin
pack_check<=1'b1;
end
else
begin
pack_check<=1'b0;//区间错误,检查存在异常
end
end
else
begin
pack_check<=pack_check;//hold
end
end
//
reg pack_end; // 检测最后一包
always @ (posedge clk or posedge rst)//接收到的包指示是否正确判决
begin
if(rst)
begin
pack_end<=1'b0;
end
else if(pack_check_pulse==1'b1)//pulse
begin
if((din[7:4]==din[3:0])&&(din[7:4]>=4'd1)&&(din[7:4]<=4'd7))//区间正确
begin
pack_end<=1'b1;
end
else
begin
pack_end<=1'b0;//区间错误,检查存在异常
end
end
else
begin
pack_end<=pack_end;//hold
end
end
//
reg length_check_pulse;// pack_check 延迟一拍
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
length_check_pulse<=1'b0;
end
else
begin
length_check_pulse<=pack_check_pulse;
end
end
//
reg length_check;//包长度检测
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
length_check<=1'b0;
end
else if(length_check_pulse)
begin
if((din<=8'd220)&&(din>=8'd1))//当前数据包长度也正确
begin
length_check<=1'b1;
end
else
begin
length_check<=1'b0; //当前数据包长度错误
end
end
else
begin
length_check<=length_check;//保持
end
end
//
reg [7:0] local_length;//从每一包中提取长度
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
local_length<=8'd0;
end
else if(length_check_pulse)
begin
local_length<=din;
end
else
begin
local_length<=local_length;//保持
end
end
//
reg wr_pulse;// pack_check 延迟二拍
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
wr_pulse<=1'b0;
end
else
begin
wr_pulse<=length_check_pulse;
end
end
//
reg [15:0] local_cnts; // 检测通过的情况下,根据 wr_pulse 开始计数
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
local_cnts<=16'hffff;
end
else if(local_cnts<=16'd230)
begin
local_cnts<=local_cnts + 1'b1;
end
else if((wr_pulse==1'b1)&&(length_check==1'b1)&&(pack_check==1'b1))
begin
local_cnts<=16'd0;
end
else
begin
local_cnts<=local_cnts;
end
end
//
reg wea_0 ;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
wea_0<=1'b0;
end
else if((select_0_1==1'b0)&&(local_cnts<=16'd220)&&(local_cnts<=local_length)&&(local_cnts>=16'd1))
begin
wea_0<=1'b1;
end
else
begin
wea_0<=1'b0;
end
end
//
reg wea_1 ; // 写入 ram 的 enable 信号
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
wea_1<=1'b0;
end
else if((select_0_1==1'b1)&&(local_cnts<=16'd220)&&(local_cnts<=local_length)&&(local_cnts>=16'd1))
begin
wea_1<=1'b1;
end
else
begin
wea_1<=1'b0;
end
end
//
reg [15:0] addra_0;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addra_0<=16'd0;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
addra_0<=16'd0;
end
else if((select_0_1==1'b0)&&(local_cnts<=16'd221)&&(local_cnts<=(local_length + 1'b1))&&(local_cnts>=16'd2))
begin
addra_0<=addra_0 + 1'b1;
end
else
begin
addra_0<=addra_0;
end
end
//
reg [15:0] addra_1; // 写入 ram 的 地址
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addra_1<=16'd0;
end
else if((select_0_1==1'b1)&&(local_cnts==16'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
addra_1<=16'd0;
end
else if((select_0_1==1'b1)&&(local_cnts<=16'd221)&&(local_cnts<=(local_length +1'b1 ))&&(local_cnts>=16'd2))
begin
addra_1<=addra_1 + 1'b1;
end
else
begin
addra_1<=addra_1;
end
end
//
reg [7:0] delay_dina_0 ; // 延迟 din
reg [7:0] delay_dina_1 ; // 延迟 din
reg [7:0] delay_dina_2 ; // 延迟 din
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_dina_0<=8'd0;
end
else
begin
delay_dina_0<=din;
end
end
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_dina_1<=8'd0;
end
else
begin
delay_dina_1<=delay_dina_0;
end
end
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_dina_2<=8'd0;
end
else
begin
delay_dina_2<=delay_dina_1;
end
end
//RD STATE
reg [15:0] all_dat_num_0;
reg [15:0] all_dat_num_1; // 写入的总数
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
all_dat_num_0<=16'd2047;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
all_dat_num_0<=addra_0;
end
else
begin
all_dat_num_0<=all_dat_num_0;
end
end
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
all_dat_num_1<=16'd2047;
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
all_dat_num_1<=addra_1;
end
else
begin
all_dat_num_1<=all_dat_num_1;
end
end
//
reg [15:0] LENGTH_REAL ;//数据的总长度
reg [23:0] LENGTH_THIMBLE ;//顶针的数据长度
reg [15:0] LENGTH_DIV4 ;//网络的最低传输长度
reg thimble_valid ;//是否需要顶针
always @ (posedge clk or posedge rst) // LENGTH_REAL 数据的总长度
begin
if(rst)
begin
LENGTH_REAL<=16'd2047;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
LENGTH_REAL<=addra_0;
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
LENGTH_REAL<=addra_1;
end
else
begin
LENGTH_REAL<=LENGTH_REAL;
end
end
always @ (posedge clk or posedge rst) // thimble_valid 是否需要顶针
begin
if(rst)
begin
thimble_valid <= 1'd0; // 默认不顶针
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_0[1:0] == 2'd0)
begin
thimble_valid <= 1'b0;
end
else
begin
thimble_valid <= 1'b1;
end
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_1[1:0] == 2'd0)
begin
thimble_valid <= 1'b0;
end
else
begin
thimble_valid <= 1'b1;
end
end
else
begin
thimble_valid <= thimble_valid;
end
end
always @ (posedge clk or posedge rst) // LENGTH_THIMBLE 顶针的数据长度
begin
if(rst)
begin
LENGTH_THIMBLE <= 24'd0;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
case(addra_0[1:0])
2'b00:begin LENGTH_THIMBLE <= 24'd0; end
2'b01:begin LENGTH_THIMBLE <= 24'd3; end
2'b10:begin LENGTH_THIMBLE <= 24'd2; end
2'b11:begin LENGTH_THIMBLE <= 24'd1; end
default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE; end
endcase
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin // addra_1[1:0]
case(addra_1[1:0])
2'b00:begin LENGTH_THIMBLE <= 24'd0; end
2'b01:begin LENGTH_THIMBLE <= 24'd3; end
2'b10:begin LENGTH_THIMBLE <= 24'd2; end
2'b11:begin LENGTH_THIMBLE <= 24'd1; end
default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE; end
endcase
end
else
begin
LENGTH_THIMBLE <= LENGTH_THIMBLE;
end
end
always @ (posedge clk or posedge rst) // LENGTH_DIV4 网络的最低传输长度
begin
if(rst)
begin
LENGTH_DIV4 <= 16'd0; // 默认不顶针
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_0[1:0] == 2'd0) // 不顶针
begin
LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]};
end
else
begin
LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]} + 1'b1;
end
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_1[1:0] == 2'd0)
begin
LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]};
end
else
begin
LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]} + 1'b1;
end
end
else
begin
LENGTH_DIV4 <= LENGTH_DIV4;
end
end
//
reg [15:0] rd_cnts; // 计数器 开始往外 写数据
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
rd_cnts<=16'hffff;
end
else if(rd_cnts<=16'd1600)//写完包的最后一个。清零,不影响下一帧的写入
begin
rd_cnts<=rd_cnts + 1'b1;
end
else if((local_cnts==16'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
rd_cnts<=16'd0;
end
else
begin
rd_cnts<=rd_cnts;
end
end
//
reg [15:0] addrb_0;
reg [15:0] addrb_1;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addrb_0<=16'd0;
end
else if(rd_cnts==16'd1599)
begin
addrb_0<=16'd0;
end
else if((select_0_1==1'b0)&&(rd_cnts<=16'd1539)&&(rd_cnts<=all_dat_num_0)&&(rd_cnts>=16'd0))
begin
addrb_0<=addrb_0 + 1'b1;
end
else
begin
addrb_0<=addrb_0;
end
end
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addrb_1<=16'd0;
end
else if(rd_cnts==16'd1599)
begin
addrb_1<=16'd0;
end
else if((select_0_1==1'b1)&&(rd_cnts<=16'd1539)&&(rd_cnts<=all_dat_num_1)&&(rd_cnts>=16'd0))
begin
addrb_1<=addrb_1 + 1'b1;
end
else
begin
addrb_1<=addrb_1;
end
end
//
reg real_clk_p; // 原文有bug
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
real_clk_p<=1'b0;
end
else if(((select_0_1==1'b1)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_1+1))&&(rd_cnts>=16'd2))||((select_0_1==1'b0)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_0+1))&&(rd_cnts>=16'd2)))
begin
real_clk_p<=1'b1;
end
else
begin
real_clk_p<=1'b0;
end
end
reg dout_clk_p; // 原文有 bug
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
dout_clk_p<=1'b0;
end
else if((rd_cnts>=16'd1)&&(rd_cnts<=16'd1541))
begin
if(( select_0_1==1'b1 )&&( rd_cnts <= ( all_dat_num_1 + 1 )))
begin
dout_clk_p<=1'b1;
end
else if((select_0_1==1'b0 )&&( rd_cnts <= ( all_dat_num_0 + 1 )))
begin
dout_clk_p<=1'b1;
end
else
begin
dout_clk_p<=1'b0;
end
end
else
begin
dout_clk_p<=dout_clk_p;
end
end
//
wire [7:0] doutb_0;
wire [7:0] doutb_1;
reg [15:0] dout;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
dout<=16'd0;
end
else if(rd_cnts==16'd1)
begin
if(select_0_1==1'b1)
begin
dout<=all_dat_num_1 ;
end
else
begin
dout<=all_dat_num_0 ;
end
end
else
begin
if(select_0_1==1'b1)
begin
dout<={dout[15:8],doutb_1};
end
else
begin
dout<={dout[15:8],doutb_0};
end
end
end
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
blk_mem_8_2048 BLKS_A_0 (
.clka(clk ),// input wire clka
.ena(1'b1 ),// input wire ena
.wea(wea_0 ),// input wire [0 : 0] wea
.addra(addra_0 ),// input wire [10 : 0] addra
.dina(delay_dina_2 ),// input wire [7 : 0] dina
.douta( ),// output wire [7 : 0] douta 不用
.clkb(clk ),// input wire clkb
.web(1'b0 ),// input wire [0 : 0] web
.addrb(addrb_0 ),// input wire [10 : 0] addrb
.dinb( ),// input wire [7 : 0] dinb 不用
.doutb(doutb_0 ) // output wire [7 : 0] doutb
);
//
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
blk_mem_8_2048 BLKS_A_1 (
.clka(clk ),// input wire clka
.ena(1'b1 ),// input wire ena
.wea(wea_1 ),// input wire [0 : 0] wea
.addra(addra_1 ),// input wire [10 : 0] addra
.dina(delay_dina_2 ),// input wire [7 : 0] dina
.douta( ),// output wire [7 : 0] douta 不用
.clkb(clk ),// input wire clkb
.web(1'b0 ),// input wire [0 : 0] web
.addrb(addrb_1 ),// input wire [10 : 0] addrb
.dinb( ),// input wire [7 : 0] dinb 不用
.doutb(doutb_1 ) // output wire [7 : 0] doutb
);
//
//ila_data_recv ila_data_recv (
// .clk(clk), // input wire clk
// .probe0(din), // input wire [7:0] probe0
// .probe1(din_clk_p), // input wire [0:0] probe1
// .probe2(delay_din_clk_p), // input wire [0:0] probe2
// .probe3(select_0_1), // input wire [0:0] probe3
// .probe4(pack_check_pulse), // input wire [0:0] probe4
// .probe5(pack_check), // input wire [0:0] probe5
// .probe6(pack_end), // input wire [0:0] probe6
// .probe7(length_check_pulse), // input wire [0:0] probe7
// .probe8(length_check), // input wire [0:0] probe8
// .probe9(local_length), // input wire [7:0] probe9
// .probe10(wr_pulse), // input wire [0:0] probe10
// .probe11(local_cnts), // input wire [15:0] probe11
// .probe12(wea_0), // input wire [0:0] probe12
// .probe13(wea_1), // input wire [0:0] probe13
// .probe14(addra_0), // input wire [15:0] probe14
// .probe15(addra_1), // input wire [15:0] probe15
// .probe16(delay_dina_0), // input wire [7:0] probe16
// .probe17(delay_dina_1), // input wire [7:0] probe17
// .probe18(delay_dina_2), // input wire [7:0] probe18
// .probe19(all_dat_num_0), // input wire [15:0] probe19
// .probe20(all_dat_num_1), // input wire [15:0] probe20
// .probe21(rd_cnts), // input wire [15:0] probe21
// .probe22(addrb_0), // input wire [15:0] probe22
// .probe23(addrb_1), // input wire [15:0] probe23
// .probe24(real_clk_p), // input wire [0:0] probe24
// .probe25(dout_clk_p), // input wire [0:0] probe25
// .probe26(doutb_0), // input wire [7:0] probe26
// .probe27(doutb_1), // input wire [7:0] probe27
// .probe28(dout), // input wire [15:0] probe28
// .probe29(LENGTH_REAL), // input wire [15:0] probe29
// .probe30(LENGTH_THIMBLE), // input wire [23:0] probe30
// .probe31(LENGTH_DIV4), // input wire [15:0] probe31
// .probe32(thimble_valid) // input wire [0:0] probe32
//);
endmodule
升级版本: 丢失一小包 整包全部丢弃
c
复制代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/08/09 19:24:42
// Design Name:
// Module Name: dat_recv_block_complete
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module dat_recv_block_complete(
clk ,//系统时钟,110M
rst ,//系统复位,高有效
din ,//接收到的数据,第一个数据为总帧长[8],其余数据均为8比特数据
din_clk_p ,//接收到的数据时钟,脉冲型
dout ,//链路数据,16比特
real_clk_p ,//接收到有效数据时钟,脉冲型
dout_clk_p , //链路数据时钟,脉冲型
LENGTH_REAL ,
LENGTH_THIMBLE ,
LENGTH_DIV4 ,
thimble_valid
);
//
input clk ;//系统时钟,110M
input rst ;//系统复位,高有效
input [7:0] din ;//接收到的数据,第一个数据为总帧长[16],其余数据均为8比特数据
input din_clk_p ;//接收到的数据时钟,脉冲型
output [15:0] dout;//链路数据,16比特
output real_clk_p ;//接收到有效数据时钟,脉冲型
output dout_clk_p ;//链路数据时钟,脉冲型
// 给传输上位机网口模块的
output [15:0] LENGTH_REAL ;//发送625字节
output [23:0] LENGTH_THIMBLE ;//发送625字节
output [15:0] LENGTH_DIV4 ;//发送625字节
output thimble_valid ;
//
reg delay_din_clk_p;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_din_clk_p<=1'b0;
end
else
begin
delay_din_clk_p<=din_clk_p;
end
end
//
reg select_0_1 ;
always @ (posedge clk or posedge rst)//提取帧计数,将前后两包区分开,避免两帧不是同一包的情况
begin
if(rst)
begin
select_0_1<=1'b0;
end
else if((din_clk_p==1'b1)&&(delay_din_clk_p==1'b0))//posedge
begin
select_0_1<=din[0];
end
else
begin
select_0_1<=select_0_1;
end
end
//
reg pack_check_pulse;// 检测到一包数据
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
pack_check_pulse<=1'b0;
end
else if((din_clk_p==1'b1)&&(delay_din_clk_p==1'b0))//posedge
begin
pack_check_pulse<=1'b1;
end
else
begin
pack_check_pulse<=1'b0;
end
end
//
reg [15:0] min_length; // 求出这包数据的最短长度,用于最终判决是否丢数据
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
min_length<=16'd0;
end
else if(pack_check_pulse==1'b1)//pulse
begin
case(din[3:0])
4'd1: begin min_length<=16'd0; end
4'd2: begin min_length<=16'd220; end
4'd3: begin min_length<=16'd440; end
4'd4: begin min_length<=16'd660; end
4'd5: begin min_length<=16'd880; end
4'd6: begin min_length<=16'd1100; end
4'd7: begin min_length<=16'd1320; end
default: begin min_length<=16'd0; end
endcase
end
else
begin
min_length<=min_length;//hold
end
end
//
reg pack_check;//接收到的包指示是否正确判决
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
pack_check<=1'b0;
end
else if(pack_check_pulse==1'b1)//pulse
begin
if((din[7:4]<=din[3:0])&&(din[7:4]>=4'd1)&&(din[7:4]<=4'd7))//区间正确
begin
pack_check<=1'b1;
end
else
begin
pack_check<=1'b0;//区间错误,检查存在异常
end
end
else
begin
pack_check<=pack_check;//hold
end
end
//
reg pack_end; // 检测最后一包
always @ (posedge clk or posedge rst)//接收到的包指示是否正确判决
begin
if(rst)
begin
pack_end<=1'b0;
end
else if(pack_check_pulse==1'b1)//pulse
begin
if((din[7:4]==din[3:0])&&(din[7:4]>=4'd1)&&(din[7:4]<=4'd7))//区间正确
begin
pack_end<=1'b1;
end
else
begin
pack_end<=1'b0;//区间错误,检查存在异常
end
end
else
begin
pack_end<=pack_end;//hold
end
end
//
reg length_check_pulse;// pack_check 延迟一拍
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
length_check_pulse<=1'b0;
end
else
begin
length_check_pulse<=pack_check_pulse;
end
end
//
reg length_check;//包长度检测
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
length_check<=1'b0;
end
else if(length_check_pulse)
begin
if((din<=8'd220)&&(din>=8'd1))//当前数据包长度也正确
begin
length_check<=1'b1;
end
else
begin
length_check<=1'b0; //当前数据包长度错误
end
end
else
begin
length_check<=length_check;//保持
end
end
//
reg [7:0] local_length;//从每一包中提取长度
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
local_length<=8'd0;
end
else if(length_check_pulse)
begin
local_length<=din;
end
else
begin
local_length<=local_length;//保持
end
end
//
reg wr_pulse;// pack_check 延迟二拍
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
wr_pulse<=1'b0;
end
else
begin
wr_pulse<=length_check_pulse;
end
end
//
reg [15:0] local_cnts; // 检测通过的情况下,根据 wr_pulse 开始计数
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
local_cnts<=16'hffff;
end
else if(local_cnts<=16'd230)
begin
local_cnts<=local_cnts + 1'b1;
end
else if((wr_pulse==1'b1)&&(length_check==1'b1)&&(pack_check==1'b1))
begin
local_cnts<=16'd0;
end
else
begin
local_cnts<=local_cnts;
end
end
//
reg wea_0 ;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
wea_0<=1'b0;
end
else if((select_0_1==1'b0)&&(local_cnts<=16'd220)&&(local_cnts<=local_length)&&(local_cnts>=16'd1))
begin
wea_0<=1'b1;
end
else
begin
wea_0<=1'b0;
end
end
//
reg wea_1 ; // 写入 ram 的 enable 信号
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
wea_1<=1'b0;
end
else if((select_0_1==1'b1)&&(local_cnts<=16'd220)&&(local_cnts<=local_length)&&(local_cnts>=16'd1))
begin
wea_1<=1'b1;
end
else
begin
wea_1<=1'b0;
end
end
//
reg [15:0] addra_0;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addra_0<=16'd0;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
addra_0<=16'd0;
end
else if((select_0_1==1'b0)&&(local_cnts<=16'd221)&&(local_cnts<=(local_length + 1'b1))&&(local_cnts>=16'd2))
begin
addra_0<=addra_0 + 1'b1;
end
else
begin
addra_0<=addra_0;
end
end
//
reg [15:0] addra_1; // 写入 ram 的 地址
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addra_1<=16'd0;
end
else if((select_0_1==1'b1)&&(local_cnts==16'd228)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
addra_1<=16'd0;
end
else if((select_0_1==1'b1)&&(local_cnts<=16'd221)&&(local_cnts<=(local_length +1'b1 ))&&(local_cnts>=16'd2))
begin
addra_1<=addra_1 + 1'b1;
end
else
begin
addra_1<=addra_1;
end
end
//
reg [7:0] delay_dina_0 ; // 延迟 din
reg [7:0] delay_dina_1 ; // 延迟 din
reg [7:0] delay_dina_2 ; // 延迟 din
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_dina_0<=8'd0;
end
else
begin
delay_dina_0<=din;
end
end
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_dina_1<=8'd0;
end
else
begin
delay_dina_1<=delay_dina_0;
end
end
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
delay_dina_2<=8'd0;
end
else
begin
delay_dina_2<=delay_dina_1;
end
end
//RD STATE
reg [15:0] all_dat_num_0;
reg [15:0] all_dat_num_1; // 写入的总数
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
all_dat_num_0<=16'd2047;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
all_dat_num_0<=addra_0;
end
else
begin
all_dat_num_0<=all_dat_num_0;
end
end
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
all_dat_num_1<=16'd2047;
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
all_dat_num_1<=addra_1;
end
else
begin
all_dat_num_1<=all_dat_num_1;
end
end
//
reg output_flag; // 检测数据包的长度是否大于最小的长度,符合则输出,不符合则丢弃这包数据
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
output_flag<=1'b1;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_0 >= min_length)
begin
output_flag<=1'b1;
end
else
begin
output_flag<=1'b0;
end
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_1 >= min_length)
begin
output_flag<=1'b1;
end
else
begin
output_flag<=1'b0;
end
end
else
begin
output_flag<=output_flag;
end
end
//
reg [15:0] LENGTH_REAL ;//数据的总长度
reg [23:0] LENGTH_THIMBLE ;//顶针的数据长度
reg [15:0] LENGTH_DIV4 ;//网络的最低传输长度
reg thimble_valid ;//是否需要顶针
always @ (posedge clk or posedge rst) // LENGTH_REAL 数据的总长度
begin
if(rst)
begin
LENGTH_REAL<=16'd2047;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
LENGTH_REAL<=addra_0;
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
LENGTH_REAL<=addra_1;
end
else
begin
LENGTH_REAL<=LENGTH_REAL;
end
end
always @ (posedge clk or posedge rst) // thimble_valid 是否需要顶针
begin
if(rst)
begin
thimble_valid <= 1'd0; // 默认不顶针
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_0[1:0] == 2'd0)
begin
thimble_valid <= 1'b0;
end
else
begin
thimble_valid <= 1'b1;
end
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_1[1:0] == 2'd0)
begin
thimble_valid <= 1'b0;
end
else
begin
thimble_valid <= 1'b1;
end
end
else
begin
thimble_valid <= thimble_valid;
end
end
always @ (posedge clk or posedge rst) // LENGTH_THIMBLE 顶针的数据长度
begin
if(rst)
begin
LENGTH_THIMBLE <= 24'd0;
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
case(addra_0[1:0])
2'b00:begin LENGTH_THIMBLE <= 24'd0; end
2'b01:begin LENGTH_THIMBLE <= 24'd3; end
2'b10:begin LENGTH_THIMBLE <= 24'd2; end
2'b11:begin LENGTH_THIMBLE <= 24'd1; end
default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE; end
endcase
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin // addra_1[1:0]
case(addra_1[1:0])
2'b00:begin LENGTH_THIMBLE <= 24'd0; end
2'b01:begin LENGTH_THIMBLE <= 24'd3; end
2'b10:begin LENGTH_THIMBLE <= 24'd2; end
2'b11:begin LENGTH_THIMBLE <= 24'd1; end
default:begin LENGTH_THIMBLE<=LENGTH_THIMBLE; end
endcase
end
else
begin
LENGTH_THIMBLE <= LENGTH_THIMBLE;
end
end
always @ (posedge clk or posedge rst) // LENGTH_DIV4 网络的最低传输长度
begin
if(rst)
begin
LENGTH_DIV4 <= 16'd0; // 默认不顶针
end
else if((select_0_1==1'b0)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_0[1:0] == 2'd0) // 不顶针
begin
LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]};
end
else
begin
LENGTH_DIV4 <= {addra_0[15],addra_0[15],addra_0[15:2]} + 1'b1;
end
end
else if((select_0_1==1'b1)&&(local_cnts==16'd224)&&(pack_end==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
if(addra_1[1:0] == 2'd0)
begin
LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]};
end
else
begin
LENGTH_DIV4 <= {addra_1[15],addra_1[15],addra_1[15:2]} + 1'b1;
end
end
else
begin
LENGTH_DIV4 <= LENGTH_DIV4;
end
end
//
reg [15:0] rd_cnts; // 计数器 开始往外 写数据
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
rd_cnts<=16'hffff;
end
else if(rd_cnts<=16'd1600)//写完包的最后一个。清零,不影响下一帧的写入
begin
rd_cnts<=rd_cnts + 1'b1;
end
else if((local_cnts==16'd228)&&(pack_end==1'b1)&&(output_flag==1'b1))//写完包的最后一个。清零,不影响下一帧的写入
begin
rd_cnts<=16'd0;
end
else
begin
rd_cnts<=rd_cnts;
end
end
//
reg [15:0] addrb_0;
reg [15:0] addrb_1;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addrb_0<=16'd0;
end
else if(rd_cnts==16'd1599)
begin
addrb_0<=16'd0;
end
else if((select_0_1==1'b0)&&(rd_cnts<=16'd1539)&&(rd_cnts<=all_dat_num_0)&&(rd_cnts>=16'd0))
begin
addrb_0<=addrb_0 + 1'b1;
end
else
begin
addrb_0<=addrb_0;
end
end
//
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
addrb_1<=16'd0;
end
else if(rd_cnts==16'd1599)
begin
addrb_1<=16'd0;
end
else if((select_0_1==1'b1)&&(rd_cnts<=16'd1539)&&(rd_cnts<=all_dat_num_1)&&(rd_cnts>=16'd0))
begin
addrb_1<=addrb_1 + 1'b1;
end
else
begin
addrb_1<=addrb_1;
end
end
//
reg real_clk_p; // 原文有bug
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
real_clk_p<=1'b0;
end
else if(((select_0_1==1'b1)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_1+1))&&(rd_cnts>=16'd2))||((select_0_1==1'b0)&&(rd_cnts<=16'd1540)&&(rd_cnts<=(all_dat_num_0+1))&&(rd_cnts>=16'd2)))
begin
real_clk_p<=1'b1;
end
else
begin
real_clk_p<=1'b0;
end
end
reg dout_clk_p; // 原文有 bug
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
dout_clk_p<=1'b0;
end
else if((rd_cnts>=16'd1)&&(rd_cnts<=16'd1541))
begin
if(( select_0_1==1'b1 )&&( rd_cnts <= ( all_dat_num_1 + 1 )))
begin
dout_clk_p<=1'b1;
end
else if((select_0_1==1'b0 )&&( rd_cnts <= ( all_dat_num_0 + 1 )))
begin
dout_clk_p<=1'b1;
end
else
begin
dout_clk_p<=1'b0;
end
end
else
begin
dout_clk_p<=dout_clk_p;
end
end
//
wire [7:0] doutb_0;
wire [7:0] doutb_1;
reg [15:0] dout;
always @ (posedge clk or posedge rst)
begin
if(rst)
begin
dout<=16'd0;
end
else if(rd_cnts==16'd1)
begin
if(select_0_1==1'b1)
begin
dout<=all_dat_num_1 ;
end
else
begin
dout<=all_dat_num_0 ;
end
end
else
begin
if(select_0_1==1'b1)
begin
dout<={dout[15:8],doutb_1};
end
else
begin
dout<={dout[15:8],doutb_0};
end
end
end
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
blk_mem_8_2048 BLKS_A_0 (
.clka(clk ),// input wire clka
.ena(1'b1 ),// input wire ena
.wea(wea_0 ),// input wire [0 : 0] wea
.addra(addra_0 ),// input wire [10 : 0] addra
.dina(delay_dina_2 ),// input wire [7 : 0] dina
.douta( ),// output wire [7 : 0] douta 不用
.clkb(clk ),// input wire clkb
.web(1'b0 ),// input wire [0 : 0] web
.addrb(addrb_0 ),// input wire [10 : 0] addrb
.dinb( ),// input wire [7 : 0] dinb 不用
.doutb(doutb_0 ) // output wire [7 : 0] doutb
);
//
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
blk_mem_8_2048 BLKS_A_1 (
.clka(clk ),// input wire clka
.ena(1'b1 ),// input wire ena
.wea(wea_1 ),// input wire [0 : 0] wea
.addra(addra_1 ),// input wire [10 : 0] addra
.dina(delay_dina_2 ),// input wire [7 : 0] dina
.douta( ),// output wire [7 : 0] douta 不用
.clkb(clk ),// input wire clkb
.web(1'b0 ),// input wire [0 : 0] web
.addrb(addrb_1 ),// input wire [10 : 0] addrb
.dinb( ),// input wire [7 : 0] dinb 不用
.doutb(doutb_1 ) // output wire [7 : 0] doutb
);
//
ila_data_recv_com ila_data_recv_com (
.clk(clk), // input wire clk
.probe0(din), // input wire [7:0] probe0
.probe1(din_clk_p), // input wire [0:0] probe1
.probe2(delay_din_clk_p), // input wire [0:0] probe2
.probe3(select_0_1), // input wire [0:0] probe3
.probe4(pack_check_pulse), // input wire [0:0] probe4
.probe5(pack_check), // input wire [0:0] probe5
.probe6(pack_end), // input wire [0:0] probe6
.probe7(length_check_pulse), // input wire [0:0] probe7
.probe8(length_check), // input wire [0:0] probe8
.probe9(local_length), // input wire [7:0] probe9
.probe10(wr_pulse), // input wire [0:0] probe10
.probe11(local_cnts), // input wire [15:0] probe11
.probe12(wea_0), // input wire [0:0] probe12
.probe13(wea_1), // input wire [0:0] probe13
.probe14(addra_0), // input wire [15:0] probe14
.probe15(addra_1), // input wire [15:0] probe15
.probe16(delay_dina_0), // input wire [7:0] probe16
.probe17(delay_dina_1), // input wire [7:0] probe17
.probe18(delay_dina_2), // input wire [7:0] probe18
.probe19(all_dat_num_0), // input wire [15:0] probe19
.probe20(all_dat_num_1), // input wire [15:0] probe20
.probe21(rd_cnts), // input wire [15:0] probe21
.probe22(addrb_0), // input wire [15:0] probe22
.probe23(addrb_1), // input wire [15:0] probe23
.probe24(real_clk_p), // input wire [0:0] probe24
.probe25(dout_clk_p), // input wire [0:0] probe25
.probe26(doutb_0), // input wire [7:0] probe26
.probe27(doutb_1), // input wire [7:0] probe27
.probe28(dout), // input wire [15:0] probe28
.probe29(LENGTH_REAL), // input wire [15:0] probe29
.probe30(LENGTH_THIMBLE), // input wire [23:0] probe30
.probe31(LENGTH_DIV4), // input wire [15:0] probe31
.probe32(thimble_valid), // input wire [0:0] probe32
.probe33(min_length), // input wire [15:0] probe33
.probe34(output_flag) // input wire [0:0] probe34
);
endmodule