1129 lines
32 KiB
ObjectPascal
1129 lines
32 KiB
ObjectPascal
unit jtag.bstream;
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes,
|
|
Types,
|
|
jtag.svfAstScan,
|
|
jtag.svfAstRuntest,
|
|
jtag.svfAstState;
|
|
|
|
type
|
|
TjtagBStream = class;
|
|
|
|
TjtagCepMode = (cmNone, cmRead, cmWrite);
|
|
|
|
TjtagTapState = (stInvalid, stReset, stIdle, stDrScan, stIrScan,
|
|
stDrCapture, stIrCapture, stDrShift, stIrShift, stDrExit1, stIrExit1,
|
|
stDrPause, stIrPause, stDrExit2, stIrExit2, stDrUpdate, stIrUpdate);
|
|
|
|
TjtagOnFullEvent = procedure(Sender: TjtagBStream;
|
|
CEPMode: TjtagCepMode) of object;
|
|
|
|
TjtagOnDumpEvent = procedure( Sender: TjtagBStream; Data: string) of object;
|
|
|
|
TjtagBStream = class
|
|
protected
|
|
fBufTDI: array [0 .. 1023] of byte;
|
|
fBufTDO: array [0 .. 1023] of byte;
|
|
fBufSMASK: array [0 .. 1023] of byte;
|
|
fBufMASK: array [0 .. 1023] of byte;
|
|
|
|
fInitDone: boolean;
|
|
fBufferSize: word;
|
|
fBuffer: array [0 .. 1023] of byte;
|
|
fCursor : word;
|
|
fCursorR : word;
|
|
|
|
fEndDR: TjtagTapState;
|
|
fEndIR: TjtagTapState;
|
|
|
|
fMaskTCK: byte;
|
|
fMaskTMS: byte;
|
|
fMaskTDI: byte;
|
|
fMaskTDO: byte;
|
|
fMaskTRST: byte;
|
|
fMaskENA: byte;
|
|
fMaskPWR: byte;
|
|
|
|
// current value of the pins
|
|
fValTCK: byte;
|
|
fValTMS: byte;
|
|
fValTDI: byte;
|
|
fValTDO: byte;
|
|
fValTRST: byte;
|
|
fValENA: byte;
|
|
fValPWR: byte;
|
|
|
|
fCEPMode: TjtagCepMode;
|
|
|
|
fLastCEPMode: TjtagCepMode;
|
|
fLastWrite: integer;
|
|
|
|
// events
|
|
fOnFull: TjtagOnFullEvent;
|
|
fOnDump: TjtagOnDumpEvent;
|
|
|
|
// ------------------------------------------------------------
|
|
// JTAG TAP state machine
|
|
// ------------------------------------------------------------
|
|
protected
|
|
fState: TjtagTapState;
|
|
|
|
function FlipByte( Data: byte): byte;
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
public
|
|
procedure SendBit(TDI: byte; TMS: byte);
|
|
|
|
procedure SendByte(Value: byte; length: byte; last: boolean = false);
|
|
overload;
|
|
|
|
procedure SendByte(TDI: byte; TDO: byte; SMASK: byte; MASK: byte;
|
|
length: word; last: boolean = false); overload;
|
|
|
|
function ReceiveByte(length: byte): byte;
|
|
|
|
// ------------------------------------------------------------
|
|
// Property handlers
|
|
// ------------------------------------------------------------
|
|
private
|
|
function GetData(i: word): byte;
|
|
procedure SetData(i: word; d: byte);
|
|
|
|
procedure SetState(newState: TjtagTapState);
|
|
procedure SetEndDR(Value: TjtagTapState);
|
|
procedure SetEndIR(Value: TjtagTapState);
|
|
|
|
|
|
|
|
protected
|
|
procedure Init(BufferSize: word; TCK: byte; TMS: byte; TDI: byte;
|
|
TDO: byte; TRST: byte; ENA: byte; PWR: byte);
|
|
|
|
public
|
|
procedure InitDsoJtag;
|
|
procedure InitPrgJtag;
|
|
|
|
procedure Clear;
|
|
procedure Emit;
|
|
procedure Pulse(n: cardinal = 1);
|
|
procedure Flush;
|
|
|
|
protected
|
|
fBufHIR: array [0 .. 255] of byte;
|
|
fBufTIR: array [0 .. 255] of byte;
|
|
fBufHDR: array [0 .. 255] of byte;
|
|
fBufTDR: array [0 .. 255] of byte;
|
|
|
|
fLenHIR: integer;
|
|
fLenTIR: integer;
|
|
fLenHDR: integer;
|
|
fLenTDR: integer;
|
|
|
|
fBitHIR: integer;
|
|
fBitTIR: integer;
|
|
fBitHDR: integer;
|
|
fBitTDR: integer;
|
|
|
|
procedure SendHTIDR(stmt: TsvfAstScan);
|
|
|
|
public
|
|
procedure Send(stmt: TsvfAstScan); overload;
|
|
procedure Send(stmt: TsvfAstRuntest); overload;
|
|
procedure Send(stmt: TsvfAstState); overload;
|
|
|
|
public
|
|
procedure AfterConstruction; override;
|
|
procedure BeforeDestruction; override;
|
|
|
|
public
|
|
property Size: word read fBufferSize;
|
|
property DataSize: word read fCursor;
|
|
property Data[i: word]: byte read GetData write SetData;
|
|
|
|
property CEPMode: TjtagCepMode read fCEPMode write fCEPMode;
|
|
|
|
property State: TjtagTapState read fState write SetState;
|
|
property EndDR: TjtagTapState read fEndDR write SetEndDR;
|
|
property EndIR: TjtagTapState read fEndIR write SetEndIR;
|
|
|
|
property TCK: byte read fValTCK write fValTCK;
|
|
property TMS: byte read fValTMS write fValTMS;
|
|
property TDI: byte read fValTDI write fValTDI;
|
|
property TRST: byte read fValTRST write fValTRST;
|
|
property ENA: byte read fValENA write fValENA;
|
|
|
|
public
|
|
property OnFull: TjtagOnFullEvent read fOnFull write fOnFull;
|
|
property OnDump: TjtagOnDumpEvent read fOnDump write fOnDump;
|
|
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Vcl.Forms,
|
|
Windows,
|
|
SysUtils;
|
|
|
|
{ TjtagBStream }
|
|
|
|
{ TjtagBStream }
|
|
|
|
// @@@: Construction/destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Construction/destruction
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
// ================================================================================================
|
|
// AfterConstruction
|
|
// ================================================================================================
|
|
procedure TjtagBStream.AfterConstruction;
|
|
begin
|
|
inherited;
|
|
|
|
fMaskTCK := 0;
|
|
fMaskTMS := 0;
|
|
fMaskTDI := 0;
|
|
fMaskTDO := 0;
|
|
fMaskTRST := 0;
|
|
fMaskENA := 0;
|
|
fMaskPWR := 0;
|
|
|
|
fCursor := 0;
|
|
fState := stInvalid;
|
|
|
|
fEndDR := stIdle;
|
|
fEndIR := stIdle;
|
|
|
|
fLastWrite := 0;
|
|
fCEPMode := cmNone;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// BeforeDestruction
|
|
// ================================================================================================
|
|
procedure TjtagBStream.BeforeDestruction;
|
|
begin
|
|
|
|
inherited;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Init
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Init(BufferSize: word; TCK, TMS, TDI, TDO, TRST, ENA,
|
|
PWR: byte);
|
|
begin
|
|
fBufferSize := 504;
|
|
// if (BufferSize <> 1024) and (BufferSize <> 512)
|
|
// then fBufferSize := 1024
|
|
// else fBufferSize := BufferSize;
|
|
|
|
if TCK <> $FF then fMaskTCK := 1 shl TCK else fMaskTCK := 0;
|
|
if TMS <> $FF then fMaskTMS := 1 shl TMS else fMaskTMS := 0;
|
|
if TDI <> $FF then fMaskTDI := 1 shl TDI else fMaskTDI := 0;
|
|
if TDO <> $FF then fMaskTDO := 1 shl TDO else fMaskTDO := 0;
|
|
if TRST <> $FF then fMaskTRST := 1 shl TRST else fMaskTRST := 0;
|
|
if ENA <> $FF then fMaskENA := 1 shl ENA else fMaskENA := 0;
|
|
if PWR <> $FF then fMaskPWR := 1 shl PWR else fMaskPWR := 0;
|
|
|
|
fInitDone := true;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// InitDsoJtag
|
|
// ================================================================================================
|
|
procedure TjtagBStream.InitDsoJtag;
|
|
begin
|
|
Init(256, 0, 1, 3, 7, $FF, $FF, $FF);
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// InitPrgJtag
|
|
// ================================================================================================
|
|
procedure TjtagBStream.InitPrgJtag;
|
|
begin
|
|
Init(256, 0, 1, 7, 3, 5, 4, 6);
|
|
end;
|
|
|
|
|
|
// @@@: JTAG TAP state machine interface ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// JTAG TAP state machine interface
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
// ================================================================================================
|
|
// State
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SetState(newState: TjtagTapState);
|
|
var
|
|
i: integer;
|
|
rc: boolean;
|
|
|
|
begin
|
|
rc := true;
|
|
|
|
// -----------------------------------------------------
|
|
// xxx -> RESET
|
|
// -----------------------------------------------------
|
|
if newState = stReset then
|
|
for i := 0 to 4 do
|
|
SendBit(0, 1)
|
|
|
|
// -----------------------------------------------------
|
|
// IDLE
|
|
// -----------------------------------------------------
|
|
else if newState = stIdle then
|
|
begin
|
|
case fState of
|
|
stReset:
|
|
begin
|
|
SendBit(0, 0);
|
|
end;
|
|
|
|
stDrShift, stDrPause, stIrShift, stIrPause:
|
|
begin
|
|
SendBit(0, 1);
|
|
SendBit(0, 1);
|
|
SendBit(0, 0);
|
|
end;
|
|
|
|
stDrExit1, stIrExit1:
|
|
begin
|
|
SendBit(0, 1);
|
|
SendBit(0, 0);
|
|
end;
|
|
|
|
else
|
|
rc := false;
|
|
end;
|
|
end
|
|
|
|
// -----------------------------------------------------
|
|
// DRSHIFT
|
|
// -----------------------------------------------------
|
|
else if newState = stDrShift then
|
|
begin
|
|
case fState of
|
|
stReset:
|
|
begin
|
|
SendBit(0, 0); // IDLE
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 0); // DRCAPTURE
|
|
SendBit(0, 0); // DRSHIFT
|
|
end;
|
|
|
|
stIdle:
|
|
begin
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 0); // DRCAPTURE
|
|
SendBit(0, 0); // DRSHIFT
|
|
end;
|
|
|
|
stDrPause:
|
|
begin
|
|
SendBit(0, 1); // DREXIT2
|
|
SendBit(0, 0); // DRSHIFT
|
|
end;
|
|
|
|
else
|
|
rc := false;
|
|
end;
|
|
end
|
|
|
|
// -----------------------------------------------------
|
|
// IRSHIFT
|
|
// -----------------------------------------------------
|
|
else if newState = stIrShift then
|
|
begin
|
|
case fState of
|
|
stReset:
|
|
begin
|
|
SendBit(0, 0); // IDLE
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 1); // IRSELECT
|
|
SendBit(0, 0); // IRCAPTURE
|
|
SendBit(0, 0); // IRSHIFT
|
|
end;
|
|
|
|
stIdle:
|
|
begin
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 1); // IRSELECT
|
|
SendBit(0, 0); // IRCAPTURE
|
|
SendBit(0, 0); // IRSHIFT
|
|
end;
|
|
|
|
stIrPause:
|
|
begin
|
|
SendBit(0, 1); // IREXIT2
|
|
SendBit(0, 0); // IRSHIFT
|
|
end;
|
|
|
|
else
|
|
rc := false;
|
|
end;
|
|
end
|
|
|
|
// -----------------------------------------------------
|
|
// DRPAUSE
|
|
// -----------------------------------------------------
|
|
else if newState = stDrPause then
|
|
begin
|
|
case fState of
|
|
stReset:
|
|
begin
|
|
SendBit(0, 0); // IDLE
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 0); // DRCAPTURE
|
|
SendBit(0, 1); // DREXIT1
|
|
SendBit(0, 0); // DRPAUSE
|
|
end;
|
|
|
|
stIdle:
|
|
begin
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 0); // DRCAPTURE
|
|
SendBit(0, 1); // DREXIT1
|
|
SendBit(0, 0); // DRPAUSE
|
|
end;
|
|
|
|
stDrShift:
|
|
begin
|
|
SendBit(0, 1); // DREXIT1
|
|
SendBit(0, 0); // DRPAUSE
|
|
end;
|
|
|
|
else
|
|
rc := false;
|
|
end;
|
|
end
|
|
|
|
// -----------------------------------------------------
|
|
// IRPAUSE
|
|
// -----------------------------------------------------
|
|
else if newState = stIrPause then
|
|
begin
|
|
case fState of
|
|
stReset:
|
|
begin
|
|
SendBit(0, 0); // IDLE
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 1); // IRSELECT
|
|
SendBit(0, 0); // IRCAPTURE
|
|
SendBit(0, 1); // IREXIT1
|
|
SendBit(0, 0); // IRPAUSE
|
|
end;
|
|
|
|
stIdle:
|
|
begin
|
|
SendBit(0, 1); // DRSELECT
|
|
SendBit(0, 1); // IRSELECT
|
|
SendBit(0, 0); // IRCAPTURE
|
|
SendBit(0, 1); // IREXIT1
|
|
SendBit(0, 0); // IRPAUSE
|
|
end;
|
|
|
|
stIrShift:
|
|
begin
|
|
SendBit(0, 1); // IREXIT1
|
|
SendBit(0, 0); // IRPAUSE
|
|
end;
|
|
|
|
else
|
|
rc := false;
|
|
end;
|
|
end;
|
|
|
|
if rc then
|
|
fState := newState;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Pulse
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Pulse(n: cardinal);
|
|
var
|
|
i: cardinal;
|
|
|
|
begin
|
|
for i := 0 to n - 1 do
|
|
begin
|
|
fValTCK := 0;
|
|
Emit;
|
|
fValTCK := 1;
|
|
Emit;
|
|
end;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Emit
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Emit;
|
|
var
|
|
b: byte;
|
|
|
|
begin
|
|
b := 0;
|
|
|
|
if fValTCK <> 0 then
|
|
b := b or fMaskTCK;
|
|
if fValTMS <> 0 then
|
|
b := b or fMaskTMS;
|
|
if fValTDI <> 0 then
|
|
b := b or fMaskTDI;
|
|
if fValTRST <> 0 then
|
|
b := b or fMaskTRST;
|
|
if fValENA = 0 then
|
|
b := b or fMaskENA;
|
|
|
|
fBuffer[fCursor] := b;
|
|
INC(fCursor);
|
|
|
|
if fCursor > fBufferSize - 1 then
|
|
Flush;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Flush
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Flush;
|
|
begin
|
|
if Assigned(fOnFull) then
|
|
fOnFull(self, fCEPMode);
|
|
|
|
fCursor := 0;
|
|
fCursorR := 0;
|
|
end;
|
|
|
|
function TjtagBStream.FlipByte(Data: byte): byte;
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
result := 0;
|
|
|
|
for i:=0 to 7 do
|
|
begin
|
|
result := result shl 1;
|
|
|
|
if Data and $01 = $01 then
|
|
result := result or $1;
|
|
|
|
Data := Data shr 1;
|
|
end;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Clear
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Clear;
|
|
var
|
|
i: integer;
|
|
b: byte;
|
|
|
|
begin
|
|
b := 0;
|
|
|
|
if fValTCK <> 0 then
|
|
b := b or fMaskTCK;
|
|
if fValTMS <> 0 then
|
|
b := b or fMaskTMS;
|
|
if fValTDI <> 0 then
|
|
b := b or fMaskTDI;
|
|
if fValTRST <> 0 then
|
|
b := b or fMaskTRST;
|
|
if fValENA <> 0 then
|
|
b := b or fMaskENA;
|
|
|
|
for i := 0 to 1023 do
|
|
fBuffer[i] := b;
|
|
|
|
fCursor := 0;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// SendBit
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SendBit(TDI: byte; TMS: byte);
|
|
begin
|
|
fValTDI := TDI;
|
|
fValTMS := TMS;
|
|
|
|
Pulse;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// SendByte
|
|
//
|
|
// Send entire byte to the device. If 'last' is 1, TMS will be high for the last bit transmitted,
|
|
// forcing transition to EXIT1 state. From EXIT1 state the TAP state will be moved to the specified
|
|
// end state, automatically.
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SendByte(Value: byte; length: byte; last: boolean);
|
|
var
|
|
i: integer;
|
|
xtdi: byte;
|
|
xtms: byte;
|
|
val: byte;
|
|
|
|
begin
|
|
val := Value;
|
|
|
|
if (length > 0) and (length < 9) then
|
|
begin
|
|
for i := 0 to length - 1 do
|
|
begin
|
|
// xtdi := val and $01;
|
|
// val := val shr 1;
|
|
|
|
if val and $80 = $80
|
|
then xtdi := 1
|
|
else xtdi := 0;
|
|
|
|
val := val shl 1;
|
|
|
|
if last and (i = length - 1)
|
|
then xtms := 1
|
|
else xtms := 0;
|
|
|
|
SendBit(xtdi, xtms);
|
|
end;
|
|
|
|
if last then
|
|
begin
|
|
if fState = stDrShift then
|
|
begin
|
|
fState := stDrExit1;
|
|
SetState(fEndDR);
|
|
end
|
|
|
|
else if fState = stIrShift then
|
|
begin
|
|
fState := stIrExit1;
|
|
SetState(fEndIR);
|
|
end
|
|
end
|
|
end
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// SendByte
|
|
//
|
|
// Send entire byte to the device. If 'last' is 1, TMS will be high for the last bit transmitted,
|
|
// forcing transition to EXIT1 state. From EXIT1 state the TAP state will be moved to the specified
|
|
// end state, automatically.
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SendByte(TDI: byte; TDO: byte; SMASK: byte; MASK: byte;
|
|
length: word; last: boolean = false);
|
|
|
|
begin
|
|
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// ReceiveByte
|
|
// ================================================================================================
|
|
function TjtagBStream.ReceiveByte(length: byte): byte;
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
result := 0;
|
|
|
|
for i := 0 to length - 1 do
|
|
begin
|
|
if (fBuffer[fCursorR] and fMaskTDO) <> 0 then
|
|
result := result or (1 shl i);
|
|
|
|
INC(fCursorR, 2);
|
|
end;
|
|
end;
|
|
|
|
|
|
// @@@: Property Handlers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Property Handlers
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
// ================================================================================================
|
|
// GetData
|
|
// ================================================================================================
|
|
function TjtagBStream.GetData(i: word): byte;
|
|
begin
|
|
if i < 1024 then
|
|
result := fBuffer[i]
|
|
else
|
|
result := 0;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// SetData
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SetData(i: word; d: byte);
|
|
begin
|
|
if i < 1024 then
|
|
fBuffer[i] := d;
|
|
// fBuffer[i] := d and fMaskTDO;
|
|
|
|
fCursor := 0;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// SetEndDR
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SetEndDR(Value: TjtagTapState);
|
|
begin
|
|
if Value in [stReset, stIdle, stDrPause] then
|
|
fEndDR := Value;
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// SetEndIR
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SetEndIR(Value: TjtagTapState);
|
|
begin
|
|
if Value in [stReset, stIdle, stIrPause] then
|
|
fEndIR := Value;
|
|
end;
|
|
|
|
|
|
|
|
// @@@: Send SVF statements +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Send SVF statements
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
// ================================================================================================
|
|
// SendHTIDR
|
|
// ================================================================================================
|
|
procedure TjtagBStream.SendHTIDR(stmt: TsvfAstScan);
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
// -------------------------------------------
|
|
// Header Instruction Register
|
|
// -------------------------------------------
|
|
if stmt.Inst = 'HIR' then
|
|
begin
|
|
fLenHIR := stmt.LenTDI;
|
|
fBitHIR := stmt.Bits;
|
|
|
|
for i := 0 to fLenHIR - 1 do
|
|
fBufHIR[i] := stmt.DataTDI[i]
|
|
|
|
// if stmt.LenTDI = stmt.LenSMASK
|
|
// then for i:=0 to fLenHIR -1 do fBufHIR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
|
|
// else for i:=0 to fLenHIR -1 do fBufHIR[i] := stmt.DataTDI[i]
|
|
end
|
|
|
|
// -------------------------------------------
|
|
// Trailer Instruction Register
|
|
// -------------------------------------------
|
|
else if stmt.Inst = 'TIR' then
|
|
begin
|
|
fLenTIR := stmt.LenTDI;
|
|
fBitTIR := stmt.Bits;
|
|
|
|
for i := 0 to fLenTIR - 1 do
|
|
fBufTIR[i] := stmt.DataTDI[i]
|
|
|
|
// if stmt.LenTDI = stmt.LenSMASK
|
|
// then for i:=0 to fLenTIR -1 do fBufTIR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
|
|
// else for i:=0 to fLenTIR -1 do fBufTIR[i] := stmt.DataTDI[i]
|
|
end
|
|
|
|
// -------------------------------------------
|
|
// Header Data Register
|
|
// -------------------------------------------
|
|
else if stmt.Inst = 'HDR' then
|
|
begin
|
|
fLenHDR := stmt.LenTDI;
|
|
fBitHDR := stmt.Bits;
|
|
|
|
for i := 0 to fLenHDR - 1 do
|
|
fBufHDR[i] := stmt.DataTDI[i]
|
|
|
|
// if stmt.LenTDI = stmt.LenSMASK
|
|
// then for i:=0 to fLenHDR -1 do fBufHDR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
|
|
// else for i:=0 to fLenHDR -1 do fBufHDR[i] := stmt.DataTDI[i]
|
|
end
|
|
|
|
// -------------------------------------------
|
|
// Trailer Data Register
|
|
// -------------------------------------------
|
|
else if stmt.Inst = 'TDR' then
|
|
begin
|
|
fLenTDR := stmt.LenTDI;
|
|
fBitTDR := stmt.Bits;
|
|
|
|
for i := 0 to fLenTDR - 1 do
|
|
fBufTDR[i] := stmt.DataTDI[i]
|
|
|
|
// if stmt.LenTDI = stmt.LenSMASK
|
|
// then for i:=0 to fLenTDR -1 do fBufTDR[i] := stmt.DataTDI[i] and stmt.DataSMASK[i]
|
|
// else for i:=0 to fLenTDR -1 do fBufTDR[i] := stmt.DataTDI[i]
|
|
end
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// SCAN
|
|
//
|
|
// Note: Scan statements may define TDO values to check the result from the device. The data length
|
|
// of these kind of statements must be less then 512 bits. The checking of the result will be
|
|
// done in thos routine, because the bstream will be fulshed before data sending, so the
|
|
// buffer will contain the data that must be checked. The event handler must fill then data
|
|
// buffer with the readed data.
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Send(stmt: TsvfAstScan);
|
|
var
|
|
i: integer;
|
|
n: integer;
|
|
b: integer;
|
|
l: boolean;
|
|
s: string;
|
|
t: string;
|
|
|
|
x1: byte;
|
|
x2: byte;
|
|
|
|
zm : boolean;
|
|
d : boolean;
|
|
|
|
begin
|
|
if (stmt.Inst = 'HIR') or
|
|
(stmt.Inst = 'TIR') or
|
|
(stmt.Inst = 'HDR') or
|
|
(stmt.Inst = 'TDR') then
|
|
SendHTIDR(stmt)
|
|
|
|
// ---------------------------------------------------------------
|
|
// SIR
|
|
// ---------------------------------------------------------------
|
|
else if stmt.Inst = 'SIR' then
|
|
begin
|
|
// ----------------------------------------
|
|
// Move to IRSHIFT
|
|
// ----------------------------------------
|
|
fCEPMode := cmWrite;
|
|
State := stIrShift;
|
|
|
|
// ----------------------------------------
|
|
// If output checking is necessary, then
|
|
// first flush the stream.
|
|
// All SIR statement that needs checking
|
|
// must fit in one package.
|
|
// ----------------------------------------
|
|
if stmt.LenTDI = stmt.LenTDO then
|
|
begin
|
|
Flush;
|
|
fCEPMode := cmRead;
|
|
end;
|
|
|
|
// ----------------------------------------
|
|
// Send HIR
|
|
// ----------------------------------------
|
|
b := fBitHIR mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
for i := 0 to fLenHIR - 1 do
|
|
if i <> fLenHIR - 1 then
|
|
SendByte(fBufHIR[i], 8)
|
|
else
|
|
SendByte(fBufHIR[i], b);
|
|
|
|
// ----------------------------------------
|
|
// Send SIR
|
|
// ----------------------------------------
|
|
b := stmt.Bits mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
l := fBitTIR = 0;
|
|
n := (stmt.Bits +7) div 8;
|
|
// for i := 0 to stmt.LenTDI - 1 do
|
|
|
|
for i := 0 to n - 1 do
|
|
if i <> n - 1
|
|
then SendByte(stmt.DataTDI[i], 8)
|
|
else SendByte(stmt.DataTDI[i], b, l);
|
|
|
|
// ----------------------------------------
|
|
// Send TIR
|
|
// ----------------------------------------
|
|
b := fBitTIR mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
for i := 0 to fLenTIR - 1 do
|
|
if i <> fLenTIR - 1
|
|
then SendByte(fBufTIR[i], 8)
|
|
else SendByte(fBufTIR[i], b, true);
|
|
|
|
// ----------------------------------------
|
|
if stmt.LenTDI = stmt.LenTDO then
|
|
begin
|
|
Flush;
|
|
|
|
// -------------------------------------
|
|
// Skip head data
|
|
// -------------------------------------
|
|
b := fBitHIR mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
for i := 0 to fLenHIR - 1 do
|
|
if i <> fLenHIR - 1
|
|
then ReceiveByte(8)
|
|
else ReceiveByte(b);
|
|
|
|
// -------------------------------------
|
|
// Check result
|
|
// fBuffer contains the readed data.
|
|
// -------------------------------------
|
|
for i := 0 to stmt.LenTDI - 1 do
|
|
begin
|
|
if stmt.LenMASK = stmt.LenTDI then
|
|
begin
|
|
x1 := ReceiveByte(8) and stmt.DataMASK[i];
|
|
x2 := stmt.DataTDO[i] and stmt.DataMASK[i];
|
|
end
|
|
|
|
else
|
|
begin
|
|
x1 := ReceiveByte(8);
|
|
x2 := stmt.DataTDO[i];
|
|
end;
|
|
|
|
s := Format('SIR:[%2.2x, %2.2x]', [x1, x2]);
|
|
|
|
if Assigned(OnDump) then
|
|
OnDump( self, s);
|
|
|
|
Application.ProcessMessages;
|
|
end;
|
|
|
|
fCEPMode := cmWrite;
|
|
end;
|
|
end
|
|
|
|
// ---------------------------------------------------------------
|
|
// SDR
|
|
// ---------------------------------------------------------------
|
|
else if stmt.Inst = 'SDR' then
|
|
begin
|
|
n := (stmt.Bits +7) div 8;
|
|
|
|
// ----------------------------------------
|
|
// Move to DRSHIFT
|
|
// ----------------------------------------
|
|
fCEPMode := cmWrite;
|
|
State := stDrShift;
|
|
|
|
// ----------------------------------------
|
|
// If output checking is necessary, then
|
|
// first flush the stream.
|
|
// All SDR statement that needs checking
|
|
// can fit in one package.
|
|
// ----------------------------------------
|
|
if stmt.LenTDI = stmt.LenTDO then
|
|
begin
|
|
Flush;
|
|
fCEPMode := cmRead;
|
|
end;
|
|
|
|
// ----------------------------------------
|
|
// Send HDR
|
|
// ----------------------------------------
|
|
b := fBitHDR mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
for i := 0 to fLenHDR - 1 do
|
|
if i <> fLenHDR - 1
|
|
then SendByte(fBufHDR[i], 8)
|
|
else SendByte(fBufHDR[i], b);
|
|
|
|
// ----------------------------------------
|
|
// Send SDR
|
|
// ----------------------------------------
|
|
b := stmt.Bits mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
l := fBitTDR = 0;
|
|
|
|
// for i := 0 to stmt.LenTDI - 1 do
|
|
for i := 0 to n - 1 do
|
|
begin
|
|
if i <> n - 1
|
|
then SendByte(stmt.DataTDI[i], 8)
|
|
else SendByte(stmt.DataTDI[i], b, l);
|
|
|
|
Application.ProcessMessages;
|
|
end;
|
|
|
|
// ----------------------------------------
|
|
// Send TDR
|
|
// ----------------------------------------
|
|
b := fBitTDR mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
for i := 0 to fLenTDR - 1 do
|
|
if i <> fLenTDR - 1
|
|
then SendByte(fBufTDR[i], 8)
|
|
else SendByte(fBufTDR[i], b, true);
|
|
|
|
// ----------------------------------------
|
|
// Check result if any
|
|
// ----------------------------------------
|
|
if (stmt.LenTDI = stmt.LenTDO) and (stmt.LenTDI < 129)then
|
|
begin
|
|
Flush;
|
|
|
|
// -------------------------------------
|
|
// Skip head data
|
|
// -------------------------------------
|
|
b := fBitHDR mod 8;
|
|
if b = 0 then
|
|
b := 8;
|
|
|
|
for i := 0 to fBitHDR - 1 do
|
|
if i <> n - 1
|
|
then x1 := ReceiveByte(8)
|
|
else x1 := ReceiveByte(b);
|
|
|
|
// -------------------------------------
|
|
// Check result
|
|
// fBuffer contains the readed data.
|
|
// -------------------------------------
|
|
s := '';
|
|
t := '';
|
|
|
|
// -------------------------------------
|
|
// If MASK is 0000...00 then don't mask
|
|
// the data. In this case, the data must
|
|
// be dumped only.
|
|
// It is a Read operation without check!
|
|
// -------------------------------------
|
|
zm := false;
|
|
|
|
if stmt.LenMASK = stmt.LenTDO then
|
|
begin
|
|
zm := true;
|
|
|
|
for i:=0 to n-1 do
|
|
if stmt.DataMASK[i] <> 0 then
|
|
begin
|
|
zm := false;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
for i := 0 to n - 1 do
|
|
begin
|
|
if (stmt.LenSMASK = stmt.LenTDI) and (not zm)
|
|
then x1 := ReceiveByte(8) and FlipByte(stmt.DataSMASK[i])
|
|
else x1 := ReceiveByte(8);
|
|
|
|
if (stmt.LenMASK = stmt.LenTDO) and (not zm)
|
|
then x2 := stmt.DataTDO[i] and FlipByte(stmt.DataMASK[i])
|
|
else x2 := stmt.DataTDO[i];
|
|
|
|
s := Format('%2.2x',[(x1)]) +s;
|
|
t := Format('%2.2x',[(x2)]) +t;
|
|
|
|
Application.ProcessMessages;
|
|
end;
|
|
|
|
if Assigned(fOnDump) then
|
|
begin
|
|
// if mask is zero, then simply dump data ...
|
|
if zm then
|
|
fOnDump( self, s)
|
|
|
|
// ... else check for difference
|
|
else begin
|
|
d := false;
|
|
|
|
for i:=1 to Length(s) do
|
|
begin
|
|
x1 := ord(s[i]);
|
|
x2 := ord(t[i]);
|
|
|
|
if ((x1 and x2) <> x2) and (x2 <> 0) then
|
|
begin
|
|
d := true;
|
|
break
|
|
end;
|
|
end;
|
|
|
|
if d then
|
|
begin
|
|
fOnDump(self,':: '+t);
|
|
fOnDump(self,'>> '+s);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
fCEPMode := cmWrite;
|
|
end;
|
|
|
|
Application.ProcessMessages;
|
|
end
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// RUNTEST
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Send(stmt: TsvfAstRuntest);
|
|
begin
|
|
Pulse(StrToInt(stmt.RunCount));
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// STATE
|
|
// ================================================================================================
|
|
procedure TjtagBStream.Send(stmt: TsvfAstState);
|
|
var
|
|
i: integer;
|
|
|
|
begin
|
|
for i := 0 to stmt.StateCount - 1 do
|
|
begin
|
|
case stmt.States[i] of
|
|
0: State := jtag.bstream.stReset;
|
|
1: State := jtag.bstream.stIdle;
|
|
end
|
|
end;
|
|
end;
|
|
|
|
end.
|