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 15

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-13 16:20:10 +0100 (Sun, 13 Feb 2011) $
6
$LastChangedBy: acapola $
7
$LastChangedRevision: 15 $
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
assign overrunErrorFlag = overrunError;
102
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 13 acapola
                safeClocksPerBit<=clocksPerBit;
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
reg ppsAccepted;
225
wire ppsDataMatch = (tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]==dataOut);
226 15 acapola
always @(posedge isoClk, negedge rxCore_nReset) begin
227
        if(~rxCore_nReset) begin
228 12 acapola
                ppsValidSoFar<=1'b0;
229
                ppsAccepted<=1'b0;
230 5 acapola
                fiCode<=4'b0001;
231
                diCode<=4'b0001;
232 6 acapola
                useT0<=1'b1;
233 5 acapola
                useT1<=1'b0;
234
                useT15<=1'b0;
235 8 acapola
                {waitCardTx,waitTermTx}<=2'b00;
236 6 acapola
                fsmState<=ATR_TDI;
237
                atrHasTck<=1'b0;
238 7 acapola
                tempBytesCnt<=8'h0;
239 6 acapola
                tdiStruct<=12'h0;
240
                atrCompleted<=1'b0;
241 8 acapola
                atrK<=4'b0;
242 5 acapola
        end else if(isActivated) begin
243
                if(~tsReceived) begin
244 8 acapola
                        {waitCardTx,waitTermTx}<=2'b10;
245 5 acapola
                end else if(~atrCompleted) begin
246 6 acapola
                        //ATR analysis
247
                        case(fsmState)
248
                                ATR_TDI: begin
249
                                        if(endOfRx) begin
250 7 acapola
                                                if(tempBytesCnt==nIfBytes) begin //TDi bytes
251
                                                        tempBytesCnt <= 2'h0;
252 6 acapola
                                                        tdiStruct <= {tdiCnt+1,dataOut};
253
                                                        if(4'h0==tdiCnt) begin//this is T0
254
                                                                atrK <= dataOut[3:0];
255
                                                                fsmState <= (4'b0!=dataOut[7:4]) ? ATR_TDI :
256
                                                                                                (4'b0!=dataOut[3:0]) ? ATR_HISTORICAL : T0_HEADER;
257
                                                        end else begin//TDi, i from 1 to 15
258
                                                                fsmState <= (4'b0!=dataOut[7:4]) ? ATR_TDI :
259
                                                                                                (4'b0!=atrK) ? ATR_HISTORICAL : T0_HEADER;
260
                                                        end
261 8 acapola
                                                        if(12'h0=={dataOut,atrK}) begin
262
                                                                atrCompleted <= 1'b1;
263
                                                                {waitCardTx,waitTermTx}<=2'b01;
264
                                                        end
265 6 acapola
                                                end else begin //TA, TB or TC bytes
266
                                                        //TODO: get relevant info
267 13 acapola
                                                        //check if we just received the last interface byte
268
                                                        if((tempBytesCnt+1==nIfBytes) & (1'b0==tdiStruct[7])) begin
269
                                                                tempBytesCnt <= 2'h0;
270
                                                                fsmState <= (4'b0!=atrK) ? ATR_HISTORICAL : T0_HEADER;
271
                                                        end else begin
272
                                                                tempBytesCnt <= tempBytesCnt+1;
273
                                                        end
274 6 acapola
                                                end
275
                                        end
276
                                end
277
                                ATR_HISTORICAL: begin
278
                                        if(endOfRx) begin
279 13 acapola
                                                if(tempBytesCnt==(atrK-1)) begin
280 8 acapola
                                                        tempBytesCnt <= 8'h0;
281
                                                        if(atrHasTck) begin
282
                                                                fsmState <= ATR_TCK;
283
                                                        end else begin
284 13 acapola
                                                                atrCompleted <= 1'b1;
285 8 acapola
                                                                {waitCardTx,waitTermTx}<=2'b10;
286
                                                                fsmState <= T0_HEADER;
287
                                                        end
288 6 acapola
                                                end else begin
289 7 acapola
                                                        tempBytesCnt <= tempBytesCnt+1;
290 6 acapola
                                                end
291
                                        end
292
                                end
293
                                ATR_TCK: begin
294
                                        if(endOfRx) begin
295
                                        //TODO:check
296
                                                atrCompleted <= 1'b1;
297 8 acapola
                                                {waitCardTx,waitTermTx}<=2'b10;
298 6 acapola
                                                fsmState <= T0_HEADER;
299
                                        end
300
                                end
301
                        endcase
302 5 acapola
                end else if(useT0) begin
303
                        //T=0 cmd/response monitoring state machine
304 8 acapola
                        case(fsmState)
305
                                T0_HEADER: begin
306
                                        if(endOfRx) begin
307
                                                tpduHeader[CLA_I+:8]<=dataOut;
308
                                                tempBytesCnt <= 1;
309
                                                if(8'hFF==dataOut)
310 12 acapola
                                                        fsmState <= T0_HEADER_PPS;
311 8 acapola
                                                else
312
                                                        fsmState <= T0_HEADER_TPDU;
313
                                        end
314
                                end
315 12 acapola
                                T0_HEADER_PPS: begin
316
                                        if(endOfRx) begin
317
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
318
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
319
                                                        tempBytesCnt <= 8'h0;
320
                                                        fsmState <= T0_PPS_RESPONSE;
321
                                                        {waitCardTx,waitTermTx}<=2'b10;
322
                                                        ppsValidSoFar<=1'b1;
323
                                                        ppsAccepted<=1'b0;
324
                                                end else begin
325
                                                        tempBytesCnt <= tempBytesCnt+1;
326
                                                end
327
                                        end
328
                                end
329
                                T0_PPS_RESPONSE: begin
330
                                        if(3==tempBytesCnt) begin//support only 4 byte PPS
331
                                                if(guardTime) begin
332
                                                        if(ppsValidSoFar & ppsDataMatch) begin
333
                                                                {fiCode,diCode}<=tpduHeader[PPS2_I+:8];
334
                                                        end
335
                                                end
336
                                        end
337
                                        if(endOfRx) begin
338
                                                ppsValidSoFar<=ppsValidSoFar & ppsDataMatch;
339
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
340
                                                        tempBytesCnt <= 8'h0;
341
                                                        fsmState <= T0_HEADER;
342
                                                        {waitCardTx,waitTermTx}<=2'b01;
343
                                                        case(tpduHeader[(PPS1_I-(tempBytesCnt*8))+:8])
344
                                                                8'h11: begin
345
                                                                        useT0<=1'b0;
346
                                                                        useT1<=1'b1;
347
                                                                        useT15<=1'b0;
348
                                                                end
349
                                                                8'h1F: begin
350
                                                                        useT0<=1'b0;
351
                                                                        useT1<=1'b0;
352
                                                                        useT15<=1'b1;
353
                                                                end
354
                                                                default: begin
355
                                                                        useT0<=1'b1;
356
                                                                        useT1<=1'b0;
357
                                                                        useT15<=1'b0;
358
                                                                end
359
                                                        endcase
360
                                                end else begin
361
                                                        tempBytesCnt <= tempBytesCnt+1;
362
                                                end
363
                                        end
364
                                end
365 8 acapola
                                T0_HEADER_TPDU: begin
366
                                        if(endOfRx) begin
367
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
368
                                                if(4==tempBytesCnt) begin
369
                                                        tempBytesCnt <= 8'h0;
370
                                                        fsmState <= T0_PB;
371
                                                        {waitCardTx,waitTermTx}<=2'b10;
372
                                                end else begin
373
                                                        tempBytesCnt <= tempBytesCnt+1;
374
                                                end
375
                                        end
376
                                end
377
                                T0_PB: begin
378
                                        if(endOfRx) begin
379
                                                case(dataOut[7:4])
380
                                                        4'h6: begin
381
                                                                fsmState <= (4'h0==dataOut[3:0]) ? T0_PB : T0_SW2;
382
                                                        end
383
                                                        4'h9: begin
384
                                                                fsmState <= T0_SW2;
385
                                                        end
386
                                                        default: begin
387
                                                                case(dataOut)
388
                                                                        tpduHeader[INS_I+:8]: begin//ACK
389
                                                                                fsmState <= T0_DATA;
390
                                                                                {waitCardTx,waitTermTx}<=2'b11;
391
                                                                        end
392
                                                                        ~tpduHeader[INS_I+:8]: begin//NACK
393
                                                                                fsmState <= T0_NACK_DATA;
394
                                                                                {waitCardTx,waitTermTx}<=2'b11;
395
                                                                        end
396
                                                                        default: begin //invalid
397
                                                                                //TODO
398
                                                                        end
399
                                                                endcase
400
                                                        end
401
                                                endcase
402
                                        end
403
                                end
404
                                T0_NACK_DATA: begin
405
                                        if(endOfRx) begin
406
                                                fsmState <= T0_PB;
407
                                                {waitCardTx,waitTermTx}<=2'b10;
408
                                                tempBytesCnt <= tempBytesCnt+1;
409
                                        end
410
                                end
411
                                T0_SW1: begin
412
                                        if(endOfRx) begin
413
                                        //TODO:check != 60 but equal to 6x or 9x
414
                                                fsmState <= T0_SW2;
415
                                                {waitCardTx,waitTermTx}<=2'b10;
416
                                        end
417
                                end
418
                                T0_SW2: begin
419
                                        if(endOfRx) begin
420
                                                fsmState <= T0_HEADER;
421
                                                {waitCardTx,waitTermTx}<=2'b01;
422
                                        end
423
                                end
424
                                T0_DATA: begin
425
                                        if(endOfRx) begin
426
                                                if(tempBytesCnt==(tpduHeader[P3_I+:8]-1)) begin
427
                                                        tempBytesCnt <= 0;
428
                                                        fsmState <= T0_SW1;
429
                                                        {waitCardTx,waitTermTx}<=2'b10;
430
                                                end else begin
431
                                                        tempBytesCnt <= tempBytesCnt+1;
432
                                                end
433
                                        end
434
                                end
435
                        endcase
436 5 acapola
                end
437
        end
438
end
439
 
440
reg [1:0] txDir;
441 10 acapola
reg proto_cardTx;
442
reg proto_termTx;
443
always @(*) begin: protoComDirectionCombiBlock
444 6 acapola
        if(guardTime & ~isoSio)
445 10 acapola
                {proto_cardTx, proto_termTx}={txDir[0],txDir[1]};
446 5 acapola
        else
447 10 acapola
                {proto_cardTx, proto_termTx}={txDir[1],txDir[0]};
448 5 acapola
end
449 15 acapola
always @(posedge isoClk, negedge rxCore_nReset) begin: protoComDirectionSeqBlock
450
        if(~rxCore_nReset | ~run) begin
451 5 acapola
                txDir<=2'b00;
452
        end else begin
453 6 acapola
                if(~guardTime) begin //{waitCardTx, waitTermTx} is updated during stop bits so we hold current value here
454 5 acapola
                        case({waitCardTx, waitTermTx})
455 8 acapola
                                2'b00: txDir<=2'b00;//no one should/is sending
456
                                2'b01: txDir<=2'b01;//terminal should/is sending
457
                                2'b10: txDir<=2'b10;//card should/is sending
458
                                2'b11: txDir<=2'b11;//either card OR terminal should/is sending (we just don't know)
459 5 acapola
                        endcase
460
                end
461
        end
462
end
463 10 acapola
 
464
reg phy_cardTx;
465
reg phy_termTx;
466 15 acapola
always @(negedge isoSio, negedge rxCore_nReset) begin: phyComDirectionBlock
467
        if(~rxCore_nReset) begin
468 10 acapola
                phy_cardTx<=1'b0;
469
                phy_termTx<=1'b0;
470
        end else begin
471
                if(~isoSioTerm) begin
472
                        phy_cardTx<=1'b0;
473
                        phy_termTx<=1'b1;
474
                end else begin
475
                        phy_cardTx<=1'b1;
476
                        phy_termTx<=1'b0;
477
                end
478
        end
479
end
480
 
481
assign cardTx = useDirectionProbe ? phy_cardTx : proto_cardTx;
482
assign termTx = useDirectionProbe ? phy_termTx : proto_termTx;
483 5 acapola
 
484
endmodule
485 11 acapola
`default_nettype wire
486 5 acapola
 

powered by: WebSVN 2.1.0

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