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 2

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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