OpenCores
URL https://opencores.org/ocsvn/10_100m_ethernet-fifo_convertor/10_100m_ethernet-fifo_convertor/trunk

Subversion Repositories 10_100m_ethernet-fifo_convertor

[/] [10_100m_ethernet-fifo_convertor/] [verilog/] [RxModule.v] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 antiquity
//author :Renliang Gu
2
//Email: gurenliang@gmail.com
3
//note: if there are some errors, please feel free to contact me. Thank you very much!
4
 
5
//Next step, reduce the resource consumed
6
 
7
//version 0.5, defined many parameter to configure the IP core, making it easier to use.
8
//vertion 0.4, add the function for TxModule to get start in a configurable ff_clk time after 
9
//                              RxModule receiving the first frame. To modify the delay time just to 
10
//                              change the value of the macro-variable delay_cnt_config.
11
//version 0.3, changed the changes made by version 0.2 back
12
//version 0.2, set empty when ff_data_buf_index's less significant bits is 3'b111 or 3'b000
13
 
14
`include "common.v"
15
 
16
`define IDXlen                  3               //2^IDXlen should be the number of cyclic queue
17
`define queue_len               (1<<3)  //define the length of the cyclic queue
18
 
19
`define rx_crc_offset   (`data_offset+(`uframelen*`num_uframe/4))       //index of first bit of crc
20
`define rx_total_len    (`rx_crc_offset + (4<<1))
21
`define rxdata_len              (`uframelen*`num_uframe/4)
22
 
23
`define delay_cnt_config        8       //the initiation value for the delay_cnt
24
 
25
module RxModule(phy_rxd, phy_rxen, phy_rxclk, phy_rxer,
26
                                ff_clk, ff_data, ff_en,
27
 
28
                                `ifdef frameIDfromRx
29
                                        frameid,
30
                                `endif
31
 
32
                                start,
33
                                test1, test2, test3, test4
34
                                );
35
        input phy_rxen, phy_rxclk, phy_rxer;    //MII interface
36
        input [3:0] phy_rxd;
37
 
38
        input ff_clk;                   //270.8333KHz
39
        output ff_data, ff_en;
40
 
41
        `ifdef frameIDfromRx
42
                output[`frameidlen-1:0] frameid;
43
                reg[`frameidlen-1:0] frameid;
44
        `endif
45
 
46
        output start;                   //to tell TxModule that buf in RxModule needs data
47
        output test1, test2, test3, test4;
48
        reg test1, test2;
49
 
50
        parameter delay_cnt_len =   (`delay_cnt_config <    2) ? 1 : (`delay_cnt_config <    4) ? 2 :
51
                                                                (`delay_cnt_config <    8) ? 3 : (`delay_cnt_config <   16) ? 4 :
52
                                                                (`delay_cnt_config <   32) ? 5 : (`delay_cnt_config <   64) ? 6 :
53
                                                                (`delay_cnt_config <  128) ? 7 : 8;
54
        parameter nibble_idx_len =      (`rx_total_len<=   2)?  1 : (`rx_total_len<=   4)?  2 :
55
                                                                (`rx_total_len<=   8)?  3 : (`rx_total_len<=  16)?  4 :
56
                                                                (`rx_total_len<=  32)?  5 : (`rx_total_len<=  64)?  6 :
57
                                                                (`rx_total_len<= 128)?  7 : (`rx_total_len<= 256)?  8 :
58
                                                                (`rx_total_len<= 512)?  9 : (`rx_total_len<=1024)? 10 :
59
                                                                (`rx_total_len<=2048)? 11 : 12;
60
        parameter ff_idx_len =  (`rxdata_len<=   2)? 1 : (`rxdata_len<=   4)? 2 :
61
                                                        (`rxdata_len<=   8)? 3 : (`rxdata_len<=  16)? 4 :
62
                                                        (`rxdata_len<=  32)? 5 : (`rxdata_len<=  64)? 6 :
63
                                                        (`rxdata_len<= 128)? 7 : (`rxdata_len<= 256)? 8 :
64
                                                        (`rxdata_len<= 512)? 9 : (`rxdata_len<=1024)?10 :
65
                                                        (`rxdata_len<=2048)?11 : 12;
66
        parameter frameid_idx_len = ((`frameidlen>>2)<=  2)? 1 : ((`frameidlen>>2)<=  4)? 2 :
67
                                                                ((`frameidlen>>2)<=  8)? 3 : ((`frameidlen>>2)<= 16)? 4 :
68
                                                                ((`frameidlen>>2)<= 32)? 5 : ((`frameidlen>>2)<= 64)? 6 :
69
                                                                ((`frameidlen>>2)<= 64)? 7 : 8;
70
        parameter ff_cnt_len  = (`uframelen <    2) ? 1 : (`uframelen <    4) ? 2 :
71
                                                        (`uframelen <    8) ? 3 : (`uframelen <   16) ? 4 :
72
                                                        (`uframelen <   32) ? 5 : (`uframelen <   64) ? 6 :
73
                                                        (`uframelen <  128) ? 7 : (`uframelen <  256) ? 8 :
74
                                                        (`uframelen <  512) ? 9 : (`uframelen < 1024) ? 10:
75
                                                        (`uframelen < 2048) ? 11: (`uframelen < 4096) ? 12:
76
                                                        (`uframelen < 8192) ? 13: 14;
77
 
78
        reg ff_data;
79
        reg ff_en;
80
 
81
        reg[ff_cnt_len-1:0] ff_cnt;
82
        reg[2:0] ff_d;
83
 
84
        reg start=1'b0;
85
        reg start_intra=1'b0;
86
        reg[delay_cnt_len-1:0] delay_cnt;
87
 
88
        reg[3:0] gap_cnt;
89
        reg[1:0] gap_len_ctl;
90
        reg[1:0] cycle;
91
 
92
        reg[3:0] rxdata_buf [0:(`rxdata_len*`queue_len+1)];       //more ram for special usage
93
        wire[ff_idx_len+`IDXlen-1:0] rxdata_buf_writer_address;
94
        reg[ff_idx_len+`IDXlen-1:0] rxdata_buf_reader_address;
95
 
96
        reg[`frameidlen-1:0] frameid_buf[0:(`queue_len-1)];
97
 
98
        reg[nibble_idx_len-1:0] nibble_idx;
99
        reg[ff_idx_len-1:0] ff_idx;
100
 
101
        reg[`IDXlen-1:0] rxIDX, ffIDX;
102
 
103
        reg bad_da;
104
        reg queue_empty;
105
 
106
        reg[2:0] rxState = 0;
107
        parameter s_preamble = 0, s_address = 1, s_typelen = 2,
108
                                s_frameid = 3, s_data = 4, s_crc = 5;
109
        reg[1:0] ff_state = 0;
110
        parameter ffs_idle = 0, ffs_transfer = 1, ffs_gap = 2;
111
 
112
        wire[47:0] mac_add;
113
        wire[3:0] da[0:11];
114
        assign mac_add = `MAC_ADD;
115
        assign da[ 0] = mac_add[ 3: 0];
116
        assign da[ 1] = mac_add[ 7: 4];
117
        assign da[ 2] = mac_add[11: 8];
118
        assign da[ 3] = mac_add[15:12];
119
        assign da[ 4] = mac_add[19:16];
120
        assign da[ 5] = mac_add[23:20];
121
        assign da[ 6] = mac_add[27:24];
122
        assign da[ 7] = mac_add[31:28];
123
        assign da[ 8] = mac_add[35:32];
124
        assign da[ 9] = mac_add[39:36];
125
        assign da[10] = mac_add[43:40];
126
        assign da[11] = mac_add[47:44];
127
 
128
        assign test4 = start_intra;
129
        assign test3 = start;
130
 
131
        always@(posedge phy_rxclk)begin                 //control the increasing of nibble_idx;
132
                if(phy_rxen & ~phy_rxer)                        //data is valid and no error
133
                        nibble_idx <= nibble_idx + 1;
134
                else
135
                        nibble_idx <= 0;
136
        end
137
 
138
        always@(posedge phy_rxclk)begin
139
                if(phy_rxen & ~phy_rxer)
140
                        case (rxState)
141
                                s_preamble:
142
                                        if(nibble_idx == `da_offset-1)          rxState <= s_address;
143
                                        else                                                            rxState <= s_preamble;
144
 
145
                                s_address:
146
                                        if(nibble_idx == `typelen_offset-1)     rxState <= s_typelen;
147
                                        else                                                            rxState <= s_address;
148
 
149
                                s_typelen:
150
                                        if(nibble_idx == `frameid_offset-1)     rxState <= s_frameid;
151
                                        else                                                            rxState <= s_typelen;
152
 
153
                                s_frameid:
154
                                        if(nibble_idx == `data_offset-1)        rxState <= s_data;
155
                                        else                                                            rxState <= s_frameid;
156
 
157
                                s_data:
158
                                        if(nibble_idx == `rx_crc_offset-1)              rxState <= s_crc;
159
                                        else                                                            rxState <= s_data;
160
 
161
                                s_crc:
162
                                        if(nibble_idx == `rx_total_len-1)               rxState <= s_preamble;
163
                                        else                                                            rxState <= s_crc;
164
 
165
                                default:                                                                rxState <= rxState;
166
                        endcase
167
                else
168
                        rxState <= s_preamble;
169
        end
170
 
171
        assign rxdata_buf_writer_address = rxIDX*`rxdata_len + nibble_idx - `data_offset;
172
 
173
        always@(posedge phy_rxclk)begin                 //receive data from Ethernet including the preamble, SFD and CRC
174
                if(phy_rxen & ~phy_rxer) begin          //data is valid and no error
175
                        case (rxState)
176
                                s_preamble: test1 <= ~test1;
177
                                s_address:
178
                                        if((phy_rxd!=da[nibble_idx-`da_offset])&(nibble_idx < `sa_offset))
179
                                                bad_da <= 1;
180
 
181
                                s_frameid: begin
182
                                        if(nibble_idx==`frameid_offset) begin
183
                                                rxIDX <= phy_rxd[2:0];
184
                                                frameid_buf[phy_rxd[2:0]][(`frameidlen-1):(`frameidlen-4)]  <= phy_rxd;
185
                                        end else
186
                                                frameid_buf[rxIDX] <= {phy_rxd, frameid_buf[rxIDX][(`frameidlen-1):4]};
187
                                end
188
 
189
                                s_data: begin
190
                                        //test2 <= ~test2;
191
                                        rxdata_buf[rxdata_buf_writer_address] <= phy_rxd;
192
                                end
193
                        endcase
194
                end     else if ((nibble_idx == `rx_total_len ) & (!bad_da)) begin
195
                //one frame has been transfered over, the destinate address is right and then been put into the buffer
196
                        start_intra <= 1;
197
                end     else
198
                        bad_da <= 0;
199
        end
200
 
201
        always@(negedge ff_clk) begin
202
                case(ff_state)
203
                        ffs_idle: begin                 //wait the first frame to come
204
                                gap_len_ctl <= 0;
205
                                if(start_intra) ff_state <= ffs_transfer;
206
                                else ff_state <= ffs_idle;
207
                        end
208
 
209
                        ffs_transfer: begin
210
                                if(ff_cnt == `uframelen-1)begin //every `uframelen bit need a gap
211
                                        ff_state <= ffs_gap;
212
                                        gap_len_ctl <= gap_len_ctl + 1;
213
                                end
214
                                else ff_state <= ffs_transfer;
215
                        end
216
                        ffs_gap: begin
217
                                if(((gap_len_ctl == 0)&(gap_cnt == 8)) | ((gap_len_ctl != 0)&(gap_cnt == 7)))
218
                                        ff_state <=ffs_transfer;
219
                                else ff_state <= ffs_gap;
220
                        end
221
                endcase
222
        end
223
 
224
        always@(negedge ff_clk) begin                           //flow the data out of the buffer
225
                case(ff_state)
226
                        ffs_idle: begin
227
                                ff_cnt <= 0;
228
                                delay_cnt <= 0;
229
                                cycle <= 0;
230
                                ff_en <= 0;
231
                                ff_idx <= 0;
232
                                ffIDX <= rxIDX + 1;
233
                                start <= 0;
234
                                rxdata_buf_reader_address <= ffIDX*`rxdata_len+ff_idx;
235
                        end
236
 
237
                        ffs_transfer: begin
238
                                `ifdef frameIDfromRx
239
                                        frameid <= frameid_buf[ffIDX];
240
                                `endif
241
                                if(delay_cnt == `delay_cnt_config) start <= 1;
242
                                delay_cnt <= delay_cnt + 1;
243
                                gap_cnt <= 0;
244
                                ff_cnt <= ff_cnt + 1;
245
                                cycle <= cycle + 1;
246
                                ff_en <= 1;
247
 
248
                                if(cycle==0) begin
249
                                        {ff_d[2:0],ff_data} <= rxdata_buf[rxdata_buf_reader_address];
250
                                        if(ff_idx == `rxdata_len-1)begin
251
                                                if(ffIDX!=rxIDX) begin
252
                                                        queue_empty <= 0;
253
                                                        if(queue_empty) begin
254
                                                                ffIDX <= rxIDX + ((`delay_cnt_config==0)? 1:2) ;
255
                                                                rxdata_buf_reader_address <= (rxIDX + ((`delay_cnt_config==0)? 1:2))*`rxdata_len;
256
                                                        end
257
                                                        else begin
258
                                                                ffIDX <= ffIDX + 1;
259
                                                                rxdata_buf_reader_address <= (ffIDX+1)*`rxdata_len;
260
                                                        end
261
                                                end else begin
262
                                                        rxdata_buf_reader_address <= ffIDX*`rxdata_len;
263
                                                        queue_empty <= 1;
264
                                                end
265
                                                ff_idx <= 0;
266
                                        end
267
                                        else begin
268
                                                ff_idx <= ff_idx + 1;
269
                                                rxdata_buf_reader_address <= ffIDX*`rxdata_len+ff_idx+1;
270
                                        end
271
                                end else
272
                                        {ff_d[1:0],ff_data} <= ff_d;
273
                        end
274
 
275
                        ffs_gap: begin          //the 8.25 bit gap is implement by (3*8+9)/4
276
                                ff_en <= 0;
277
                                ff_data <= 0;
278
                                ff_cnt <= 0;
279
                                gap_cnt <= gap_cnt + 1;
280
                        end
281
                endcase
282
        end
283
endmodule

powered by: WebSVN 2.1.0

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