/*
|
/*
|
* tsu.v
|
* tsu.v
|
*
|
*
|
* Copyright (c) 2012, BABY&HW. All rights reserved.
|
* Copyright (c) 2012, BABY&HW. All rights reserved.
|
*
|
*
|
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
* License as published by the Free Software Foundation; either
|
* License as published by the Free Software Foundation; either
|
* version 2.1 of the License, or (at your option) any later version.
|
* version 2.1 of the License, or (at your option) any later version.
|
*
|
*
|
* This library is distributed in the hope that it will be useful,
|
* This library is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
*
|
*
|
* You should have received a copy of the GNU Lesser General Public
|
* You should have received a copy of the GNU Lesser General Public
|
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
*/
|
*/
|
|
|
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
|
|
module tsu (
|
module tsu (
|
input rst,
|
input rst,
|
|
|
input gmii_clk,
|
input gmii_clk,
|
input gmii_ctrl,
|
input gmii_ctrl,
|
input [7:0] gmii_data,
|
input [7:0] gmii_data,
|
input giga_mode,
|
input giga_mode,
|
|
|
input [7:0] ptp_msgid_mask,
|
input [7:0] ptp_msgid_mask,
|
|
|
input rtc_timer_clk,
|
input rtc_timer_clk,
|
input [79:0] rtc_timer_in, // timeStamp1s_48bit + timeStamp1ns_32bit
|
input [79:0] rtc_timer_in, // timeStamp1s_48bit + timeStamp1ns_32bit
|
|
|
input q_rst,
|
input q_rst,
|
input q_rd_clk,
|
input q_rd_clk,
|
input q_rd_en,
|
input q_rd_en,
|
output [ 7:0] q_rd_stat,
|
output [ 7:0] q_rd_stat,
|
output [127:0] q_rd_data // null_16bit + timeStamp1s_48bit + timeStamp1ns_32bit + msgId_4bit + ckSum_12bit + seqId_16bit
|
output [127:0] q_rd_data // null_16bit + timeStamp1s_48bit + timeStamp1ns_32bit + msgId_4bit + ckSum_12bit + seqId_16bit
|
);
|
);
|
|
|
// mii to gmii converter
|
// mii to gmii converter
|
reg nibble_h;
|
reg nibble_h;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst)
|
if (rst)
|
nibble_h <= 1'b0;
|
nibble_h <= 1'b0;
|
else if (gmii_ctrl)
|
else if (gmii_ctrl)
|
nibble_h <= !nibble_h;
|
nibble_h <= !nibble_h;
|
end
|
end
|
|
|
reg gmii_ctrl_conv;
|
reg gmii_ctrl_conv;
|
reg [7:0] gmii_data_conv;
|
reg [7:0] gmii_data_conv;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst) begin
|
if (rst) begin
|
gmii_ctrl_conv <= 1'b0;
|
gmii_ctrl_conv <= 1'b0;
|
gmii_data_conv <= 8'd0;
|
gmii_data_conv <= 8'd0;
|
end
|
end
|
else begin
|
else begin
|
if (giga_mode) begin
|
if (giga_mode) begin
|
gmii_ctrl_conv <= gmii_ctrl;
|
gmii_ctrl_conv <= gmii_ctrl;
|
gmii_data_conv[7:0] <= gmii_data[7:0];
|
gmii_data_conv[7:0] <= gmii_data[7:0];
|
end
|
end
|
else begin
|
else begin
|
// 4b-8b datapath gearbox
|
// 4b-8b datapath gearbox
|
if (gmii_ctrl) begin
|
if (gmii_ctrl) begin
|
gmii_ctrl_conv <= ( nibble_h)? 1'b1:1'b0;
|
gmii_ctrl_conv <= ( nibble_h)? 1'b1:1'b0;
|
gmii_data_conv[7:4] <= ( nibble_h)? gmii_data[3:0]:gmii_data_conv[7:4];
|
gmii_data_conv[7:4] <= ( nibble_h)? gmii_data[3:0]:gmii_data_conv[7:4];
|
gmii_data_conv[3:0] <= (!nibble_h)? gmii_data[3:0]:gmii_data_conv[3:0];
|
gmii_data_conv[3:0] <= (!nibble_h)? gmii_data[3:0]:gmii_data_conv[3:0];
|
end
|
end
|
else begin
|
else begin
|
gmii_ctrl_conv <= 1'b0;
|
gmii_ctrl_conv <= 1'b0;
|
gmii_data_conv[7:4] <= gmii_data_conv[7:4];
|
gmii_data_conv[7:4] <= gmii_data_conv[7:4];
|
gmii_data_conv[3:0] <= gmii_data_conv[3:0];
|
gmii_data_conv[3:0] <= gmii_data_conv[3:0];
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// buffer gmii input
|
// buffer gmii input
|
reg gmii_ctrl_conv_d1, gmii_ctrl_conv_d2, gmii_ctrl_conv_d3, gmii_ctrl_conv_d4,
|
reg gmii_ctrl_conv_d1, gmii_ctrl_conv_d2, gmii_ctrl_conv_d3, gmii_ctrl_conv_d4,
|
gmii_ctrl_conv_d5, gmii_ctrl_conv_d6, gmii_ctrl_conv_d7, gmii_ctrl_conv_d8,
|
gmii_ctrl_conv_d5, gmii_ctrl_conv_d6, gmii_ctrl_conv_d7, gmii_ctrl_conv_d8,
|
gmii_ctrl_conv_d9, gmii_ctrl_conv_da;
|
gmii_ctrl_conv_d9, gmii_ctrl_conv_da;
|
reg [7:0] gmii_data_conv_d1, gmii_data_conv_d2, gmii_data_conv_d3, gmii_data_conv_d4,
|
reg [7:0] gmii_data_conv_d1, gmii_data_conv_d2, gmii_data_conv_d3, gmii_data_conv_d4,
|
gmii_data_conv_d5, gmii_data_conv_d6, gmii_data_conv_d7, gmii_data_conv_d8,
|
gmii_data_conv_d5, gmii_data_conv_d6, gmii_data_conv_d7, gmii_data_conv_d8,
|
gmii_data_conv_d9, gmii_data_conv_da;
|
gmii_data_conv_d9, gmii_data_conv_da;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst) begin
|
if (rst) begin
|
gmii_ctrl_conv_d1 <= 1'b0;
|
gmii_ctrl_conv_d1 <= 1'b0;
|
gmii_ctrl_conv_d2 <= 1'b0;
|
gmii_ctrl_conv_d2 <= 1'b0;
|
gmii_ctrl_conv_d3 <= 1'b0;
|
gmii_ctrl_conv_d3 <= 1'b0;
|
gmii_ctrl_conv_d4 <= 1'b0;
|
gmii_ctrl_conv_d4 <= 1'b0;
|
gmii_ctrl_conv_d5 <= 1'b0;
|
gmii_ctrl_conv_d5 <= 1'b0;
|
gmii_ctrl_conv_d6 <= 1'b0;
|
gmii_ctrl_conv_d6 <= 1'b0;
|
gmii_ctrl_conv_d7 <= 1'b0;
|
gmii_ctrl_conv_d7 <= 1'b0;
|
gmii_ctrl_conv_d8 <= 1'b0;
|
gmii_ctrl_conv_d8 <= 1'b0;
|
gmii_ctrl_conv_d9 <= 1'b0;
|
gmii_ctrl_conv_d9 <= 1'b0;
|
gmii_ctrl_conv_da <= 1'b0;
|
gmii_ctrl_conv_da <= 1'b0;
|
gmii_data_conv_d1 <= 8'd0;
|
gmii_data_conv_d1 <= 8'd0;
|
gmii_data_conv_d2 <= 8'd0;
|
gmii_data_conv_d2 <= 8'd0;
|
gmii_data_conv_d3 <= 8'd0;
|
gmii_data_conv_d3 <= 8'd0;
|
gmii_data_conv_d4 <= 8'd0;
|
gmii_data_conv_d4 <= 8'd0;
|
gmii_data_conv_d5 <= 8'd0;
|
gmii_data_conv_d5 <= 8'd0;
|
gmii_data_conv_d6 <= 8'd0;
|
gmii_data_conv_d6 <= 8'd0;
|
gmii_data_conv_d7 <= 8'd0;
|
gmii_data_conv_d7 <= 8'd0;
|
gmii_data_conv_d8 <= 8'd0;
|
gmii_data_conv_d8 <= 8'd0;
|
gmii_data_conv_d9 <= 8'd0;
|
gmii_data_conv_d9 <= 8'd0;
|
gmii_data_conv_da <= 8'd0;
|
gmii_data_conv_da <= 8'd0;
|
end
|
end
|
else begin
|
else begin
|
gmii_ctrl_conv_d1 <= gmii_ctrl_conv;
|
gmii_ctrl_conv_d1 <= gmii_ctrl_conv;
|
gmii_ctrl_conv_d2 <= gmii_ctrl_conv_d1;
|
gmii_ctrl_conv_d2 <= gmii_ctrl_conv_d1;
|
gmii_ctrl_conv_d3 <= gmii_ctrl_conv_d2;
|
gmii_ctrl_conv_d3 <= gmii_ctrl_conv_d2;
|
gmii_ctrl_conv_d4 <= gmii_ctrl_conv_d3;
|
gmii_ctrl_conv_d4 <= gmii_ctrl_conv_d3;
|
gmii_ctrl_conv_d5 <= gmii_ctrl_conv_d4;
|
gmii_ctrl_conv_d5 <= gmii_ctrl_conv_d4;
|
gmii_ctrl_conv_d6 <= gmii_ctrl_conv_d5;
|
gmii_ctrl_conv_d6 <= gmii_ctrl_conv_d5;
|
gmii_ctrl_conv_d7 <= gmii_ctrl_conv_d6;
|
gmii_ctrl_conv_d7 <= gmii_ctrl_conv_d6;
|
gmii_ctrl_conv_d8 <= gmii_ctrl_conv_d7;
|
gmii_ctrl_conv_d8 <= gmii_ctrl_conv_d7;
|
gmii_ctrl_conv_d9 <= gmii_ctrl_conv_d8;
|
gmii_ctrl_conv_d9 <= gmii_ctrl_conv_d8;
|
gmii_ctrl_conv_da <= gmii_ctrl_conv_d9;
|
gmii_ctrl_conv_da <= gmii_ctrl_conv_d9;
|
gmii_data_conv_d1 <= gmii_data_conv;
|
gmii_data_conv_d1 <= gmii_data_conv;
|
gmii_data_conv_d2 <= gmii_data_conv_d1;
|
gmii_data_conv_d2 <= gmii_data_conv_d1;
|
gmii_data_conv_d3 <= gmii_data_conv_d2;
|
gmii_data_conv_d3 <= gmii_data_conv_d2;
|
gmii_data_conv_d4 <= gmii_data_conv_d3;
|
gmii_data_conv_d4 <= gmii_data_conv_d3;
|
gmii_data_conv_d5 <= gmii_data_conv_d4;
|
gmii_data_conv_d5 <= gmii_data_conv_d4;
|
gmii_data_conv_d6 <= gmii_data_conv_d5;
|
gmii_data_conv_d6 <= gmii_data_conv_d5;
|
gmii_data_conv_d7 <= gmii_data_conv_d6;
|
gmii_data_conv_d7 <= gmii_data_conv_d6;
|
gmii_data_conv_d8 <= gmii_data_conv_d7;
|
gmii_data_conv_d8 <= gmii_data_conv_d7;
|
gmii_data_conv_d9 <= gmii_data_conv_d8;
|
gmii_data_conv_d9 <= gmii_data_conv_d8;
|
gmii_data_conv_da <= gmii_data_conv_d9;
|
gmii_data_conv_da <= gmii_data_conv_d9;
|
end
|
end
|
end
|
end
|
|
|
// choose buffered gmii input
|
// choose buffered gmii input
|
reg int_gmii_ctrl;
|
reg int_gmii_ctrl;
|
reg int_gmii_ctrl_d1, int_gmii_ctrl_d2, int_gmii_ctrl_d3, int_gmii_ctrl_d4,
|
reg int_gmii_ctrl_d1, int_gmii_ctrl_d2, int_gmii_ctrl_d3, int_gmii_ctrl_d4,
|
int_gmii_ctrl_d5;
|
int_gmii_ctrl_d5;
|
reg [7:0] int_gmii_data;
|
reg [7:0] int_gmii_data;
|
reg [7:0] int_gmii_data_d1, int_gmii_data_d2, int_gmii_data_d3, int_gmii_data_d4,
|
reg [7:0] int_gmii_data_d1, int_gmii_data_d2, int_gmii_data_d3, int_gmii_data_d4,
|
int_gmii_data_d5;
|
int_gmii_data_d5;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst) begin
|
if (rst) begin
|
int_gmii_ctrl <= 1'b0;
|
int_gmii_ctrl <= 1'b0;
|
int_gmii_data <= 8'h00;
|
int_gmii_data <= 8'h00;
|
int_gmii_ctrl_d1 <= 1'b0;
|
int_gmii_ctrl_d1 <= 1'b0;
|
int_gmii_data_d1 <= 8'h00;
|
int_gmii_data_d1 <= 8'h00;
|
int_gmii_ctrl_d2 <= 1'b0;
|
int_gmii_ctrl_d2 <= 1'b0;
|
int_gmii_data_d2 <= 8'h00;
|
int_gmii_data_d2 <= 8'h00;
|
int_gmii_ctrl_d3 <= 1'b0;
|
int_gmii_ctrl_d3 <= 1'b0;
|
int_gmii_data_d3 <= 8'h00;
|
int_gmii_data_d3 <= 8'h00;
|
int_gmii_ctrl_d4 <= 1'b0;
|
int_gmii_ctrl_d4 <= 1'b0;
|
int_gmii_data_d4 <= 8'h00;
|
int_gmii_data_d4 <= 8'h00;
|
int_gmii_ctrl_d5 <= 1'b0;
|
int_gmii_ctrl_d5 <= 1'b0;
|
int_gmii_data_d5 <= 8'h00;
|
int_gmii_data_d5 <= 8'h00;
|
end
|
end
|
else begin
|
else begin
|
if (giga_mode) begin
|
if (giga_mode) begin
|
int_gmii_ctrl <= gmii_ctrl_conv;
|
int_gmii_ctrl <= gmii_ctrl_conv;
|
int_gmii_data <= gmii_data_conv;
|
int_gmii_data <= gmii_data_conv;
|
int_gmii_ctrl_d1 <= gmii_ctrl_conv_d1;
|
int_gmii_ctrl_d1 <= gmii_ctrl_conv_d1;
|
int_gmii_data_d1 <= gmii_data_conv_d1;
|
int_gmii_data_d1 <= gmii_data_conv_d1;
|
int_gmii_ctrl_d2 <= gmii_ctrl_conv_d2;
|
int_gmii_ctrl_d2 <= gmii_ctrl_conv_d2;
|
int_gmii_data_d2 <= gmii_data_conv_d2;
|
int_gmii_data_d2 <= gmii_data_conv_d2;
|
int_gmii_ctrl_d3 <= gmii_ctrl_conv_d3;
|
int_gmii_ctrl_d3 <= gmii_ctrl_conv_d3;
|
int_gmii_data_d3 <= gmii_data_conv_d3;
|
int_gmii_data_d3 <= gmii_data_conv_d3;
|
int_gmii_ctrl_d4 <= gmii_ctrl_conv_d4;
|
int_gmii_ctrl_d4 <= gmii_ctrl_conv_d4;
|
int_gmii_data_d4 <= gmii_data_conv_d4;
|
int_gmii_data_d4 <= gmii_data_conv_d4;
|
int_gmii_ctrl_d5 <= gmii_ctrl_conv_d5;
|
int_gmii_ctrl_d5 <= gmii_ctrl_conv_d5;
|
int_gmii_data_d5 <= gmii_data_conv_d5;
|
int_gmii_data_d5 <= gmii_data_conv_d5;
|
end
|
end
|
else begin
|
else begin
|
int_gmii_ctrl <= gmii_ctrl_conv;
|
int_gmii_ctrl <= gmii_ctrl_conv;
|
int_gmii_data <= gmii_data_conv;
|
int_gmii_data <= gmii_data_conv;
|
int_gmii_ctrl_d1 <= gmii_ctrl_conv_d2;
|
int_gmii_ctrl_d1 <= gmii_ctrl_conv_d2;
|
int_gmii_data_d1 <= gmii_data_conv_d2;
|
int_gmii_data_d1 <= gmii_data_conv_d2;
|
int_gmii_ctrl_d2 <= gmii_ctrl_conv_d4;
|
int_gmii_ctrl_d2 <= gmii_ctrl_conv_d4;
|
int_gmii_data_d2 <= gmii_data_conv_d4;
|
int_gmii_data_d2 <= gmii_data_conv_d4;
|
int_gmii_ctrl_d3 <= gmii_ctrl_conv_d6;
|
int_gmii_ctrl_d3 <= gmii_ctrl_conv_d6;
|
int_gmii_data_d3 <= gmii_data_conv_d6;
|
int_gmii_data_d3 <= gmii_data_conv_d6;
|
int_gmii_ctrl_d4 <= gmii_ctrl_conv_d8;
|
int_gmii_ctrl_d4 <= gmii_ctrl_conv_d8;
|
int_gmii_data_d4 <= gmii_data_conv_d8;
|
int_gmii_data_d4 <= gmii_data_conv_d8;
|
int_gmii_ctrl_d5 <= gmii_ctrl_conv_da;
|
int_gmii_ctrl_d5 <= gmii_ctrl_conv_da;
|
int_gmii_data_d5 <= gmii_data_conv_da;
|
int_gmii_data_d5 <= gmii_data_conv_da;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// ptp CDC time stamping
|
// ptp CDC time stamping
|
wire ts_req = int_gmii_ctrl; // TODO: check frame start delimiter
|
wire ts_req = int_gmii_ctrl; // TODO: check frame start delimiter
|
reg ts_req_d1, ts_req_d2, ts_req_d3;
|
reg ts_req_d1, ts_req_d2, ts_req_d3;
|
always @(posedge rst or posedge rtc_timer_clk) begin
|
always @(posedge rst or posedge rtc_timer_clk) begin
|
if (rst) begin
|
if (rst) begin
|
ts_req_d1 <= 1'b0;
|
ts_req_d1 <= 1'b0;
|
ts_req_d2 <= 1'b0;
|
ts_req_d2 <= 1'b0;
|
ts_req_d3 <= 1'b0;
|
ts_req_d3 <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
ts_req_d1 <= ts_req;
|
ts_req_d1 <= ts_req;
|
ts_req_d2 <= ts_req_d1;
|
ts_req_d2 <= ts_req_d1;
|
ts_req_d3 <= ts_req_d2;
|
ts_req_d3 <= ts_req_d2;
|
end
|
end
|
end
|
end
|
reg [79:0] rtc_time_stamp;
|
reg [79:0] rtc_time_stamp;
|
always @(posedge rst or posedge rtc_timer_clk) begin
|
always @(posedge rst or posedge rtc_timer_clk) begin
|
if (rst)
|
if (rst)
|
rtc_time_stamp <= 80'd0;
|
rtc_time_stamp <= 80'd0;
|
else
|
else
|
if (ts_req_d2 & !ts_req_d3)
|
if (ts_req_d2 & !ts_req_d3)
|
rtc_time_stamp <= rtc_timer_in;
|
rtc_time_stamp <= rtc_timer_in;
|
end
|
end
|
reg ts_ack, ts_ack_clr;
|
reg ts_ack, ts_ack_clr;
|
always @(posedge ts_ack_clr or posedge rtc_timer_clk) begin
|
always @(posedge ts_ack_clr or posedge rtc_timer_clk) begin
|
if (ts_ack_clr)
|
if (ts_ack_clr)
|
ts_ack <= 1'b0;
|
ts_ack <= 1'b0;
|
else
|
else
|
if (ts_req_d2 & !ts_req_d3)
|
if (ts_req_d2 & !ts_req_d3)
|
ts_ack <= 1'b1;
|
ts_ack <= 1'b1;
|
end
|
end
|
|
|
reg ts_ack_d1, ts_ack_d2, ts_ack_d3;
|
reg ts_ack_d1, ts_ack_d2, ts_ack_d3;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst) begin
|
if (rst) begin
|
ts_ack_d1 <= 1'b0;
|
ts_ack_d1 <= 1'b0;
|
ts_ack_d2 <= 1'b0;
|
ts_ack_d2 <= 1'b0;
|
ts_ack_d3 <= 1'b0;
|
ts_ack_d3 <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
ts_ack_d1 <= ts_ack;
|
ts_ack_d1 <= ts_ack;
|
ts_ack_d2 <= ts_ack_d1;
|
ts_ack_d2 <= ts_ack_d1;
|
ts_ack_d3 <= ts_ack_d2;
|
ts_ack_d3 <= ts_ack_d2;
|
end
|
end
|
end
|
end
|
reg [79:0] tsu_time_stamp;
|
reg [79:0] tsu_time_stamp;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst) begin
|
if (rst) begin
|
tsu_time_stamp <= 80'd0;
|
tsu_time_stamp <= 80'd0;
|
ts_ack_clr <= 1'b0;
|
ts_ack_clr <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
if (ts_ack_d2 & !ts_ack_d3) begin
|
if (ts_ack_d2 & !ts_ack_d3) begin
|
tsu_time_stamp <= rtc_time_stamp;
|
tsu_time_stamp <= rtc_time_stamp;
|
ts_ack_clr <= 1'b1;
|
ts_ack_clr <= 1'b1;
|
end
|
end
|
else begin
|
else begin
|
tsu_time_stamp <= tsu_time_stamp;
|
tsu_time_stamp <= tsu_time_stamp;
|
ts_ack_clr <= 1'b0;
|
ts_ack_clr <= 1'b0;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// 8b-32b datapath gearbox
|
// 8b-32b datapath gearbox
|
reg int_valid;
|
reg int_valid;
|
reg int_sop, int_eop;
|
reg int_sop, int_eop;
|
reg [ 1:0] int_bcnt, int_mod;
|
reg [ 1:0] int_bcnt, int_mod;
|
reg [31:0] int_data;
|
reg [31:0] int_data;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst)
|
if (rst)
|
int_bcnt <= 2'd0;
|
int_bcnt <= 2'd0;
|
else
|
else
|
if ( int_gmii_ctrl & !int_gmii_ctrl_d1)
|
if ( int_gmii_ctrl & !int_gmii_ctrl_d1)
|
int_bcnt <= 2'd0; // clear on sop
|
int_bcnt <= 2'd0; // clear on sop
|
else if ( int_gmii_ctrl)
|
else if ( int_gmii_ctrl)
|
int_bcnt <= int_bcnt + 2'd1; // increment
|
int_bcnt <= int_bcnt + 2'd1; // increment
|
else if (!int_gmii_ctrl & int_gmii_ctrl_d3 & (int_bcnt!=2'd0))
|
else if (!int_gmii_ctrl & int_gmii_ctrl_d3 & (int_bcnt!=2'd0))
|
int_bcnt <= int_bcnt + 2'd1; // end on eop with mod
|
int_bcnt <= int_bcnt + 2'd1; // end on eop with mod
|
end
|
end
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst) begin
|
if (rst) begin
|
int_data <= 32'd0;
|
int_data <= 32'd0;
|
int_valid <= 1'b0;
|
int_valid <= 1'b0;
|
int_mod <= 2'd0;
|
int_mod <= 2'd0;
|
end
|
end
|
else begin
|
else begin
|
if (int_gmii_ctrl) begin
|
if (int_gmii_ctrl) begin
|
int_data[ 7: 0] <= (int_bcnt==2'd3)? int_gmii_data_d1:int_data[ 7: 0];
|
int_data[ 7: 0] <= (int_bcnt==2'd3)? int_gmii_data_d1:int_data[ 7: 0];
|
int_data[15: 8] <= (int_bcnt==2'd2)? int_gmii_data_d1:int_data[15: 8];
|
int_data[15: 8] <= (int_bcnt==2'd2)? int_gmii_data_d1:int_data[15: 8];
|
int_data[23:16] <= (int_bcnt==2'd1)? int_gmii_data_d1:int_data[23:16];
|
int_data[23:16] <= (int_bcnt==2'd1)? int_gmii_data_d1:int_data[23:16];
|
int_data[31:24] <= (int_bcnt==2'd0)? int_gmii_data_d1:int_data[31:24];
|
int_data[31:24] <= (int_bcnt==2'd0)? int_gmii_data_d1:int_data[31:24];
|
end
|
end
|
|
|
if (int_gmii_ctrl & int_bcnt==2'd3)
|
if (int_gmii_ctrl & int_bcnt==2'd3)
|
int_valid <= 1'b1;
|
int_valid <= 1'b1;
|
else
|
else
|
int_valid <= 1'b0;
|
int_valid <= 1'b0;
|
|
|
if (int_gmii_ctrl_d1 & !int_gmii_ctrl_d2)
|
if (int_gmii_ctrl_d1 & !int_gmii_ctrl_d2)
|
int_mod <= 2'd0;
|
int_mod <= 2'd0;
|
else if (!int_gmii_ctrl_d1 & int_gmii_ctrl_d2)
|
else if (!int_gmii_ctrl_d1 & int_gmii_ctrl_d2)
|
int_mod <= int_bcnt;
|
int_mod <= int_bcnt;
|
|
|
if (int_gmii_ctrl_d4 & !int_gmii_ctrl_d5 & int_bcnt==2'd3)
|
if (int_gmii_ctrl_d4 & !int_gmii_ctrl_d5 & int_bcnt==2'd3)
|
int_sop <= 1'b1;
|
int_sop <= 1'b1;
|
else
|
else
|
int_sop <= 1'b0;
|
int_sop <= 1'b0;
|
|
|
if (!int_gmii_ctrl & int_gmii_ctrl_d3 & int_bcnt==2'd3)
|
if (!int_gmii_ctrl & int_gmii_ctrl_d3 & int_bcnt==2'd3)
|
int_eop <= 1'b1;
|
int_eop <= 1'b1;
|
else
|
else
|
int_eop <= 1'b0;
|
int_eop <= 1'b0;
|
|
|
end
|
end
|
end
|
end
|
|
|
reg [31:0] int_data_d1;
|
reg [31:0] int_data_d1;
|
reg int_valid_d1;
|
reg int_valid_d1;
|
reg int_sop_d1;
|
reg int_sop_d1;
|
reg int_eop_d1;
|
reg int_eop_d1;
|
reg [ 1:0] int_mod_d1;
|
reg [ 1:0] int_mod_d1;
|
always @(posedge rst or posedge gmii_clk) begin
|
always @(posedge rst or posedge gmii_clk) begin
|
if (rst) begin
|
if (rst) begin
|
int_data_d1 <= 32'h00000000;
|
int_data_d1 <= 32'h00000000;
|
int_valid_d1 <= 1'b0;
|
int_valid_d1 <= 1'b0;
|
int_sop_d1 <= 1'b0;
|
int_sop_d1 <= 1'b0;
|
int_eop_d1 <= 1'b0;
|
int_eop_d1 <= 1'b0;
|
int_mod_d1 <= 2'b00;
|
int_mod_d1 <= 2'b00;
|
end
|
end
|
else begin
|
else begin
|
if (int_valid) begin
|
if (int_valid) begin
|
int_data_d1 <= int_data;
|
int_data_d1 <= int_data;
|
int_mod_d1 <= int_mod;
|
int_mod_d1 <= int_mod;
|
end
|
end
|
int_valid_d1 <= int_valid;
|
int_valid_d1 <= int_valid;
|
int_sop_d1 <= int_sop;
|
int_sop_d1 <= int_sop;
|
int_eop_d1 <= int_eop;
|
int_eop_d1 <= int_eop;
|
end
|
end
|
end
|
end
|
|
|
// ptp packet parser here
|
// ptp packet parser here
|
// works at 1/4 gmii_clk frequency, needs multicycle timing constraint
|
// works at 1/4 gmii_clk frequency, needs multicycle timing constraint
|
wire ptp_found;
|
wire ptp_found;
|
wire [31:0] ptp_infor;
|
wire [31:0] ptp_infor;
|
ptp_parser parser(
|
ptp_parser parser(
|
.clk(gmii_clk),
|
.clk(gmii_clk),
|
.rst(rst),
|
.rst(rst),
|
.int_data(int_data_d1),
|
.int_data(int_data_d1),
|
.int_valid(int_valid_d1),
|
.int_valid(int_valid_d1),
|
.int_sop(int_sop_d1),
|
.int_sop(int_sop_d1),
|
.int_eop(int_eop_d1),
|
.int_eop(int_eop_d1),
|
.int_mod(int_mod_d1),
|
.int_mod(int_mod_d1),
|
.ptp_msgid_mask(ptp_msgid_mask),
|
.ptp_msgid_mask(ptp_msgid_mask),
|
.ptp_found(ptp_found),
|
.ptp_found(ptp_found),
|
.ptp_infor(ptp_infor)
|
.ptp_infor(ptp_infor)
|
);
|
);
|
|
|
// ptp time stamp dcfifo
|
// ptp time stamp dcfifo
|
wire q_wr_clk = gmii_clk;
|
wire q_wr_clk = gmii_clk;
|
wire q_wr_en = ptp_found && int_eop_d1;
|
wire q_wr_en = ptp_found && int_eop_d1;
|
wire [127:0] q_wr_data = {16'd0, tsu_time_stamp, ptp_infor}; // 16+80+32 bit
|
wire [127:0] q_wr_data = {16'd0, tsu_time_stamp, ptp_infor}; // 16+80+32 bit
|
wire [3:0] q_wrusedw;
|
wire [3:0] q_wrusedw;
|
wire [3:0] q_rdusedw;
|
wire [3:0] q_rdusedw;
|
|
wire q_wr_full;
|
|
wire q_rd_empty;
|
|
|
ptp_queue queue(
|
ptp_queue queue(
|
.aclr(q_rst),
|
.aclr(q_rst),
|
|
|
.wrclk(q_wr_clk),
|
.wrclk(q_wr_clk),
|
.wrreq(q_wr_en && q_wrusedw<15), // write with overflow protection
|
.wrreq(q_wr_en && !q_wr_full), // write with overflow protection
|
.data(q_wr_data),
|
.data(q_wr_data),
|
|
.wrfull(q_wr_full),
|
.wrusedw(q_wrusedw),
|
.wrusedw(q_wrusedw),
|
|
|
.rdclk(q_rd_clk),
|
.rdclk(q_rd_clk),
|
.rdreq(q_rd_en && q_rdusedw>0 ), // read with underflow protection
|
.rdreq(q_rd_en && !q_rd_empty), // read with underflow protection
|
.q(q_rd_data),
|
.q(q_rd_data),
|
|
.rdempty(q_rd_empty),
|
.rdusedw(q_rdusedw)
|
.rdusedw(q_rdusedw)
|
);
|
);
|
|
|
assign q_rd_stat = {4'd0, q_rdusedw};
|
assign q_rd_stat = {4'd0, q_rdusedw};
|
|
|
endmodule
|
endmodule
|
|
|