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 12

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

powered by: WebSVN 2.1.0

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