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 20

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-18 12:57:36 +0200 (Mon, 18 Apr 2011) $
6
$LastChangedBy: acapola $
7
$LastChangedRevision: 20 $
8
$HeadURL: file:///svn/iso7816_3_master/iso7816_3_master/trunk/test/iso7816_3_t0_analyzer.v $
9
 
10 20 acapola
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 11 acapola
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 20 acapola
                .PRECISE_STOP_BIT(1'b1))
136
        rxCore (
137
    .dataOut(rxData),
138
    .overrunErrorFlag(overrunError),
139
    .dataOutReadyFlag(bufferFull),
140
    .frameErrorFlag(frameError),
141 5 acapola
    .endOfRx(endOfRx),
142 20 acapola
    .run(rxRun),
143 5 acapola
    .startBit(rxStartBit),
144 20 acapola
         .stopBit(guardTime),
145
    .clkPerCycle(clkPerCycle),
146
    .clocksPerBit(safeClocksPerBit),
147
    .stopBit2(stopBit2),
148 5 acapola
    .oddParity(oddParity),
149 20 acapola
    .msbFirst(msbFirst),
150
         .ackFlags(ackFlags),
151
    .serialIn(isoSio),
152
    .comClk(isoClk),
153
    .clk(clk),
154
    .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 17 acapola
                                                        if((1'b0==tdiStruct[7]) |//we just received the last interface byte
258
                                                                (4'b0==dataOut[7:4])) begin //or new TDi indicate no further interface bytes
259 20 acapola
 
260 19 acapola
                                                                if(4'b0!=earlyAtrK) begin
261
                                                                        fsmState <= ATR_HISTORICAL;
262
                                                                end else if(atrHasTck) begin
263
                                                                        fsmState <= ATR_TCK;
264
                                                                end else begin
265
                                                                        fsmState <= T0_HEADER;
266
                                                                        atrCompleted <= 1'b1;
267
                                                                        {waitCardTx,waitTermTx}<=2'b01;
268
                                                                end
269 17 acapola
                                                        end else begin//TDi, i from 1 to 15
270
                                                                fsmState <= ATR_TDI;
271
                                                        end
272
 
273 6 acapola
                                                end else begin //TA, TB or TC bytes
274
                                                        //TODO: get relevant info
275 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
276 6 acapola
                                                end
277
                                        end
278
                                end
279
                                ATR_HISTORICAL: begin
280
                                        if(endOfRx) begin
281 17 acapola
                                                if(tempBytesCnt+1==atrK) begin
282 8 acapola
                                                        tempBytesCnt <= 8'h0;
283
                                                        if(atrHasTck) begin
284
                                                                fsmState <= ATR_TCK;
285
                                                        end else begin
286 13 acapola
                                                                atrCompleted <= 1'b1;
287 8 acapola
                                                                {waitCardTx,waitTermTx}<=2'b10;
288
                                                                fsmState <= T0_HEADER;
289
                                                        end
290 6 acapola
                                                end else begin
291 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
292 6 acapola
                                                end
293
                                        end
294
                                end
295
                                ATR_TCK: begin
296
                                        if(endOfRx) begin
297
                                        //TODO:check
298
                                                atrCompleted <= 1'b1;
299 8 acapola
                                                {waitCardTx,waitTermTx}<=2'b10;
300 6 acapola
                                                fsmState <= T0_HEADER;
301
                                        end
302
                                end
303
                        endcase
304 5 acapola
                end else if(useT0) begin
305
                        //T=0 cmd/response monitoring state machine
306 8 acapola
                        case(fsmState)
307
                                T0_HEADER: begin
308
                                        if(endOfRx) begin
309
                                                tpduHeader[CLA_I+:8]<=dataOut;
310
                                                tempBytesCnt <= 1;
311
                                                if(8'hFF==dataOut)
312 12 acapola
                                                        fsmState <= T0_HEADER_PPS;
313 8 acapola
                                                else
314
                                                        fsmState <= T0_HEADER_TPDU;
315
                                        end
316
                                end
317 12 acapola
                                T0_HEADER_PPS: begin
318
                                        if(endOfRx) begin
319
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
320
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
321
                                                        tempBytesCnt <= 8'h0;
322
                                                        fsmState <= T0_PPS_RESPONSE;
323
                                                        {waitCardTx,waitTermTx}<=2'b10;
324
                                                        ppsValidSoFar<=1'b1;
325 18 acapola
                                                        //ppsAccepted<=1'b0;
326 12 acapola
                                                end else begin
327 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
328 12 acapola
                                                end
329
                                        end
330
                                end
331
                                T0_PPS_RESPONSE: begin
332
                                        if(3==tempBytesCnt) begin//support only 4 byte PPS
333
                                                if(guardTime) begin
334
                                                        if(ppsValidSoFar & ppsDataMatch) begin
335
                                                                {fiCode,diCode}<=tpduHeader[PPS2_I+:8];
336
                                                        end
337
                                                end
338
                                        end
339
                                        if(endOfRx) begin
340
                                                ppsValidSoFar<=ppsValidSoFar & ppsDataMatch;
341
                                                if(3==tempBytesCnt) begin//support only 4 byte PPS
342
                                                        tempBytesCnt <= 8'h0;
343
                                                        fsmState <= T0_HEADER;
344
                                                        {waitCardTx,waitTermTx}<=2'b01;
345
                                                        case(tpduHeader[(PPS1_I-(tempBytesCnt*8))+:8])
346
                                                                8'h11: begin
347
                                                                        useT0<=1'b0;
348
                                                                        useT1<=1'b1;
349
                                                                        useT15<=1'b0;
350
                                                                end
351
                                                                8'h1F: begin
352
                                                                        useT0<=1'b0;
353
                                                                        useT1<=1'b0;
354
                                                                        useT15<=1'b1;
355
                                                                end
356
                                                                default: begin
357
                                                                        useT0<=1'b1;
358
                                                                        useT1<=1'b0;
359
                                                                        useT15<=1'b0;
360
                                                                end
361
                                                        endcase
362
                                                end else begin
363 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
364 12 acapola
                                                end
365
                                        end
366
                                end
367 8 acapola
                                T0_HEADER_TPDU: begin
368
                                        if(endOfRx) begin
369
                                                tpduHeader[(CLA_I-(tempBytesCnt*8))+:8]<=dataOut;
370
                                                if(4==tempBytesCnt) begin
371
                                                        tempBytesCnt <= 8'h0;
372
                                                        fsmState <= T0_PB;
373
                                                        {waitCardTx,waitTermTx}<=2'b10;
374
                                                end else begin
375 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
376 8 acapola
                                                end
377
                                        end
378
                                end
379
                                T0_PB: begin
380
                                        if(endOfRx) begin
381
                                                case(dataOut[7:4])
382
                                                        4'h6: begin
383
                                                                fsmState <= (4'h0==dataOut[3:0]) ? T0_PB : T0_SW2;
384
                                                        end
385
                                                        4'h9: begin
386
                                                                fsmState <= T0_SW2;
387
                                                        end
388
                                                        default: begin
389
                                                                case(dataOut)
390
                                                                        tpduHeader[INS_I+:8]: begin//ACK
391
                                                                                fsmState <= T0_DATA;
392
                                                                                {waitCardTx,waitTermTx}<=2'b11;
393
                                                                        end
394
                                                                        ~tpduHeader[INS_I+:8]: begin//NACK
395
                                                                                fsmState <= T0_NACK_DATA;
396
                                                                                {waitCardTx,waitTermTx}<=2'b11;
397
                                                                        end
398
                                                                        default: begin //invalid
399
                                                                                //TODO
400
                                                                        end
401
                                                                endcase
402
                                                        end
403
                                                endcase
404
                                        end
405
                                end
406
                                T0_NACK_DATA: begin
407
                                        if(endOfRx) begin
408
                                                fsmState <= T0_PB;
409
                                                {waitCardTx,waitTermTx}<=2'b10;
410 18 acapola
                                                tempBytesCnt <= tempBytesCnt+1'b1;
411 8 acapola
                                        end
412
                                end
413
                                T0_SW1: begin
414
                                        if(endOfRx) begin
415
                                        //TODO:check != 60 but equal to 6x or 9x
416
                                                fsmState <= T0_SW2;
417
                                                {waitCardTx,waitTermTx}<=2'b10;
418
                                        end
419
                                end
420
                                T0_SW2: begin
421
                                        if(endOfRx) begin
422
                                                fsmState <= T0_HEADER;
423
                                                {waitCardTx,waitTermTx}<=2'b01;
424
                                        end
425
                                end
426
                                T0_DATA: begin
427
                                        if(endOfRx) begin
428
                                                if(tempBytesCnt==(tpduHeader[P3_I+:8]-1)) begin
429
                                                        tempBytesCnt <= 0;
430
                                                        fsmState <= T0_SW1;
431
                                                        {waitCardTx,waitTermTx}<=2'b10;
432
                                                end else begin
433 18 acapola
                                                        tempBytesCnt <= tempBytesCnt+1'b1;
434 8 acapola
                                                end
435
                                        end
436
                                end
437
                        endcase
438 5 acapola
                end
439
        end
440
end
441
 
442
reg [1:0] txDir;
443 10 acapola
reg proto_cardTx;
444
reg proto_termTx;
445
always @(*) begin: protoComDirectionCombiBlock
446 6 acapola
        if(guardTime & ~isoSio)
447 10 acapola
                {proto_cardTx, proto_termTx}={txDir[0],txDir[1]};
448 5 acapola
        else
449 10 acapola
                {proto_cardTx, proto_termTx}={txDir[1],txDir[0]};
450 5 acapola
end
451 15 acapola
always @(posedge isoClk, negedge rxCore_nReset) begin: protoComDirectionSeqBlock
452
        if(~rxCore_nReset | ~run) begin
453 5 acapola
                txDir<=2'b00;
454
        end else begin
455 6 acapola
                if(~guardTime) begin //{waitCardTx, waitTermTx} is updated during stop bits so we hold current value here
456 5 acapola
                        case({waitCardTx, waitTermTx})
457 8 acapola
                                2'b00: txDir<=2'b00;//no one should/is sending
458
                                2'b01: txDir<=2'b01;//terminal should/is sending
459
                                2'b10: txDir<=2'b10;//card should/is sending
460
                                2'b11: txDir<=2'b11;//either card OR terminal should/is sending (we just don't know)
461 5 acapola
                        endcase
462
                end
463
        end
464
end
465 10 acapola
 
466
reg phy_cardTx;
467
reg phy_termTx;
468 15 acapola
always @(negedge isoSio, negedge rxCore_nReset) begin: phyComDirectionBlock
469
        if(~rxCore_nReset) begin
470 10 acapola
                phy_cardTx<=1'b0;
471
                phy_termTx<=1'b0;
472
        end else begin
473
                if(~isoSioTerm) begin
474
                        phy_cardTx<=1'b0;
475
                        phy_termTx<=1'b1;
476
                end else begin
477
                        phy_cardTx<=1'b1;
478
                        phy_termTx<=1'b0;
479
                end
480
        end
481
end
482
 
483
assign cardTx = useDirectionProbe ? phy_cardTx : proto_cardTx;
484
assign termTx = useDirectionProbe ? phy_termTx : proto_termTx;
485 5 acapola
 
486
endmodule
487 11 acapola
`default_nettype wire
488 5 acapola
 

powered by: WebSVN 2.1.0

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