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

Subversion Repositories srdydrdy_lib

[/] [srdydrdy_lib/] [trunk/] [examples/] [bridge/] [rtl/] [sd_rx_gigmac.v] - Blame information for rev 9

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

Line No. Rev Author Line
1 9 ghutchis
// mock-up of RX portion of gigabit ethernet MAC
2
// performs packet reception and creates internal
3
// packet codes, as well as checking CRC on incoming
4
// packets.
5
 
6
// incoming data is synchronous to "clk", which should
7
// be the GMII RX clock.  Output data is also synchronous
8
// to this clock, so needs to go through a sync FIFO.
9
 
10
// If output is not ready while receiving data,
11
// truncates the packet and makes it an error packet.
12
 
13
module sd_rx_gigmac
14
  (
15
   input        clk,
16
   input        reset,
17
   input        gmii_rx_dv,
18
   input [7:0]  gmii_rxd,
19
 
20
   output       rxg_srdy,
21
   input        rxg_drdy,
22
   output [1:0] rxg_code,
23
   output [7:0] rxg_data
24
   );
25
 
26
  reg           rxdv1, rxdv2;
27
  reg [7:0]      rxd1, rxd2;
28
  reg [31:0]     calc_crc, nxt_calc_crc;
29
  reg [31:0]     pkt_crc, nxt_pkt_crc;
30
  reg [3:0]      valid_bits, nxt_valid_bits;
31
 
32
  reg [5:0]      state, nxt_state;
33
  reg           ic_srdy;
34
  wire          ic_drdy;
35
  reg [1:0]      ic_code;
36
  reg [7:0]      ic_data;
37
 
38
  wire [31:0]    crc_comp_a, crc_comp_b;
39
 
40
  assign crc_comp_a = { pkt_crc[23:0], rxd2 };
41
  assign crc_comp_b = fixup_crc (calc_crc);
42
  localparam    CRC32_POLY = 32'h04C11DB7;
43
 
44
  function [31:0] add_crc32;
45
    input [7:0] add_byte;
46
    input [31:0] prev_crc;
47
    integer      b, msb;
48
    reg [31:0]    tmp_crc;
49
    begin
50
      tmp_crc = prev_crc;
51
      for (b = 0; b < 8; b = b + 1)
52
        begin
53
          msb = tmp_crc[31];
54
          tmp_crc = tmp_crc << 1;
55
          if (msb != add_byte[b])
56
            begin
57
              tmp_crc = tmp_crc ^ CRC32_POLY;
58
              tmp_crc[0] = 1;
59
            end
60
        end
61
      add_crc32 = tmp_crc;
62
    end
63
  endfunction // for
64
 
65
  function [31:0] fixup_crc;
66
    input [31:0] calc_crc;
67
    reg [31:0]    temp;
68
    integer      b;
69
    begin
70
      // Mirror:
71
      for (b = 0; b < 32; b = b + 1)
72
         temp[31-b] = calc_crc[b];
73
 
74
      // Swap and Complement:
75
      fixup_crc = ~{temp[7:0], temp[15:8], temp[23:16], temp[31:24]};
76
    end
77
  endfunction // for
78
 
79
 
80
/* -----\/----- EXCLUDED -----\/-----
81
  // Copied from: http://www.mindspring.com/~tcoonan/gencrc.v
82
  //
83
  // Generate a (DOCSIS) CRC32.
84
  //
85
  // Uses the GLOBAL variables:
86
  //
87
  //    Globals referenced:
88
  //       parameter    CRC32_POLY = 32'h04C11DB7;
89
  //       reg [ 7:0]   crc32_packet[0:255];
90
  //       integer      crc32_length;
91
  //
92
  //    Globals modified:
93
  //       reg [31:0]   crc32_result;
94
  //
95
task gencrc32;
96
   integer      byte, bit;
97
   reg          msb;
98
   reg [7:0]    current_byte;
99
   reg [31:0]   temp;
100
   begin
101
      crc32_result = 32'hffffffff;
102
      for (byte = 0; byte < crc32_length; byte = byte + 1) begin
103
         current_byte = crc32_packet[byte];
104
         for (bit = 0; bit < 8; bit = bit + 1) begin
105
            msb = crc32_result[31];
106
            crc32_result = crc32_result << 1;
107
            if (msb != current_byte[bit]) begin
108
               crc32_result = crc32_result ^ CRC32_POLY;
109
               crc32_result[0] = 1;
110
            end
111
         end
112
      end
113
 
114
      // Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit.
115
      //
116
      // Mirror:
117
      for (bit = 0; bit < 32; bit = bit + 1)
118
         temp[31-bit] = crc32_result[bit];
119
 
120
      // Swap and Complement:
121
      crc32_result = ~{temp[7:0], temp[15:8], temp[23:16], temp[31:24]};
122
   end
123
endtask
124
 -----/\----- EXCLUDED -----/\----- */
125
 
126
  always @(posedge clk)
127
    begin
128
      if (reset)
129
        begin
130
          rxd1  <= #1 0;
131
          rxdv1 <= #1 0;
132
          rxd2  <= #1 0;
133
          rxdv2 <= #1 0;
134
        end
135
      else
136
        begin
137
          rxd1  <= #1 gmii_rxd;
138
          rxdv1 <= #1 gmii_rx_dv;
139
          rxd2  <= #1 rxd1;
140
          rxdv2 <= #1 rxdv1;
141
        end
142
    end // always @ (posedge clk)
143
 
144
  localparam s_idle = 0, s_preamble = 1, s_sop = 2, s_payload = 3, s_trunc = 4, s_sink = 5;
145
  localparam ns_idle = 1, ns_preamble = 2, ns_sop = 4, ns_payload = 8, ns_trunc = 16, ns_sink = 32;
146
 
147
  always @*
148
    begin
149
      nxt_calc_crc = calc_crc;
150
      ic_srdy = 0;
151
      ic_code = `PCC_DATA;
152
      ic_data = 0;
153
      nxt_valid_bits = valid_bits;
154
 
155
      case (1'b1)
156
        state[s_idle] :
157
          begin
158
            nxt_calc_crc = {32{1'b1}};
159
            nxt_pkt_crc  = 0;
160
            nxt_valid_bits = 0;
161
            if (rxdv2 & (rxd2 == `GMII_SFD))
162
              begin
163
                nxt_state = ns_sop;
164
              end
165
            else if (rxdv2)
166
              begin
167
                nxt_state = ns_preamble;
168
              end
169
          end // case: state[s_idle]
170
 
171
        state[s_preamble]:
172
          begin
173
            if (!rxdv2)
174
              nxt_state = ns_idle;
175
            else if (rxd2 == `GMII_SFD)
176
              nxt_state = ns_sop;
177
          end
178
 
179
        state[s_sop] :
180
          begin
181
            if (!rxdv2)
182
              begin
183
                nxt_state = ns_idle;
184
              end
185
            else if (!ic_drdy)
186
              nxt_state = ns_sink;
187
            else
188
              begin
189
                ic_srdy = 1;
190
                ic_code = `PCC_SOP;
191
                ic_data = rxd2;
192
                nxt_state = ns_payload;
193
                nxt_pkt_crc = { 24'h0, gmii_rxd };
194
                nxt_valid_bits = 4'b0001;
195
                //nxt_calc_crc = add_crc32 (gmii_rxd, calc_crc);
196
              end
197
          end // case: state[ns_payload]
198
 
199
        state[s_payload] :
200
          begin
201
            if (!ic_drdy)
202
              nxt_state = ns_trunc;
203
            else if (!rxdv1)
204
              begin
205
                nxt_state = ns_idle;
206
                ic_srdy = 1;
207
                ic_data = rxd2;
208
                //if ( { pkt_crc[23:0], rxd2 } == add_crc32 (rxd2, calc_crc))
209
                `ifdef RX_CHECK_CRC
210
                if ({ pkt_crc[23:0], rxd2 } == fixup_crc (calc_crc))
211
                  ic_code = `PCC_EOP;
212
                else
213
                  ic_code = `PCC_BADEOP;
214
                `else
215
                ic_code = `PCC_EOP;
216
                `endif
217
              end
218
            else
219
              begin
220
                ic_srdy = 1;
221
                ic_code = `PCC_DATA;
222
                ic_data = rxd2;
223
                nxt_pkt_crc = { pkt_crc[23:0], rxd2 };
224
                nxt_valid_bits = { valid_bits[2:0], 1'b1 };
225
                if (valid_bits[2])
226
                  nxt_calc_crc = add_crc32 (pkt_crc[23:16], calc_crc);
227
              end // else: !if(!rxdv1)
228
          end // case: state[ns_payload]
229
 
230
        state[s_trunc] :
231
          begin
232
            ic_srdy = 1;
233
            ic_code = `PCC_BADEOP;
234
            ic_data = 0;
235
            if (ic_drdy)
236
              nxt_state = ns_sink;
237
          end
238
 
239
        state[s_sink] :
240
          begin
241
            if (!rxdv2)
242
              nxt_state = ns_idle;
243
          end
244
 
245
        default : nxt_state = ns_idle;
246
      endcase // case (1'b1)    
247
    end // always @ *
248
 
249
  always @(posedge clk)
250
    begin
251
      if (reset)
252
        begin
253
          state <= #1 1;
254
          /*AUTORESET*/
255
          // Beginning of autoreset for uninitialized flops
256
          calc_crc <= 32'h0;
257
          pkt_crc <= 32'h0;
258
          valid_bits <= 4'h0;
259
          // End of automatics
260
        end
261
      else
262
        begin
263
          calc_crc <= #1 nxt_calc_crc;
264
          pkt_crc  <= #1 nxt_pkt_crc;
265
          state    <= #1 nxt_state;
266
          valid_bits <= #1 nxt_valid_bits;
267
        end // else: !if(reset)
268
    end // always @ (posedge clk)
269
 
270
  sd_output #(8+2) out_hold
271
    (.clk (clk), .reset (reset),
272
     .ic_srdy (ic_srdy),
273
     .ic_drdy (ic_drdy),
274
     .ic_data ({ic_code,ic_data}),
275
     .p_srdy  (rxg_srdy),
276
     .p_drdy  (rxg_drdy),
277
     .p_data  ({rxg_code, rxg_data}));
278
 
279
endmodule // sd_rx_gigmac

powered by: WebSVN 2.1.0

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