asyn_fifo

  1 //Module Name:afifo_ctrl
  2 //Description:parameterized afifo
  3 
  4 module afifo_ctrl(
  5   clk_push,
  6   rst_push_n,
  7   clk_pop,
  8   rst_pop_n,
  9   push,
 10   push_data,
 11   full,
 12   pop,
 13   pop_data,
 14   empty,
 15   mem_waddr,
 16   mem_wen,
 17   mem_wdata,
 18   mem_raddr,
 19   mem_ren,
 20   mem_rdata,
 21   almost_full
 22   );
 23 
 24 parameter DATAWIDTH = 32;         //the data width of AFIFO
 25 parameter ADDRWIDTH = 8;          //the address bits of AFIFO and it must be >=2
 26                                   //the AFIFO depth must be 2^ADDRWIDTH
 27 //input declaration
 28 input clk_push;                   //push clock
 29 input rst_push_n;                 //reset signal in push clock domain
 30 
 31 input clk_pop;                    //pop clock
 32 input rst_pop_n;                  //reset signal in pop clock domain
 33 input push ;                      //push enable to AFIFO
 34 input [DATAWIDTH-1:0]  push_data; //push data to AFIFO
 35 input pop  ;                      //pop enable to AFIFO 
 36 input [DATAWIDTH-1:0]  mem_rdata; //read data from memory stack
 37  
 38 //output declaration
 39 output full;                      //full indicator,and the logic of user can't push data when this signal is high                                                           //ok
 40 output [DATAWIDTH-1:0] pop_data ; //pop data from AFIFO              //ok
 41 output empty;                     //empty indicator, and the logic of user can't pop data when this signal is high                                                           //ok
 42 output [ADDRWIDTH-1:0] mem_waddr; //write address to memory stack    //ok
 43 output mem_wen;                   //write enable to memory stack     //ok
 44 output [DATAWIDTH-1:0] mem_wdata; //write data to memory stack       //ok
 45 output [ADDRWIDTH-1:0] mem_raddr; //read address to memory stack     //ok
 46 output mem_ren;                   //read enable to memory stack      //ok
 47 output almost_full;
 48 
 49 
 50 //register declaration
 51  
 52 reg [ADDRWIDTH-1:0]  mem_waddr;
 53 reg [ADDRWIDTH-1:0]  mem_raddr;
 54 reg [ADDRWIDTH-1:0]  gray_waddr_1r;
 55 reg [ADDRWIDTH-1:0]  gray_waddr_2r_1_sync;
 56 reg [ADDRWIDTH-1:0]  gray_waddr_3r_2_sync;
 57 reg [ADDRWIDTH-1:0]  gray_raddr_1r;
 58 reg [ADDRWIDTH-1:0]  gray_raddr_2r_1_sync;
 59 reg [ADDRWIDTH-1:0]  gray_raddr_3r_2_sync;
 60 reg [ADDRWIDTH-1:0]  gray_waddr_temp;
 61 reg [ADDRWIDTH-1:0]  gray_raddr_temp;
 62 reg [ADDRWIDTH-1:0]  biny_waddr;
 63 reg [ADDRWIDTH-1:0]  biny_raddr;
 64 reg [ADDRWIDTH-1:0]  biny_waddr_temp;
 65 reg [ADDRWIDTH-1:0]  biny_raddr_temp;
 66 reg [DATAWIDTH-1:0]  pop_data_r;
 67 reg pop_r;
 68 reg empty_flag;
 69 reg full_flag;
 70 
 71 //net declaration
 72 wire mem_wen;
 73 wire mem_ren;
 74 wire [DATAWIDTH-1:0] mem_wdata;
 75 wire [DATAWIDTH-1:0] pop_data;
 76 wire [ADDRWIDTH-1:0] gray_waddr;
 77 wire [ADDRWIDTH-1:0] gray_raddr;
 78 wire pop_one_left;
 79 wire pop_ptr_diff;
 80 wire push_one_left;
 81 wire push_ptr_diff;
 82 
 83 integer i;
 84 
 85 
 86 assign mem_wen = push;
 87 assign mem_wdata[DATAWIDTH-1:0] = push_data[DATAWIDTH-1:0];
 88 assign mem_ren = pop;
 89 
 90 
 91 
 92 //for output signal pop_data
 93 always@(posedge clk_pop or negedge rst_pop_n)
 94 begin
 95   if(~rst_pop_n)
 96     pop_r<=1'b0;
 97   else
 98     pop_r<=pop;
 99 end
100 
101 always@(posedge clk_pop or negedge rst_pop_n)
102 begin
103   if(~rst_pop_n)
104     pop_data_r[DATAWIDTH-1:0] <= 0;
105   else
106     pop_data_r[DATAWIDTH-1:0] <= mem_rdata[DATAWIDTH-1:0];
107 end
108 
109 assign pop_data[DATAWIDTH-1:0] = pop_r ? mem_rdata[DATAWIDTH-1:0]:pop_data_r[DATAWIDTH-1:0];
110 
111 //for output signal mem_waddr
112 always@(posedge clk_push or negedge rst_push_n)
113 begin
114   if(~rst_push_n)
115     mem_waddr[ADDRWIDTH-1:0] <=0;
116   else
117     mem_waddr[ADDRWIDTH-1:0] <= mem_waddr[ADDRWIDTH-1:0] + 1'b1;
118 end
119 
120 //for output signal mem_raddr
121 always@(posedge clk_pop or negedge rest_pop_n)
122 begin
123   if(~rst_pop_n)
124     mem_raddr[ADDRWIDTH-1:0]<=0;
125   else
126     mem_raddr[ADDRWIDTH-1:0] <= mem_raddr[ADDRWIDTH-1:0] + 1'b1;
127 end
128 
129 //for output signal empty
130 assign gray_addr[ADDRWIDTH-1:0] = {mem_waddr[ADDRWIDTH-1],gray_waddr_temp[ADDRWIDTH-2:0]};
131 always@(* )
132   for(i=0;i<(ADDRWIDTH-1);i=i+1)
133     gray_waddr_temp[i] = mem_waddr[i]^mem_waddr[i+1];
134 
135 always@(posedge clk_push or negedge rst_push_n)
136 begin
137   if(~rst_push_n)
138     gray_waddr_1r[ADDRWIDTH-1:0] <=0 ;
139   else
140     gray_waddr_1r[ADDRWIDTH-1:0] <= gray_waddr[ADDRWIDTH-1:0];
141 end
142 
143 always@(posedge clk_pop or negedge rst_pop_n)
144 begin
145   if(~rst_pop_n) begin
146     gray_waddr_2r_1_sync[ADDRWIDTH-1:0] <=0;
147     gray_waddr_3r_2_sync[ADDRWIDTH-1:0] <=0;
148   end
149   else begin
150      gray_waddr_2r_1_sync[ADDRWIDTH-1:0] <= gray_waddr_1r[ADDRWIDTH-1:0];
151      gray_waddr_3r_2_sync[ADDRWIDTH-1:0] <= gray_waddr_2r_1_sync[ADDRWIDTH-1:0];
152   end
153 end
154 
155 always@(*)
156   biny_waddr[ADDRWIDTH-1] = gray_waddr_3r_2_sync[ADDRWIDTH-1];
157 
158 always@(*)
159   for(i=0;i<(ADDRWIDTH-1);i=i+1)
160     biny_waddr[ADDRWIDTH-2-i] = gray_waddr_3r_2_sync[ADDRWIDTH-2-i]^biny_waddr_temp[ADDRWIDTH-1-i];
161 
162 always@(*)
163   biny_waddr_temp[ADDRWIDTH-1:0] = biny_waddr[ADDRWIDTH-1:0];
164 
165 assign pop_one_left = (biny_waddr[ADDRWIDTH-1:0] ==(mem_raddr[ADDRWIDTH-1:0] + 1'b1));
166 assign pop_ptr_diff = (biny_waddr[ADDRWIDTH-1:0] != mem_raddr[ADDRWIDTH-1:0]);
167 
168 always@(posedge clk_pop or negedge rst_pop_n)
169 begin
170   if(~rst_pop_n)
171     empty_flag <=1'b1;
172   else if(pop_one_left && pop)
173     empty_flag <= 1'b1;
174   else if(empty_flag && pop_ptr_diff)
175     empty_flag <= 1'b0;
176 end
177 
178 assign empty = ~pop_ptr_diff && empty_flag;
179 
180 //for output signal full
181 assign gray_raddr[ADDRWIDTH-1:0] = {mem_raddr[ADDRWIDTH-1],gray_raddr_temp[ADDRWIDTH-2:0]};
182 
183 always@(*)
184   for(i=0;i<(ADDRWIDTH-1);i=i+1)
185     gray_raddr_temp[i] = mem_raddr[i] ^ mem_raddr[i+1];
186 
187 always@(posedge clk_pop or negedge rst_pop_n)
188 begin
189   if(~rst_pop_n)
190     gray_raddr_1r[ADDRWIDTH-1:0] <=0;
191   else
192     gray_raddr_1r[ADDRWIDTH-1:0] <= gray_raddr[ADDRWIDTH-1:0];
193 end
194 
195 always@(posedge clk_push or negedge rst_push_n)
196 begin
197   if(~rst_push_n)begin
198     gray_raddr_2r_1_sync[ADDRWIDTH-1:0]<=0;
199     gray_raddr_3r_2_sync[ADDRWIDTH-1:0]<=0;
200   end
201   else begin
202     gray_raddr_2r_1_sync[ADDRWIDTH-1:0] <= gray_raddr_1r[ADDRWIDTH-1:0]:
203     gray_raddr_3r_2_sync[ADDRWIDTH-1:0] <= gray_raddr_2r_sync[ADDRWIDTH-1:0];
204   end
205 end
206 
207 always@(*)
208   biny_raddr[ADDRWIDTH-1] = gray_raddr_3r_2_sync[ADDRWIDTH-1];
209 always@(*)
210    for(i=0;i<(ADDRWIDTH-1);i=i+1)
211      biny_raddr[ADDRWIDTH-2-i] = gray_raddr_3r_2_sync[ADDRWIDTH-2-i] ^biny_raddr_temp[ADDRWIDTH-1-i];
212 
213 always@(*)
214   biny_raddr_temp[ADDRWIDTH-1:0] = biny_raddr[ADDRWIDTH-1:0];
215 
216 assign push_one_left = (biny_raddr[ADDRWIDTH-1:0] ==(mem_waddr[ADDRWIDTH-1:0] + 1'b1));
217 assign push_ptr_diff = (biny_raddr[ADDRWIDTH-1:0] !=(mem_waddr[ADDRWIDTH-1:0]));
218 
219 always@(posedge clk_push or negedge rst_push_n)
220 begin
221   if(~rst_push_n)
222     full_flag <= 1'b0;
223   else if(push_one_left && push)
224     full_flag <= 1'b1;
225   else if(full_flag && push_ptr_diff)
226     full_flag <=1'b0
227 end
228 
229 assign full= ~push_ptr_diff && full_flag;
230 assign almost_full = push_one_left;
231 
232 
233 endmodule

 

posted @ 2016-02-01 22:17  CHIPER  阅读(277)  评论(0编辑  收藏  举报