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 2

Go to most recent revision | 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
    parameter asz=$clog2(depth))
44
    (
45
     input       clk,
46
     input       reset,
47
     input       enable,
48
 
49
     input [asz-1:0]      bound_low,
50
     input [asz-1:0]      bound_high,
51
 
52
     output reg [asz-1:0]   cur_rdptr,
53
     output reg [asz-1:0]   com_rdptr,
54
     input  [asz-1:0]       wrptr,
55
     output reg           mem_re,
56
 
57
     output reg [asz:0]   usage,
58
 
59
     output               p_srdy,
60
     input                p_drdy,
61
     input                p_commit,
62
     input                p_abort,
63
     input [width-1:0]    mem_rd_data,
64
     output [width-1:0]   p_data
65
     );
66
 
67
  reg [asz-1:0]           cur_rdptr;
68
  reg [asz-1:0]           nxt_cur_rdptr;
69
  reg [asz-1:0]           cur_rdptr_p1;
70
  reg [asz-1:0]    com_rdptr;
71
  reg                   empty, full;
72
 
73
  reg                   p_srdy;
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
  reg [asz:0]           tmp_usage;
80
  reg [asz:0]           fifo_size;
81
 
82
  // Stage 1 -- Read pipeline
83
  // issue a read if:
84
  //   1) we are enabled
85
  //   2) valid_a is 0, OR
86
  //   3) valid_b is 0, OR
87
  //   4) valid_a && valid_b && trdy
88
  always @*
89
    begin
90
 
91
      if (cur_rdptr[asz-1:0] == (bound_high))
92
        begin
93
          cur_rdptr_p1[asz-1:0] = bound_low;
94
        end
95
      else
96
        cur_rdptr_p1 = cur_rdptr + 1;
97
 
98
      empty = (wrptr == cur_rdptr);
99
 
100
      if (commit && p_abort)
101
        begin
102
          nxt_cur_rdptr = com_rdptr;
103
          mem_re = 0;
104
        end
105
      else if (enable & !empty & (!valid_a | (!prev_re & !valid_b) |
106
                             (valid_a & valid_b & p_drdy)))
107
        begin
108
          nxt_cur_rdptr = cur_rdptr_p1;
109
          mem_re = 1;
110
        end
111
      else
112
        begin
113
          nxt_cur_rdptr = cur_rdptr;
114
          mem_re = 0;
115
        end // else: !if(enable & !empty & (!valid_a | !valid_b |...
116
 
117
      fifo_size = (bound_high - bound_low + 1);
118
      tmp_usage = wrptr[asz-1:0] - cur_rdptr[asz-1:0];
119
      if (~tmp_usage[asz])
120
        usage = tmp_usage[asz-1:0];
121
      else
122
        usage = fifo_size - (cur_rdptr[asz-1:0] - wrptr[asz-1:0]);
123
    end
124
 
125
  always @(posedge clk)
126
    begin
127
      if (reset)
128
        cur_rdptr <= `SDLIB_DELAY bound_low;
129
      else
130
        cur_rdptr <= `SDLIB_DELAY nxt_cur_rdptr;
131
    end
132
 
133
  generate
134
    if (commit == 1)
135
      begin : gen_s0
136
        reg [asz-1:0]  rdaddr_s0, rdaddr_a, rdaddr_b;
137
        reg [asz-1:0]  nxt_com_rdptr;
138
 
139
        always @(posedge clk)
140
          begin
141
            if (reset)
142
              com_rdptr <= `SDLIB_DELAY bound_low;
143
            else
144
              com_rdptr <= `SDLIB_DELAY nxt_com_rdptr;
145
 
146
            if (mem_re)
147
              rdaddr_s0 <= `SDLIB_DELAY cur_rdptr;
148
          end
149
      end
150
    else
151
      begin : gen_ns0
152
        always @*
153
          com_rdptr = cur_rdptr;
154
      end
155
  endgenerate
156
 
157
  // Stage 2 -- read buffering
158
  always @(`SDLIB_CLOCKING)
159
    begin
160
      if (reset)
161
        begin
162
          valid_a <= `SDLIB_DELAY 0;
163
          hold_a  <= `SDLIB_DELAY 0;
164
          prev_re <= `SDLIB_DELAY 0;
165
        end
166
      else
167
        begin
168
          if (commit && p_abort)
169
            prev_re <= `SDLIB_DELAY 0;
170
          else
171
            prev_re <= `SDLIB_DELAY mem_re;
172
 
173
          if (commit && p_abort)
174
            valid_a <= `SDLIB_DELAY 0;
175
          else if (prev_re)
176
            begin
177
              valid_a <= `SDLIB_DELAY 1;
178
              hold_a  <= `SDLIB_DELAY mem_rd_data;
179
            end
180
          else if (!valid_b | p_drdy)
181
            valid_a <= `SDLIB_DELAY 0;
182
        end
183
    end // always @ (posedge clk or posedge reset)
184
 
185
  generate
186
    if (commit == 1)
187
      begin : gen_s2
188
        always @(posedge clk)
189
          begin
190
            if (prev_re)
191
              rdaddr_a <= `SDLIB_DELAY rdaddr_s0;
192
          end
193
      end
194
  endgenerate
195
 
196
  // Stage 3 -- output irdy/trdy
197
  always @(`SDLIB_CLOCKING)
198
    begin
199
      if (reset)
200
        begin
201
          valid_b <= `SDLIB_DELAY 0;
202
          hold_b  <= `SDLIB_DELAY 0;
203
        end
204
      else
205
        begin
206
          if (commit && p_abort)
207
            valid_b <= `SDLIB_DELAY 0;
208
          else if (valid_a & (!valid_b | p_drdy))
209
            begin
210
              valid_b <= `SDLIB_DELAY 1;
211
              hold_b  <= `SDLIB_DELAY hold_a;
212
            end
213
          else if (valid_b & p_drdy)
214
            valid_b <= `SDLIB_DELAY 0;
215
        end
216
    end // always @ (posedge clk or posedge reset)
217
 
218
  generate
219
    if (commit == 1)
220
      begin : gen_s3
221
        always @(posedge clk)
222
          begin
223
            if (valid_a & (!valid_b | p_drdy))
224
              rdaddr_b <= `SDLIB_DELAY rdaddr_a;
225
          end
226
 
227
        always @*
228
          begin
229
            if (p_commit)
230
              nxt_com_rdptr = rdaddr_b;
231
            else
232
              nxt_com_rdptr = com_rdptr;
233
          end
234
      end
235
  endgenerate
236
 
237
  assign p_srdy = valid_b;
238
  assign p_data = hold_b;
239
 
240
endmodule // it_fifo

powered by: WebSVN 2.1.0

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