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

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [basal/] [src/] [FIFOs/] [tiny_async_fifo.sv] - Blame information for rev 34

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 qaztronic
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// Copyright (C) 2015 Authors and OPENCORES.ORG                 ////
4
////                                                              ////
5
//// This source file may be used and distributed without         ////
6
//// restriction provided that this copyright statement is not    ////
7
//// removed from the file and that any derivative work contains  ////
8
//// the original copyright notice and the associated disclaimer. ////
9
////                                                              ////
10
//// This source file is free software; you can redistribute it   ////
11
//// and/or modify it under the terms of the GNU Lesser General   ////
12
//// Public License as published by the Free Software Foundation; ////
13
//// either version 2.1 of the License, or (at your option) any   ////
14
//// later version.                                               ////
15
////                                                              ////
16
//// This source is distributed in the hope that it will be       ////
17
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
18
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
19
//// PURPOSE.  See the GNU Lesser General Public License for more ////
20
//// details.                                                     ////
21
////                                                              ////
22
//// You should have received a copy of the GNU Lesser General    ////
23
//// Public License along with this source; if not, download it   ////
24
//// from http://www.opencores.org/lgpl.shtml                     ////
25
////                                                              ////
26
//////////////////////////////////////////////////////////////////////
27
 
28
 
29
module
30
  tiny_async_fifo
31
  #(
32
    parameter W = 8
33
  )
34
  (
35
    output            wr_full,
36
    input  [W-1:0]    wr_data,
37
    input             wr_en,
38
    input             wr_clk,
39
    input             wr_reset,
40
 
41
    output            rd_empty,
42
    output  [W-1:0]   rd_data,
43
    input             rd_en,
44
    input             rd_clk,
45
    input             rd_reset
46
  );
47
 
48
  // --------------------------------------------------------------------
49
  //
50
  wire        writing = wr_en && ~wr_full;
51
  wire        reading = rd_en && ~rd_empty;
52
 
53
 
54
  // --------------------------------------------------------------------
55
  //
56
  function logic [1:0]
57
    grey_counter_2_bit
58
    (
59
      input logic [1:0] count
60
    );
61
 
62
      case(count)
63
        2'b00:  grey_counter_2_bit = 2'b00;
64
        2'b01:  grey_counter_2_bit = 2'b01;
65
        2'b10:  grey_counter_2_bit = 2'b11;
66
        2'b11:  grey_counter_2_bit = 2'b10;
67
      endcase
68
 
69
  endfunction
70
 
71
 
72
  // --------------------------------------------------------------------
73
  //  sync grey_wr_ptr to rd clk domain
74
  reg [1:0] grey_wr_ptr;
75
  reg [1:0] grey_wr_ptr_r;
76
  reg [1:0] grey_wr_ptr_s;
77
 
78
  always_ff @(posedge rd_clk)
79
    if(rd_reset)
80
      {grey_wr_ptr_s, grey_wr_ptr_r} <= 0;
81
    else
82
      {grey_wr_ptr_s, grey_wr_ptr_r} <= {grey_wr_ptr_r, grey_wr_ptr};
83
 
84
 
85
  // --------------------------------------------------------------------
86
  //  sync grey_rd_ptr to wr clk domain
87
  reg [1:0] grey_rd_ptr;
88
  reg [1:0] grey_rd_ptr_r;
89
  reg [1:0] grey_rd_ptr_s;
90
 
91
  always_ff @(posedge wr_clk)
92
    if(rd_reset)
93
      {grey_rd_ptr_s, grey_rd_ptr_r} <= 0;
94
    else
95
      {grey_rd_ptr_s, grey_rd_ptr_r} <= {grey_rd_ptr_r, grey_rd_ptr};
96
 
97
 
98
  // --------------------------------------------------------------------
99
  //
100
  reg [1:0]   bin_rd_ptr;
101
  wire [1:0]  bin_rd_ptr_next = bin_rd_ptr + reading;
102
 
103
  always_ff @(posedge rd_clk)
104
    if(rd_reset)
105
      bin_rd_ptr <= 0;
106
    else
107
      bin_rd_ptr <= bin_rd_ptr_next;
108
 
109
 
110
  // --------------------------------------------------------------------
111
  //
112
  wire [1:0] grey_rd_ptr_next = grey_counter_2_bit(bin_rd_ptr_next);
113
 
114
  always_ff @(posedge rd_clk)
115
    if(rd_reset)
116
      grey_rd_ptr <= 0;
117
    else
118
      grey_rd_ptr <= grey_rd_ptr_next;
119
 
120
 
121
  // --------------------------------------------------------------------
122
  //
123
  reg asf_empty_r;
124
 
125
  always_ff @(posedge rd_clk)
126
    if(rd_reset)
127
      asf_empty_r <= 1;
128
    else
129
      asf_empty_r <= (grey_rd_ptr_next == grey_wr_ptr_s);
130
 
131
 
132
  // --------------------------------------------------------------------
133
  //
134
  reg [1:0] bin_wr_ptr;
135
  wire [1:0] bin_wr_ptr_next = bin_wr_ptr + writing;
136
 
137
  always_ff @(posedge wr_clk)
138
    if(wr_reset)
139
      bin_wr_ptr <= 0;
140
    else
141
      bin_wr_ptr <= bin_wr_ptr_next;
142
 
143
 
144
  // --------------------------------------------------------------------
145
  //
146
  wire [1:0] grey_wr_ptr_next = grey_counter_2_bit(bin_wr_ptr_next);
147
 
148
  always_ff @(posedge wr_clk)
149
    if(wr_reset)
150
      grey_wr_ptr <= 0;
151
    else
152
      grey_wr_ptr <= grey_wr_ptr_next;
153
 
154
 
155
  // --------------------------------------------------------------------
156
  //
157
  reg asf_full_r;
158
 
159
  always_ff @(posedge wr_clk)
160
    if(wr_reset)
161
      asf_full_r <= 1;
162
    else
163
      asf_full_r <= (grey_wr_ptr_next == ~grey_rd_ptr_s);
164
 
165
 
166
  // --------------------------------------------------------------------
167
  //
168
  reg   [W-1:0] data_0_r;
169
  reg   [W-1:0] data_1_r;
170
  wire  [W-1:0] rd_data_mux = bin_rd_ptr[0] ? data_1_r : data_0_r;
171
  assign rd_data = rd_data_mux;
172
 
173
  always_ff @(posedge wr_clk)
174
    if (writing)
175
      if(bin_wr_ptr[0])
176
        data_1_r <= wr_data;
177
      else
178
        data_0_r <= wr_data;
179
 
180
 
181
  // --------------------------------------------------------------------
182
  //
183
  assign rd_empty   = asf_empty_r;
184
  assign wr_full  = asf_full_r;
185
 
186
 
187
endmodule
188
 
189
 

powered by: WebSVN 2.1.0

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