Files
bds.mr.jtg/src.jtag/svf2/jtag.svf2.pas
T
2026-01-08 19:12:06 +01:00

1334 lines
39 KiB
ObjectPascal

unit jtag.svf2;
interface
uses
Classes,
jtag.types;
type
TsvfReturnCode =
(
SVF_OK = 0,
SVF_InvalidFile = -1
);
TScan =
(
SCAN_HIR,
SCAN_HDR,
SCAN_TIR,
SCAN_TDR,
SCAN_SIR,
SCAN_SDR
);
TsvfDataTypeBit =
(
dtTDIData, // TDI data is present
dtTDOData, // TDO data is present
dtMASKData, // MASK data is present
dtSMASKData // SMASK data us present
);
TsvfDataType = set of TsvfDataTypeBit;
TjtagSVF = class
protected
fStream : TStream;
fLogLevel : integer;
fBuffer : PAnsiChar;
fBufferIdx : cardinal;
fBufferSize : cardinal;
fJTAG : IJTAG;
fLog : IJTAGLOG;
fDataHIR : TsvfDataType;
fDataHDR : TsvfDataType;
fDataTIR : TsvfDataType;
fDataTDR : TsvfDataType;
fDataSIR : TsvfDataType;
fDataSDR : TsvfDataType;
protected
fHIRSize : word;
fHDRSize : word;
fTIRSize : word;
fTDRSize : word;
fSIRSize : word;
fSDRSize : word;
fHIR_TDIData : PByte;
fHDR_TDIData : PByte;
fTIR_TDIData : PByte;
fTDR_TDIData : PByte;
fSIR_TDIData : PByte;
fSDR_TDIData : PByte;
fHIR_TDOData : PByte;
fHDR_TDOData : PByte;
fTIR_TDOData : PByte;
fTDR_TDOData : PByte;
fSIR_TDOData : PByte;
fSDR_TDOData : PByte;
fHIR_MASKData : PByte;
fHDR_MASKData : PByte;
fTIR_MASKData : PByte;
fTDR_MASKData : PByte;
fSIR_MASKData : PByte;
fSDR_MASKData : PByte;
fHIR_SMASKData : PByte;
fHDR_SMASKData : PByte;
fTIR_SMASKData : PByte;
fTDR_SMASKData : PByte;
fSIR_SMASKData : PByte;
fSDR_SMASKData : PByte;
fRUN_State : TJTAGState;
protected
procedure svfMemManager( scan : TScan;
bits : cardinal);
private
function svfPRG : TsvfReturnCode;
function svfScan( scan : TScan): TsvfReturnCode;
function svfData( buf : PBYTE;
bits : cardinal): TsvfReturnCode;
function svfENDxR : TsvfReturnCode;
function svfFreq : TsvfReturnCode;
function svfState : TsvfReturnCode;
function svfRun : TsvfReturnCode;
public
function SVF( Stream: TStream): TsvfReturnCode;
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
public
property LogLevel : integer read fLogLevel write fLogLevel;
property JTAGLOG : IJTAGLOG read fLog write fLog;
property JTAG : IJTAG read fJTAG write fJTAG;
end;
implementation
uses
SysUtils;
{ TjtagSVF }
// ================================================================================================
// after construction
// ================================================================================================
procedure TjtagSVF.AfterConstruction;
begin
fRUN_State := DRPAUSE
end;
// ================================================================================================
// before destruction
// ================================================================================================
procedure TjtagSVF.BeforeDestruction;
begin
svfMemManager( SCAN_HIR, 0);
svfMemManager( SCAN_HDR, 0);
svfMemManager( SCAN_TIR, 0);
svfMemManager( SCAN_TDR, 0);
svfMemManager( SCAN_SIR, 0);
svfMemManager( SCAN_SDR, 0);
inherited;
end;
// ================================================================================================
// svf
// ================================================================================================
function TjtagSVF.SVF(Stream: TStream): TsvfReturnCode;
begin
if Assigned(Stream) then
begin
fBufferIdx := 0;
fBufferSize := Stream.Size;
fBuffer := GetMemory( fBufferSize);
Stream.Seek( 0,soFromBeginning);
Stream.Read( fBuffer^, Stream.Size);
svfPRG;
FreeMemory(fBuffer);
fBuffer := nil;
fBufferIdx := 0
end;
end;
// ================================================================================================
// svfPRG
// ================================================================================================
function TjtagSVF.svfPRG: TsvfReturnCode;
var
tmp: AnsiString;
begin
result := SVF_OK;
while true do
begin
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9,#13,#10]) do
inc(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
case fBuffer[fBufferIdx] of
// ----------------------------------------------------
// comment
// ----------------------------------------------------
'!':
begin
tmp := '';
while (fBufferIdx < fBufferSize) and not (fBuffer[fBufferIdx] in [#13,#10]) do
begin
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
writeln(tmp);
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#13,#10]) do
inc(fBufferIdx);
end;
'/':
begin
inc( fBufferIdx);
if fBuffer[fBufferIdx] = '/' then
begin
tmp := '/';
while (fBufferIdx < fBufferSize) and not (fBuffer[fBufferIdx] in [#13,#10]) do
begin
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
writeln(tmp);
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#13,#10]) do
inc(fBufferIdx);
end;
end;
// ----------------------------------------------------
// HIR/HDR
// ----------------------------------------------------
'H':
if fBufferIdx < fBufferSize then
begin
case fBuffer[fBufferIdx+1] of
'I': result := svfScan( SCAN_HIR);
'D': result := svfScan( SCAN_HDR);
else result := SVF_InvalidFile;
end;
end;
// ----------------------------------------------------
// TIR/TDR
// ----------------------------------------------------
// TODO 1 : Implement TRST (xilinx miatt)
'T':
if fBufferIdx < fBufferSize then
begin
case fBuffer[fBufferIdx+1] of
'I': result := svfScan( SCAN_TIR);
'D': result := svfScan( SCAN_TDR);
else result := SVF_InvalidFile;
end;
end;
// ----------------------------------------------------
// SIR/SDR
// ----------------------------------------------------
'S':
if fBufferIdx < fBufferSize then
begin
case fBuffer[fBufferIdx+1] of
'I': result := svfScan( SCAN_SIR);
'D': result := svfScan( SCAN_SDR);
'T': result := svfState;
else result := SVF_InvalidFile;
end;
end;
// ----------------------------------------------------
// ENDIR/ENDDR
// ----------------------------------------------------
'E':
if fBufferIdx < fBufferSize then
begin
if (fBuffer[fBufferIdx+1] = 'N') and
(fBuffer[fBufferIdx+2] = 'D') then
begin
case fBuffer[fBufferIdx+3] of
'I': result := svfENDxR;
'D': result := svfENDxR;
else result := SVF_InvalidFile
end;
end;
end;
// ----------------------------------------------------
// FREQUENCY
// ----------------------------------------------------
'F':
result := svfFreq;
// ----------------------------------------------------
// RUNTEST
// ----------------------------------------------------
'R':
result := svfRun;
end;
end;
end;
// ================================================================================================
// SCAN
// ================================================================================================
function TjtagSVF.svfSCAN(scan: TScan): TsvfReturnCode;
function reverse( data: PByte; length: integer): string;
var
i : integer;
n : byte;
begin
result := '';
for i:=0 to length-1 do
begin
n := (data[i] shr 4) and $0f;
case n of
0 : result := '0' + result;
1 : result := '8' + result;
2 : result := '4' + result;
3 : result := 'C' + result;
4 : result := '2' + result;
5 : result := 'A' + result;
6 : result := '6' + result;
7 : result := 'E' + result;
8 : result := '1' + result;
9 : result := '9' + result;
$a : result := '5' + result;
$b : result := 'D' + result;
$c : result := '3' + result;
$d : result := 'B' + result;
$e : result := '7' + result;
$f : result := 'F' + result;
end;
n := (data[i] shr 0) and $0f;
case n of
0 : result := '0' + result;
1 : result := '8' + result;
2 : result := '4' + result;
3 : result := 'C' + result;
4 : result := '2' + result;
5 : result := 'A' + result;
6 : result := '6' + result;
7 : result := 'E' + result;
8 : result := '1' + result;
9 : result := '9' + result;
$a : result := '5' + result;
$b : result := 'D' + result;
$c : result := '3' + result;
$d : result := 'B' + result;
$e : result := '7' + result;
$f : result := 'F' + result;
end;
end;
end;
var
bits : cardinal;
bytes : cardinal;
tmp : AnsiString;
i : integer;
s : string;
sTDI : string;
sTDO : string;
begin
result := SVF_InvalidFile;
if (fBuffer[fBufferIdx+2] = 'R') and (fBuffer[fBufferIdx+3] in [#32,#9]) then
begin
INC(fBufferIdx,3);
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
// check for digit
if not (fBuffer[fBufferIdx] in ['0'..'9']) then
exit;
// read size
bits := 0;
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do
begin
bits := bits * 10 + ord(fBuffer[fBufferIdx]) - ord('0');
INC(fBufferIdx);
end;
svfMemManager( scan, bits);
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
case scan of
SCAN_HIR: Exclude( fDataHIR, dtTDOData);
SCAN_HDR: Exclude( fDataHDR, dtTDOData);
SCAN_TIR: Exclude( fDataTIR, dtTDOData);
SCAN_TDR: Exclude( fDataTDR, dtTDOData);
SCAN_SIR: Exclude( fDataSIR, dtTDOData);
SCAN_SDR: Exclude( fDataSDR, dtTDOData);
end;
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['T','M','S']) do
begin
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
case scan of
SCAN_HIR:
begin
if tmp = 'TDI' then Include( fDataHIR, dtTDIData) else
if tmp = 'TDO' then Include( fDataHIR, dtTDOData) else
if tmp = 'MASK' then Include( fDataHIR, dtMASKData) else
if tmp = 'SMASK' then Include( fDataHIR, dtSMASKData) else exit;
if tmp = 'TDI' then result := svfData(fHIR_TDIData, bits) else
if tmp = 'TDO' then result := svfData(fHIR_TDOData, bits) else
if tmp = 'MASK' then result := svfData(fHIR_MASKData, bits) else
if tmp = 'SMASK' then result := svfData(fHIR_SMASKData, bits)
end;
SCAN_HDR:
begin
if tmp = 'TDI' then Include( fDataHDR, dtTDIData) else
if tmp = 'TDO' then Include( fDataHDR, dtTDOData) else
if tmp = 'MASK' then Include( fDataHDR, dtMASKData) else
if tmp = 'SMASK' then Include( fDataHDR, dtSMASKData) else exit;
if tmp = 'TDI' then result := svfData(fHDR_TDIData, bits) else
if tmp = 'TDO' then result := svfData(fHDR_TDOData, bits) else
if tmp = 'MASK' then result := svfData(fHDR_MASKData, bits) else
if tmp = 'SMASK' then result := svfData(fHDR_SMASKData, bits)
end;
SCAN_TIR:
begin
if tmp = 'TDI' then Include( fDataTIR, dtTDIData) else
if tmp = 'TDO' then Include( fDataTIR, dtTDOData) else
if tmp = 'MASK' then Include( fDataTIR, dtMASKData) else
if tmp = 'SMASK' then Include( fDataTIR, dtSMASKData) else exit;
if tmp = 'TDI' then result := svfData(fTIR_TDIData, bits) else
if tmp = 'TDO' then result := svfData(fTIR_TDOData, bits) else
if tmp = 'MASK' then result := svfData(fTIR_MASKData, bits) else
if tmp = 'SMASK' then result := svfData(fTIR_SMASKData, bits)
end;
SCAN_TDR:
begin
if tmp = 'TDI' then Include( fDataTDR, dtTDIData) else
if tmp = 'TDO' then Include( fDataTDR, dtTDOData) else
if tmp = 'MASK' then Include( fDataTDR, dtMASKData) else
if tmp = 'SMASK' then Include( fDataTDR, dtSMASKData) else exit;
if tmp = 'TDI' then result := svfData(fTDR_TDIData, bits) else
if tmp = 'TDO' then result := svfData(fTDR_TDOData, bits) else
if tmp = 'MASK' then result := svfData(fTDR_MASKData, bits) else
if tmp = 'SMASK' then result := svfData(fTDR_SMASKData, bits)
end;
SCAN_SIR:
begin
if tmp = 'TDI' then Include( fDataSIR, dtTDIData) else
if tmp = 'TDO' then Include( fDataSIR, dtTDOData) else
if tmp = 'MASK' then Include( fDataSIR, dtMASKData) else
if tmp = 'SMASK' then Include( fDataSIR, dtSMASKData) else exit;
if tmp = 'TDI' then result := svfData(fSIR_TDIData, bits) else
if tmp = 'TDO' then result := svfData(fSIR_TDOData, bits) else
if tmp = 'MASK' then result := svfData(fSIR_MASKData, bits) else
if tmp = 'SMASK' then result := svfData(fSIR_SMASKData, bits)
end;
SCAN_SDR:
begin
if tmp = 'TDI' then Include( fDataSDR, dtTDIData) else
if tmp = 'TDO' then Include( fDataSDR, dtTDOData) else
if tmp = 'MASK' then Include( fDataSDR, dtMASKData) else
if tmp = 'SMASK' then Include( fDataSDR, dtSMASKData) else exit;
if tmp = 'TDI' then result := svfData(fSDR_TDIData, bits) else
if tmp = 'TDO' then result := svfData(fSDR_TDOData, bits) else
if tmp = 'MASK' then result := svfData(fSDR_MASKData, bits) else
if tmp = 'SMASK' then result := svfData(fSDR_SMASKData, bits) else exit;
end;
end;
end;
if fBuffer[fBufferIdx] = ';' then
begin
INC(fBufferIdx);
result := SVF_OK;
end;
if Assigned( fJTAG) then
begin
bytes := (bits + 7) div 8;
case scan of
SCAN_SIR:
begin
writeln( Format('SIR(s) : %s', [reverse(fSIR_TDIData,bytes)]));
fJTAG.sir( fSIR_TDIData, bits);
writeln( Format('SIR(r) : %s', [reverse(fSIR_TDIData,bytes)]));
if dtTDOData in fDataSIR then
begin
writeln( Format('SIR(o) : %s', [reverse(fSIR_TDOData,bytes)]));
if dtMASKData in fDataSIR then
begin
writeln( Format('SIR(m) : %s', [reverse(fSIR_MASKData,bytes)]));
for i:=0 to bytes -1 do
begin
fSIR_TDIData[i] := fSIR_TDIData[i] and fSIR_MASKData[i];
fSIR_TDOData[i] := fSIR_TDOData[i] and fSIR_MASKData[i];
if fSIR_TDIData[i] <> fSIR_TDOData[i] then
begin
bits := 0;
end;
end;
writeln( Format('SIR(mr): %s', [reverse(fSIR_TDIData,bytes)]));
writeln( Format('SIR(mo): %s', [reverse(fSIR_TDOData,bytes)]));
end;
end;
writeln;
end;
SCAN_SDR:
begin
writeln( Format('SDR(s) : %s', [reverse(fSDR_TDIData,bytes)]));
fJTAG.sdr( fSDR_TDIData, bits);
writeln( Format('SDR(r) : %s', [reverse(fSDR_TDIData,bytes)]));
if dtTDOData in fDataSDR then
begin
writeln( Format('SDR(o) : %s', [reverse(fSDR_TDOData,bytes)]));
if dtMASKData in fDataSDR then
begin
writeln( Format('SDR(m) : %s', [reverse(fSDR_MASKData,bytes)]));
for i:=0 to bytes -1 do
begin
fSDR_TDIData[i] := fSDR_TDIData[i] and fSDR_MASKData[i];
fSDR_TDOData[i] := fSDR_TDOData[i] and fSDR_MASKData[i];
end;
sTDI := reverse(fSDR_TDIData,bytes);
sTDO := reverse(fSDR_TDOData,bytes);
writeln( Format('SDR(mr): %s', [sTDI]));
writeln( Format('SDR(mo): %s', [sTDO]));
end;
s := '';
for i:=1 to Length(sTDI) do
if sTDI[i] <> sTDO[i]
then s := s + '^'
else s := s + ' ';
if Trim(s) <> '' then
writeln( Format(' %s', [s]));
end;
writeln;
end;
end;
end;
end;
end;
// ================================================================================================
// ENDIR/ENDDR
// ================================================================================================
function TjtagSVF.svfENDxR: TsvfReturnCode;
var
state : AnsiChar;
tmp : AnsiString;
begin
result := SVF_InvalidFile;
state := '0';
tmp := '';
if (fBuffer[fBufferIdx+4] = 'R') and (fBuffer[fBufferIdx+5] in [#32,#9]) then
begin
INC(fBufferIdx,5);
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
if not (fBuffer[fBufferIdx] in ['I','D','R']) then
exit;
// read state name
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
// check state name
if tmp = 'IRPAUSE' then else
if tmp = 'DRPAUSE' then else
if tmp = 'RESET' then else
if tmp = 'IDLE' then else exit;
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
if fBuffer[fBufferIdx] = ';' then
begin
inc( fBufferIdx);
result := SVF_OK
end;
end;
end;
// ================================================================================================
// FREQUENCY
// ================================================================================================
function TjtagSVF.svfFreq: TsvfReturnCode;
var
tmp: AnsiString;
begin
result := SVF_InvalidFile;
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
if fBufferIdx = fBufferSize then
exit;
if tmp = 'FREQUENCY' then
begin
// just skip for now
while (fBufferIdx < fBufferSize) and not (fBuffer[fBufferIdx] in [#13,#10]) do
inc(fBufferIdx);
end;
end;
// ================================================================================================
// RUNTEST
// ================================================================================================
function TjtagSVF.svfRun: TsvfReturnCode;
var
tmp: AnsiString;
tck : integer;
int : integer;
frc : integer;
exp : integer;
state : TJTAGState;
save : cardinal;
pulses: cardinal;
burst : WORD;
label
pulse;
begin
result := SVF_InvalidFile;
tmp := '';
tck := 0;
pulses := 0;
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
if fBufferIdx = fBufferSize then
exit;
if tmp = 'RUNTEST' then
begin
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
// get optional state
state := UNDEF;
if fBuffer[fBufferIdx] in ['I','D','R'] then
begin
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
if tmp = 'DRPAUSE' then state := DRPAUSE else
if tmp = 'IRPAUSE' then state := IRPAUSE else
if tmp = 'RESET' then state := RESET else
if tmp = 'IDLE' then state := IDLE else exit;
end;
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if (fBufferIdx = fBufferSize) or not (fBuffer[fBufferIdx] in ['0'..'9']) then
exit;
save := fBufferIdx; // remember position
// get number of TCK pulses or integer part of mintime
int := 0;
frc := 0;
exp := 0;
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do
begin
int := int * 10 + integer(fBuffer[fBufferIdx]) - ord('0');
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
if fBufferIdx = fBufferSize then
exit;
// "run_count run_clk" case
if fBuffer[fBufferIdx] <> '.' then
begin
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
// read 'TCK' or 'SCK'
if (fBuffer[fBufferIdx+0] in ['T','S']) and
(fBuffer[fBufferIdx+1] = 'C') and
(fBuffer[fBufferIdx+2] = 'K') then
begin
tck := int;
int := 0;
inc(fBufferIdx,3);
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
if fBuffer[fBufferIdx] = ';' then
begin
result := SVF_OK;
inc(fBufferIdx);
goto pulse;
end;
end
else
exit;
end
else
fBufferIdx := save;
// read mintime
int := 0;
frc := 0;
exp := 0;
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do
begin
int := int * 10 + integer(fBuffer[fBufferIdx]) - ord('0');
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
if (fBufferIdx = fBufferSize) or (fBuffer[fBufferIdx] <> '.') then
exit;
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
if (fBufferIdx = fBufferSize) or not (fBuffer[fBufferIdx] in ['0'..'9']) then
exit;
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do
begin
frc := frc + integer(fBuffer[fBufferIdx]) - ord('0');
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
// match exponent letter: 'E'
if (fBufferIdx = fBufferSize) or (fBuffer[fBufferIdx] <> 'E') then
exit;
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
// match optional sign: ('+' | '-')
if fBuffer[fBufferIdx] in ['-','+'] then
begin
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
// match exponent: ('0'..'9')+
if (fBufferIdx = fBufferSize) or not (fBuffer[fBufferIdx] in ['0'..'9']) then
exit;
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9']) do
begin
exp := exp + integer(fBuffer[fBufferIdx]) - ord('0');
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
// skip WS: (' ' | '\t')*
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
pulses := Round(StrToFloat(tmp) / 1e-6);
// match second mark: 'SEC'
if (fBufferIdx = fBufferSize) or (fBuffer[fBufferIdx] <> 'S') then
exit;
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['S','E','C']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
if tmp <> 'SEC' then
exit;
// skip WS: (' ' | '\t')*
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
// TODO:maxtime, endstate....
// match instruction terminator: ';'
if fBuffer[fBufferIdx] <> ';' then
exit;
inc(fBufferIdx);
result := SVF_OK;
// ------------------------------------------------------------
// execute command
// ------------------------------------------------------------
pulse:
if Assigned( fJTAG) then
begin
pulses := pulses + tck;
while(pulses > 0) do
begin
if pulses > 50000 then
begin
burst := 50000;
pulses := pulses - 50000
end
else begin
burst := pulses;
pulses := 0
end;
fJTAG.run(state,burst);
end;
end;
end;
end;
// ================================================================================================
// STATE
// ================================================================================================
function TjtagSVF.svfState : TsvfReturnCode;
var
tmp : AnsiString;
state : TJTAGState;
begin
result := SVF_InvalidFile;
state := UNDEF;
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
if fBufferIdx = fBufferSize then
exit;
if tmp = 'STATE' then
begin
while true do
begin
tmp := '';
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
// read state name
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['A'..'Z']) do
begin
tmp := tmp + fBuffer[fBufferIdx];
INC(fBufferIdx);
end;
// check state name
if tmp = 'IRPAUSE' then state := IRPAUSE else
if tmp = 'DRPAUSE' then state := DRPAUSE else
if tmp = 'RESET' then state := RESET else
if tmp = 'IDLE' then state := IDLE else exit;
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
if Assigned(JTAG) then
JTAG.state(state);
if fBuffer[fBufferIdx] = ';' then
begin
inc( fBufferIdx);
result := SVF_OK;
break;
end;
end;
end;
end;
// ================================================================================================
// svfData
// ================================================================================================
function TjtagSVF.svfData(buf: PBYTE; bits: cardinal): TsvfReturnCode;
var
tmp : AnsiString;
bytes : cardinal;
count : cardinal;
b : byte;
i : integer;
function Reverse( c: AnsiChar): BYTE;
var
b: BYTE;
begin
Result := 0;
case c of
'0'..'9': b := ord(c) - ord('0');
'A'..'F': b := ord(c) - ord('A') + 10;
'a'..'f': b := ord(c) - ord('a') + 10;
end;
if b and $08 = $08 then Result := Result + $01;
if b and $04 = $04 then Result := Result + $02;
if b and $02 = $02 then Result := Result + $04;
if b and $01 = $01 then Result := Result + $08;
end;
begin
result := SVF_InvalidFile;
bytes := (bits + 7) div 8;
// skip whitespaces
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
if fBuffer[fBufferIdx] <> '(' then
exit;
inc( fBufferIdx);
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
if not (fBuffer[fBufferIdx] in ['0'..'9','A'..'F','a'..'f']) then
exit;
tmp := '';
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in ['0'..'9','A'..'F','a'..'f',#32,#9,#13,#10]) do
begin
if fBuffer[fBufferIdx] in ['0'..'9','A'..'F','a'..'f'] then
tmp := tmp + fBuffer[fBufferIdx];
inc(fBufferIdx);
end;
if length(tmp) < (bits + 3) div 4 then
exit;
bytes := 0;
count := 0;
for i:=length(tmp) downto 1 do
begin
b := Reverse(tmp[i]);
if count mod 2 = 0
then buf[bytes] := b shl 4
else buf[bytes] := buf[bytes] + b;
if count mod 2 = 1 then
inc(bytes);
inc(count);
if count * 4 >= bits then
break;
end;
if fBufferIdx = fBufferSize then
exit;
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
if fBuffer[fBufferIdx] <> ')' then
exit;
inc( fBufferIdx);
while (fBufferIdx < fBufferSize) and (fBuffer[fBufferIdx] in [#32,#9,#13,#10]) do
INC(fBufferIdx);
if fBufferIdx = fBufferSize then
exit;
result := SVF_OK
end;
// ================================================================================================
// svfMemManager
// ================================================================================================
procedure TjtagSVF.svfMemManager( scan: TScan; bits: cardinal);
var
bytes: cardinal;
begin
bytes := (bits + 7) div 8;
case scan of
SCAN_HIR:
begin
if (bits = 0) or (bits > fHIRSize) then
begin
if Assigned(fHIR_TDIData) then FreeMemory(fHIR_TDIData);
if Assigned(fHIR_TDOData) then FreeMemory(fHIR_TDOData);
if Assigned(fHIR_MASKData) then FreeMemory(fHIR_MASKData);
if Assigned(fHIR_SMASKData) then FreeMemory(fHIR_SMASKData);
if bits = 0 then
begin
fHIR_TDIData := nil;
fHIR_TDOData := nil;
fHIR_MASKData := nil;
fHIR_SMASKData := nil
end
else begin
fHIR_TDIData := GetMemory(bytes);
fHIR_TDOData := GetMemory(bytes);
fHIR_MASKData := GetMemory(bytes);
fHIR_SMASKData := GetMemory(bytes)
end
end;
if fHIRSize <> bits then
begin
fHIRSize := bits;
fDataHIR := []
end
end;
SCAN_HDR:
begin
if (bits = 0) or (bits > fHDRSize) then
begin
if Assigned(fHDR_TDIData) then FreeMemory(fHDR_TDIData);
if Assigned(fHDR_TDOData) then FreeMemory(fHDR_TDOData);
if Assigned(fHDR_MASKData) then FreeMemory(fHDR_MASKData);
if Assigned(fHDR_SMASKData) then FreeMemory(fHDR_SMASKData);
if bits = 0 then
begin
fHDR_TDIData := nil;
fHDR_TDOData := nil;
fHDR_MASKData := nil;
fHDR_SMASKData := nil
end
else begin
fHDR_TDIData := GetMemory(bytes);
fHDR_TDOData := GetMemory(bytes);
fHDR_MASKData := GetMemory(bytes);
fHDR_SMASKData := GetMemory(bytes)
end
end;
if fHDRSize <> bits then
begin
fHDRSize := bits;
fDataHDR := []
end
end;
SCAN_TIR:
begin
if (bits = 0) or (bits > fTIRSize) then
begin
if Assigned(fTIR_TDIData) then FreeMemory(fTIR_TDIData);
if Assigned(fTIR_TDOData) then FreeMemory(fTIR_TDOData);
if Assigned(fTIR_MASKData) then FreeMemory(fTIR_MASKData);
if Assigned(fTIR_SMASKData) then FreeMemory(fTIR_SMASKData);
if bits = 0 then
begin
fTIR_TDIData := nil;
fTIR_TDOData := nil;
fTIR_MASKData := nil;
fTIR_SMASKData := nil
end
else begin
fTIR_TDIData := GetMemory(bytes);
fTIR_TDOData := GetMemory(bytes);
fTIR_MASKData := GetMemory(bytes);
fTIR_SMASKData := GetMemory(bytes)
end
end;
if fTIRSize <> bits then
begin
fTIRSize := bits;
fDataTIR := []
end
end;
SCAN_TDR:
begin
if (bits = 0) or (bits > fTDRSize) then
begin
if Assigned(fTDR_TDIData) then FreeMemory(fTDR_TDIData);
if Assigned(fTDR_TDOData) then FreeMemory(fTDR_TDOData);
if Assigned(fTDR_MASKData) then FreeMemory(fTDR_MASKData);
if Assigned(fTDR_SMASKData) then FreeMemory(fTDR_SMASKData);
if bits = 0 then
begin
fTDR_TDIData := nil;
fTDR_TDOData := nil;
fTDR_MASKData := nil;
fTDR_SMASKData := nil
end
else begin
fTDR_TDIData := GetMemory(bytes);
fTDR_TDOData := GetMemory(bytes);
fTDR_MASKData := GetMemory(bytes);
fTDR_SMASKData := GetMemory(bytes)
end
end;
if fTDRSize <> bits then
begin
fTDRSize := bits;
fDataTDR := []
end
end;
SCAN_SIR:
begin
if (bits = 0) or (bits > fSIRSize) then
begin
if Assigned(fSIR_TDIData) then FreeMemory(fSIR_TDIData);
if Assigned(fSIR_TDOData) then FreeMemory(fSIR_TDOData);
if Assigned(fSIR_MASKData) then FreeMemory(fSIR_MASKData);
if Assigned(fSIR_SMASKData) then FreeMemory(fSIR_SMASKData);
if bits = 0 then
begin
fSIR_TDIData := nil;
fSIR_TDOData := nil;
fSIR_MASKData := nil;
fSIR_SMASKData := nil
end
else begin
fSIR_TDIData := GetMemory(bytes);
fSIR_TDOData := GetMemory(bytes);
fSIR_MASKData := GetMemory(bytes);
fSIR_SMASKData := GetMemory(bytes)
end
end;
if fSIRSize <> bits then
begin
fSIRSize := bits;
fDataSIR := []
end
end;
SCAN_SDR:
begin
if (bits = 0) or (bits > fSDRSize) then
begin
if Assigned(fSDR_TDIData) then FreeMemory(fSDR_TDIData);
if Assigned(fSDR_TDOData) then FreeMemory(fSDR_TDOData);
if Assigned(fSDR_MASKData) then FreeMemory(fSDR_MASKData);
if Assigned(fSDR_SMASKData) then FreeMemory(fSDR_SMASKData);
if bits = 0 then
begin
fSDR_TDIData := nil;
fSDR_TDOData := nil;
fSDR_MASKData := nil;
fSDR_SMASKData := nil
end
else begin
fSDR_TDIData := GetMemory(bytes);
fSDR_TDOData := GetMemory(bytes);
fSDR_MASKData := GetMemory(bytes);
fSDR_SMASKData := GetMemory(bytes)
end
end;
if fSDRSize <> bits then
begin
fSDRSize := bits;
fDataSDR := []
end
end;
end;
end;
end.