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

Subversion Repositories iso7816_3_master

[/] [iso7816_3_master/] [trunk/] [test/] [iso7816_3_t0_analyzer.v] - Blame information for rev 19

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 acapola
/*
2
Author: Sebastien Riou (acapola)
3
Creation date: 22:22:43 01/10/2011
4
 
5
$LastChangedDate: 2011-04-17 23:31:29 +0200 (Sun, 17 Apr 2011) $
6
$LastChangedBy: acapola $
7
$LastChangedRevision: 19 $
8
$HeadURL: file:///svn/iso7816_3_master/iso7816_3_master/trunk/test/iso7816_3_t0_analyzer.v $
9
 
10
This file is under the BSD licence:
11
Copyright (c) 2011, Sebastien Riou
12
 
13
All rights reserved.
14
 
15
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
16
 
17
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
18
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
19
The names of contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
20
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32 5 acapola
`default_nettype none
33
 
34 11 acapola
 
35 10 acapola
module Iso7816_3_t0_analyzer
36 13 acapola
#(
37
        parameter DIVIDER_WIDTH = 1
38
)
39 10 acapola
(
40 5 acapola
        input wire nReset,
41
        input wire clk,
42 6 acapola
        input wire [DIVIDER_WIDTH-1:0] clkPerCycle,
43 5 acapola
        input wire isoReset,
44
        input wire isoClk,
45
        input wire isoVdd,
46 10 acapola
        input wire isoSioTerm,
47
        input wire isoSioCard,
48
        input wire useDirectionProbe,//if 1, isoSioTerm and isoSioCard must be connected to Iso7816_directionProbe outputs
49 5 acapola
        output reg [3:0] fiCode,
50
        output reg [3:0] diCode,
51 6 acapola
        output wire [12:0] fi,
52
        output wire [7:0] di,
53
        output wire [12:0] cyclesPerEtu,
54
        output wire [7:0] fMax,
55 5 acapola
        output wire isActivated,
56
        output wire tsReceived,
57
        output wire tsError,
58
        output wire useIndirectConvention,
59
        output wire atrIsEarly,//high if TS received before 400 cycles after reset release
60
        output wire atrIsLate,//high if TS is still not received after 40000 cycles after reset release
61 6 acapola
        output reg [3:0] atrK,//number of historical bytes
62
        output reg atrHasTck,
63
        output reg atrCompleted,
64 5 acapola
        output reg useT0,
65
        output reg useT1,
66
        output reg useT15,
67
        output reg waitCardTx,
68
        output reg waitTermTx,
69 10 acapola
        output wire cardTx,
70
        output wire termTx,
71 5 acapola
        output wire guardTime,
72
        output wire overrunError,
73
        output wire frameError,
74 15 acapola
        output reg comOnGoing,
75 7 acapola
        output reg [7:0] lastByte,
76
        output reg [31:0] bytesCnt
77 5 acapola
        );
78 13 acapola
localparam CLOCK_PER_BIT_WIDTH = 4'd13;
79 10 acapola
 
80
wire isoSio = isoSioTerm & isoSioCard;
81 5 acapola
 
82
reg [8:0] tsCnt;//counter to start ATR 400 cycles after reset release
83
 
84
reg [7:0] buffer[256+5:0];
85
localparam CLA_I= 8*4;
86
localparam INS_I= 8*3;
87
localparam P1_I = 8*2;
88
localparam P2_I = 8*1;
89
localparam P3_I = 0;
90
reg [CLA_I+7:0] tpduHeader;
91 12 acapola
localparam PPS0_I= CLA_I;
92
localparam PPS1_I= INS_I;
93
localparam PPS2_I= P1_I;
94
localparam PPS3_I= P2_I;
95 7 acapola
//wire COM_clk=isoClk;
96
//integer COM_errorCnt;
97
//wire txPending=1'b0;
98
//wire txRun=1'b0;
99 5 acapola
 
100
wire rxRun, rxStartBit, overrunErrorFlag, frameErrorFlag, bufferFull;
101 19 acapola
assign overrunErrorFlag = overrunError;
102 5 acapola
assign frameErrorFlag = frameError;
103
 
104
wire [7:0] rxData;
105 7 acapola
reg ackFlags;
106 5 acapola
 
107 6 acapola
wire msbFirst = useIndirectConvention;
108
wire sioHighValue = ~useIndirectConvention;
109
wire oddParity = 1'b0;
110
 
111
wire [7:0] dataOut = sioHighValue ? rxData : ~rxData;
112 5 acapola
wire endOfRx;
113
 
114 6 acapola
wire stopBit2 = useT0;//1 if com use 2 stop bits --> 12 ETU / byte
115 13 acapola
wire [CLOCK_PER_BIT_WIDTH-1:0] clocksPerBit = cyclesPerEtu-1;
116
 
117 15 acapola
wire rxCore_nReset = nReset & isoVdd & isoReset;
118 13 acapola
reg [CLOCK_PER_BIT_WIDTH-1:0] safeClocksPerBit;
119 15 acapola
 
120
always @(*) comOnGoing = rxRun|rxStartBit;
121
 
122
always @(posedge clk, negedge rxCore_nReset) begin
123
        if(~rxCore_nReset) begin
124 18 acapola
                safeClocksPerBit<={CLOCK_PER_BIT_WIDTH{1'b0}};
125 15 acapola
        end else if(endOfRx|~comOnGoing) begin
126 13 acapola
                safeClocksPerBit<=clocksPerBit;
127
        end
128
end
129
 
130 15 acapola
wire [7:0] ts;
131
 
132 5 acapola
RxCoreSelfContained #(
133 6 acapola
                .DIVIDER_WIDTH(DIVIDER_WIDTH),
134 13 acapola
                .CLOCK_PER_BIT_WIDTH(CLOCK_PER_BIT_WIDTH),
135 7 acapola
                .PRECISE_STOP_BIT(1'b1))
136 5 acapola
        rxCore (
137
    .dataOut(rxData),
138
    .overrunErrorFlag(overrunError),
139
    .dataOutReadyFlag(bufferFull),
140
    .frameErrorFlag(frameError),
141
    .endOfRx(endOfRx),
142
    .run(rxRun),
143
    .startBit(rxStartBit),
144
         .stopBit(guardTime),
145
    .clkPerCycle(clkPerCycle),
146 13 acapola
    .clocksPerBit(safeClocksPerBit),
147 5 acapola
    .stopBit2(stopBit2),
148
    .oddParity(oddParity),
149
    .msbFirst(msbFirst),
150 7 acapola
         .ackFlags(ackFlags),
151 5 acapola
    .serialIn(isoSio),
152 6 acapola
    .comClk(isoClk),
153 5 acapola
    .clk(clk),
154 15 acapola
    .nReset(rxCore_nReset)
155 5 acapola
    );
156
 
157
TsAnalyzer tsAnalyzer(
158
        .nReset(nReset),
159
        .isoReset(isoReset),
160
        .isoClk(isoClk),
161
        .isoVdd(isoVdd),
162
        .isoSio(isoSio),
163
        .endOfRx(endOfRx),
164
        .rxData(rxData),
165
        .isActivated(isActivated),
166
        .tsReceived(tsReceived),
167
        .tsError(tsError),
168
        .atrIsEarly(atrIsEarly),
169
        .atrIsLate(atrIsLate),
170 15 acapola
        .useIndirectConvention(useIndirectConvention),
171
        .ts(ts)
172 5 acapola
        );
173
 
174
FiDiAnalyzer fiDiAnalyzer(
175
        .fiCode(fiCode),
176
        .diCode(diCode),
177
        .fi(fi),
178
        .di(di),
179
        .cyclesPerEtu(cyclesPerEtu),
180
        .fMax(fMax)
181
        );
182
 
183
wire run = rxStartBit | rxRun;
184 6 acapola
localparam ATR_T0 = 0;
185
localparam ATR_TDI = 1;
186
localparam ATR_HISTORICAL = 2;
187
localparam ATR_TCK = 3;
188
localparam T0_HEADER = 0;
189 8 acapola
localparam T0_HEADER_TPDU = 1;
190
localparam T0_PB = 2;
191
localparam T0_DATA = 3;
192
localparam T0_NACK_DATA = 4;
193
localparam T0_SW1 = 5;
194
localparam T0_SW2 = 6;
195
localparam T0_HEADER_PPS = 100;
196 12 acapola
localparam T0_PPS_RESPONSE = 101;
197 8 acapola
 
198 6 acapola
integer fsmState;
199
 
200
reg [11:0] tdiStruct;
201
wire [3:0] tdiCnt;//i+1
202
wire [7:0] tdiData;//value of TDi
203
assign {tdiCnt,tdiData}=tdiStruct;
204
 
205
wire [1:0] nIfBytes;
206
HammingWeight hammingWeight(.dataIn(tdiData[7:4]), .hammingWeight(nIfBytes));
207 7 acapola
reg [7:0] tempBytesCnt;
208 6 acapola
always @(posedge isoClk, negedge nReset) begin
209 5 acapola
        if(~nReset) begin
210 7 acapola
                lastByte<=8'b0;
211
                ackFlags<=1'b0;
212
                bytesCnt<=32'b0;
213
        end else if(ackFlags) begin
214
                ackFlags<=1'b0;
215
        end else if(frameErrorFlag|bufferFull) begin
216 15 acapola
                if(tsReceived) lastByte<=dataOut;//ts is read by tsAnalyzer
217 7 acapola
                ackFlags<=1'b1;
218
                bytesCnt<=bytesCnt+1'b1;
219 15 acapola
        end else if((32'b1==bytesCnt) & tsReceived) begin
220
                lastByte<=ts;
221
        end
222 7 acapola
end
223 12 acapola
reg ppsValidSoFar;
224 18 acapola
//reg ppsAccepted;
225 12 acapola
wire ppsDataMatch = (tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]==dataOut);
226 17 acapola
wire [3:0] earlyAtrK = (4'h0==tdiCnt) ? dataOut[3:0] : atrK;
227 15 acapola
always @(posedge isoClk, negedge rxCore_nReset) begin
228
        if(~rxCore_nReset) begin
229 12 acapola
                ppsValidSoFar<=1'b0;
230 18 acapola
                //ppsAccepted<=1'b0;
231 5 acapola
                fiCode<=4'b0001;
232
                diCode<=4'b0001;
233 6 acapola
                useT0<=1'b1;
234 5 acapola
                useT1<=1'b0;
235
                useT15<=1'b0;
236 8 acapola
                {waitCardTx,waitTermTx}<=2'b00;
237 6 acapola
                fsmState<=ATR_TDI;
238
                atrHasTck<=1'b0;
239 7 acapola
                tempBytesCnt<=8'h0;
240 17 acapola
                tdiStruct<={4'h0,8'h80};//0x80 as default TDi to consider T0 as a TDi
241 6 acapola
                atrCompleted<=1'b0;
242 8 acapola
                atrK<=4'b0;
243 5 acapola
        end else if(isActivated) begin
244
                if(~tsReceived) begin
245 8 acapola
                        {waitCardTx,waitTermTx}<=2'b10;
246 5 acapola
                end else if(~atrCompleted) begin
247 6 acapola
                        //ATR analysis
248
                        case(fsmState)
249
                                ATR_TDI: begin
250
                                        if(endOfRx) begin
251 17 acapola
                                                if(tempBytesCnt+1==nIfBytes) begin //TDi bytes
252 6 acapola
                                                        if(4'h0==tdiCnt) begin//this is T0
253
                                                                atrK <= dataOut[3:0];
254
                                                        end
255 17 acapola
                                                        tempBytesCnt <= 2'h0;
256 18 acapola
                                                        tdiStruct <= {tdiCnt+1'b1,dataOut};
257 19 acapola
                                                        //if(12'h0=={dataOut,atrK}) begin
258
                                                        //      atrCompleted <= 1'b1;
259
                                                        //      {waitCardTx,waitTermTx}<=2'b01;
260
                                                        //end
261 17 acapola
                                                        if((1'b0==tdiStruct[7]) |//we just received the last interface byte
262
                                                                (4'b0==dataOut[7:4])) begin //or new TDi indicate no further interface bytes
263 19 acapola
                                                                //fsmState <= (4'b0!=earlyAtrK) ? ATR_HISTORICAL :
264
                                                                //                              atrHasTck ? ATR_TCK : T0_HEADER;
265
                                                                if(4'b0!=earlyAtrK) begin
266
                                                                        fsmState <= ATR_HISTORICAL;
267
                                                                end else if(atrHasTck) begin
268
                                                                        fsmState <= ATR_TCK;
269
                                                                end else begin
270
                                                                        fsmState <= T0_HEADER;
271
                                                                        atrCompleted <= 1'b1;
272
                                                                        {waitCardTx,waitTermTx}<=2'b01;
273
                                                                end
274 17 acapola
                                                        end else begin//TDi, i from 1 to 15
275
                                                                fsmState <= ATR_TDI;
276
                                                        end
277
 
278 6 acapola
                                                end else begin //TA, TB or TC bytes
279
                                                        //TODO: get relevant info
280 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
281 6 acapola
                                                end
282
                                        end
283
                                end
284
                                ATR_HISTORICAL: begin
285
                                        if(endOfRx) begin
286 17 acapola
                                                if(tempBytesCnt+1==atrK) begin
287 8 acapola
                                                        tempBytesCnt <= 8'h0;
288
                                                        if(atrHasTck) begin
289
                                                                fsmState <= ATR_TCK;
290
                                                        end else begin
291 13 acapola
                                                                atrCompleted <= 1'b1;
292 8 acapola
                                                                {waitCardTx,waitTermTx}<=2'b10;
293
                                                                fsmState <= T0_HEADER;
294
                                                        end
295 6 acapola
                                                end else begin
296 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
297 6 acapola
                                                end
298
                                        end
299
                                end
300
                                ATR_TCK: begin
301
                                        if(endOfRx) begin
302
                                        //TODO:check
303
                                                atrCompleted <= 1'b1;
304 8 acapola
                                                {waitCardTx,waitTermTx}<=2'b10;
305 6 acapola
                                                fsmState <= T0_HEADER;
306
                                        end
307
                                end
308
                        endcase
309 5 acapola
                end else if(useT0) begin
310
                        //T=0 cmd/response monitoring state machine
311 8 acapola
                        case(fsmState)
312
                                T0_HEADER: begin
313
                                        if(endOfRx) begin
314
                                                tpduHeader[CLA_I+:8]<=dataOut;
315
                                                tempBytesCnt <= 1;
316
                                                if(8'hFF==dataOut)
317 12 acapola
                                                        fsmState <= T0_HEADER_PPS;
318 8 acapola
                                                else
319
                                                        fsmState <= T0_HEADER_TPDU;
320
                                        end
321
                                end
322 12 acapola
                                T0_HEADER_PPS: begin
323
                                        if(endOfRx) begin
324
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
325
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
326
                                                        tempBytesCnt <= 8'h0;
327
                                                        fsmState <= T0_PPS_RESPONSE;
328
                                                        {waitCardTx,waitTermTx}<=2'b10;
329
                                                        ppsValidSoFar<=1'b1;
330 18 acapola
                                                        //ppsAccepted<=1'b0;
331 12 acapola
                                                end else begin
332 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
333 12 acapola
                                                end
334
                                        end
335
                                end
336
                                T0_PPS_RESPONSE: begin
337
                                        if(3==tempBytesCnt) begin//support only 4 byte PPS
338
                                                if(guardTime) begin
339
                                                        if(ppsValidSoFar & ppsDataMatch) begin
340
                                                                {fiCode,diCode}<=tpduHeader[PPS2_I+:8];
341
                                                        end
342
                                                end
343
                                        end
344
                                        if(endOfRx) begin
345
                                                ppsValidSoFar<=ppsValidSoFar & ppsDataMatch;
346
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
347
                                                        tempBytesCnt <= 8'h0;
348
                                                        fsmState <= T0_HEADER;
349
                                                        {waitCardTx,waitTermTx}<=2'b01;
350
                                                        case(tpduHeader[(PPS1_I-(tempBytesCnt*8))+:8])
351
                                                                8'h11: begin
352
                                                                        useT0<=1'b0;
353
                                                                        useT1<=1'b1;
354
                                                                        useT15<=1'b0;
355
                                                                end
356
                                                                8'h1F: begin
357
                                                                        useT0<=1'b0;
358
                                                                        useT1<=1'b0;
359
                                                                        useT15<=1'b1;
360
                                                                end
361
                                                                default: begin
362
                                                                        useT0<=1'b1;
363
                                                                        useT1<=1'b0;
364
                                                                        useT15<=1'b0;
365
                                                                end
366
                                                        endcase
367
                                                end else begin
368 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
369 12 acapola
                                                end
370
                                        end
371
                                end
372 8 acapola
                                T0_HEADER_TPDU: begin
373
                                        if(endOfRx) begin
374
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
375
                                                if(4==tempBytesCnt) begin
376
                                                        tempBytesCnt <= 8'h0;
377
                                                        fsmState <= T0_PB;
378
                                                        {waitCardTx,waitTermTx}<=2'b10;
379
                                                end else begin
380 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
381 8 acapola
                                                end
382
                                        end
383
                                end
384
                                T0_PB: begin
385
                                        if(endOfRx) begin
386
                                                case(dataOut[7:4])
387
                                                        4'h6: begin
388
                                                                fsmState <= (4'h0==dataOut[3:0]) ? T0_PB : T0_SW2;
389
                                                        end
390
                                                        4'h9: begin
391
                                                                fsmState <= T0_SW2;
392
                                                        end
393
                                                        default: begin
394
                                                                case(dataOut)
395
                                                                        tpduHeader[INS_I+:8]: begin//ACK
396
                                                                                fsmState <= T0_DATA;
397
                                                                                {waitCardTx,waitTermTx}<=2'b11;
398
                                                                        end
399
                                                                        ~tpduHeader[INS_I+:8]: begin//NACK
400
                                                                                fsmState <= T0_NACK_DATA;
401
                                                                                {waitCardTx,waitTermTx}<=2'b11;
402
                                                                        end
403
                                                                        default: begin //invalid
404
                                                                                //TODO
405
                                                                        end
406
                                                                endcase
407
                                                        end
408
                                                endcase
409
                                        end
410
                                end
411
                                T0_NACK_DATA: begin
412
                                        if(endOfRx) begin
413
                                                fsmState <= T0_PB;
414
                                                {waitCardTx,waitTermTx}<=2'b10;
415 18 acapola
                                                tempBytesCnt <= tempBytesCnt+1'b1;
416 8 acapola
                                        end
417
                                end
418
                                T0_SW1: begin
419
                                        if(endOfRx) begin
420
                                        //TODO:check != 60 but equal to 6x or 9x
421
                                                fsmState <= T0_SW2;
422
                                                {waitCardTx,waitTermTx}<=2'b10;
423
                                        end
424
                                end
425
                                T0_SW2: begin
426
                                        if(endOfRx) begin
427
                                                fsmState <= T0_HEADER;
428
                                                {waitCardTx,waitTermTx}<=2'b01;
429
                                        end
430
                                end
431
                                T0_DATA: begin
432
                                        if(endOfRx) begin
433
                                                if(tempBytesCnt==(tpduHeader[P3_I+:8]-1)) begin
434
                                                        tempBytesCnt <= 0;
435
                                                        fsmState <= T0_SW1;
436
                                                        {waitCardTx,waitTermTx}<=2'b10;
437
                                                end else begin
438 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
439 8 acapola
                                                end
440
                                        end
441
                                end
442
                        endcase
443 5 acapola
                end
444
        end
445
end
446
 
447
reg [1:0] txDir;
448 10 acapola
reg proto_cardTx;
449
reg proto_termTx;
450
always @(*) begin: protoComDirectionCombiBlock
451 6 acapola
        if(guardTime & ~isoSio)
452 10 acapola
                {proto_cardTx, proto_termTx}={txDir[0],txDir[1]};
453 5 acapola
        else
454 10 acapola
                {proto_cardTx, proto_termTx}={txDir[1],txDir[0]};
455 5 acapola
end
456 15 acapola
always @(posedge isoClk, negedge rxCore_nReset) begin: protoComDirectionSeqBlock
457
        if(~rxCore_nReset | ~run) begin
458 5 acapola
                txDir<=2'b00;
459
        end else begin
460 6 acapola
                if(~guardTime) begin //{waitCardTx, waitTermTx} is updated during stop bits so we hold current value here
461 5 acapola
                        case({waitCardTx, waitTermTx})
462 8 acapola
                                2'b00: txDir<=2'b00;//no one should/is sending
463
                                2'b01: txDir<=2'b01;//terminal should/is sending
464
                                2'b10: txDir<=2'b10;//card should/is sending
465
                                2'b11: txDir<=2'b11;//either card OR terminal should/is sending (we just don't know)
466 5 acapola
                        endcase
467
                end
468
        end
469
end
470 10 acapola
 
471
reg phy_cardTx;
472
reg phy_termTx;
473 15 acapola
always @(negedge isoSio, negedge rxCore_nReset) begin: phyComDirectionBlock
474
        if(~rxCore_nReset) begin
475 10 acapola
                phy_cardTx<=1'b0;
476
                phy_termTx<=1'b0;
477
        end else begin
478
                if(~isoSioTerm) begin
479
                        phy_cardTx<=1'b0;
480
                        phy_termTx<=1'b1;
481
                end else begin
482
                        phy_cardTx<=1'b1;
483
                        phy_termTx<=1'b0;
484
                end
485
        end
486
end
487
 
488
assign cardTx = useDirectionProbe ? phy_cardTx : proto_cardTx;
489
assign termTx = useDirectionProbe ? phy_termTx : proto_termTx;
490 5 acapola
 
491
endmodule
492 11 acapola
`default_nettype wire
493 5 acapola
 

powered by: WebSVN 2.1.0

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