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

Subversion Repositories srdydrdy_lib

[/] [srdydrdy_lib/] [trunk/] [rtl/] [verilog/] [utility/] [llmanager.v] - Blame information for rev 30

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 ghutchis
//----------------------------------------------------------------------
2
//  Linked List Manager
3
//
4
//----------------------------------------------------------------------
5
//  Author: Guy Hutchison
6
//
7
// This block is uncopyrighted and released into the public domain.
8
//----------------------------------------------------------------------
9
 
10
module llmanager
11
  (/*AUTOARG*/
12
  // Outputs
13
  par_drdy, parr_srdy, parr_page, lnp_drdy, rlp_drdy, rlpr_srdy,
14
  rlpr_data, drf_drdy, refup_drdy, pgmem_wr_en, pgmem_wr_addr,
15
  pgmem_wr_data, pgmem_rd_addr, pgmem_rd_en, ref_wr_en, ref_wr_addr,
16
  ref_wr_data, ref_rd_addr, ref_rd_en, free_count,
17
  // Inputs
18
  clk, reset, par_srdy, parr_drdy, lnp_srdy, lnp_pnp, rlp_srdy,
19
  rlp_rd_page, rlpr_drdy, drf_srdy, drf_page_list, refup_srdy,
20
  refup_page, refup_count, pgmem_rd_data, ref_rd_data
21
  );
22
 
23
  parameter lpsz = 8;    // link list page size, in bits
24
  parameter lpdsz = lpsz+1;  // link page data size, must be at least size of address
25
  parameter pages = 256; // number of pages
26
  //parameter sidsz = 2; // source ID size, in bits
27
  parameter sources = 4; // number of sources
28
  parameter sinks = 4;    // number of sinks
29
  parameter sksz = 2;     // number of sink address bits
30
  parameter maxref = 7;   // maximum reference count, disable with maxref = 0
31
  parameter refsz  = 3;   // size of reference count bits
32
 
33
  input clk;
34
  input reset;
35
 
36
  // page allocation request i/f
37
  input [sources-1:0] par_srdy;
38
  output [sources-1:0] par_drdy;
39
 
40
  // page allocation request reply i/f
41
  output [sources-1:0] parr_srdy;
42
  input [sources-1:0] parr_drdy;
43
  output [lpsz-1:0]   parr_page;
44
 
45
  // link to next page i/f
46
  input [sources-1:0]  lnp_srdy;
47
  output [sources-1:0] lnp_drdy;
48
  input [sources*(lpsz+lpdsz)-1:0] lnp_pnp;
49
 
50
  // read link page i/f
51
  input [sinks-1:0]      rlp_srdy;
52
  output [sinks-1:0]     rlp_drdy;
53
  input [sinks*lpsz-1:0] rlp_rd_page;
54
 
55
  // read link page reply i/f
56
  output [sinks-1:0]     rlpr_srdy;
57
  input [sinks-1:0]      rlpr_drdy;
58
  output [lpdsz-1:0]     rlpr_data;
59
 
60
  // page dereference interface
61
  input [sinks-1:0]   drf_srdy;
62
  output [sinks-1:0]  drf_drdy;
63
  input [sinks*lpsz*2-1:0] drf_page_list;
64
 
65
  // reference count update interface
66
  input                  refup_srdy;
67
  output                 refup_drdy;
68
  input [lpsz-1:0]       refup_page;
69
  input [refsz-1:0]      refup_count;
70
 
71
  // link memory interface
72
  output                 pgmem_wr_en;
73
  output [lpsz-1:0]      pgmem_wr_addr;
74
  output [lpdsz-1:0]     pgmem_wr_data;
75
  output [lpsz-1:0]      pgmem_rd_addr;
76
  output                 pgmem_rd_en;
77
  input [lpdsz-1:0]      pgmem_rd_data;
78
 
79
  // reference count memory interface
80
  output                 ref_wr_en;
81
  output [lpsz-1:0]      ref_wr_addr;
82
  output [refsz-1:0]     ref_wr_data;
83
  output [lpsz-1:0]      ref_rd_addr;
84
  output                 ref_rd_en;
85
  input [refsz-1:0]      ref_rd_data;
86
 
87
 
88
  output [lpsz:0]        free_count;
89
 
90
  reg [lpsz-1:0]       r_free_head_ptr, free_tail_ptr;
91
  wire [lpsz-1:0]      free_head_ptr;
92
 
93
  reg                  pmstate;
94
  integer              i;
95
  wire [sources-1:0]   req_src_id;
96
  reg [sources-1:0]    iparr_src_id;
97
  wire                 req_srdy;
98
 
99
  wire reclaim_srdy;
100
  reg  reclaim_drdy;
101
  wire [lpsz-1:0] reclaim_start_page, reclaim_end_page;
102
 
103
  reg [lpdsz-1:0]  pgmem_wr_data;
104
  reg             pgmem_wr_en;
105
  reg [lpsz-1:0]  pgmem_wr_addr;
106
  reg [lpsz-1:0]  pgmem_rd_addr;
107
  reg             pgmem_rd_en;
108
 
109
  reg             init;
110
  reg [lpsz:0]    init_count;
111
  reg [lpsz:0]    free_count;
112
  wire            free_empty;
113
  reg             req_drdy;
114
 
115
  wire            irlp_srdy;
116
  reg             irlp_drdy;
117
  wire [lpsz-1:0] irlp_rd_page;
118
  wire [sinks-1:0] irlp_grant;
119
 
120
  reg             irlpr_srdy;
121
  wire            irlpr_drdy;
122
  reg [sinks-1:0] irlpr_grant, nxt_irlpr_grant;
123
  reg              load_head_ptr, nxt_load_head_ptr;
124
  reg              load_lp_data, nxt_load_lp_data;
125
 
126
  wire            ilnp_srdy;
127
  reg             ilnp_drdy;
128
  wire [lpsz-1:0] ilnp_page;
129
  wire [lpdsz-1:0] ilnp_nxt_page;
130
 
131
  wire dsbuf_srdy, dsbuf_drdy;
132
  wire [sources-1:0] dsbuf_source;
133
  wire [lpsz-1:0]    dsbuf_data;
134
  wire               iparr_drdy;
135
 
136
  assign free_empty = (free_head_ptr == free_tail_ptr);
137
  assign free_head_ptr = (load_head_ptr) ? pgmem_rd_data : r_free_head_ptr;
138
 
139
  sd_rrmux #(.mode(0), .fast_arb(1),
140
             .width(1), .inputs(sources)) req_mux
141
    (
142
     .clk         (clk),
143
     .reset       (reset),
144
 
145
     .c_srdy      (par_srdy),
146
     .c_drdy      (par_drdy),
147
     .c_data      ({sources{1'b0}}),
148
     .c_rearb     (1'b1),
149
 
150
     .p_srdy      (req_srdy),
151
     .p_drdy      (req_drdy),
152
     .p_data      (),
153
     .p_grant     (req_src_id)
154
     );
155
 
156
  sd_rrmux #(.mode(0), .fast_arb(1),
157
             .width(lpsz+lpdsz), .inputs(sources)) lnp_mux
158
    (
159
     .clk         (clk),
160
     .reset       (reset),
161
 
162
     .c_srdy      (lnp_srdy),
163
     .c_drdy      (lnp_drdy),
164
     .c_data      (lnp_pnp),
165
     .c_rearb     (1'b1),
166
 
167
     .p_srdy      (ilnp_srdy),
168
     .p_drdy      (ilnp_drdy),
169
     .p_data      ({ilnp_page,ilnp_nxt_page}),
170
     .p_grant     ()
171
     );
172
 
173
  sd_rrmux #(.mode(0), .fast_arb(1),
174
             .width(lpsz), .inputs(sources)) rlp_mux
175
    (
176
     .clk         (clk),
177
     .reset       (reset),
178
 
179
     .c_srdy      (rlp_srdy),
180
     .c_drdy      (rlp_drdy),
181
     .c_data      (rlp_rd_page),
182
     .c_rearb     (1'b1),
183
 
184
     .p_srdy      (irlp_srdy),
185
     .p_drdy      (irlp_drdy),
186
     .p_data      (irlp_rd_page),
187
     .p_grant     (irlp_grant)
188
     );
189
 
190
  always @(posedge clk)
191
    begin
192
      if (reset)
193
        begin
194
          init <= 1;
195
          init_count <= 0;
196
          r_free_head_ptr <= 0;
197
          free_tail_ptr <= pages - 1;
198
          free_count <= pages;
199
          load_head_ptr <= 0;
200
          load_lp_data <= 0;
201
          irlpr_grant <= 0;
202
          iparr_src_id <= 0;
203
        end
204
      else
205
        begin
206
          load_head_ptr <= nxt_load_head_ptr;
207
          load_lp_data  <= nxt_load_lp_data;
208
          irlpr_grant <= nxt_irlpr_grant;
209
 
210
          if (init)
211
            begin
212
              init_count <= init_count + 1;
213
              if (init_count == (pages-1))
214
                init <= 0;
215
            end
216
          else
217
            begin
218
              if (load_head_ptr)
219
                r_free_head_ptr <= pgmem_rd_data;
220
 
221
              if (req_drdy)
222
                iparr_src_id    <= req_src_id;
223
 
224
              if (reclaim_srdy & reclaim_drdy)
225
                free_tail_ptr <= reclaim_end_page;
226
 
227
              if (pgmem_rd_en & !pgmem_wr_en)
228
                free_count <= free_count - 1;
229
              else if (pgmem_wr_en & !pgmem_rd_en)
230
                free_count <= free_count + 1;
231
            end
232
        end // else: !if(reset)
233
    end // always @ (posedge clk)
234
 
235
  always @*
236
    begin
237
      pgmem_wr_data = 0;
238
      pgmem_wr_en = 0;
239
      pgmem_wr_addr = 0;
240
      pgmem_rd_addr = 0;
241
      pgmem_rd_en = 0;
242
      ilnp_drdy = 0;
243
      nxt_load_head_ptr = 0;
244
      nxt_load_lp_data = 0;
245
      nxt_irlpr_grant = irlpr_grant;
246
      irlp_drdy = 0;
247
      req_drdy = 0;
248
 
249
      if (init)
250
        begin
251
          pgmem_wr_en = 1;
252
          pgmem_wr_addr = init_count;
253
          pgmem_wr_data[lpsz-1:0] = init_count + 1;
254
          pgmem_wr_data[lpdsz-1:lpsz] = 0;
255
          reclaim_drdy = 0;
256
        end
257
      else
258
        begin
259
          reclaim_drdy = 1;
260
          // load_lp check is to predict flow control on next cycle,
261
          // prevents back-to-pack Read Link Page requests
262
          if (irlp_srdy & irlpr_drdy & !load_lp_data)
263
            begin
264
              pgmem_rd_en = 1;
265
              pgmem_rd_addr = irlp_rd_page;
266
              nxt_load_lp_data = 1;
267
              nxt_irlpr_grant = irlp_grant;
268
              irlp_drdy = 1;
269
            end
270
          else if (req_srdy & (iparr_drdy & dsbuf_drdy) & !free_empty)
271
            begin
272
              pgmem_rd_en = 1;
273
              pgmem_rd_addr = free_head_ptr;
274
              nxt_load_head_ptr = 1;
275
              req_drdy = 1;
276
            end
277
 
278
          if (reclaim_srdy)
279
            begin
280
              pgmem_wr_en = 1;
281
              pgmem_wr_addr = free_tail_ptr;
282
              pgmem_wr_data = reclaim_start_page;
283
            end
284
          else if (ilnp_srdy)
285
            begin
286
              ilnp_drdy = 1;
287
              pgmem_wr_en = 1;
288
              pgmem_wr_addr = ilnp_page;
289
              pgmem_wr_data = ilnp_nxt_page;
290
           end
291
       end
292
    end
293
 
294
  sd_input #(.width(lpsz+sources)) lp_disp_buf
295
    (.clk (clk), .reset (reset),
296
     .c_srdy (load_head_ptr),
297
     .c_drdy (iparr_drdy),
298
     .c_data ({iparr_src_id,r_free_head_ptr}),
299
     .ip_srdy (dsbuf_srdy),
300
     .ip_drdy (dsbuf_drdy),
301
     .ip_data ({dsbuf_source,dsbuf_data}));
302
 
303
  sd_mirror #(.mirror(sources), .width(lpsz)) lp_dispatch
304
    (.clk   (clk),
305
     .reset (reset),
306
 
307
     .c_srdy (dsbuf_srdy),
308
     .c_drdy (dsbuf_drdy),
309
     .c_data (dsbuf_data),
310
     .c_dst_vld (dsbuf_source),
311
 
312
     .p_srdy (parr_srdy),
313
     .p_drdy (parr_drdy),
314
     .p_data (parr_page)
315
     );
316
 
317
  // output reflector for read link page interface
318
  sd_mirror #(.mirror(sinks), .width(lpdsz)) read_link_return
319
    (.clk   (clk),
320
     .reset (reset),
321
 
322
     .c_srdy (load_lp_data),
323
     .c_drdy (irlpr_drdy),
324
     .c_data (pgmem_rd_data),
325
     .c_dst_vld (irlpr_grant),
326
 
327
     .p_srdy (rlpr_srdy),
328
     .p_drdy (rlpr_drdy),
329
     .p_data (rlpr_data)
330
     );
331
 
332
  generate if (maxref == 0)
333
    begin : no_ref_count
334
  sd_rrmux #(.mode(0), .fast_arb(1),
335
             .width(lpsz*2), .inputs(sinks)) reclaim_mux
336
    (
337
     .clk         (clk),
338
     .reset       (reset),
339
 
340
     .c_srdy      (drf_srdy),
341
     .c_drdy      (drf_drdy),
342
     .c_data      (drf_page_list),
343
     .c_rearb     (1'b1),
344
 
345
     .p_srdy      (reclaim_srdy),
346
     .p_drdy      (reclaim_drdy),
347
     .p_data      ({reclaim_start_page,reclaim_end_page}),
348
     .p_grant     ()
349
     );
350
    end // block: no_ref_count
351
  else
352
    begin : enable_ref_count
353
      wire drq_srdy, drq_drdy;
354
      wire [lpsz-1:0] drq_start_page, drq_end_page;
355
 
356
      sd_rrmux #(.mode(0), .fast_arb(1),
357
                 .width(lpsz*2), .inputs(sinks)) reclaim_mux
358
        (
359
         .clk         (clk),
360
         .reset       (reset),
361
 
362
         .c_srdy      (drf_srdy),
363
         .c_drdy      (drf_drdy),
364
         .c_data      (drf_page_list),
365
         .c_rearb     (1'b1),
366
 
367
         .p_srdy      (drq_srdy),
368
         .p_drdy      (drq_drdy),
369
         .p_data      ({drq_start_page,drq_end_page}),
370
         .p_grant     ()
371
         );
372
 
373
      llmanager_refcount #(/*AUTOINSTPARAM*/
374
                           // Parameters
375
                           .lpsz                (lpsz),
376
                           .refsz               (refsz)) llref
377
        (/*AUTOINST*/
378
         // Outputs
379
         .drq_drdy                      (drq_drdy),
380
         .reclaim_srdy                  (reclaim_srdy),
381
         .reclaim_start_page            (reclaim_start_page[(lpsz)-1:0]),
382
         .reclaim_end_page              (reclaim_end_page[(lpsz)-1:0]),
383
         .refup_drdy                    (refup_drdy),
384
         .ref_wr_en                     (ref_wr_en),
385
         .ref_wr_addr                   (ref_wr_addr[(lpsz)-1:0]),
386
         .ref_wr_data                   (ref_wr_data[(refsz)-1:0]),
387
         .ref_rd_addr                   (ref_rd_addr[(lpsz)-1:0]),
388
         .ref_rd_en                     (ref_rd_en),
389
         // Inputs
390
         .clk                           (clk),
391
         .reset                         (reset),
392
         .drq_srdy                      (drq_srdy),
393
         .drq_start_page                (drq_start_page[(lpsz)-1:0]),
394
         .drq_end_page                  (drq_end_page[(lpsz)-1:0]),
395
         .reclaim_drdy                  (reclaim_drdy),
396
         .refup_srdy                    (refup_srdy),
397
         .refup_page                    (refup_page[(lpsz)-1:0]),
398
         .refup_count                   (refup_count[(refsz)-1:0]),
399
         .ref_rd_data                   (ref_rd_data[(refsz)-1:0]));
400
    end
401
  endgenerate
402
 
403
endmodule // llmanager

powered by: WebSVN 2.1.0

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