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
/
- from Rev 14 to Rev 15
- ↔ Reverse comparison
Rev 14 → Rev 15
/iso7816_3_master/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 |
|
/iso7816_3_master/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 |
/iso7816_3_master/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 |
/iso7816_3_master/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 |
|
/iso7816_3_master/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."); |
/iso7816_3_master/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 |
/iso7816_3_master/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), |
/iso7816_3_master/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 |
/iso7816_3_master/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}; |
|