OpenCores
URL https://opencores.org/ocsvn/iso7816_3_master/iso7816_3_master/trunk

Subversion Repositories iso7816_3_master

[/] [iso7816_3_master/] [trunk/] [sources/] [RxCoreSpec.v] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 acapola
/*
2
Author: Sebastien Riou (acapola)
3
Creation date: 23:57:02 09/04/2010
4
 
5
$LastChangedDate: 2011-01-29 13:16:17 +0100 (Sat, 29 Jan 2011) $
6
$LastChangedBy: acapola $
7
$LastChangedRevision: 11 $
8
$HeadURL: file:///svn/iso7816_3_master/iso7816_3_master/trunk/sources/RxCoreSpec.v $
9
 
10
This file is under the BSD licence:
11
Copyright (c) 2011, Sebastien Riou
12 2 acapola
 
13 11 acapola
All rights reserved.
14 2 acapola
 
15 11 acapola
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
`default_nettype none
33
 
34
/*
35
non synthetizable model used as reference in test bench
36 2 acapola
*/
37
 
38
module RxCoreSpec(
39
    output reg [7:0] dataOut,
40
    output reg overrunErrorFlag,        //new data has been received before dataOut was read
41
    output reg dataOutReadyFlag,        //new data available
42
    output reg frameErrorFlag,          //bad parity or bad stop bits
43
    output reg endOfRx,
44
    output reg run,                                     //rx is definitely started, one of the three flag will be set
45
    output reg startBit,                                //rx is started, but we don't know yet if real rx or just a glitch
46
         input [CLOCK_PER_BIT_WIDTH-1:0] clocksPerBit,
47
         input stopBit2,//0: 1 stop bit, 1: 2 stop bits
48
         input ackFlags,
49
         input serialIn,
50
    input clk,
51
    input nReset
52
    );
53
parameter CLK_PERIOD = 10;//should be %2
54
//parameters to override
55
parameter CLOCK_PER_BIT_WIDTH = 13;     //allow to support default speed of ISO7816
56
//invert the polarity of the output or not
57
parameter IN_POLARITY = 1'b0;
58
parameter PARITY_POLARITY = 1'b0;
59
//default conventions
60
parameter START_BIT = 1'b0;
61
parameter STOP_BIT1 = 1'b1;
62
parameter STOP_BIT2 = 1'b1;
63
 
64
//constant definition for states
65
localparam IDLE_BIT = ~START_BIT;
66
 
67
integer bitCounter;
68
 
69
reg parityBit;
70
reg rxStarted;
71
 
72
wire internalIn;
73
wire parityError;
74
 
75
assign internalIn = serialIn ^ IN_POLARITY;
76
assign parityError= parityBit ^ internalIn ^ PARITY_POLARITY ^ 1'b1;
77
reg syncClk;
78
 
79
/*logic to avoid race condition on flags
80
if internal logic set the flag and at the same time
81
the signal ackFlags is set (that normally clears the flags), the flag should be set
82
*/
83
reg setOverrunErrorFlag;
84
reg nResetOverrunErrorFlag;
85
always @(negedge clk) begin
86
        setOverrunErrorFlag<=1'b0;
87
end
88
 
89
//flag set has priority over flag nReset
90
always @(setOverrunErrorFlag,nResetOverrunErrorFlag) begin
91
        if((setOverrunErrorFlag===1'b1) || (setOverrunErrorFlag===1'bx)) begin
92
                overrunErrorFlag<=setOverrunErrorFlag;
93
                if(nResetOverrunErrorFlag)
94
                        nResetOverrunErrorFlag=0;
95
        end else begin
96
                if(nResetOverrunErrorFlag) begin
97
                        overrunErrorFlag<=0;
98
                        nResetOverrunErrorFlag=0;
99
                end
100
        end
101
end
102
 
103
reg setDataOutReadyFlag;
104
reg nResetDataOutReadyFlag;
105
always @(negedge clk) begin
106
        setDataOutReadyFlag<=1'b0;
107
end
108
 
109
//flag set has priority over flag nReset
110
always @(setDataOutReadyFlag,nResetDataOutReadyFlag) begin
111
        if((setDataOutReadyFlag===1'b1) || (setDataOutReadyFlag===1'bx)) begin
112
                dataOutReadyFlag<=setDataOutReadyFlag;
113
                if(nResetDataOutReadyFlag)
114
                        nResetDataOutReadyFlag=0;
115
        end else begin
116
                if(nResetDataOutReadyFlag) begin
117
                        dataOutReadyFlag<=0;
118
                        nResetDataOutReadyFlag=0;
119
                end
120
        end
121
end
122
 
123
reg setFrameErrorFlag;
124
reg nResetFrameErrorFlag;
125
always @(negedge clk) begin
126
        setFrameErrorFlag<=1'b0;
127
end
128
 
129
//flag set has priority over flag nReset
130
always @(setFrameErrorFlag,nResetFrameErrorFlag) begin
131
        if((setFrameErrorFlag===1'b1) || (setFrameErrorFlag===1'bx)) begin
132
                frameErrorFlag<=setFrameErrorFlag;
133
                if(nResetFrameErrorFlag)
134
                        nResetFrameErrorFlag=0;
135
        end else begin
136
                if(nResetFrameErrorFlag) begin
137
                        frameErrorFlag<=0;
138
                        nResetFrameErrorFlag=0;
139
                end
140
        end
141
end
142
 
143
reg dataOutReadyFlagAckDone;
144
reg frameErrorFlagAckDone;
145
 
146
always @(posedge clk) begin:ACK_FLAGS
147
        if(ackFlags) begin
148
                if(0==rxStarted)
149
                        nResetOverrunErrorFlag<=1;//otherwise, done in OVERRUN_BIT block
150
                if(dataOutReadyFlag!==1'bx)
151
                        nResetDataOutReadyFlag<=1'b1;
152
                dataOutReadyFlagAckDone<=1'b1;
153
                if(frameErrorFlag!==1'bx)
154
                        nResetFrameErrorFlag<=1'b1;
155
                frameErrorFlagAckDone<=1'b1;
156
        end
157
end
158
 
159
reg internalStart;
160
integer clockCounter;
161
always@(posedge internalStart) begin:CLOCK_COUNTER
162
        for(clockCounter=0;clockCounter<(11+stopBit2)*(clocksPerBit+1);clockCounter=clockCounter+1) begin
163
                syncClk=0;
164
                #(CLK_PERIOD/2);
165
                syncClk=1;
166
                #(CLK_PERIOD/2);
167
        end
168
end
169
 
170
reg abortStart;
171
always@(posedge abortStart) begin:ABORT_START
172
        abortStart<=0;
173
        startBit<=1'bx;
174
        #(CLK_PERIOD*(clocksPerBit+1)/4);
175
        if(internalIn)
176
                startBit<=0;
177
end
178
//Start bit spec
179
always@(negedge internalIn) begin:START_BIT_BLK
180
        if(frameErrorFlag | overrunErrorFlag) begin
181
                //nothing to do, wait clear from outside 
182
        end else begin
183
                internalStart<=1;
184
                startBit<=1'bx;
185
                #(CLK_PERIOD*(clocksPerBit+1)/4);
186
                internalStart<=0;
187
                startBit<=1;
188
                #(CLK_PERIOD*(clocksPerBit+1)/4);
189
                if(internalIn==0) begin
190
                        startBit<=1'bx;
191
                        #(CLK_PERIOD*(clocksPerBit+1)/4);
192
                        startBit<=0;
193
                        #(CLK_PERIOD*(clocksPerBit+1)/4);
194
                        #(CLK_PERIOD*(10+stopBit2)*(clocksPerBit+1));//ignore falling edge until end of the byte
195
                end else begin
196
                        abortStart<=1;
197
                end
198
        end
199
end
200
 
201
wire [31:0] stopStart=10*(clocksPerBit+1);
202
wire [31:0] stopEnd=((10+stopBit2)*(clocksPerBit+1)+((clocksPerBit+1)*3)/4);
203
wire isInStop=(clockCounter>=stopStart) && (clockCounter<stopEnd);
204
reg runBitSet;
205
//Run bit spec
206
always@(negedge internalIn) begin:RUN_BIT_SET
207
        if(frameErrorFlag | overrunErrorFlag) begin
208
                //nothing to do, wait clear from outside 
209
        end else if(~isInStop) begin
210
                runBitSet<=1'b0;
211
                #(CLK_PERIOD*(clocksPerBit+1)/2);
212
                if(internalIn == 0) begin
213
                        fork
214
                                begin
215
                                        runBitSet<=1'b1;
216
                                        run<=1'bx;
217
                                        #(CLK_PERIOD*(clocksPerBit+1)/4);
218
                                        run<=1;
219
                                end
220
                                begin
221
                                        #(CLK_PERIOD*(clocksPerBit+1)/2);
222
                                        #(CLK_PERIOD*(9+stopBit2)*(clocksPerBit+1));
223
                                end
224
                        join
225
                end
226
        end
227
end
228
 
229
always@(posedge runBitSet) begin:RUN_BIT_CLEAR
230
        #(CLK_PERIOD*(clocksPerBit+1)/2);
231
        #(CLK_PERIOD*(((10+stopBit2)*(clocksPerBit+1))-2));
232
   if(runBitSet)
233
      endOfRx<=1'bx;
234
        #(CLK_PERIOD);
235
        if(runBitSet) begin//might be cleared by nReset
236
                run<=1'bx;
237
                #(CLK_PERIOD*(clocksPerBit+1)/4);
238
      endOfRx<=1'b0;
239
      run<=0;
240
        end
241
end
242
 
243
//overrun  bit spec
244
reg internalOv;
245
wire [31:0] minOvCount=(clocksPerBit+1);//WARNING: DATA_OUT block rely on this
246
wire [31:0] maxOvCount=((clocksPerBit+1)/2)+(clocksPerBit+1)+(clocksPerBit+1)/4;
247
always@(posedge syncClk) begin:OVERRUN_BIT
248
        if(clockCounter<maxOvCount) begin//internal requests to set the flag have priority over clear by ackFlags
249
                if(clockCounter==minOvCount)
250
                        if(dataOutReadyFlag)
251
                                setOverrunErrorFlag <= 1'bx;
252
        end else if(clockCounter==maxOvCount) begin
253
                if(1'bx===overrunErrorFlag)
254
                        setOverrunErrorFlag <= 1;
255
        end else
256
                if(ackFlags)
257
                        nResetOverrunErrorFlag <= 1;
258
end
259
 
260
reg [7:0] dataStorage;
261
reg waitStartBit;
262
//dataOut spec
263
//frameErrorFlag spec (1/2)
264
always@(negedge internalIn) begin:DATA_OUT
265
        if(frameErrorFlag | overrunErrorFlag) begin
266
                //nothing to do, wait clear from outside 
267
        end else begin
268
                waitStartBit<=1'b0;
269
                #(CLK_PERIOD*(clocksPerBit+1)/2);
270
                if(internalIn==0) begin
271
                        #(CLK_PERIOD*(minOvCount-((clocksPerBit+1)/2)));
272
                        fork
273
                                if(0==dataOutReadyFlag) begin
274
                                        dataOut<=8'bx;
275
                                        #(CLK_PERIOD*(clocksPerBit+1)/2);
276
                                        #(CLK_PERIOD*8*(clocksPerBit+1));//wait 8 bits + parity
277
                                        parityBit <= ^dataStorage;
278
                                        if(0==(^dataStorage) ^ internalIn ^ PARITY_POLARITY ^ 1'b1) begin
279
                                                setDataOutReadyFlag<=1'bx;
280
                                                dataOutReadyFlagAckDone<=1'b0;
281
                                                #(CLK_PERIOD*2);//#(CLK_PERIOD*(clocksPerBit+1)/4);//allow 1/4 bit time latency
282
                                                dataOut<=dataStorage;
283
                                                if(~dataOutReadyFlagAckDone)
284
                                                        setDataOutReadyFlag<=1'b1;
285
                                                else
286
                                                        nResetDataOutReadyFlag<=1'b1;
287
                                        end else begin
288
                                                setFrameErrorFlag <= 1'bx;
289
                                                frameErrorFlagAckDone<=1'b0;
290
                                                #(CLK_PERIOD*2);//#(CLK_PERIOD*(clocksPerBit+1)/4);//allow 1/4 bit time latency
291
                                                if(~frameErrorFlagAckDone)
292
                                                        setFrameErrorFlag<=1'b1;
293
                                                else
294
                                                        nResetFrameErrorFlag<=1'b1;
295
                                        end
296
                                end
297
                                begin
298
                                        #(CLK_PERIOD*(clocksPerBit+1)/4);//we can detect start bit a 1/4 of bit time before the actual end of the transfer
299
                                        #(CLK_PERIOD*(9+stopBit2)*(clocksPerBit+1));
300
                                        #(CLK_PERIOD*(clocksPerBit+1)/2);
301
                                end
302
                        join
303
                end
304
                waitStartBit<=1'b1;
305
        end
306
end
307
 
308
//frameErrorFlag spec (2/2)
309
always@(negedge internalIn) begin:FRAME_ERROR
310
        if(frameErrorFlag | overrunErrorFlag) begin
311
                //nothing to do, wait clear from outside 
312
        end else begin
313
                if(isInStop) begin
314
                        setFrameErrorFlag <= 1'bx;
315
                        frameErrorFlagAckDone<=1'b0;
316
                        #(CLK_PERIOD*(clocksPerBit+1)/1);//allow 1 bit time latency
317
                        if(~frameErrorFlagAckDone)
318
                                setFrameErrorFlag<=1'b1;
319
                        else
320
                                nResetFrameErrorFlag<=1'b1;
321
                end
322
        end
323
end
324
 
325
initial begin
326
        internalStart=0;
327
        clockCounter=0;
328
        abortStart=0;
329
        internalOv=0;
330
end
331
 
332
always @(negedge internalIn, negedge nReset) begin:MAIN
333
        if(~nReset) begin
334
                bitCounter <= 0;
335
                parityBit <= 0;
336
                nResetOverrunErrorFlag <= 1'b1;
337
                setOverrunErrorFlag <= 1'b0;
338
                nResetDataOutReadyFlag <= 1'b1;
339
                setDataOutReadyFlag <= 1'b0;
340
                nResetFrameErrorFlag <= 1'b1;
341
                setFrameErrorFlag<=1'b0;
342
      endOfRx<=1'b0;
343
                run <= 0;
344
                startBit <= 0;
345
                runBitSet<=0;
346
        end else if(frameErrorFlag | overrunErrorFlag) begin
347
                //nothing to do, wait clear from outside
348
        end else begin
349
                rxStarted<=1'b1;
350
                #(CLK_PERIOD*(clocksPerBit+1)/2);
351
                if(internalIn == 0) begin
352
                        @(posedge clk);
353
                        for(bitCounter=0;bitCounter<8;bitCounter=bitCounter+1) begin
354
                                #(CLK_PERIOD*(clocksPerBit+1)/1);
355
                                if(~dataOutReadyFlag) begin
356
                                        dataStorage[bitCounter]<=internalIn;
357
                                end
358
                        end
359
                        #(CLK_PERIOD*(clocksPerBit+1)/1);
360
                        #(CLK_PERIOD*(clocksPerBit+1)/1);
361
                        if(stopBit2) begin
362
                                #(CLK_PERIOD*(clocksPerBit+1)/1);
363
                        end
364
                        rxStarted <= 1'b0;
365
                end
366
        end
367
end
368
 
369
endmodule
370 11 acapola
`default_nettype wire

powered by: WebSVN 2.1.0

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