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 13

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-02-09 13:34:14 +0100 (Wed, 09 Feb 2011) $
6
$LastChangedBy: acapola $
7
$LastChangedRevision: 13 $
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 7 acapola
        output reg [7:0] lastByte,
75
        output reg [31:0] bytesCnt
76 5 acapola
        );
77 13 acapola
localparam CLOCK_PER_BIT_WIDTH = 4'd13;
78 10 acapola
 
79
wire isoSio = isoSioTerm & isoSioCard;
80 5 acapola
 
81
reg [8:0] tsCnt;//counter to start ATR 400 cycles after reset release
82
 
83
reg [7:0] buffer[256+5:0];
84
localparam CLA_I= 8*4;
85
localparam INS_I= 8*3;
86
localparam P1_I = 8*2;
87
localparam P2_I = 8*1;
88
localparam P3_I = 0;
89
reg [CLA_I+7:0] tpduHeader;
90 12 acapola
localparam PPS0_I= CLA_I;
91
localparam PPS1_I= INS_I;
92
localparam PPS2_I= P1_I;
93
localparam PPS3_I= P2_I;
94 7 acapola
//wire COM_clk=isoClk;
95
//integer COM_errorCnt;
96
//wire txPending=1'b0;
97
//wire txRun=1'b0;
98 5 acapola
 
99
wire rxRun, rxStartBit, overrunErrorFlag, frameErrorFlag, bufferFull;
100
assign overrunErrorFlag = overrunError;
101
assign frameErrorFlag = frameError;
102
 
103
wire [7:0] rxData;
104 7 acapola
reg ackFlags;
105 5 acapola
 
106 6 acapola
wire msbFirst = useIndirectConvention;
107
wire sioHighValue = ~useIndirectConvention;
108
wire oddParity = 1'b0;
109
 
110
wire [7:0] dataOut = sioHighValue ? rxData : ~rxData;
111 5 acapola
wire endOfRx;
112
 
113 6 acapola
wire stopBit2 = useT0;//1 if com use 2 stop bits --> 12 ETU / byte
114 13 acapola
wire [CLOCK_PER_BIT_WIDTH-1:0] clocksPerBit = cyclesPerEtu-1;
115
 
116
reg [CLOCK_PER_BIT_WIDTH-1:0] safeClocksPerBit;
117
always @(posedge clk, negedge nReset) begin
118
        if(~nReset) begin
119
                safeClocksPerBit<=clocksPerBit;
120
        end else if(endOfRx|~(rxRun|rxStartBit)) begin
121
                safeClocksPerBit<=clocksPerBit;
122
        end
123
end
124
 
125 5 acapola
RxCoreSelfContained #(
126 6 acapola
                .DIVIDER_WIDTH(DIVIDER_WIDTH),
127 13 acapola
                .CLOCK_PER_BIT_WIDTH(CLOCK_PER_BIT_WIDTH),
128 7 acapola
                .PRECISE_STOP_BIT(1'b1))
129 5 acapola
        rxCore (
130
    .dataOut(rxData),
131
    .overrunErrorFlag(overrunError),
132
    .dataOutReadyFlag(bufferFull),
133
    .frameErrorFlag(frameError),
134
    .endOfRx(endOfRx),
135
    .run(rxRun),
136
    .startBit(rxStartBit),
137
         .stopBit(guardTime),
138
    .clkPerCycle(clkPerCycle),
139 13 acapola
    .clocksPerBit(safeClocksPerBit),
140 5 acapola
    .stopBit2(stopBit2),
141
    .oddParity(oddParity),
142
    .msbFirst(msbFirst),
143 7 acapola
         .ackFlags(ackFlags),
144 5 acapola
    .serialIn(isoSio),
145 6 acapola
    .comClk(isoClk),
146 5 acapola
    .clk(clk),
147
    .nReset(nReset)
148
    );
149
 
150
TsAnalyzer tsAnalyzer(
151
        .nReset(nReset),
152
        .isoReset(isoReset),
153
        .isoClk(isoClk),
154
        .isoVdd(isoVdd),
155
        .isoSio(isoSio),
156
        .endOfRx(endOfRx),
157
        .rxData(rxData),
158
        .isActivated(isActivated),
159
        .tsReceived(tsReceived),
160
        .tsError(tsError),
161
        .atrIsEarly(atrIsEarly),
162
        .atrIsLate(atrIsLate),
163
        .useIndirectConvention(useIndirectConvention)
164
        );
165
 
166
FiDiAnalyzer fiDiAnalyzer(
167
        .fiCode(fiCode),
168
        .diCode(diCode),
169
        .fi(fi),
170
        .di(di),
171
        .cyclesPerEtu(cyclesPerEtu),
172
        .fMax(fMax)
173
        );
174
 
175
wire run = rxStartBit | rxRun;
176 6 acapola
localparam ATR_T0 = 0;
177
localparam ATR_TDI = 1;
178
localparam ATR_HISTORICAL = 2;
179
localparam ATR_TCK = 3;
180
localparam T0_HEADER = 0;
181 8 acapola
localparam T0_HEADER_TPDU = 1;
182
localparam T0_PB = 2;
183
localparam T0_DATA = 3;
184
localparam T0_NACK_DATA = 4;
185
localparam T0_SW1 = 5;
186
localparam T0_SW2 = 6;
187
localparam T0_HEADER_PPS = 100;
188 12 acapola
localparam T0_PPS_RESPONSE = 101;
189 8 acapola
 
190 6 acapola
integer fsmState;
191
 
192
reg [11:0] tdiStruct;
193
wire [3:0] tdiCnt;//i+1
194
wire [7:0] tdiData;//value of TDi
195
assign {tdiCnt,tdiData}=tdiStruct;
196
 
197
wire [1:0] nIfBytes;
198
HammingWeight hammingWeight(.dataIn(tdiData[7:4]), .hammingWeight(nIfBytes));
199 7 acapola
reg [7:0] tempBytesCnt;
200 6 acapola
always @(posedge isoClk, negedge nReset) begin
201 5 acapola
        if(~nReset) begin
202 7 acapola
                lastByte<=8'b0;
203
                ackFlags<=1'b0;
204
                bytesCnt<=32'b0;
205
        end else if(ackFlags) begin
206
                ackFlags<=1'b0;
207
        end else if(frameErrorFlag|bufferFull) begin
208
                lastByte<=dataOut;
209
                ackFlags<=1'b1;
210
                bytesCnt<=bytesCnt+1'b1;
211
        end
212
end
213 12 acapola
reg ppsValidSoFar;
214
reg ppsAccepted;
215
wire ppsDataMatch = (tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]==dataOut);
216 7 acapola
always @(posedge isoClk, negedge nReset) begin
217
        if(~nReset) begin
218 12 acapola
                ppsValidSoFar<=1'b0;
219
                ppsAccepted<=1'b0;
220 5 acapola
                fiCode<=4'b0001;
221
                diCode<=4'b0001;
222 6 acapola
                useT0<=1'b1;
223 5 acapola
                useT1<=1'b0;
224
                useT15<=1'b0;
225 8 acapola
                {waitCardTx,waitTermTx}<=2'b00;
226 6 acapola
                fsmState<=ATR_TDI;
227
                atrHasTck<=1'b0;
228 7 acapola
                tempBytesCnt<=8'h0;
229 6 acapola
                tdiStruct<=12'h0;
230
                atrCompleted<=1'b0;
231 8 acapola
                atrK<=4'b0;
232 5 acapola
        end else if(isActivated) begin
233
                if(~tsReceived) begin
234 8 acapola
                        {waitCardTx,waitTermTx}<=2'b10;
235 5 acapola
                end else if(~atrCompleted) begin
236 6 acapola
                        //ATR analysis
237
                        case(fsmState)
238
                                ATR_TDI: begin
239
                                        if(endOfRx) begin
240 7 acapola
                                                if(tempBytesCnt==nIfBytes) begin //TDi bytes
241
                                                        tempBytesCnt <= 2'h0;
242 6 acapola
                                                        tdiStruct <= {tdiCnt+1,dataOut};
243
                                                        if(4'h0==tdiCnt) begin//this is T0
244
                                                                atrK <= dataOut[3:0];
245
                                                                fsmState <= (4'b0!=dataOut[7:4]) ? ATR_TDI :
246
                                                                                                (4'b0!=dataOut[3:0]) ? ATR_HISTORICAL : T0_HEADER;
247
                                                        end else begin//TDi, i from 1 to 15
248
                                                                fsmState <= (4'b0!=dataOut[7:4]) ? ATR_TDI :
249
                                                                                                (4'b0!=atrK) ? ATR_HISTORICAL : T0_HEADER;
250
                                                        end
251 8 acapola
                                                        if(12'h0=={dataOut,atrK}) begin
252
                                                                atrCompleted <= 1'b1;
253
                                                                {waitCardTx,waitTermTx}<=2'b01;
254
                                                        end
255 6 acapola
                                                end else begin //TA, TB or TC bytes
256
                                                        //TODO: get relevant info
257 13 acapola
                                                        //check if we just received the last interface byte
258
                                                        if((tempBytesCnt+1==nIfBytes) & (1'b0==tdiStruct[7])) begin
259
                                                                tempBytesCnt <= 2'h0;
260
                                                                fsmState <= (4'b0!=atrK) ? ATR_HISTORICAL : T0_HEADER;
261
                                                        end else begin
262
                                                                tempBytesCnt <= tempBytesCnt+1;
263
                                                        end
264 6 acapola
                                                end
265
                                        end
266
                                end
267
                                ATR_HISTORICAL: begin
268
                                        if(endOfRx) begin
269 13 acapola
                                                if(tempBytesCnt==(atrK-1)) begin
270 8 acapola
                                                        tempBytesCnt <= 8'h0;
271
                                                        if(atrHasTck) begin
272
                                                                fsmState <= ATR_TCK;
273
                                                        end else begin
274 13 acapola
                                                                atrCompleted <= 1'b1;
275 8 acapola
                                                                {waitCardTx,waitTermTx}<=2'b10;
276
                                                                fsmState <= T0_HEADER;
277
                                                        end
278 6 acapola
                                                end else begin
279 7 acapola
                                                        tempBytesCnt <= tempBytesCnt+1;
280 6 acapola
                                                end
281
                                        end
282
                                end
283
                                ATR_TCK: begin
284
                                        if(endOfRx) begin
285
                                        //TODO:check
286
                                                atrCompleted <= 1'b1;
287 8 acapola
                                                {waitCardTx,waitTermTx}<=2'b10;
288 6 acapola
                                                fsmState <= T0_HEADER;
289
                                        end
290
                                end
291
                        endcase
292 5 acapola
                end else if(useT0) begin
293
                        //T=0 cmd/response monitoring state machine
294 8 acapola
                        case(fsmState)
295
                                T0_HEADER: begin
296
                                        if(endOfRx) begin
297
                                                tpduHeader[CLA_I+:8]<=dataOut;
298
                                                tempBytesCnt <= 1;
299
                                                if(8'hFF==dataOut)
300 12 acapola
                                                        fsmState <= T0_HEADER_PPS;
301 8 acapola
                                                else
302
                                                        fsmState <= T0_HEADER_TPDU;
303
                                        end
304
                                end
305 12 acapola
                                T0_HEADER_PPS: begin
306
                                        if(endOfRx) begin
307
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
308
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
309
                                                        tempBytesCnt <= 8'h0;
310
                                                        fsmState <= T0_PPS_RESPONSE;
311
                                                        {waitCardTx,waitTermTx}<=2'b10;
312
                                                        ppsValidSoFar<=1'b1;
313
                                                        ppsAccepted<=1'b0;
314
                                                end else begin
315
                                                        tempBytesCnt <= tempBytesCnt+1;
316
                                                end
317
                                        end
318
                                end
319
                                T0_PPS_RESPONSE: begin
320
                                        if(3==tempBytesCnt) begin//support only 4 byte PPS
321
                                                if(guardTime) begin
322
                                                        if(ppsValidSoFar & ppsDataMatch) begin
323
                                                                {fiCode,diCode}<=tpduHeader[PPS2_I+:8];
324
                                                        end
325
                                                end
326
                                        end
327
                                        if(endOfRx) begin
328
                                                ppsValidSoFar<=ppsValidSoFar & ppsDataMatch;
329
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
330
                                                        tempBytesCnt <= 8'h0;
331
                                                        fsmState <= T0_HEADER;
332
                                                        {waitCardTx,waitTermTx}<=2'b01;
333
                                                        case(tpduHeader[(PPS1_I-(tempBytesCnt*8))+:8])
334
                                                                8'h11: begin
335
                                                                        useT0<=1'b0;
336
                                                                        useT1<=1'b1;
337
                                                                        useT15<=1'b0;
338
                                                                end
339
                                                                8'h1F: begin
340
                                                                        useT0<=1'b0;
341
                                                                        useT1<=1'b0;
342
                                                                        useT15<=1'b1;
343
                                                                end
344
                                                                default: begin
345
                                                                        useT0<=1'b1;
346
                                                                        useT1<=1'b0;
347
                                                                        useT15<=1'b0;
348
                                                                end
349
                                                        endcase
350
                                                end else begin
351
                                                        tempBytesCnt <= tempBytesCnt+1;
352
                                                end
353
                                        end
354
                                end
355 8 acapola
                                T0_HEADER_TPDU: begin
356
                                        if(endOfRx) begin
357
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
358
                                                if(4==tempBytesCnt) begin
359
                                                        tempBytesCnt <= 8'h0;
360
                                                        fsmState <= T0_PB;
361
                                                        {waitCardTx,waitTermTx}<=2'b10;
362
                                                end else begin
363
                                                        tempBytesCnt <= tempBytesCnt+1;
364
                                                end
365
                                        end
366
                                end
367
                                T0_PB: begin
368
                                        if(endOfRx) begin
369
                                                case(dataOut[7:4])
370
                                                        4'h6: begin
371
                                                                fsmState <= (4'h0==dataOut[3:0]) ? T0_PB : T0_SW2;
372
                                                        end
373
                                                        4'h9: begin
374
                                                                fsmState <= T0_SW2;
375
                                                        end
376
                                                        default: begin
377
                                                                case(dataOut)
378
                                                                        tpduHeader[INS_I+:8]: begin//ACK
379
                                                                                fsmState <= T0_DATA;
380
                                                                                {waitCardTx,waitTermTx}<=2'b11;
381
                                                                        end
382
                                                                        ~tpduHeader[INS_I+:8]: begin//NACK
383
                                                                                fsmState <= T0_NACK_DATA;
384
                                                                                {waitCardTx,waitTermTx}<=2'b11;
385
                                                                        end
386
                                                                        default: begin //invalid
387
                                                                                //TODO
388
                                                                        end
389
                                                                endcase
390
                                                        end
391
                                                endcase
392
                                        end
393
                                end
394
                                T0_NACK_DATA: begin
395
                                        if(endOfRx) begin
396
                                                fsmState <= T0_PB;
397
                                                {waitCardTx,waitTermTx}<=2'b10;
398
                                                tempBytesCnt <= tempBytesCnt+1;
399
                                        end
400
                                end
401
                                T0_SW1: begin
402
                                        if(endOfRx) begin
403
                                        //TODO:check != 60 but equal to 6x or 9x
404
                                                fsmState <= T0_SW2;
405
                                                {waitCardTx,waitTermTx}<=2'b10;
406
                                        end
407
                                end
408
                                T0_SW2: begin
409
                                        if(endOfRx) begin
410
                                                fsmState <= T0_HEADER;
411
                                                {waitCardTx,waitTermTx}<=2'b01;
412
                                        end
413
                                end
414
                                T0_DATA: begin
415
                                        if(endOfRx) begin
416
                                                if(tempBytesCnt==(tpduHeader[P3_I+:8]-1)) begin
417
                                                        tempBytesCnt <= 0;
418
                                                        fsmState <= T0_SW1;
419
                                                        {waitCardTx,waitTermTx}<=2'b10;
420
                                                end else begin
421
                                                        tempBytesCnt <= tempBytesCnt+1;
422
                                                end
423
                                        end
424
                                end
425
                        endcase
426 5 acapola
                end
427
        end
428
end
429
 
430
reg [1:0] txDir;
431 10 acapola
reg proto_cardTx;
432
reg proto_termTx;
433
always @(*) begin: protoComDirectionCombiBlock
434 6 acapola
        if(guardTime & ~isoSio)
435 10 acapola
                {proto_cardTx, proto_termTx}={txDir[0],txDir[1]};
436 5 acapola
        else
437 10 acapola
                {proto_cardTx, proto_termTx}={txDir[1],txDir[0]};
438 5 acapola
end
439 10 acapola
always @(posedge isoClk, negedge nReset) begin: protoComDirectionSeqBlock
440 5 acapola
        if(~nReset | ~run) begin
441
                txDir<=2'b00;
442
        end else begin
443 6 acapola
                if(~guardTime) begin //{waitCardTx, waitTermTx} is updated during stop bits so we hold current value here
444 5 acapola
                        case({waitCardTx, waitTermTx})
445 8 acapola
                                2'b00: txDir<=2'b00;//no one should/is sending
446
                                2'b01: txDir<=2'b01;//terminal should/is sending
447
                                2'b10: txDir<=2'b10;//card should/is sending
448
                                2'b11: txDir<=2'b11;//either card OR terminal should/is sending (we just don't know)
449 5 acapola
                        endcase
450
                end
451
        end
452
end
453 10 acapola
 
454
reg phy_cardTx;
455
reg phy_termTx;
456
always @(negedge isoSio, negedge nReset) begin: phyComDirectionBlock
457
        if(~nReset) begin
458
                phy_cardTx<=1'b0;
459
                phy_termTx<=1'b0;
460
        end else begin
461
                if(~isoSioTerm) begin
462
                        phy_cardTx<=1'b0;
463
                        phy_termTx<=1'b1;
464
                end else begin
465
                        phy_cardTx<=1'b1;
466
                        phy_termTx<=1'b0;
467
                end
468
        end
469
end
470
 
471
assign cardTx = useDirectionProbe ? phy_cardTx : proto_cardTx;
472
assign termTx = useDirectionProbe ? phy_termTx : proto_termTx;
473 5 acapola
 
474
endmodule
475 11 acapola
`default_nettype wire
476 5 acapola
 

powered by: WebSVN 2.1.0

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