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

Subversion Repositories iso7816_3_master

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /iso7816_3_master
    from Rev 14 to Rev 15
    Reverse comparison

Rev 14 → Rev 15

/trunk/test/ComTxDriverTasks.v
64,6 → 64,8
 
 
//Higher level tasks
 
 
task sendHexBytes;
input [16*257:0] bytesString;
integer i;
79,3 → 81,93
end
endtask
 
task sendT0TpduLc;
input [8*3*(256+5+1+2):0] bytesString;
integer i;
reg [15:0] byteInHex;
reg [7:0] byteToSend;
reg [8*(256+5+1+2):0] cmdBytes;
integer nBytes;
begin
hexStringToBytes(bytesString,cmdBytes,nBytes);
sendByte(cmdBytes[0*8+:8]);
sendByte(cmdBytes[1*8+:8]);
sendByte(cmdBytes[2*8+:8]);
sendByte(cmdBytes[3*8+:8]);
sendByte(cmdBytes[4*8+:8]);
if(0!==cmdBytes[4*8+:8]) begin
i=5;
receiveAndCheckByte(cmdBytes[1*8+:8]);//TODO: handle NACK
while(i!=nBytes) begin
sendByte(cmdBytes[i*8+:8]);
i=i+1;
end
end
end
endtask
 
task sendT0TpduLeFull;
input [8*3*5:0] bytesString;
output [8*256:0] leBytes;
output integer le;
integer i;
reg [15:0] byteInHex;
reg [7:0] byteToSend;
reg [8*(256+5+1+2):0] cmdBytes;
integer nBytes;
begin
hexStringToBytes(bytesString,cmdBytes,nBytes);
sendByte(cmdBytes[0*8+:8]);
sendByte(cmdBytes[1*8+:8]);
sendByte(cmdBytes[2*8+:8]);
sendByte(cmdBytes[3*8+:8]);
sendByte(cmdBytes[4*8+:8]);
le = (0===cmdBytes[4*8+:8]) ? 256 : cmdBytes[4*8+:8];
if((nBytes!==5) & (le !== nBytes-5)) begin
$display("ERROR: le (%d) don't match with nBytes (%d) in command %s",le,nBytes,bytesString);
$finish;
end
receiveByte(cmdBytes[1*8+:8]);
for(i=0;i<le;i=i+1) begin
receiveByte(leBytes[i*8+:8]);
end
end
endtask
 
task sendT0TpduLe;
input [8*3*5:0] bytesString;
output [8*256:0] leBytes;
integer i;
begin
sendT0TpduLeFull(bytesString,leBytes,i);
end
endtask
 
task sendT0TpduLeCheck;
input [8*3*5:0] bytesString;
input [8*3*256:0] expectedLeBytesString;
integer i;
reg [15:0] byteInHex;
reg [7:0] byteToSend;
reg [8*(256+5+1+2):0] cmdBytes;
reg [8*256:0] leBytes;
reg [8*256:0] expectedLeBytes;
integer nBytes;
integer expectedLe;
integer le;
begin
sendT0TpduLeFull(bytesString,leBytes,le);
hexStringToBytes(expectedLeBytesString,expectedLeBytes,expectedLe);
if(expectedLe !== le) begin
$display("ERROR: expectedLe (%d) don't match with le (%d) in command %s, %s",expectedLe,le,bytesString, expectedLeBytesString);
$finish;
end
for(i=0;i<le;i=i+1) begin
if(leBytes[i*8+:8]!==expectedLeBytes[i*8+:8]) begin
$display("ERROR: recived %x instead of %x at index %d in command %s, %s",leBytes[i*8+:8],expectedLeBytes[i*8+:8],i,bytesString, expectedLeBytesString);
$finish;
end
end
end
endtask
 
/trunk/test/HexStringConversion.v
53,9 → 53,9
end
end
endfunction
 
task getNextHexByte;
input [8*3*257:0] bytesString;
input [8*3*(256+5+1+2):0] bytesString;
input integer indexIn;
output reg [7:0] byteOut;
output integer indexOut;
78,3 → 78,23
end
end
endtask
 
task hexStringToBytes;
input [8*3*(256+5+1+2):0] bytesString;
output reg [8*(256+5+1+2):0] bytesOut;
output integer nBytes;
integer i;
reg [7:0] newByte;
begin
nBytes=0;
i=8*3*(256+5+1+2);
//$display("bytesString: %x",bytesString);
getNextHexByte(bytesString, i, newByte, i);
while(i!=-1) begin
//$display("i: %d, nBytes: %d, newByte: %x",i, nBytes, newByte);
bytesOut[nBytes*8+:8]=newByte;
nBytes=nBytes+1;
getNextHexByte(bytesString, i, newByte, i);
end
end
endtask
/trunk/test/DummyCard.v
46,20 → 46,35
reg nCsStatusOut;
 
// Outputs
wire [7:0] dataOut;
wire [7:0] uart_dataOut;
wire [7:0] statusOut;
wire serialOut;
reg [12:0] cyclesPerEtu;
 
wire cardIsoClk;//card use its own generated clock (like true UARTs)
 
reg useIndirectConventionConfig;//can be changed by commands
reg useIndirectConvention;
wire stopBit2=1'b1;//0: 1 stop bit, 1: 2 stop bits
wire msbFirst = useIndirectConvention;//if 1, bits order is: startBit, b7, b6, b5...b0, parity
wire oddParity = 1'b0;//if 1, parity bit is such that data+parity have an odd number of 1
wire sioHighValue = ~useIndirectConvention;//apply only to data bits
 
wire [7:0] uart_dataIn = sioHighValue ? dataIn : ~dataIn;
wire [7:0] dataOut = sioHighValue ? uart_dataOut : ~uart_dataOut;
HalfDuplexUartIf uartIf (
.nReset(isoReset),
.clk(isoClk),
.clkPerCycle(clkPerCycle),
.dataIn(dataIn),
.dataIn(uart_dataIn),
.nWeDataIn(nWeDataIn),
.clocksPerBit(cyclesPerEtu),
.dataOut(dataOut),
.stopBit2(stopBit2),
.oddParity(oddParity),
.msbFirst(msbFirst),
.dataOut(uart_dataOut),
.nCsDataOut(nCsDataOut),
.statusOut(statusOut),
.nCsStatusOut(nCsStatusOut),
106,6 → 121,9
tpdu: 00 0A 00 00 LE
response: data
sw: 90 00
toggle communication convention (take effect at next reset):
tpdu 00 FC 00 00 00
sw: 90 00
any other:
sw: 69 86
*/
138,7 → 156,20
end
endtask
 
task toggleConventionCmd;
integer i;
begin
useIndirectConventionConfig=~useIndirectConventionConfig;
sendHexBytes("9000");//sendWord(16'h9000);
end
endtask
 
//stuff which can be changed by command and affect ATR
always @(posedge isoVdd) begin
useIndirectConventionConfig<=1'b1;
end
 
integer i;
always @(posedge isoClk, negedge isoReset) begin
if(~isoReset) begin
nWeDataIn<=1'b1;
147,13 → 178,16
tsCnt<=9'b0;
sendAtr<=1'b1;
cyclesPerEtu <= 13'd372-1'b1;
useIndirectConvention<=useIndirectConventionConfig;
end else if(tsCnt!=9'd400) begin
tsCnt <= tsCnt + 1'b1;
end else if(sendAtr) begin
sendAtr<=1'b0;
//sendHexBytes("3B00");
sendHexBytes("3B");
//sendHexBytes("3F");
if(useIndirectConvention)
sendHexBytes("3F");
else
sendHexBytes("3B");
//sendHexBytes("9497801F42BABEBABE");
//sendHexBytes("9E 97 80 1F C7 80 31 E0 73 FE 21 1B 66 D0 00 28 24 01 00 0D");
sendHexBytes("9E 97 80 1F C7 80 31 E0 73 FE 21 1B 66 D0 00 28 24 01 00 ");
180,7 → 214,8
case(tpduHeader[7+CLA_I:P2_I])
32'h000C0000: writeBufferCmd;
32'h000A0000: readBufferCmd;
default: sendHexBytes("6986");//sendWord(16'h6986);
32'h00FC0000: toggleConventionCmd;
default: sendHexBytes("6986");
endcase
end
end
/trunk/test/tsAnalyzer.v
45,7 → 45,8
output wire tsError,
output wire atrIsEarly,//high if TS received before 400 cycles after reset release
output wire atrIsLate,//high if TS is still not received after 40000 cycles after reset release
output wire useIndirectConvention
output wire useIndirectConvention,
output reg [7:0] ts
);
 
54,16 → 55,15
reg [16:0] resetCnt;
reg waitTs;
assign tsReceived = ~waitTs;
reg [7:0] ts;
assign atrIsEarly = ~waitTs & (resetCnt<(16'h100+16'd400));
assign atrIsLate = resetCnt>(16'h100+16'd40000);
assign useIndirectConvention = ~waitTs & (ts==8'hFC);//FC is 3F written LSB first
assign useIndirectConvention = ~waitTs & (ts==8'h03);//03 is 3F written LSB first and complemented
assign tsError = ~waitTs & (ts!=8'h3B) & ~useIndirectConvention;
 
assign isActivated = isoReset & isoVdd;
 
always @(posedge isoClk, negedge nReset) begin
if(~nReset) begin
wire fsm_nReset=nReset & isoReset & isoVdd;
always @(posedge isoClk, negedge fsm_nReset) begin
if(~fsm_nReset) begin
resetCnt<=16'b0;
waitTs<=1'b1;
end else if(isActivated) begin
70,16 → 70,20
if(waitTs) begin
if(endOfRx) begin
waitTs<=1'b0;
ts<=rxData;
case(rxData)
8'h3B: ts<=rxData;
8'h03: ts<=8'h3F;
default: ts<=rxData;
endcase
end
resetCnt<=resetCnt+1;
end
end else begin
if(isoVdd & isoReset) begin
//if(isoVdd & isoReset) begin
resetCnt<=resetCnt + 1;
end else begin
resetCnt<=16'b0;
end
//end else begin
// resetCnt<=16'b0;
//end
end
end
/trunk/test/tbIso7816_3_Master.v
89,6 → 89,7
wire spy_atrHasTck,spy_atrCompleted;
wire spy_useT0,spy_useT1,spy_useT15,spy_waitCardTx,spy_waitTermTx,spy_cardTx,spy_termTx,spy_guardTime;
wire spy_overrunError,spy_frameError;
wire spy_comOnGoing;
wire [7:0] spy_lastByte;
wire [31:0] spy_bytesCnt;
 
167,7 → 168,8
.guardTime(spy_guardTime),
.overrunError(spy_overrunError),
.frameError(spy_frameError),
.lastByte(spy_lastByte),
.comOnGoing(spy_comOnGoing),
.lastByte(spy_lastByte),
.bytesCnt(spy_bytesCnt)
);
 
210,8 → 212,8
tbErrorCnt=tbErrorCnt+1;
end
@(posedge clk);
while((txRun===1'b1)||(rxRun===1'b1)||(rxStartBit===1'b1)) begin
while((txRun===1'b1)||(rxRun===1'b1)||(rxStartBit===1'b1)) begin
while((1'b0===spy_atrCompleted)||(txRun===1'b1)||(rxRun===1'b1)||(rxStartBit===1'b1)) begin
while((1'b0===spy_atrCompleted)||(txRun===1'b1)||(rxRun===1'b1)||(rxStartBit===1'b1)) begin
@(posedge clk);
end
@(posedge clk);
223,11 → 225,12
end
end
//T=0 tpdu stimuli
reg [7:0] byteFromCard;
//reg [7:0] byteFromCard;
reg [8*256:0] bytesFromCard;
initial begin
tbTestSequenceDone=1'b0;
//receiveAndCheckHexBytes("3B00");
receiveByte(byteFromCard);//3B or 3F, so we don't check (Master and Spy do)
receiveByte(bytesFromCard[7:0]);//3B or 3F, so we don't check (Master and Spy do)
//receiveAndCheckHexBytes("9497801F42BABEBABE");
//TODO: handle TCK-->receiveAndCheckHexBytes("9E 97 80 1F C7 80 31 E0 73 FE 21 1B 66 D0 00 28 24 01 00 0D");
receiveAndCheckHexBytes("9E 97 80 1F C7 80 31 E0 73 FE 21 1B 66 D0 00 28 24 01 00");
234,10 → 237,33
sendHexBytes("FF109778");
receiveAndCheckHexBytes("FF109778");
cyclesPerEtu=8-1;
sendHexBytes("000C000001");
receiveAndCheckHexBytes("0C");
sendHexBytes("55");
//sendHexBytes("000C000001");
//receiveAndCheckHexBytes("0C");
//sendHexBytes("55");
sendT0TpduLc("000C000004 CAFEBABE");//write buffer
receiveAndCheckHexBytes("9000");
sendT0TpduLc("00FC000000");//change convention for next ATR
receiveAndCheckHexBytes("9000");
sendT0TpduLeCheck("000A000004","CAFEBABE");//read buffer
receiveAndCheckHexBytes("9000");
/* //Reset not supported by the dummy card yet because we use "wait()" in Com tasks...
wait(spy_comOnGoing===1'b0);
wait(spy_guardTime===1'b0);
startActivation = 1'b0;
startDeactivation = 1'b1;
cyclesPerEtu = 372-1;
wait(1'b0===spy_isActivated);
startDeactivation = 0;
startActivation = 1'b1;
receiveAndCheckHexBytes("3B 9E 97 80 1F C7 80 31 E0 73 FE 21 1B 66 D0 00 28 24 01 00");
sendT0TpduLeCheck("000A000004","CAFEBABE");//read buffer
receiveAndCheckHexBytes("9000");
*/
tbTestSequenceDone=1'b1;
#(CLK_PERIOD*372*12);
if(0===tbErrorCnt) $display("SUCCESS: test sequence completed.");
/trunk/test/iso7816_3_t0_analyzer.v
71,6 → 71,7
output wire guardTime,
output wire overrunError,
output wire frameError,
output reg comOnGoing,
output reg [7:0] lastByte,
output reg [31:0] bytesCnt
);
113,15 → 114,21
wire stopBit2 = useT0;//1 if com use 2 stop bits --> 12 ETU / byte
wire [CLOCK_PER_BIT_WIDTH-1:0] clocksPerBit = cyclesPerEtu-1;
 
wire rxCore_nReset = nReset & isoVdd & isoReset;
reg [CLOCK_PER_BIT_WIDTH-1:0] safeClocksPerBit;
always @(posedge clk, negedge nReset) begin
if(~nReset) begin
 
always @(*) comOnGoing = rxRun|rxStartBit;
 
always @(posedge clk, negedge rxCore_nReset) begin
if(~rxCore_nReset) begin
safeClocksPerBit<=clocksPerBit;
end else if(endOfRx|~(rxRun|rxStartBit)) begin
end else if(endOfRx|~comOnGoing) begin
safeClocksPerBit<=clocksPerBit;
end
end
 
wire [7:0] ts;
 
RxCoreSelfContained #(
.DIVIDER_WIDTH(DIVIDER_WIDTH),
.CLOCK_PER_BIT_WIDTH(CLOCK_PER_BIT_WIDTH),
144,7 → 151,7
.serialIn(isoSio),
.comClk(isoClk),
.clk(clk),
.nReset(nReset)
.nReset(rxCore_nReset)
);
 
TsAnalyzer tsAnalyzer(
160,7 → 167,8
.tsError(tsError),
.atrIsEarly(atrIsEarly),
.atrIsLate(atrIsLate),
.useIndirectConvention(useIndirectConvention)
.useIndirectConvention(useIndirectConvention),
.ts(ts)
);
 
FiDiAnalyzer fiDiAnalyzer(
205,16 → 213,18
end else if(ackFlags) begin
ackFlags<=1'b0;
end else if(frameErrorFlag|bufferFull) begin
lastByte<=dataOut;
if(tsReceived) lastByte<=dataOut;//ts is read by tsAnalyzer
ackFlags<=1'b1;
bytesCnt<=bytesCnt+1'b1;
end
end else if((32'b1==bytesCnt) & tsReceived) begin
lastByte<=ts;
end
end
reg ppsValidSoFar;
reg ppsAccepted;
wire ppsDataMatch = (tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]==dataOut);
always @(posedge isoClk, negedge nReset) begin
if(~nReset) begin
always @(posedge isoClk, negedge rxCore_nReset) begin
if(~rxCore_nReset) begin
ppsValidSoFar<=1'b0;
ppsAccepted<=1'b0;
fiCode<=4'b0001;
436,8 → 446,8
else
{proto_cardTx, proto_termTx}={txDir[1],txDir[0]};
end
always @(posedge isoClk, negedge nReset) begin: protoComDirectionSeqBlock
if(~nReset | ~run) begin
always @(posedge isoClk, negedge rxCore_nReset) begin: protoComDirectionSeqBlock
if(~rxCore_nReset | ~run) begin
txDir<=2'b00;
end else begin
if(~guardTime) begin //{waitCardTx, waitTermTx} is updated during stop bits so we hold current value here
453,8 → 463,8
 
reg phy_cardTx;
reg phy_termTx;
always @(negedge isoSio, negedge nReset) begin: phyComDirectionBlock
if(~nReset) begin
always @(negedge isoSio, negedge rxCore_nReset) begin: phyComDirectionBlock
if(~rxCore_nReset) begin
phy_cardTx<=1'b0;
phy_termTx<=1'b0;
end else begin
/trunk/sources/Uart.v
83,11 → 83,20
assign loadDataIn = startTx & ~rxStartBit & (~rxRun | endOfRx);
 
reg [CLOCK_PER_BIT_WIDTH-1:0] safeClocksPerBit;
reg safeStopBit2;
reg safeOddParity;
reg safeMsbFirst;
always @(posedge clk, negedge nReset) begin
if(~nReset) begin
safeClocksPerBit<=clocksPerBit;
safeStopBit2<=stopBit2;
safeOddParity<=oddParity;
safeMsbFirst<=msbFirst;
end else if(endOfRx|endOfTx|~(rxRun|rxStartBit|txRun)) begin
safeClocksPerBit<=clocksPerBit;
safeStopBit2<=stopBit2;
safeOddParity<=oddParity;
safeMsbFirst<=msbFirst;
end
end
 
108,9 → 117,9
.stopBit(stopBit),
.clkPerCycle(clkPerCycle),
.clocksPerBit(safeClocksPerBit),
.stopBit2(stopBit2),
.oddParity(oddParity),
.msbFirst(msbFirst),
.stopBit2(safeStopBit2),
.oddParity(safeOddParity),
.msbFirst(safeMsbFirst),
.ackFlags(ackFlags),
.serialIn(rxSerialIn),
.comClk(comClk),
129,9 → 138,9
.dataIn(txData),
.clkPerCycle(clkPerCycle),
.clocksPerBit(safeClocksPerBit),
.stopBit2(stopBit2),
.oddParity(oddParity),
.msbFirst(msbFirst),
.stopBit2(safeStopBit2),
.oddParity(safeOddParity),
.msbFirst(safeMsbFirst),
.loadDataIn(loadDataIn),
.comClk(comClk),
.clk(clk),
/trunk/sources/Iso7816_3_Master.v
39,7 → 39,7
input wire [7:0] dataIn,
input wire nWeDataIn,
input wire [12:0] cyclesPerEtu,
output wire [7:0] dataOut,
output reg [7:0] dataOut,
input wire nCsDataOut,
output wire [7:0] statusOut,
input wire nCsStatusOut,
64,6 → 64,16
pullup(isoSio);
wire comClk;
 
wire stopBit2=1'b1;//0: 1 stop bit, 1: 2 stop bits
wire msbFirst = useIndirectConvention;//if 1, bits order is: startBit, b7, b6, b5...b0, parity
wire oddParity = 1'b0;//if 1, parity bit is such that data+parity have an odd number of 1
wire sioHighValue = ~useIndirectConvention;//apply only to data bits
 
wire [7:0] uart_dataOut;
wire [7:0] uart_dataIn = sioHighValue ? dataIn : ~dataIn;
always @(*) dataOut = sioHighValue ? uart_dataOut : ~uart_dataOut;
 
 
HalfDuplexUartIf #(
.DIVIDER_WIDTH(1'b1),
.CLOCK_PER_BIT_WIDTH(4'd13)
72,10 → 82,13
.nReset(nReset),
.clk(clk),
.clkPerCycle(1'b0),
.dataIn(dataIn),
.dataIn(uart_dataIn),
.nWeDataIn(nWeDataIn),
.clocksPerBit(cyclesPerEtu),
.dataOut(dataOut),
.stopBit2(stopBit2),
.oddParity(oddParity),
.msbFirst(msbFirst),
.dataOut(uart_dataOut),
.nCsDataOut(nCsDataOut),
.statusOut(statusOut),
.nCsStatusOut(nCsStatusOut),
107,7 → 120,11
if(waitTs) begin
if(statusOut[0]) begin
waitTs<=1'b0;
ts<=dataOut;
case(dataOut)
8'h3B: ts<=dataOut;
8'h03: ts<=8'h3F;
default: ts<=dataOut;
endcase
end
resetCnt<=resetCnt+1;
end
/trunk/sources/HalfDuplexUartIf.v
43,7 → 43,10
input wire [7:0] dataIn,
input wire nWeDataIn,
input wire [CLOCK_PER_BIT_WIDTH-1:0] clocksPerBit,
output wire [7:0] dataOut,
input wire stopBit2,//0: 1 stop bit, 1: 2 stop bits
input wire oddParity, //if 1, parity bit is such that data+parity have an odd number of 1
input wire msbFirst, //if 1, bits order is: startBit, b7, b6, b5...b0, parity
output wire [7:0] dataOut,
input wire nCsDataOut,
output wire [7:0] statusOut,
input wire nCsStatusOut,
57,10 → 60,6
 
// Inputs
wire [7:0] txData;
//wire [12:0] clocksPerBit;
wire stopBit2=1;
wire oddParity=0; //if 1, parity bit is such that data+parity have an odd number of 1
wire msbFirst=0; //if 1, bits will be send in the order startBit, b7, b6, b5...b0, parity
reg txPending;
wire ackFlags;
 
81,8 → 80,7
reg [1:0] flagsReg;
assign txData = dataReg;
//assign clocksPerBit = 7;
 
assign dataOut=dataReg;
assign statusOut[7:0]={txRun, txPending, rxRun, rxStartBit, isTx, flagsReg, bufferFull};
 

powered by: WebSVN 2.1.0

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