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

Subversion Repositories srdydrdy_lib

[/] [srdydrdy_lib/] [trunk/] [rtl/] [verilog/] [buffers/] [sd_fifo_tail_b.v] - Blame information for rev 22

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ghutchis
//----------------------------------------------------------------------
2
// Srdy/Drdy FIFO Tail "B"
3
//
4
// Building block for FIFOs.  The "B" (big) FIFO is design for larger FIFOs
5
// based around memories, with sizes that may not be a power of 2.
6
//
7
// The bound inputs allow multiple FIFO controllers to share a single
8
// memory.  The enable input is for arbitration between multiple FIFO
9
// controllers, or between the fifo head and tail controllers on a
10
// single port memory.
11
//
12
// The commit parameter enables read/commit behavior.  This creates
13
// two read pointers, one which is used for reading from memory and
14
// a commit pointer which is sent to the head block.  The abort behavior
15
// has a 3-cycle performance penalty due to pipeline flush.
16
//
17
// The FIFO tail assumes a memory with one-cycle read latency, and
18
// has output buffering to compensate for this.
19
//
20
// Naming convention: c = consumer, p = producer, i = internal interface
21
//----------------------------------------------------------------------
22
// Author: Guy Hutchison
23
//
24
// This block is uncopyrighted and released into the public domain.
25
//----------------------------------------------------------------------
26
 
27
// Clocking statement for synchronous blocks.  Default is for
28
// posedge clocking and positive async reset
29
`ifndef SDLIB_CLOCKING
30
 `define SDLIB_CLOCKING posedge clk or posedge reset
31
`endif
32
 
33
// delay unit for nonblocking assigns, default is to #1
34
`ifndef SDLIB_DELAY
35
 `define SDLIB_DELAY #1
36
`endif
37
 
38
 
39
module sd_fifo_tail_b
40
  #(parameter width=8,
41
    parameter depth=16,
42
    parameter commit=0,
43 16 ghutchis
    parameter asz=$clog2(depth),
44
    parameter usz=$clog2(depth+1)
45
    )
46 2 ghutchis
    (
47
     input       clk,
48
     input       reset,
49
     input       enable,
50
 
51
     input [asz-1:0]      bound_low,
52
     input [asz-1:0]      bound_high,
53
 
54
     output reg [asz-1:0]   cur_rdptr,
55
     output reg [asz-1:0]   com_rdptr,
56
     input  [asz-1:0]       wrptr,
57
     output reg           mem_re,
58 13 ghutchis
     input                mem_we,
59 2 ghutchis
 
60 19 ghutchis
     output reg [usz-1:0] p_usage,
61 2 ghutchis
 
62
     output               p_srdy,
63
     input                p_drdy,
64
     input                p_commit,
65
     input                p_abort,
66
     input [width-1:0]    mem_rd_data,
67
     output [width-1:0]   p_data
68
     );
69
 
70
  reg [asz-1:0]           nxt_cur_rdptr;
71
  reg [asz-1:0]           cur_rdptr_p1;
72
  reg                   empty, full;
73
 
74
  reg                   nxt_irdy;
75
 
76
  reg [width-1:0]       hold_a, hold_b;
77
  reg                   valid_a, valid_b;
78
  reg                   prev_re;
79 16 ghutchis
  reg [usz:0]           tmp_usage;
80
  reg [usz:0]           fifo_size;
81 6 ghutchis
  wire                  rbuf1_drdy;
82
  wire                  ip_srdy, ip_drdy;
83
  wire [width-1:0]       ip_data;
84 2 ghutchis
 
85
  // Stage 1 -- Read pipeline
86
  // issue a read if:
87
  //   1) we are enabled
88
  //   2) valid_a is 0, OR
89
  //   3) valid_b is 0, OR
90
  //   4) valid_a && valid_b && trdy
91
  always @*
92
    begin
93
 
94
      if (cur_rdptr[asz-1:0] == (bound_high))
95
        begin
96
          cur_rdptr_p1[asz-1:0] = bound_low;
97
        end
98
      else
99
        cur_rdptr_p1 = cur_rdptr + 1;
100
 
101
      empty = (wrptr == cur_rdptr);
102
 
103
      if (commit && p_abort)
104
        begin
105
          nxt_cur_rdptr = com_rdptr;
106
          mem_re = 0;
107
        end
108 22 ghutchis
      else if (enable & !empty & (ip_drdy | (rbuf1_drdy & !prev_re)))
109 2 ghutchis
        begin
110
          nxt_cur_rdptr = cur_rdptr_p1;
111
          mem_re = 1;
112
        end
113
      else
114
        begin
115
          nxt_cur_rdptr = cur_rdptr;
116
          mem_re = 0;
117
        end // else: !if(enable & !empty & (!valid_a | !valid_b |...
118
 
119
      fifo_size = (bound_high - bound_low + 1);
120
      tmp_usage = wrptr[asz-1:0] - cur_rdptr[asz-1:0];
121 16 ghutchis
      if (~tmp_usage[usz])
122
        p_usage = tmp_usage[usz-1:0];
123 2 ghutchis
      else
124 16 ghutchis
        p_usage = fifo_size - (cur_rdptr[asz-1:0] - wrptr[asz-1:0]);
125 13 ghutchis
    end // always @ *
126
 
127
  always @(posedge clk)
128
    begin
129
      if (reset)
130 2 ghutchis
        cur_rdptr <= `SDLIB_DELAY bound_low;
131
      else
132
        cur_rdptr <= `SDLIB_DELAY nxt_cur_rdptr;
133
    end
134
 
135 11 ghutchis
  reg [asz-1:0]  rdaddr_s0, rdaddr_a, rdaddr_b;
136
  reg [asz-1:0]  nxt_com_rdptr;
137 2 ghutchis
  generate
138
    if (commit == 1)
139
      begin : gen_s0
140
 
141
        always @(posedge clk)
142
          begin
143
            if (reset)
144
              com_rdptr <= `SDLIB_DELAY bound_low;
145
            else
146
              com_rdptr <= `SDLIB_DELAY nxt_com_rdptr;
147
 
148
            if (mem_re)
149
              rdaddr_s0 <= `SDLIB_DELAY cur_rdptr;
150
          end
151
      end
152
    else
153
      begin : gen_ns0
154
        always @*
155
          com_rdptr = cur_rdptr;
156
      end
157
  endgenerate
158
 
159
  // Stage 2 -- read buffering
160
  always @(`SDLIB_CLOCKING)
161
    begin
162
      if (reset)
163
        begin
164
          prev_re <= `SDLIB_DELAY 0;
165 6 ghutchis
        end
166 2 ghutchis
      else
167
        begin
168
          if (commit && p_abort)
169
            prev_re <= `SDLIB_DELAY 0;
170
          else
171
            prev_re <= `SDLIB_DELAY mem_re;
172 6 ghutchis
        end // else: !if(reset)
173
    end // always @ (`SDLIB_CLOCKING)
174 2 ghutchis
 
175
  generate
176
    if (commit == 1)
177 11 ghutchis
      begin : gen_s2
178 6 ghutchis
        wire [asz-1:0] ip_rdaddr, p_rdaddr;
179 2 ghutchis
 
180 6 ghutchis
        sd_input #(asz+width) rbuf1
181
          (.clk (clk), .reset (p_abort | reset),
182
           .c_srdy (prev_re),
183
           .c_drdy (rbuf1_drdy),
184
           .c_data ({rdaddr_s0,mem_rd_data}),
185
           .ip_srdy (ip_srdy), .ip_drdy (ip_drdy),
186
           .ip_data ({ip_rdaddr,ip_data}));
187
 
188
        sd_output #(asz+width) rbuf2
189
          (.clk (clk), .reset (p_abort | reset),
190
           .ic_srdy (ip_srdy),
191
           .ic_drdy (ip_drdy),
192
           .ic_data ({ip_rdaddr,ip_data}),
193
           .p_srdy (p_srdy), .p_drdy (p_drdy),
194
           .p_data ({p_rdaddr,p_data}));
195 2 ghutchis
 
196
        always @*
197
          begin
198 14 ghutchis
            if (p_commit & p_srdy & p_drdy)
199 6 ghutchis
              nxt_com_rdptr = p_rdaddr;
200 2 ghutchis
            else
201
              nxt_com_rdptr = com_rdptr;
202
          end
203 6 ghutchis
      end // if (commit == 1)
204
    else
205 11 ghutchis
      begin : gen_ns2
206 6 ghutchis
        sd_input #(width) rbuf1
207
          (.clk (clk), .reset (p_abort | reset),
208
           .c_srdy (prev_re),
209
           .c_drdy (rbuf1_drdy),
210
           .c_data (mem_rd_data),
211
           .ip_srdy (ip_srdy), .ip_drdy (ip_drdy),
212
           .ip_data (ip_data));
213
 
214
        sd_output #(width) rbuf2
215
          (.clk (clk), .reset (p_abort | reset),
216
           .ic_srdy (ip_srdy),
217
           .ic_drdy (ip_drdy),
218
           .ic_data (ip_data),
219
           .p_srdy (p_srdy), .p_drdy (p_drdy),
220
           .p_data (p_data));
221
      end // else: !if(commit == 1)
222 2 ghutchis
  endgenerate
223
 
224
endmodule // it_fifo

powered by: WebSVN 2.1.0

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