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 18

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

powered by: WebSVN 2.1.0

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