OpenCores
URL https://opencores.org/ocsvn/ha1588/ha1588/trunk

Subversion Repositories ha1588

[/] [ha1588/] [trunk/] [doc/] [tool/] [ptpv2_timing_analyzer/] [ptpv2_timing_analyzer.sce] - Rev 66

Compare with Previous | Blame | View Log

///*
// * ptpv2_timing_analyzer.sce
// * 
// * Copyright (c) 2013, BABY&HW. All rights reserved.
// *
// * This library is free software; you can redistribute it and/or
// * modify it under the terms of the GNU Lesser General Public
// * License as published by the Free Software Foundation; either
// * 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,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// * Lesser General Public License for more details.
// *
// * You should have received a copy of the GNU Lesser General Public
// * License along with this library; if not, write to the Free Software
// * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// * MA 02110-1301  USA
// */

clear;
clc;
stacksize('max');
/////////////////////////////////////
// Read pcap file for PTP
/////////////////////////////////////
pcapFile='ptpdv2_long.pcap';
fd1=mopen(pcapFile,'rb');
// skip file header
// check endianness
mseek(24); //24B

// parse capture
packetNum_cap         = {};
messageId_cap         = {};
clockId_cap           = {};
sequenceId_cap        = {};
embeddedTimestamp_cap = {};
capturedTimestamp_cap = {};
packetNum = 0;
while 1
  // parsing capture header per frame
  // get time stamp in second
  capturedTimestamp_Sec =mget(1,'uil',fd1);
  // get time stamp in nsecond
  capturedTimestamp_NSec=mget(1,'uil',fd1);
  // get capture length
  lCaptr=mget(1,'uil',fd1);
  // get frame length
  lFrame=mget(1,'uil',fd1);
  
  // ptp packet parsing here
  
  // ptp packet address filter here
  
  // ptp packet number
  packetNum=packetNum+1;
  
  // skip packet header
  mseek(mtell(fd1)+(14+20+8)); //14B:MAC, 20B:IP, 8B:UDP
  
  // messageId
  mseek(mtell(fd1)+0); // 0B from beginning of ptp
  messageId=modulo(mget(1,'ucb',fd1),2^4); //1B
  mseek(mtell(fd1)-(0+1)); //return to beginning of ptp
  
  // ClockIdentity
  mseek(mtell(fd1)+20); // 20B from beginning of ptp
  clockId=mget(1,'uib',fd1); //4B
  clockId=mget(1,'uib',fd1); //4B
  mseek(mtell(fd1)-(20+4+4)); //return to beginning of ptp
  
  // sequenceId
  mseek(mtell(fd1)+30); // 30B from beginning of ptp
  sequenceId=mget(1,'usb',fd1); //2B
  mseek(mtell(fd1)-(30+2)); //return to beginning of ptp
  
  // embeddedTimestamp
  mseek(mtell(fd1)+34); // 34B from beginning of ptp
  embeddedTimestamp_SecH=mget(1,'usb',fd1); //2B
  embeddedTimestamp_SecL=mget(1,'uib',fd1); //4B
  embeddedTimestamp_NSec=mget(1,'uib',fd1); //4B
  mseek(mtell(fd1)-(34+2+4+4)); //return to beginning of ptp
  
  // return to beginning of packet
  mseek(mtell(fd1)-(14+20+8)); //14B:MAC, 20B:IP, 8B:UDP
  
  // go to end of packet
  mseek(mtell(fd1)+lCaptr);
  
  // get ptp messages
  packetNum_cap         = [packetNum_cap, packetNum];
  messageId_cap         = [messageId_cap, messageId];
  clockId_cap           = [clockId_cap, clockId];
  sequenceId_cap        = [sequenceId_cap, sequenceId];
  embeddedTimestamp_cap = [embeddedTimestamp_cap, (embeddedTimestamp_SecH*4294967296 + embeddedTimestamp_SecL) + embeddedTimestamp_NSec*10^(-9)];
  capturedTimestamp_cap = [capturedTimestamp_cap,  capturedTimestamp_Sec                                       + capturedTimestamp_NSec*10^(-9)];
  
  // EOF checking
  mget(1,'ui',fd1);
  if meof(fd1)
    // break from the loop
    break;
  else
    // switch to the next packet
    mseek(mtell(fd1)-4);
  end
end
mtell;
mclose(fd1);

// find Master and Slave clockId
clockId_mastrs=clockId_cap(find(messageId_cap==0));
clockId_mastr =clockId_mastrs(1);
clockId_slaves=clockId_cap(find(clockId_cap~=clockId_mastr));
clockId_slave =clockId_slaves(1);

// function: calc_delta
funcprot(0);
function timestamp_delta=calc_delta(timestamp)
  timestamp=timestamp-timestamp(1);
  timestamp_delta=zeros(1,length(timestamp)-1);
  for i = 1:(length(timestamp)-1)
    timestamp_delta(i)=timestamp(i+1)-timestamp(i);
  end
endfunction

///////////////////////////////////////
// Generate CSV
///////////////////////////////////////
// [packetNum_cap', capturedTimestamp_cap', messageId_cap', clockId_cap', sequenceId_cap', embeddedTimestamp_cap']

// Port Direction
clockId_str_cap={};
for i = 1:length(clockId_cap)
  select clockId_cap(i)
    case  clockId_mastr then clockId_str_cap = {clockId_str_cap, 'M -> S'},
    else                     clockId_str_cap = {clockId_str_cap, 'M <- S'},
  end
end

// MessageId
messageId_str_cap={};
for i = 1:length(messageId_cap)
  select messageId_cap(i)
    case  0 then messageId_str_cap = {messageId_str_cap, '0x0: EVENT:SYNC'},
    case  1 then messageId_str_cap = {messageId_str_cap, '0x1: EVENT:DELAY_REQ'},
    case  2 then messageId_str_cap = {messageId_str_cap, '0x2: EVENT:PATH_DELAY_REQ'},
    case  3 then messageId_str_cap = {messageId_str_cap, '0x3: EVENT:PATH_DELAY_RESP'},
  //case  4- 7 Reserved
    case  8 then messageId_str_cap = {messageId_str_cap, '0x8: GENER:FOLLOW_UP'},
    case  9 then messageId_str_cap = {messageId_str_cap, '0x9: GENER:DELAY_RESP'},
    case 10 then messageId_str_cap = {messageId_str_cap, '0xA: GENER:PATH_DELAY_RESP_FOLLOW_UP'},
    case 11 then messageId_str_cap = {messageId_str_cap, '0xB: GENER:ANNOUNCE'},
    case 12 then messageId_str_cap = {messageId_str_cap, '0xC: GENER:SIGNALLING'},
    case 13 then messageId_str_cap = {messageId_str_cap, '0xD: GENER:MANAGEMENT'},
  //case 14-15 Reserved
    else         messageId_str_cap = {messageId_str_cap, messageId},
  end
end

// Inter-Packet Time
interPacketTime={0, calc_delta(capturedTimestamp_cap)};

// Inter-Message Time
interMessageTime=zeros(1,length(capturedTimestamp_cap));
indexMastr=find(clockId_cap==clockId_mastr);
indexSlave=find(clockId_cap==clockId_slave);
indexSync=indexMastr(find(messageId_cap(indexMastr)== 0));
indexDreq=indexMastr(find(messageId_cap(indexMastr)== 1));
indexPreq=indexMastr(find(messageId_cap(indexMastr)== 2));
indexPres=indexMastr(find(messageId_cap(indexMastr)== 3));
indexFlup=indexMastr(find(messageId_cap(indexMastr)== 8));
indexDres=indexMastr(find(messageId_cap(indexMastr)== 9));
indexPrfl=indexMastr(find(messageId_cap(indexMastr)==10));
indexAnnc=indexMastr(find(messageId_cap(indexMastr)==11));
indexSign=indexMastr(find(messageId_cap(indexMastr)==12));
indexMang=indexMastr(find(messageId_cap(indexMastr)==13));
interMessageTime(indexSync)={0, calc_delta(capturedTimestamp_cap(indexSync))};
interMessageTime(indexDreq)={0, calc_delta(capturedTimestamp_cap(indexDreq))};
interMessageTime(indexPreq)={0, calc_delta(capturedTimestamp_cap(indexPreq))};
interMessageTime(indexPres)={0, calc_delta(capturedTimestamp_cap(indexPres))};
interMessageTime(indexFlup)={0, calc_delta(capturedTimestamp_cap(indexFlup))};
interMessageTime(indexDres)={0, calc_delta(capturedTimestamp_cap(indexDres))};
interMessageTime(indexPrfl)={0, calc_delta(capturedTimestamp_cap(indexPrfl))};
interMessageTime(indexAnnc)={0, calc_delta(capturedTimestamp_cap(indexAnnc))};
interMessageTime(indexSign)={0, calc_delta(capturedTimestamp_cap(indexSign))};
interMessageTime(indexMang)={0, calc_delta(capturedTimestamp_cap(indexMang))};
indexSync=indexSlave(find(messageId_cap(indexSlave)== 0));
indexDreq=indexSlave(find(messageId_cap(indexSlave)== 1));
indexPreq=indexSlave(find(messageId_cap(indexSlave)== 2));
indexPres=indexSlave(find(messageId_cap(indexSlave)== 3));
indexFlup=indexSlave(find(messageId_cap(indexSlave)== 8));
indexDres=indexSlave(find(messageId_cap(indexSlave)== 9));
indexPrfl=indexSlave(find(messageId_cap(indexSlave)==10));
indexAnnc=indexSlave(find(messageId_cap(indexSlave)==11));
indexSign=indexSlave(find(messageId_cap(indexSlave)==12));
indexMang=indexSlave(find(messageId_cap(indexSlave)==13));
interMessageTime(indexSync)={0, calc_delta(capturedTimestamp_cap(indexSync))};
interMessageTime(indexDreq)={0, calc_delta(capturedTimestamp_cap(indexDreq))};
interMessageTime(indexPreq)={0, calc_delta(capturedTimestamp_cap(indexPreq))};
interMessageTime(indexPres)={0, calc_delta(capturedTimestamp_cap(indexPres))};
interMessageTime(indexFlup)={0, calc_delta(capturedTimestamp_cap(indexFlup))};
interMessageTime(indexDres)={0, calc_delta(capturedTimestamp_cap(indexDres))};
interMessageTime(indexPrfl)={0, calc_delta(capturedTimestamp_cap(indexPrfl))};
interMessageTime(indexAnnc)={0, calc_delta(capturedTimestamp_cap(indexAnnc))};
interMessageTime(indexSign)={0, calc_delta(capturedTimestamp_cap(indexSign))};
interMessageTime(indexMang)={0, calc_delta(capturedTimestamp_cap(indexMang))};

u=file('open',PWD+'/ptpv2_'+'parsed'+'.csv','unknown');
  fprintf(u,"Port, Packet #, Arrival Time, Inter-Packet Time, Inter-Message Time, messageType, sequenceId, embedded Time");
for i = 1:(length(packetNum_cap))
  fprintf(u,"%s, %d, %6.9f, %6.9f, %6.9f, %s, %d, %6.9f", clockId_str_cap(i), packetNum_cap(i), capturedTimestamp_cap(i)-capturedTimestamp_cap(1), interPacketTime(i), interMessageTime(i), messageId_str_cap(i), sequenceId_cap(i), embeddedTimestamp_cap(i));
end
file('close',u);

///////////////////////////////////////
// Generate graph
///////////////////////////////////////

// 1. SYNC PDV
subplot(8,1,1);
xtitle('', '', 'SYNC PDV/s');
indexSync=find(messageId_cap==0);
indexFlup=find(messageId_cap==8);
indexSync=indexSync(find(clockId_cap(indexSync)==clockId_mastr)); // SYNC M->S
indexFlup=indexFlup(find(clockId_cap(indexFlup)==clockId_mastr)); // FLUP M->S
capturedTimestamp_sync=capturedTimestamp_cap(indexSync); // t2
sequenceId_sync       =sequenceId_cap       (indexSync);
embeddedTimestamp_flup=embeddedTimestamp_cap(indexFlup); // t1
sequenceId_flup       =sequenceId_cap       (indexFlup);

captured_sync={};
embedded_flup={};
for i=1:length(sequenceId_sync)
  index=find(sequenceId_flup==sequenceId_sync(i));
  if index==[]
    continue;
  else
    captured_sync={captured_sync, capturedTimestamp_sync(i)};
    embedded_flup={embedded_flup, embeddedTimestamp_flup(index)};
  end
end

captured_syncDelta=calc_delta(captured_sync);
embedded_flupDelta=calc_delta(embedded_flup);
plot((captured_sync(2:length(captured_sync))-capturedTimestamp_cap(1)), (captured_syncDelta-embedded_flupDelta));

// 2. DELAY_REQ PDV
subplot(8,1,2);
xtitle('', '', 'DELAY_REQ PDV/s');
indexReq=find(messageId_cap==2);
indexRes=find(messageId_cap==3);
indexReq=indexSync(find(clockId_cap(indexReq)==clockId_slave)); // DELAY_REQ S->M
indexRes=indexFlup(find(clockId_cap(indexRes)==clockId_mastr)); // DELAY_RES M->S
capturedTimestamp_req=capturedTimestamp_cap(indexReq); // t3
sequenceId_req       =sequenceId_cap       (indexReq);
embeddedTimestamp_res=embeddedTimestamp_cap(indexRes); // t4
sequenceId_res       =sequenceId_cap       (indexRes);

captured_req={};
embedded_res={};
for i=1:length(sequenceId_req)
  index=find(sequenceId_res==sequenceId_req(i));
  if index==[]
    continue;
  else
    captured_req={captured_req, capturedTimestamp_req(i)};
    embedded_res={embedded_res, embeddedTimestamp_res(index)};
  end
end

captured_reqDelta=calc_delta(captured_req);
embedded_resDelta=calc_delta(embedded_res);
plot((captured_req(2:length(captured_req))-capturedTimestamp_cap(1)), (captured_reqDelta-embedded_resDelta));

// 3. FOLLOW_UP PDV
subplot(8,1,3);
xtitle('', '', 'FOLLOW_UP PDV/s');
indexSync=find(messageId_cap==0);
indexFlup=find(messageId_cap==8);
indexSync=indexSync(find(clockId_cap(indexSync)==clockId_mastr)); // SYNC M->S
indexFlup=indexFlup(find(clockId_cap(indexFlup)==clockId_mastr)); // FLUP M->S
capturedTimestamp_sync=capturedTimestamp_cap(indexSync); // t2
sequenceId_sync       =sequenceId_cap       (indexSync);
capturedTimestamp_flup=capturedTimestamp_cap(indexFlup);
sequenceId_flup       =sequenceId_cap       (indexFlup);

captured_sync={};
captured_flup={};
for i=1:length(sequenceId_sync)
  index=find(sequenceId_flup==sequenceId_sync(i));
  if index==[]
    continue;
  else
    captured_sync={captured_sync, capturedTimestamp_sync(i)};
    captured_flup={captured_flup, capturedTimestamp_flup(index)};
  end
end

captured_syncDelta=calc_delta(captured_sync);
captured_flupDelta=calc_delta(captured_flup);
plot((captured_sync(2:length(captured_sync))-capturedTimestamp_cap(1)), (captured_flupDelta-captured_syncDelta));

// 4. Slave Clock Wander
subplot(8,1,4);
xtitle('', '', 'Slave Clock Wander/s');
indexReq=find(messageId_cap==2);
indexReq=indexReq(find(clockId_cap(indexReq)==clockId_slave)); // PATH_DELAY_REQ S->M
capturedTimestamp_req=capturedTimestamp_cap(indexReq); // t4
embeddedTimestamp_req=embeddedTimestamp_cap(indexReq);
sequenceId_req       =sequenceId_cap       (indexReq);

captured_req={};
embedded_req={};
for i=1:length(sequenceId_req)
  index=find(sequenceId_req==sequenceId_req(i));
  if index==[]
    continue;
  else
    captured_req={captured_req, capturedTimestamp_req(index)};
    embedded_req={embedded_req, embeddedTimestamp_req(index)};
  end
end

embedded_reqDelta=calc_delta(embedded_req);
plot((captured_req(2:length(captured_req))-capturedTimestamp_cap(1)), embedded_reqDelta-mean(embedded_reqDelta));

// 5. Round Trip Delay variation
subplot(8,1,5);
xtitle('', '', 'RTD Variation/s');
indexSync=find(messageId_cap==0);
indexFlup=find(messageId_cap==8);
indexSync=indexSync(find(clockId_cap(indexSync)==clockId_mastr)); // SYNC M->S
indexFlup=indexFlup(find(clockId_cap(indexFlup)==clockId_mastr)); // FLUP M->S
capturedTimestamp_sync=capturedTimestamp_cap(indexSync); // t2
sequenceId_sync       =sequenceId_cap       (indexSync);
embeddedTimestamp_flup=embeddedTimestamp_cap(indexFlup); // t1
sequenceId_flup       =sequenceId_cap       (indexFlup);

captured_sync={};
embedded_flup={};
for i=1:length(sequenceId_sync)
  index=find(sequenceId_flup==sequenceId_sync(i));
  if index==[]
    continue;
  else
    captured_sync={captured_sync, capturedTimestamp_sync(i)};
    embedded_flup={embedded_flup, embeddedTimestamp_flup(index)};
  end
end

indexReq=find(messageId_cap==2);
indexRes=find(messageId_cap==3);
indexReq=indexReq(find(clockId_cap(indexReq)==clockId_slave)); // DELAY_REQ S->M
indexRes=indexRes(find(clockId_cap(indexRes)==clockId_mastr)); // DELAY_RES M->S 
capturedTimestamp_req=capturedTimestamp_cap(indexReq); // t3
sequenceId_req       =sequenceId_cap       (indexReq);
embeddedTimestamp_res=embeddedTimestamp_cap(indexRes); // t4
sequenceId_res       =sequenceId_cap       (indexRes);

captured_req={};
embedded_res={};
for i=1:length(sequenceId_req)
  index=find(sequenceId_res==sequenceId_req(i));
  if index==[]
    continue;
  else
    captured_req={captured_req, capturedTimestamp_req(i)};
    embedded_res={embedded_res, embeddedTimestamp_res(index)};
  end
end

captured_syncDelta=calc_delta(captured_sync);
embedded_flupDelta=calc_delta(embedded_flup);
captured_reqDelta=calc_delta(captured_req);
embedded_resDelta=calc_delta(embedded_res);
commonLength=min(length(captured_sync),length(captured_req));
captured_syncDelta=captured_syncDelta(1:commonLength-1);
embedded_flupDelta=embedded_flupDelta(1:commonLength-1);
captured_reqDelta=captured_reqDelta(1:commonLength-1);
embedded_resDelta=embedded_resDelta(1:commonLength-1);
plot((captured_req(2:commonLength)-capturedTimestamp_cap(1)), ((captured_syncDelta-embedded_flupDelta)+(embedded_resDelta-captured_reqDelta))/2); //((t2-t1)+(t4-t3))/2

// 6. Asymmetry
subplot(8,1,6);
xtitle('', '', 'Delay Asymmetry/s');
indexSync=find(messageId_cap==0);
indexFlup=find(messageId_cap==8);
indexSync=indexSync(find(clockId_cap(indexSync)==clockId_mastr)); // SYNC M->S
indexFlup=indexFlup(find(clockId_cap(indexFlup)==clockId_mastr)); // FLUP M->S
capturedTimestamp_sync=capturedTimestamp_cap(indexSync); // t2
sequenceId_sync       =sequenceId_cap       (indexSync);
embeddedTimestamp_flup=embeddedTimestamp_cap(indexFlup); // t1
sequenceId_flup       =sequenceId_cap       (indexFlup);

captured_sync={};
embedded_flup={};
for i=1:length(sequenceId_sync)
  index=find(sequenceId_flup==sequenceId_sync(i));
  if index==[]
    continue;
  else
    captured_sync={captured_sync, capturedTimestamp_sync(i)};
    embedded_flup={embedded_flup, embeddedTimestamp_flup(index)};
  end
end

indexReq=find(messageId_cap==2);
indexRes=find(messageId_cap==3);
indexReq=indexReq(find(clockId_cap(indexReq)==clockId_slave)); // DELAY_REQ S->M
indexRes=indexRes(find(clockId_cap(indexRes)==clockId_mastr)); // DELAY_RES M->S 
capturedTimestamp_req=capturedTimestamp_cap(indexReq); // t3
sequenceId_req       =sequenceId_cap       (indexReq);
embeddedTimestamp_res=embeddedTimestamp_cap(indexRes); // t4
sequenceId_res       =sequenceId_cap       (indexRes);

captured_req={};
embedded_res={};
for i=1:length(sequenceId_req)
  index=find(sequenceId_res==sequenceId_req(i));
  if index==[]
    continue;
  else
    captured_req={captured_req, capturedTimestamp_req(i)};
    embedded_res={embedded_res, embeddedTimestamp_res(index)};
  end
end

commonLength=min(length(captured_sync),length(captured_req));
captured_sync=captured_sync(1:commonLength);
embedded_flup=embedded_flup(1:commonLength);
captured_req=captured_req(1:commonLength);
embedded_res=embedded_res(1:commonLength);
plot((captured_req(1:commonLength)-capturedTimestamp_cap(1)), (captured_sync-embedded_flup)-(embedded_res-captured_req)); //(t2-t1)-(t4-t3)

// 7. Sync Inter-Packet Gap
subplot(8,1,7);
xtitle('', '', 'SYNC IPG/s');
indexSync=find(messageId_cap==0);
indexSync=indexSync(find(clockId_cap(indexSync)==clockId_mastr)); // SYNC M->S
capturedTimestamp_sync=capturedTimestamp_cap(indexSync); // t2
sequenceId_sync       =sequenceId_cap       (indexSync);

captured_sync={};
for i=1:length(sequenceId_sync)
  index=find(sequenceId_sync==sequenceId_sync(i));
  if index==[]
    continue;
  else
    captured_sync={captured_sync, capturedTimestamp_sync(index)};
  end
end

captured_syncDelta=calc_delta(captured_sync);
plot((captured_sync(2:length(captured_sync))-capturedTimestamp_cap(1)), captured_syncDelta);

// 8. Delay-Resp Round Trip Delay
subplot(8,1,8);
xtitle('', '', 'Delay-Resp Latency/s');
indexReq=find(messageId_cap==2);
indexRes=find(messageId_cap==3);
indexReq=indexReq(find(clockId_cap(indexReq)==clockId_slave)); // DELAY_REQ S->M
indexRes=indexRes(find(clockId_cap(indexRes)==clockId_mastr)); // DELAY_RES M->S 
capturedTimestamp_req=capturedTimestamp_cap(indexReq); // t3
sequenceId_req       =sequenceId_cap       (indexReq);
capturedTimestamp_res=capturedTimestamp_cap(indexRes);
sequenceId_res       =sequenceId_cap       (indexRes);

captured_req={};
captured_res={};
for i=1:length(sequenceId_req)
  index=find(sequenceId_res==sequenceId_req(i));
  if index==[]
    continue;
  else
    captured_req={captured_req, capturedTimestamp_req(i)};
    captured_res={captured_res, capturedTimestamp_res(index)};
  end
end

plot((captured_req(1:length(captured_req))-capturedTimestamp_cap(1)), (captured_res-captured_req));

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.