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

Subversion Repositories loadbalancer

[/] [loadbalancer/] [trunk/] [classifier_arbiter/] [classifier_arbiter.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: input_arbiter.v 2075 2007-08-02 01:40:11Z grg $
4
//
5
// Module: input_arbiter.v
6
// Project: NF2.1
7
// Description: Goes round-robin around the input queues and services one pkt
8
//              out of each (if available). Note that this is unfair for queues
9
//              that always receive small packets since they pile up!
10
//
11
///////////////////////////////////////////////////////////////////////////////
12
`timescale 1ns/1ps
13
  module classifier_arbiter
14
    #(parameter DATA_WIDTH = 64,
15
      parameter CTRL_WIDTH=DATA_WIDTH/8,
16
      parameter UDP_REG_SRC_WIDTH = 2,
17
      parameter STAGE_NUMBER = 2,
18
      parameter NUM_QUEUES = 8
19
      )
20
 
21
   (// --- data path interface
22
    output reg [63:0]        out_data,
23
    output reg [7:0]        out_ctrl,
24
    output reg                         out_wr,
25
    input                              out_rdy,
26
 
27
    // interface to rx queues
28
    input  [63:0]            in_data_0,
29
    input  [7:0]            in_ctrl_0,
30
    input                              in_wr_0,
31
    output                             in_rdy_0,
32
 
33
    input  [63:0]            in_data_1,
34
    input  [7:0]            in_ctrl_1,
35
    input                              in_wr_1,
36
    output                             in_rdy_1,
37
 
38
    input  [63:0]            in_data_2,
39
    input  [7:0]            in_ctrl_2,
40
    input                              in_wr_2,
41
    output                             in_rdy_2,
42
 
43
    input  [63:0]            in_data_3,
44
    input  [7:0]            in_ctrl_3,
45
    input                              in_wr_3,
46
    output                             in_rdy_3,
47
 
48
    input  [63:0]            in_data_4,
49
    input  [7:0]            in_ctrl_4,
50
    input                              in_wr_4,
51
    output                             in_rdy_4,
52
 
53
    input  [63:0]            in_data_5,
54
    input  [7:0]            in_ctrl_5,
55
    input                              in_wr_5,
56
    output                             in_rdy_5,
57
 
58
    input  [63:0]            in_data_6,
59
    input  [7:0]            in_ctrl_6,
60
    input                              in_wr_6,
61
    output                             in_rdy_6,
62
 
63
    input  [63:0]            in_data_7,
64
    input  [7:0]            in_ctrl_7,
65
    input                              in_wr_7,
66
    output                             in_rdy_7,
67
 
68
 
69
 
70
 
71
 
72
    // --- Misc
73
 
74
    input                              reset,
75
    input                              clk
76
   );
77
 
78
 
79
   function integer log2;
80
      input integer number;
81
      begin
82
         log2=0;
83
         while(2**log2<number) begin
84
            log2=log2+1;
85
         end
86
      end
87
   endfunction // log2
88
 
89
   // ------------ Internal Params --------
90
   parameter NUM_QUEUES_WIDTH = log2(NUM_QUEUES);
91
 
92
   parameter NUM_STATES = 1;
93
   parameter IDLE = 0;
94
   parameter WR_PKT = 1;
95
 
96
   // ------------- Regs/ wires -----------
97
   wire [NUM_QUEUES-1:0]               nearly_full;
98
   wire [NUM_QUEUES-1:0]               empty;
99
   wire [DATA_WIDTH-1:0]               in_data      [NUM_QUEUES-1:0];
100
   wire [CTRL_WIDTH-1:0]               in_ctrl      [NUM_QUEUES-1:0];
101
   wire [NUM_QUEUES-1:0]               in_wr;
102
   wire [CTRL_WIDTH-1:0]               fifo_out_ctrl[NUM_QUEUES-1:0];
103
   wire [DATA_WIDTH-1:0]               fifo_out_data[NUM_QUEUES-1:0];
104
   reg [NUM_QUEUES-1:0]                rd_en;
105
 
106
   wire [NUM_QUEUES_WIDTH-1:0]         cur_queue_plus1;
107
   reg [NUM_QUEUES_WIDTH-1:0]          cur_queue;
108
   reg [NUM_QUEUES_WIDTH-1:0]          cur_queue_next;
109
 
110
   reg [NUM_STATES-1:0]                state;
111
   reg [NUM_STATES-1:0]                state_next;
112
 
113
   reg [CTRL_WIDTH-1:0]                fifo_out_ctrl_prev;
114
   reg [CTRL_WIDTH-1:0]                fifo_out_ctrl_prev_next;
115
 
116
   wire [CTRL_WIDTH-1:0]               fifo_out_ctrl_sel;
117
   wire [DATA_WIDTH-1:0]               fifo_out_data_sel;
118
 
119
   reg [DATA_WIDTH-1:0]                out_data_next;
120
   reg [CTRL_WIDTH-1:0]                out_ctrl_next;
121
   reg                                 out_wr_next;
122
 
123
   reg                                 eop;
124
 
125
   // ------------ Modules -------------
126
 
127
   generate
128
   genvar i;
129
   for(i=0; i<NUM_QUEUES; i=i+1) begin: in_arb_queues
130
      small_fifo
131
        #( .WIDTH(DATA_WIDTH+CTRL_WIDTH),
132
           .MAX_DEPTH_BITS(8),
133
           .NEARLY_FULL(8**2-4))
134
      in_arb_fifo
135
        (// Outputs
136
         .dout                           ({fifo_out_ctrl[i], fifo_out_data[i]}),
137
         .full                           (),
138
         .nearly_full                    (nearly_full[i]),
139
         .empty                          (empty[i]),
140
         // Inputs
141
         .din                            ({in_ctrl[i], in_data[i]}),
142
         .wr_en                          (in_wr[i]),
143
         .rd_en                          (rd_en[i]),
144
         .reset                          (reset),
145
         .clk                            (clk));
146
   end // block: in_arb_queues
147
   endgenerate
148
 
149
 
150
   // ------------- Logic ------------
151
 
152
   assign in_data[0]         = in_data_0;
153
   assign in_ctrl[0]         = in_ctrl_0;
154
   assign in_wr[0]           = in_wr_0;
155
   assign in_rdy_0           = !nearly_full[0];
156
 
157
   assign in_data[1]         = in_data_1;
158
   assign in_ctrl[1]         = in_ctrl_1;
159
   assign in_wr[1]           = in_wr_1;
160
   assign in_rdy_1           = !nearly_full[1];
161
 
162
   assign in_data[2]         = in_data_2;
163
   assign in_ctrl[2]         = in_ctrl_2;
164
   assign in_wr[2]           = in_wr_2;
165
   assign in_rdy_2           = !nearly_full[2];
166
 
167
   assign in_data[3]         = in_data_3;
168
   assign in_ctrl[3]         = in_ctrl_3;
169
   assign in_wr[3]           = in_wr_3;
170
   assign in_rdy_3           = !nearly_full[3];
171
 
172
   assign in_data[4]         = in_data_4;
173
   assign in_ctrl[4]         = in_ctrl_4;
174
   assign in_wr[4]           = in_wr_4;
175
   assign in_rdy_4           = !nearly_full[4];
176
 
177
   assign in_data[5]         = in_data_5;
178
   assign in_ctrl[5]         = in_ctrl_5;
179
   assign in_wr[5]           = in_wr_5;
180
   assign in_rdy_5           = !nearly_full[5];
181
 
182
   assign in_data[6]         = in_data_6;
183
   assign in_ctrl[6]         = in_ctrl_6;
184
   assign in_wr[6]           = in_wr_6;
185
   assign in_rdy_6           = !nearly_full[6];
186
 
187
   assign in_data[7]         = in_data_7;
188
   assign in_ctrl[7]         = in_ctrl_7;
189
   assign in_wr[7]           = in_wr_7;
190
   assign in_rdy_7           = !nearly_full[7];
191
 
192
   /* disable regs for this module */
193
   assign cur_queue_plus1    = (cur_queue == NUM_QUEUES-1) ? 0 : cur_queue + 1;
194
 
195
   assign fifo_out_ctrl_sel  = fifo_out_ctrl[cur_queue];
196
   assign fifo_out_data_sel  = fifo_out_data[cur_queue];
197
 
198
   always @(*) begin
199
      state_next     = state;
200
      cur_queue_next = cur_queue;
201
      fifo_out_ctrl_prev_next = fifo_out_ctrl_prev;
202
      out_wr_next    = 0;
203
      out_ctrl_next  = fifo_out_ctrl_sel;
204
      out_data_next  = fifo_out_data_sel;
205
      rd_en          = 0;
206
      eop            = 0;
207
 
208
      case(state)
209
 
210
        /* cycle between input queues until one is not empty */
211
        IDLE: begin
212
           if(!empty[cur_queue] && out_rdy) begin
213
              state_next = WR_PKT;
214
              rd_en[cur_queue] = 1;
215
              fifo_out_ctrl_prev_next = STAGE_NUMBER;
216
           end
217
           if(empty[cur_queue] && out_rdy) begin
218
              cur_queue_next = cur_queue_plus1;
219
           end
220
        end
221
 
222
        /* wait until eop */
223
        WR_PKT: begin
224
           /* if this is the last word then write it and get out */
225
           if(out_rdy & |fifo_out_ctrl_sel & (fifo_out_ctrl_prev==0) ) begin
226
              out_wr_next = 1;
227
              state_next = IDLE;
228
              cur_queue_next = cur_queue_plus1;
229
              eop = 1;
230
           end
231
           /* otherwise read and write as usual */
232
           else if (out_rdy & !empty[cur_queue]) begin
233
              fifo_out_ctrl_prev_next = fifo_out_ctrl_sel;
234
              out_wr_next = 1;
235
              rd_en[cur_queue] = 1;
236
           end
237
        end // case: WR_PKT
238
 
239
      endcase // case(state)
240
   end // always @ (*)
241
 
242
   always @(posedge clk) begin
243
      if(reset) begin
244
         state <= IDLE;
245
         cur_queue <= 0;
246
         fifo_out_ctrl_prev <= 1;
247
         out_wr <= 0;
248
         out_ctrl <= 1;
249
         out_data <= 0;
250
      end
251
      else begin
252
         state <= state_next;
253
         cur_queue <= cur_queue_next;
254
         fifo_out_ctrl_prev <= fifo_out_ctrl_prev_next;
255
         out_wr <= out_wr_next;
256
         out_ctrl <= out_ctrl_next;
257
         out_data <= out_data_next;
258
      end
259
   end
260
 
261
endmodule // input_arbiter
262
 
263
// Local Variables:
264
// verilog-library-directories:(".")
265
// End:

powered by: WebSVN 2.1.0

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