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
狠芯低成本,专芯低功耗,计划高性能。