asyn_fifo
2016-02-01 22:17
369 查看
//Module Name:afifo_ctrl //Description:parameterized afifo module afifo_ctrl( clk_push, rst_push_n, clk_pop, rst_pop_n, push, push_data, full, pop, pop_data, empty, mem_waddr, mem_wen, mem_wdata, mem_raddr, mem_ren, mem_rdata, almost_full ); parameter DATAWIDTH = 32; //the data width of AFIFO parameter ADDRWIDTH = 8; //the address bits of AFIFO and it must be >=2 //the AFIFO depth must be 2^ADDRWIDTH //input declaration input clk_push; //push clock input rst_push_n; //reset signal in push clock domain input clk_pop; //pop clock input rst_pop_n; //reset signal in pop clock domain input push ; //push enable to AFIFO input [DATAWIDTH-1:0] push_data; //push data to AFIFO input pop ; //pop enable to AFIFO input [DATAWIDTH-1:0] mem_rdata; //read data from memory stack //output declaration output full; //full indicator,and the logic of user can't push data when this signal is high //ok output [DATAWIDTH-1:0] pop_data ; //pop data from AFIFO //ok output empty; //empty indicator, and the logic of user can't pop data when this signal is high //ok output [ADDRWIDTH-1:0] mem_waddr; //write address to memory stack //ok output mem_wen; //write enable to memory stack //ok output [DATAWIDTH-1:0] mem_wdata; //write data to memory stack //ok output [ADDRWIDTH-1:0] mem_raddr; //read address to memory stack //ok output mem_ren; //read enable to memory stack //ok output almost_full; //register declaration reg [ADDRWIDTH-1:0] mem_waddr; reg [ADDRWIDTH-1:0] mem_raddr; reg [ADDRWIDTH-1:0] gray_waddr_1r; reg [ADDRWIDTH-1:0] gray_waddr_2r_1_sync; reg [ADDRWIDTH-1:0] gray_waddr_3r_2_sync; reg [ADDRWIDTH-1:0] gray_raddr_1r; reg [ADDRWIDTH-1:0] gray_raddr_2r_1_sync; reg [ADDRWIDTH-1:0] gray_raddr_3r_2_sync; reg [ADDRWIDTH-1:0] gray_waddr_temp; reg [ADDRWIDTH-1:0] gray_raddr_temp; reg [ADDRWIDTH-1:0] biny_waddr; reg [ADDRWIDTH-1:0] biny_raddr; reg [ADDRWIDTH-1:0] biny_waddr_temp; reg [ADDRWIDTH-1:0] biny_raddr_temp; reg [DATAWIDTH-1:0] pop_data_r; reg pop_r; reg empty_flag; reg full_flag; //net declaration wire mem_wen; wire mem_ren; wire [DATAWIDTH-1:0] mem_wdata; wire [DATAWIDTH-1:0] pop_data; wire [ADDRWIDTH-1:0] gray_waddr; wire [ADDRWIDTH-1:0] gray_raddr; wire pop_one_left; wire pop_ptr_diff; wire push_one_left; wire push_ptr_diff; integer i; assign mem_wen = push; assign mem_wdata[DATAWIDTH-1:0] = push_data[DATAWIDTH-1:0]; assign mem_ren = pop; //for output signal pop_data always@(posedge clk_pop or negedge rst_pop_n) begin if(~rst_pop_n) pop_r<=1'b0; else pop_r<=pop; end always@(posedge clk_pop or negedge rst_pop_n) begin if(~rst_pop_n) pop_data_r[DATAWIDTH-1:0] <= 0; else pop_data_r[DATAWIDTH-1:0] <= mem_rdata[DATAWIDTH-1:0]; end assign pop_data[DATAWIDTH-1:0] = pop_r ? mem_rdata[DATAWIDTH-1:0]:pop_data_r[DATAWIDTH-1:0]; //for output signal mem_waddr always@(posedge clk_push or negedge rst_push_n) begin if(~rst_push_n) mem_waddr[ADDRWIDTH-1:0] <=0; else mem_waddr[ADDRWIDTH-1:0] <= mem_waddr[ADDRWIDTH-1:0] + 1'b1; end //for output signal mem_raddr always@(posedge clk_pop or negedge rest_pop_n) begin if(~rst_pop_n) mem_raddr[ADDRWIDTH-1:0]<=0; else mem_raddr[ADDRWIDTH-1:0] <= mem_raddr[ADDRWIDTH-1:0] + 1'b1; end //for output signal empty assign gray_addr[ADDRWIDTH-1:0] = {mem_waddr[ADDRWIDTH-1],gray_waddr_temp[ADDRWIDTH-2:0]}; always@(* ) for(i=0;i<(ADDRWIDTH-1);i=i+1) gray_waddr_temp[i] = mem_waddr[i]^mem_waddr[i+1]; always@(posedge clk_push or negedge rst_push_n) begin if(~rst_push_n) gray_waddr_1r[ADDRWIDTH-1:0] <=0 ; else gray_waddr_1r[ADDRWIDTH-1:0] <= gray_waddr[ADDRWIDTH-1:0]; end always@(posedge clk_pop or negedge rst_pop_n) begin if(~rst_pop_n) begin gray_waddr_2r_1_sync[ADDRWIDTH-1:0] <=0; gray_waddr_3r_2_sync[ADDRWIDTH-1:0] <=0; end else begin gray_waddr_2r_1_sync[ADDRWIDTH-1:0] <= gray_waddr_1r[ADDRWIDTH-1:0]; gray_waddr_3r_2_sync[ADDRWIDTH-1:0] <= gray_waddr_2r_1_sync[ADDRWIDTH-1:0]; end end always@(*) biny_waddr[ADDRWIDTH-1] = gray_waddr_3r_2_sync[ADDRWIDTH-1]; always@(*) for(i=0;i<(ADDRWIDTH-1);i=i+1) biny_waddr[ADDRWIDTH-2-i] = gray_waddr_3r_2_sync[ADDRWIDTH-2-i]^biny_waddr_temp[ADDRWIDTH-1-i]; always@(*) biny_waddr_temp[ADDRWIDTH-1:0] = biny_waddr[ADDRWIDTH-1:0]; assign pop_one_left = (biny_waddr[ADDRWIDTH-1:0] ==(mem_raddr[ADDRWIDTH-1:0] + 1'b1)); assign pop_ptr_diff = (biny_waddr[ADDRWIDTH-1:0] != mem_raddr[ADDRWIDTH-1:0]); always@(posedge clk_pop or negedge rst_pop_n) begin if(~rst_pop_n) empty_flag <=1'b1; else if(pop_one_left && pop) empty_flag <= 1'b1; else if(empty_flag && pop_ptr_diff) empty_flag <= 1'b0; end assign empty = ~pop_ptr_diff && empty_flag; //for output signal full assign gray_raddr[ADDRWIDTH-1:0] = {mem_raddr[ADDRWIDTH-1],gray_raddr_temp[ADDRWIDTH-2:0]}; always@(*) for(i=0;i<(ADDRWIDTH-1);i=i+1) gray_raddr_temp[i] = mem_raddr[i] ^ mem_raddr[i+1]; always@(posedge clk_pop or negedge rst_pop_n) begin if(~rst_pop_n) gray_raddr_1r[ADDRWIDTH-1:0] <=0; else gray_raddr_1r[ADDRWIDTH-1:0] <= gray_raddr[ADDRWIDTH-1:0]; end always@(posedge clk_push or negedge rst_push_n) begin if(~rst_push_n)begin gray_raddr_2r_1_sync[ADDRWIDTH-1:0]<=0; gray_raddr_3r_2_sync[ADDRWIDTH-1:0]<=0; end else begin gray_raddr_2r_1_sync[ADDRWIDTH-1:0] <= gray_raddr_1r[ADDRWIDTH-1:0]: gray_raddr_3r_2_sync[ADDRWIDTH-1:0] <= gray_raddr_2r_sync[ADDRWIDTH-1:0]; end end always@(*) biny_raddr[ADDRWIDTH-1] = gray_raddr_3r_2_sync[ADDRWIDTH-1]; always@(*) for(i=0;i<(ADDRWIDTH-1);i=i+1) biny_raddr[ADDRWIDTH-2-i] = gray_raddr_3r_2_sync[ADDRWIDTH-2-i] ^biny_raddr_temp[ADDRWIDTH-1-i]; always@(*) biny_raddr_temp[ADDRWIDTH-1:0] = biny_raddr[ADDRWIDTH-1:0]; assign push_one_left = (biny_raddr[ADDRWIDTH-1:0] ==(mem_waddr[ADDRWIDTH-1:0] + 1'b1)); assign push_ptr_diff = (biny_raddr[ADDRWIDTH-1:0] !=(mem_waddr[ADDRWIDTH-1:0])); always@(posedge clk_push or negedge rst_push_n) begin if(~rst_push_n) full_flag <= 1'b0; else if(push_one_left && push) full_flag <= 1'b1; else if(full_flag && push_ptr_diff) full_flag <=1'b0 end assign full= ~push_ptr_diff && full_flag; assign almost_full = push_one_left; endmodule
相关文章推荐
- Your First Java Program
- JavaScript
- 一些集合面试题
- docker常用的命令
- MVC学习1
- m3u文件转pls文件(go语言实现)
- JAVA-事件处理
- 读书列表
- find的用法基础
- 默认软件
- Jquery自定义扩展方法(二)--HTML日历控件
- oracle system change number(SCN) 下 检查点
- win32 文件写入(包括追加到文件尾)WriteFile CreateFile
- QT5.5.0版本添加icon图标步骤
- QT5.5.0版本添加icon图标步骤
- 微软智能云布局高端服务,全面升级云计算竞争
- 使用grep搜索文件内容
- javascript实现端口扫描
- 源码分享-Qt利用动画类实现酷酷的图片展示
- 高精度计算练习2