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

Subversion Repositories loadbalancer

[/] [loadbalancer/] [trunk/] [output_port_lookup.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 atalla
///////////////////////////////////////////////////////////////////////////////
2
// vim:set shiftwidth=3 softtabstop=3 expandtab:
3
// $Id: output_port_lookup.v 2201 2007-08-21 06:52:51Z jnaous $
4
//
5
// Module: switch_output_port.v
6
// Project: NF2.1
7
// Description: reads incoming packets parses them and decides on the output port
8
//  and adds it as a header. The design of this module assumes that only one eop
9
//  will be in the pipeline of this module at any given time.
10
//  i.e. we assume pkt length incl pkt and module headers >= 8*DATA_WIDTH bits
11
//  for a 64 bit datapath, this is 64 bytes.
12
//
13
///////////////////////////////////////////////////////////////////////////////
14
`timescale 1ns/1ps
15
  module output_port_lookup
16
    #(parameter DATA_WIDTH = 64,
17
      parameter CTRL_WIDTH=DATA_WIDTH/8,
18
      parameter UDP_REG_SRC_WIDTH = 2,
19
      parameter INPUT_ARBITER_STAGE_NUM = 2,
20
      parameter NUM_OUTPUT_QUEUES = 8,
21
      parameter STAGE_NUM = 4,
22
      parameter NUM_IQ_BITS = 3)
23
 
24
   (// --- data path interface
25
    output reg [DATA_WIDTH-1:0]        out_data,
26
    output reg [CTRL_WIDTH-1:0]        out_ctrl,
27
    output reg                         out_wr,
28
    input                              out_rdy,
29
 
30
    input  [DATA_WIDTH-1:0]            in_data,
31
    input  [CTRL_WIDTH-1:0]            in_ctrl,
32
    input                              in_wr,
33
    output                             in_rdy,
34
 
35
 
36
        input                              en,
37
    // --- Misc
38
    input                              clk,
39
    input                              reset);
40
 
41
   function integer log2;
42
      input integer number;
43
      begin
44
         log2=0;
45
         while(2**log2<number) begin
46
            log2=log2+1;
47
         end
48
      end
49
   endfunction // log2
50
 
51
   //--------------------- Internal Parameter-------------------------
52
   parameter LUT_DEPTH_BITS = 4;
53
   parameter DEFAULT_MISS_OUTPUT_PORTS = 8'b01010101; // exclude the CPU queues
54
 
55
   parameter NUM_STATES = 4;
56
   parameter WAIT_TILL_DONE_DECODE = 1;
57
   parameter WRITE_HDR             = 2;
58
   parameter SKIP_HDRS             = 4;
59
   parameter WAIT_EOP              = 8;
60
 
61
   //---------------------- Wires and regs----------------------------
62
 
63
   wire                         lookup_ack;
64
   wire [47:0]                  dst_mac;
65
   wire [47:0]                  src_mac;
66
   wire [15:0]                  ethertype;
67
   wire [NUM_IQ_BITS-1:0]       src_port;
68
   wire                         eth_done;
69
   wire [NUM_OUTPUT_QUEUES-1:0] dst_ports;
70
   wire [NUM_OUTPUT_QUEUES-1:0] dst_ports_latched;
71
 
72
   wire [LUT_DEPTH_BITS-1:0]    rd_addr;          // address in table to read
73
   wire                         rd_req;           // request a read
74
   wire [NUM_OUTPUT_QUEUES-1:0] rd_oq;            // data read from the LUT at rd_addr
75
   wire                         rd_wr_protect;    // wr_protect bit read
76
   wire [47:0]                  rd_mac;           // data to match in the CAM
77
   wire                         rd_ack;           // pulses high when data is rdy
78
 
79
   wire [LUT_DEPTH_BITS-1:0]    wr_addr;
80
   wire                         wr_req;
81
   wire [NUM_OUTPUT_QUEUES-1:0] wr_oq;
82
   wire                         wr_protect;       // wr_protect bit to write
83
   wire [47:0]                  wr_mac;           // data to match in the CAM
84
   wire                         wr_ack;           // pulses high when wr is done
85
 
86
   wire                         lut_hit;          // pulses high on a hit
87
   wire                         lut_miss;         // pulses high on a miss
88
 
89
   reg                          in_fifo_rd_en;
90
   wire [CTRL_WIDTH-1:0]        in_fifo_ctrl_dout;
91
   wire [DATA_WIDTH-1:0]        in_fifo_data_dout;
92
   wire                         in_fifo_nearly_full;
93
   wire                         in_fifo_empty;
94
 
95
   reg                          dst_port_rd;
96
   wire                         dst_port_fifo_nearly_full;
97
   wire                         dst_port_fifo_empty;
98
 
99
   reg [NUM_STATES-1:0]         state, state_next;
100
 
101
   //------------------------- Modules-------------------------------
102
   ethernet_parser
103
     #(.DATA_WIDTH (DATA_WIDTH),
104
       .CTRL_WIDTH (CTRL_WIDTH),
105
       .NUM_IQ_BITS(NUM_IQ_BITS),
106
       .INPUT_ARBITER_STAGE_NUM(INPUT_ARBITER_STAGE_NUM))
107
     eth_parser
108
         (.in_data(in_data),
109
          .in_ctrl(in_ctrl),
110
          .in_wr(in_wr),
111
          .eth_done (eth_done),
112
          .src_port(src_port),
113
          .reset(reset),
114
          .clk(clk));
115
 
116
 
117
   /* The size of this fifo has to be large enough to fit the previous modules' headers
118
    * and the ethernet header */
119
   small_fifo #(.WIDTH(DATA_WIDTH+CTRL_WIDTH), .MAX_DEPTH_BITS(4), .NEARLY_FULL(15))
120
      input_fifo
121
        (.din ({in_ctrl,in_data}),     // Data in
122
         .wr_en (in_wr),               // Write enable
123
         .rd_en (in_fifo_rd_en),       // Read the next word 
124
         .dout ({in_fifo_ctrl_dout, in_fifo_data_dout}),
125
         .full (),
126
         .nearly_full (in_fifo_nearly_full),
127
         .empty (in_fifo_empty),
128
         .reset (reset),
129
         .clk (clk)
130
         );
131
 
132
   small_fifo #(.WIDTH(NUM_OUTPUT_QUEUES), .MAX_DEPTH_BITS(2), .NEARLY_FULL(3))
133
      dst_port_fifo
134
        (.din (dst_ports),     // Data in
135
         .wr_en (lut_hit|lut_miss),             // Write enable
136
         .rd_en (dst_port_rd),       // Read the next word 
137
         .dout (dst_ports_latched),
138
         .full (),
139
         .nearly_full (dst_port_fifo_nearly_full),
140
         .empty (dst_port_fifo_empty),
141
         .reset (reset),
142
         .clk (clk)
143
         );
144
 
145
 
146
 
147
 
148
   //----------------------- Logic -----------------------------
149
 
150
   assign    in_rdy = !in_fifo_nearly_full && !dst_port_fifo_nearly_full;
151
 
152
   /*********************************************************************
153
    * Wait until the ethernet header has been decoded and the output
154
    * port is found, then write the module header and move the packet
155
    * to the output
156
    **********************************************************************/
157
   always @(*) begin
158
      out_ctrl = in_fifo_ctrl_dout;
159
      out_data = in_fifo_data_dout;
160
      state_next = state;
161
      out_wr = 0;
162
      in_fifo_rd_en = 0;
163
      dst_port_rd = 0;
164
 
165
      case(state)
166
        WAIT_TILL_DONE_DECODE: begin
167
           if(!dst_port_fifo_empty) begin
168
              dst_port_rd     = 1;
169
              state_next      = WRITE_HDR;
170
              in_fifo_rd_en   = 1;
171
           end
172
        end
173
 
174
        /* write Destionation output ports */
175
        WRITE_HDR: begin
176
           if(out_rdy) begin
177
              if(in_fifo_ctrl_dout==2'hFF) begin
178
                 out_data[31:16] = dst_ports_latched;
179
              end
180
              out_wr          = 1;
181
              in_fifo_rd_en   = 1;
182
              state_next      = SKIP_HDRS;
183
           end
184
        end
185
 
186
        /* Skip the rest of the headers */
187
        SKIP_HDRS: begin
188
           if(in_fifo_ctrl_dout==0) begin
189
              state_next = WAIT_EOP;
190
           end
191
           if(!in_fifo_empty & out_rdy) begin
192
              in_fifo_rd_en   = 1;
193
              out_wr          = 1;
194
           end
195
        end
196
 
197
        /* write all data */
198
        WAIT_EOP: begin
199
           if(in_fifo_ctrl_dout!=0)begin
200
              if(out_rdy) begin
201
                 state_next   = WAIT_TILL_DONE_DECODE;
202
                 out_wr       = 1;
203
              end
204
           end
205
           else if(!in_fifo_empty & out_rdy) begin
206
              in_fifo_rd_en   = 1;
207
              out_wr          = 1;
208
           end
209
        end // case: WAIT_EOP
210
 
211
      endcase // case(state)
212
   end // always @ (*)
213
 
214
   always @(posedge clk) begin
215
      if(reset) begin
216
         state <= WAIT_TILL_DONE_DECODE;
217
      end
218
      else begin
219
         state <= state_next;
220
      end
221
   end
222
endmodule // switch_output_port
223
 

powered by: WebSVN 2.1.0

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