可以先配合異步FIFO基礎(chǔ)知識食用
Part.1
第一塊Binary Logic:判斷二進(jìn)制Pointer什么時候+1,生成ptr_bin_next信號
assign wptr_bin_next = wptr_bin + (winc & (!wfull));
Part.2
第二塊Gray Logic:由Binary Pointer生成Gary Pointer,其實(shí)這里根據(jù)經(jīng)典AFIFO論文[1]里應(yīng)該是用新的wptr_bin_next生成wptr_gray_next,這樣wptr_bin和wptr_gray可以同步更新。(這里為了Pass??途W(wǎng)的測試案例,需要將wptr_bin_next改為 wptr_bin生成,這樣格雷碼指針會比二進(jìn)制指針慢一拍)
assign wptr_gray_next = wptr_bin_next ^ (wptr_bin_next >> 1);
新態(tài)邏輯寫完后賦值給Reg變量
{wptr_bin,wptr_gray} <= {wptr_bin_next, wptr_gray_next};
Part.3
第三塊Empty Logic:將wptr_gray在read時鐘域打2拍,做空判斷
assign rempty = ?rptr_gray == wptr_gray_rr2;
Part.4
第四塊Full Logic:將rptr_gray在write時鐘域打2拍,做滿判斷
assign wfull = wptr_gray == {~rptr_gray_wr2[ADDR_WIDTH:ADDR_WIDTH-1], rptr_gray_wr2[ADDR_WIDTH-2:0]};
Part.5
第五塊Full Logic:例化RAM,addr為ptr_bin次高位到最低位
最后添加一點(diǎn)點(diǎn)細(xì)節(jié),形成完整代碼
`timescale 1ns/1ns /***************************************RAM*****************************************/ module dual_port_RAM #(parameter DEPTH = 16, parameter WIDTH = 8)( input wclk ,input wenc ,input [$clog2(DEPTH)-1:0] waddr //深度對2取對數(shù),得到地址的位寬。 ,input [WIDTH-1:0] wdata //數(shù)據(jù)寫入 ,input rclk ,input renc ,input [$clog2(DEPTH)-1:0] raddr //深度對2取對數(shù),得到地址的位寬。 ,output reg [WIDTH-1:0] rdata //數(shù)據(jù)輸出 ); reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1]; always @(posedge wclk) begin if(wenc) RAM_MEM[waddr] <= wdata; end always @(posedge rclk) begin if(renc) rdata <= RAM_MEM[raddr]; end endmodule /***************************************AFIFO*****************************************/ module asyn_fifo#( parameter WIDTH = 8, parameter DEPTH = 16 )( input wclk , input rclk , input wrstn , input rrstn , input winc , input rinc , input [WIDTH-1:0] wdata , output wire wfull , output wire rempty , output wire [WIDTH-1:0] rdata ); parameter ADDR_WIDTH = $clog2(DEPTH); /***************************************Bin Logic*****************************************/ reg [ADDR_WIDTH:0] wptr_bin; reg [ADDR_WIDTH:0] rptr_bin; wire [ADDR_WIDTH:0] wptr_bin_next; wire [ADDR_WIDTH:0] rptr_bin_next; assign wptr_bin_next = wptr_bin + (winc & (!wfull)); assign rptr_bin_next = rptr_bin + (rinc & (!rempty)); /***************************************Gray Logic*****************************************/ reg [ADDR_WIDTH:0] wptr_gray; reg [ADDR_WIDTH:0] rptr_gray; wire [ADDR_WIDTH:0] wptr_gray_next; wire [ADDR_WIDTH:0] rptr_gray_next; assign wptr_gray_next = wptr_bin_next ^ (wptr_bin_next >> 1); assign rptr_gray_next = rptr_bin_next ^ (rptr_bin_next >> 1); always @ (posedge wclk or negedge wrstn) begin if (!wrstn) begin {wptr_bin,wptr_gray} <= 'd0; end else {wptr_bin,wptr_gray} <= {wptr_bin_next, wptr_gray_next}; end always @ (posedge rclk or negedge rrstn) begin if (!rrstn) begin {rptr_bin,rptr_gray} <= 'd0; end else {rptr_bin,rptr_gray} <= {rptr_bin_next, rptr_gray_next}; end /***************************************Full Logic*****************************************/ reg [ADDR_WIDTH:0] rptr_gray_wr,rptr_gray_wr2; always @ (posedge wclk or negedge wrstn) begin if (!wrstn) begin {rptr_gray_wr,rptr_gray_wr2} <= 'd0; end else {rptr_gray_wr2,rptr_gray_wr} <= {rptr_gray_wr,rptr_gray}; end assign wfull = wptr_gray == {~rptr_gray_wr2[ADDR_WIDTH:ADDR_WIDTH-1], rptr_gray_wr2[ADDR_WIDTH-2:0]}; /***************************************Empty Logic*****************************************/ reg [ADDR_WIDTH:0] wptr_gray_rr,wptr_gray_rr2; always @ (posedge rclk or negedge rrstn) begin if (!rrstn) begin {wptr_gray_rr2,wptr_gray_rr} <= 'd0; end else {wptr_gray_rr2,wptr_gray_rr} <= {wptr_gray_rr,wptr_gray}; end assign rempty = rptr_gray == wptr_gray_rr2; /***************************************Dual RAM*****************************************/ wire wenc, renc; wire [ADDR_WIDTH-1:0] raddr, waddr; assign wenc = winc & !wfull; assign renc = rinc & !rempty; assign raddr = rptr_bin[ADDR_WIDTH-1:0]; assign waddr = wptr_bin[ADDR_WIDTH-1:0]; dual_port_RAM #(.DEPTH(DEPTH), .WIDTH(WIDTH)) u_dual_port_RAM ( .wclk(wclk), .rclk(rclk), .wenc(wenc), .renc(renc), .raddr(raddr), .waddr(waddr), .wdata(wdata), .rdata(rdata) ); /***************************************AFIFO*****************************************/ endmodule
編輯:黃飛
評論
查看更多