欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳解同步FIFO和異步FIFO?

FPGA之家 ? 來源:FPGA之家 ? 作者:FPGA之家 ? 2021-04-09 17:31 ? 次閱讀

1.定義

FIFO是英文First In First Out 的縮寫,是一種先進(jìn)先出的數(shù)據(jù)緩存器,他與普通存儲(chǔ)器的區(qū)別是沒有外部讀寫地址線,這樣使用起來非常簡(jiǎn)單,但缺點(diǎn)就是只能順序?qū)懭霐?shù)據(jù),順序的讀出數(shù)據(jù), 其數(shù)據(jù)地址由內(nèi)部讀寫指針自動(dòng)加1完成,不能像普通存儲(chǔ)器那樣可以由地址線決定讀取或?qū)懭肽硞€(gè)指定的地址。

FIFO一般用于不同時(shí)鐘域之間的數(shù)據(jù)傳輸,比如FIFO的一端是AD數(shù)據(jù)采集, 另一端是計(jì)算機(jī)的PCI總線,假設(shè)其AD采集的速率為16位 100K SPS,那么每秒的數(shù)據(jù)量為100K×16bit=1.6Mbps,而PCI總線的速度為33MHz,總線寬度32bit,其最大傳輸速率為 1056Mbps,在兩個(gè)不同的時(shí)鐘域間就可以采用FIFO來作為數(shù)據(jù)緩沖。另外對(duì)于不同寬度的數(shù)據(jù)接口也可以用FIFO,例如單片機(jī)位8位數(shù)據(jù)輸出,而 DSP可能是16位數(shù)據(jù)輸入,在單片機(jī)與DSP連接時(shí)就可以使用FIFO來達(dá)到數(shù)據(jù)匹配的目的。

FIFO的分類根均FIFO工作的時(shí)鐘域,可以將FIFO分為同步FIFO和異步FIFO。同步FIFO是指讀時(shí)鐘和寫時(shí)鐘為同一個(gè)時(shí)鐘。在時(shí)鐘沿來臨時(shí)同時(shí)發(fā)生讀寫操作。異步FIFO是指讀寫時(shí)鐘不一致,讀寫時(shí)鐘是互相獨(dú)立的。

FIFO設(shè)計(jì)的難點(diǎn) FIFO設(shè)計(jì)的難點(diǎn)在于怎樣判斷FIFO的空/滿狀態(tài)。為了保證數(shù)據(jù)正確的寫入或讀出,而不發(fā)生益處或讀空的狀態(tài)出現(xiàn),必須保證FIFO在滿的情況下,不 能進(jìn)行寫操作。在空的狀態(tài)下不能進(jìn)行讀操作。怎樣判斷FIFO的滿/空就成了FIFO設(shè)計(jì)的核心問題。

1.同步FIFO之Verilog實(shí)現(xiàn)

同步FIFO的意思是說FIFO的讀寫時(shí)鐘是同一個(gè)時(shí)鐘,不同于異步FIFO,異步FIFO的讀寫時(shí)鐘是完全異步的。同步FIFO的對(duì)外接口包括時(shí)鐘,清零,讀請(qǐng)求,寫請(qǐng)求,數(shù)據(jù)輸入總線,數(shù)據(jù)輸出總線,空以及滿信號(hào)。下面分別對(duì)同步FIFO的對(duì)外接口信號(hào)作一描述:

1. 時(shí)鐘,輸入,用于同步FIFO的讀和寫,上升沿有效;

2. 清零,輸入,異步清零信號(hào),低電平有效,該信號(hào)有效時(shí),F(xiàn)IFO被清空;

3. 寫請(qǐng)求,輸入,低電平有效,該信號(hào)有效時(shí),表明外部電路請(qǐng)求向FIFO寫入數(shù)據(jù);

4. 讀請(qǐng)求,輸入,低電平有效,該信號(hào)有效時(shí),表明外部電路請(qǐng)求從FIFO中讀取數(shù)據(jù);

5. 數(shù)據(jù)輸入總線,輸入,當(dāng)寫信號(hào)有效時(shí),數(shù)據(jù)輸入總線上的數(shù)據(jù)被寫入到FIFO中;

6. 數(shù)據(jù)輸出總線,輸出,當(dāng)讀信號(hào)有效時(shí),數(shù)據(jù)從FIFO中被讀出并放到數(shù)據(jù)輸出總線上;

7. 空,輸出,高電平有效,當(dāng)該信號(hào)有效時(shí),表明FIFO中沒有任何數(shù)據(jù),全部為空;

8. 滿,輸出,高電平有效,當(dāng)該信號(hào)有效時(shí),表明FIFO已經(jīng)滿了,沒有空間可用來存貯數(shù)據(jù)。

下面的框圖主要描述同步FIFO的內(nèi)部結(jié)構(gòu),畫出框圖有助于對(duì)電路結(jié)構(gòu)的理解,同樣也有助于RTL代碼的編寫 :

8389ba5c-990f-11eb-8b86-12bb97331649.jpg

同步FIFO的Verilog代碼 之一

在modlesim中驗(yàn)證過。


/******************************************************

A fifo controller verilog description.

******************************************************/

module fifo(datain, rd, wr, rst, clk, dataout, full, empty);

input [7:0] datain;

input rd, wr, rst, clk;

output [7:0] dataout;

output full, empty;

wire [7:0] dataout;

reg full_in, empty_in;

reg [7:0] mem [15:0];

reg [3:0] rp, wp;

assign full = full_in;

assign empty = empty_in;

// memory read out

assign dataout = mem[rp];

// memory write in

always@(posedge clk) begin

if(wr && ~full_in) mem[wp]《=datain;

end

// memory write pointer increment

always@(posedge clk or negedge rst) begin

if(!rst) wp《=0;

else begin

if(wr && ~full_in) wp《= wp+1‘b1;

end

end

// memory read pointer increment

always@(posedge clk or negedge rst)begin

if(!rst) rp 《= 0;

else begin

if(rd && ~empty_in) rp 《= rp + 1’b1;

end

end

// Full signal generate

always@(posedge clk or negedge rst) begin

if(!rst) full_in 《= 1‘b0;

else begin

if( (~rd && wr)&&((wp==rp-1)||(rp==4’h0&&wp==4‘hf)))

full_in 《= 1’b1;

else if(full_in && rd) full_in 《= 1‘b0;

end

end

// Empty signal generate

always@(posedge clk or negedge rst) begin

if(!rst) empty_in 《= 1’b1;

else begin

if((rd&&~wr)&&(rp==wp-1 || (rp==4‘hf&&wp==4’h0)))

empty_in《=1‘b1;

else if(empty_in && wr) empty_in《=1’b0;

end

end

endmodule

…………………………………………………………………………………………………………………………………………………………………………………………。。

同步FIFO的Verilog代碼 之二 這一種設(shè)計(jì)的FIFO,是基于觸發(fā)器的。寬度,深度的擴(kuò)展更加方便,結(jié)構(gòu)化跟強(qiáng)。以下代碼在modelsim中驗(yàn)證過。

module fifo_cell (sys_clk, sys_rst_n, read_fifo, write_fifo, fifo_input_data,

next_cell_data, next_cell_full, last_cell_full, cell_data_out, cell_full);

parameter WIDTH =8;

parameter D = 2;

input sys_clk;

input sys_rst_n;

input read_fifo, write_fifo;

input [WIDTH-1:0] fifo_input_data;

input [WIDTH-1:0] next_cell_data;

input next_cell_full, last_cell_full;

output [WIDTH-1:0] cell_data_out;

output cell_full;

reg [WIDTH-1:0] cell_data_reg_array;

reg [WIDTH-1:0] cell_data_ld;

reg cell_data_ld_en;

reg cell_full;

reg cell_full_next;

assign cell_data_out=cell_data_reg_array;

always @(posedge sys_clk or negedge sys_rst_n)

if (!sys_rst_n)

cell_full 《= #D 0;

else if (read_fifo || write_fifo)

cell_full 《= #D cell_full_next;

always @(write_fifo or read_fifo or next_cell_full or last_cell_full or cell_full)

casex ({read_fifo, write_fifo})

2‘b00: cell_full_next = cell_full;

2’b01: cell_full_next = next_cell_full;

2‘b10: cell_full_next = last_cell_full;

2’b11: cell_full_next = cell_full;

endcase

always @(posedge sys_clk or negedge sys_rst_n)

if (!sys_rst_n)

cell_data_reg_array [WIDTH-1:0] 《= #D 0;

else if (cell_data_ld_en)

cell_data_reg_array [WIDTH-1:0] 《= #D cell_data_ld [WIDTH-1:0];

always @(write_fifo or read_fifo or cell_full or last_cell_full)

casex ({write_fifo,read_fifo,cell_full,last_cell_full})

4‘bx1_xx: cell_data_ld_en = 1’b1;

4‘b10_01: cell_data_ld_en = 1’b1;

default: cell_data_ld_en =1‘b0;

endcase

always @(write_fifo or read_fifo or next_cell_full or cell_full or last_cell_full or fifo_input_data or next_cell_data)

casex ({write_fifo, read_fifo, next_cell_full, cell_full, last_cell_full})

5’b10_x01: cell_data_ld[WIDTH-1:0] = fifo_input_data[WIDTH-1:0];

5‘b11_01x: cell_data_ld[WIDTH-1:0] = fifo_input_data[WIDTH-1:0];

default: cell_data_ld[WIDTH-1:0] = next_cell_data[WIDTH-1:0];

endcase

endmodule

module fifo_4cell(sys_clk, sys_rst_n, fifo_input_data, write_fifo, fifo_out_data,

read_fifo, full_cell0, full_cell1, full_cell2, full_cell3);

parameter WIDTH = 8;

parameter D = 2;

input sys_clk;

input sys_rst_n;

input [WIDTH-1:0] fifo_input_data;

output [WIDTH-1:0] fifo_out_data;

input read_fifo, write_fifo;

output full_cell0, full_cell1, full_cell2, full_cell3;

wire [WIDTH-1:0] dara_out_cell0, data_out_cell1, data_out_cell2,

data_out_cell3, data_out_cell4;

wire full_cell4;

fifo_cell #(WIDTH,D) cell0

( .sys_clk (sys_clk),

.sys_rst_n (sys_rst_n),

.fifo_input_data (fifo_input_data[WIDTH-1:0]),

.write_fifo (write_fifo),

.next_cell_data (data_out_cell1[WIDTH-1:0]),

.next_cell_full (full_cell1),

.last_cell_full (1’b1),

.cell_data_out (fifo_out_data [WIDTH-1:0]),

.read_fifo (read_fifo),

.cell_full (full_cell0)

);

fifo_cell #(WIDTH,D) cell1

( .sys_clk (sys_clk),

.sys_rst_n (sys_rst_n),

.fifo_input_data (fifo_input_data[WIDTH-1:0]),

.write_fifo (write_fifo),

.next_cell_data (data_out_cell2[WIDTH-1:0]),

.next_cell_full (full_cell2),

.last_cell_full (full_cell0),

.cell_data_out (data_out_cell1[WIDTH-1:0]),

.read_fifo (read_fifo),

.cell_full (full_cell1)

);

fifo_cell #(WIDTH,D) cell2

( .sys_clk (sys_clk),

.sys_rst_n (sys_rst_n),

.fifo_input_data (fifo_input_data[WIDTH-1:0]),

.write_fifo (write_fifo),

.next_cell_data (data_out_cell3[WIDTH-1:0]),

.next_cell_full (full_cell3),

.last_cell_full (full_cell1),

.cell_data_out (data_out_cell2[WIDTH-1:0]),

.read_fifo (read_fifo),

.cell_full (full_cell2)

);

fifo_cell #(WIDTH,D) cell3

( .sys_clk (sys_clk),

.sys_rst_n (sys_rst_n),

.fifo_input_data (fifo_input_data[WIDTH-1:0]),

.write_fifo (write_fifo),

.next_cell_data (data_out_cell4[WIDTH-1:0]),

.next_cell_full (full_cell4),

.last_cell_full (full_cell2),

.cell_data_out (data_out_cell3[WIDTH-1:0]),

.read_fifo (read_fifo),

.cell_full (full_cell3)

);

assign data_out_cell4[WIDTH-1:0] = {WIDTH{1‘B0}};

assign full_cell4 = 1’b0;

endmodule

2.異步FIFO之Verilog實(shí)現(xiàn)

FIFO (先進(jìn)先出隊(duì)列)是一種在電子系統(tǒng)得到廣泛應(yīng)用的器件,通常用于數(shù)據(jù)的緩存和用于容納異步信號(hào)的頻率或相位的差異。FIFO的實(shí)現(xiàn)通常是利用雙口RAM和讀寫地址產(chǎn)生模塊來實(shí)現(xiàn)的。FIFO的接口信號(hào)包括異步的寫時(shí)鐘(wr_clk)和讀時(shí)鐘(rd_clk)、與寫時(shí)鐘同步的寫有效(wren)和寫數(shù)據(jù)(wr_data)、與讀時(shí)鐘同步的讀有效(rden)和讀數(shù)據(jù)(rd_data)。為了實(shí)現(xiàn)正確的讀寫和避免FIFO的上溢或下溢,通常還應(yīng)該給出與讀時(shí)鐘和寫時(shí)鐘同步的FIFO的空標(biāo)志(empty)和滿標(biāo)志(full)以禁止讀寫操作。

1 異步FIFO功能描述

圖1給出了FIFO的接口信號(hào)和內(nèi)部模塊圖。

由圖1可以看出,寫地址產(chǎn)生模塊根據(jù)寫時(shí)鐘和寫有效信號(hào)產(chǎn)生遞增的寫地睛,讀地址產(chǎn)生模塊根據(jù)讀時(shí)鐘和讀有效信號(hào)產(chǎn)生遞增的讀地址。FIFO的操作如下:在寫時(shí)鐘wr_clk的升沿,當(dāng)wren有效時(shí),將wr_data寫入雙口RAM中寫地址對(duì)應(yīng)的位置中;始終將讀地址對(duì)應(yīng)的雙口RAM中的數(shù)據(jù)輸出到讀數(shù)據(jù)總線上。這樣就實(shí)現(xiàn)了先進(jìn)先出的功能。

寫地址產(chǎn)生模塊還根據(jù)讀地址和寫地址關(guān)系產(chǎn)生FIFO的滿標(biāo)志。當(dāng)wren有效時(shí),若寫地址+2=讀地址時(shí),full為1;當(dāng)wren無效時(shí),若寫地址+ 1=讀地址時(shí),full為1。讀地址產(chǎn)生模塊還根據(jù)讀地址和寫地址的差產(chǎn)生FIFO的空標(biāo)志。當(dāng)rden有效時(shí),若寫地址-1=讀地址時(shí),empty為 1;當(dāng)rden無效時(shí),若寫地址=讀地址時(shí),empty為1。按照以上方式產(chǎn)生標(biāo)志信號(hào)是為了提前一個(gè)時(shí)鐘周期產(chǎn)生對(duì)應(yīng)的標(biāo)志信號(hào)。

由于空標(biāo)志和滿標(biāo)志控制了FIFO的操作,因此標(biāo)志錯(cuò)誤會(huì)引起操作的錯(cuò)誤。如上所述,標(biāo)志的產(chǎn)生是通過對(duì)讀寫地址的比較產(chǎn)生的,當(dāng)讀寫時(shí)鐘完全異步時(shí),對(duì)讀寫地址進(jìn)行比較時(shí),可能得出錯(cuò)誤的結(jié)果。例如,在讀地址變化過程中,由于讀地址的各位變化并不同步,計(jì)算讀寫地址的差值,可能產(chǎn)生錯(cuò)誤的差值,導(dǎo)致產(chǎn)生錯(cuò)誤的滿標(biāo)志信號(hào)。若將未滿標(biāo)志置為滿標(biāo)志時(shí),可能降低了應(yīng)用的性能,降低寫數(shù)據(jù)速率;而將滿置標(biāo)志置為未滿時(shí),執(zhí)行一次寫操作,則可能產(chǎn)生溢出錯(cuò)誤,這對(duì)于實(shí)際應(yīng)用來說是絕對(duì)應(yīng)該避免的??諛?biāo)志信號(hào)的產(chǎn)生也可能產(chǎn)生類似的錯(cuò)誤。

2 異步FIFO的改進(jìn)設(shè)計(jì)

從以上分析中可以看出,異步FIFO之所以會(huì)發(fā)生錯(cuò)誤是國(guó)為在地址變化時(shí),由于多位地址各位變化時(shí)間不同,異步時(shí)鐘對(duì)其進(jìn)行采樣時(shí)數(shù)值可能為不同于地址變化喪后數(shù)值的其他值,異步產(chǎn)生錯(cuò)誤的空標(biāo)志和滿標(biāo)志,以致于產(chǎn)生FIFO的操作錯(cuò)誤。

格雷碼是一種在相鄰計(jì)數(shù)值之間只有一位發(fā)生變化的編碼方式??梢钥闯?,若讀寫地址采用格雷碼編碼方式,就可以解決上面的問題。

為了應(yīng)用的靈活,還增加了兩個(gè)標(biāo)志信號(hào),將滿(almosf_full)標(biāo)志和空(almost_empty)標(biāo)志分別定義如下:當(dāng)寫地址與讀地址的距離小于某個(gè)預(yù)先定義數(shù)值時(shí),almost_full為1;當(dāng)讀地址與寫地址的距離小于這個(gè)預(yù)先定義的數(shù)值時(shí),almost_empty為1。

3 異步FIFO的Verilog

……………………………………………………………………………………………………………………………………………………………………………………………………………………………。

異步FIFO的Verilog代碼 之一

這個(gè)是基于RAM的異步FIFO代碼,個(gè)人認(rèn)為代碼結(jié)構(gòu)簡(jiǎn)單易懂,非常適合于考試中填寫。記得10月份參加威盛的筆試的時(shí)候,就考過異步FIFO的實(shí)現(xiàn)。想當(dāng)初要是早點(diǎn)復(fù)習(xí),可能就可以通過威盛的筆試了。

與之前的用RAM實(shí)現(xiàn)的同步FIFO的程序相比,異步更為復(fù)雜。增加了讀寫控制信號(hào)的跨時(shí)鐘域的同步。此外,判空與判滿的也稍有不同。

module fifo1(rdata, wfull, rempty, wdata, winc, wclk, wrst_n,rinc, rclk, rrst_n);

parameter DSIZE = 8; parameter ASIZE = 4;

output [DSIZE-1:0] rdata;

output wfull;

output rempty;

input [DSIZE-1:0] wdata;

input winc, wclk, wrst_n;

input rinc, rclk, rrst_n;

reg wfull,rempty;

reg [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr, wq1_rptr,rq1_wptr;

reg [ASIZE:0] rbin, wbin;

reg [DSIZE-1:0] mem[0:(1《《ASIZE)-1];

wire [ASIZE-1:0] waddr, raddr;

wire [ASIZE:0] rgraynext, rbinnext,wgraynext,wbinnext;

wire rempty_val,wfull_val;

//-----------------雙口RAM存儲(chǔ)器--------------------

assign rdata=mem[raddr];

always@(posedge wclk)

if (winc && !wfull) mem[waddr] 《= wdata;

//-------------同步rptr 指針-------------------------

always @(posedge wclk or negedge wrst_n)

if (!wrst_n) {wq2_rptr,wq1_rptr} 《= 0;

else {wq2_rptr,wq1_rptr} 《= {wq1_rptr,rptr};

//-------------同步wptr指針---------------------------

always @(posedge rclk or negedge rrst_n)

if (!rrst_n) {rq2_wptr,rq1_wptr} 《= 0;

else {rq2_wptr,rq1_wptr} 《= {rq1_wptr,wptr};

//-------------rempty產(chǎn)生與raddr產(chǎn)生-------------------

always @(posedge rclk or negedge rrst_n) // GRAYSTYLE2 pointer

begin

if (!rrst_n) {rbin, rptr} 《= 0;

else {rbin, rptr} 《= {rbinnext, rgraynext};

end

// Memory read-address pointer (okay to use binary to address memory)

assign raddr = rbin[ASIZE-1:0];

assign rbinnext = rbin + (rinc & ~rempty);

assign rgraynext = (rbinnext》》1) ^ rbinnext;

// FIFO empty when the next rptr == synchronized wptr or on reset

assign rempty_val = (rgraynext == rq2_wptr);

always @(posedge rclk or negedge rrst_n)

begin

if (!rrst_n) rempty 《= 1‘b1;

else rempty 《= rempty_val;

end

//---------------wfull產(chǎn)生與waddr產(chǎn)生------------------------------

always @(posedge wclk or negedge wrst_n) // GRAYSTYLE2 pointer

if (!wrst_n) {wbin, wptr} 《= 0;

else {wbin, wptr} 《= {wbinnext, wgraynext};

// Memory write-address pointer (okay to use binary to address memory)

assign waddr = wbin[ASIZE-1:0];

assign wbinnext = wbin + (winc & ~wfull);

assign wgraynext = (wbinnext》》1) ^ wbinnext;

assign wfull_val = (wgraynext=={~wq2_rptr[ASIZE:ASIZE-1], wq2_rptr[ASIZE-2:0]}); //:ASIZE-1]

always @(posedge wclk or negedge wrst_n)

if (!wrst_n) wfull 《= 1’b0;

else wfull 《= wfull_val;

endmodule

………………………………………………………………………………………………………………………………………………………………

異步FIFO的Verilog代碼 之二

與前一段異步FIFO代碼的主要區(qū)別在于,空/滿狀態(tài)標(biāo)志的不同算法

第一個(gè)算法:Clifford E. Cummings的文章中提到的STYLE #1,構(gòu)造一個(gè)指針寬度為N+1,深度為2^N字節(jié)的FIFO(為便方比較將格雷碼指針轉(zhuǎn)換為二進(jìn)制指針)。當(dāng)指針的二進(jìn)制碼中最高位不一致而其它N位都 相等時(shí),F(xiàn)IFO為滿(在Clifford E. Cummings的文章中以格雷碼表示是前兩位均不相同,而后兩位LSB相同為滿,這與換成二進(jìn)制表示的MSB不同其他相同為滿是一樣的)。當(dāng)指針完全相 等時(shí),F(xiàn)IFO為空。

這種方法思路非常明了,為了比較不同時(shí)鐘產(chǎn)生的指針,需要把不同時(shí)鐘域的信號(hào)同步到本時(shí)鐘域中來,而使用Gray碼的目的就是使這個(gè)異步同步化的過 程發(fā)生亞穩(wěn)態(tài)的機(jī)率最小,而為什么要構(gòu)造一個(gè)N+1的指針,Clifford E. Cummings也闡述的很明白,有興趣的讀者可以看下作者原文是怎么論述的,Clifford E. Cummings的這篇文章有Rev1.1 Rev1.2兩個(gè)版本,兩者在比較Gray碼指針時(shí)的方法略有不同,個(gè)Rev1.2版更為精簡(jiǎn)。

第二種算法:Clifford E. Cummings的文章中提到的STYLE #2。它將FIFO地址分成了4部分,每部分分別用高兩位的MSB 00 、01、 11、 10決定FIFO是否為going full 或going empty (即將滿或空)。如果寫指針的高兩位MSB小于讀指針的高兩位MSB則FIFO為“幾乎滿”,若寫指針的高兩位MSB大于讀指針的高兩位MSB則FIFO 為“幾乎空”。

它是利用將地址空間分成4個(gè)象限(也就是四個(gè)等大小的區(qū)域),然后觀察兩個(gè)指針的相對(duì)位置,如果寫指針落后讀指針一個(gè)象限(25%的距離,呵呵), 則證明很可能要寫滿,反之則很可能要讀空,這個(gè)時(shí)候分別設(shè)置兩個(gè)標(biāo)志位dirset和dirrst,然后在地址完全相等的情況下,如果dirset有效就 是寫滿,如果dirrst有效就是讀空。

這種方法對(duì)深度為2^N字節(jié)的FIFO只需N位的指針即可,處理的速度也較第一種方法快。

這段是說明的原話,算法一,還好理解。算法二,似乎沒有說清楚,不太明白。有興趣的可以查查論文,詳細(xì)研究下。

總之,第二種寫法是推薦的寫法。因?yàn)楫惒降亩鄷r(shí)鐘設(shè)計(jì)應(yīng)按以下幾個(gè)原則進(jìn)行設(shè)計(jì):

1,盡可能的將多時(shí)鐘的邏輯電路(非同步器)分割為多個(gè)單時(shí)鐘的模塊,這樣有利于靜態(tài)時(shí)序分析工具來進(jìn)行時(shí)序驗(yàn)證。

2,同步器的實(shí)現(xiàn)應(yīng)使得所有輸入來自同一個(gè)時(shí)鐘域,而使用另一個(gè)時(shí)鐘域的異步時(shí)鐘信號(hào)采樣數(shù)據(jù)。

3,面向時(shí)鐘信號(hào)的命名方式可以幫助我們確定那些在不同異步時(shí)鐘域間需要處理的信號(hào)。

4,當(dāng)存在多個(gè)跨時(shí)鐘域的控制信號(hào)時(shí),我們必須特別注意這些信號(hào),保證這些控制信號(hào)到達(dá)新的時(shí)鐘域仍然能夠保持正確的順序。

module fifo2 (rdata, wfull, rempty, wdata,

winc, wclk, wrst_n, rinc, rclk, rrst_n);

parameter DSIZE = 8;

parameter ASIZE = 4;

output [DSIZE-1:0] rdata;

output wfull;

output rempty;

input [DSIZE-1:0] wdata;

input winc, wclk, wrst_n;

input rinc, rclk, rrst_n;

wire [ASIZE-1:0] wptr, rptr;

wire [ASIZE-1:0] waddr, raddr;

async_cmp #(ASIZE) async_cmp(.aempty_n(aempty_n),

.afull_n(afull_n),

.wptr(wptr), .rptr(rptr),

.wrst_n(wrst_n));

fifomem2 #(DSIZE, ASIZE) fifomem2(.rdata(rdata),

.wdata(wdata),

.waddr(wptr),

.raddr(rptr),

.wclken(winc),

.wclk(wclk));

rptr_empty2 #(ASIZE) rptr_empty2(.rempty(rempty),

.rptr(rptr),

.aempty_n(aempty_n),

.rinc(rinc),

.rclk(rclk),

.rrst_n(rrst_n));

wptr_full2 #(ASIZE) wptr_full2(.wfull(wfull),

.wptr(wptr),

.afull_n(afull_n),

.winc(winc),

.wclk(wclk),

.wrst_n(wrst_n));

endmodule

module fifomem2 (rdata, wdata, waddr, raddr, wclken, wclk);

parameter DATASIZE = 8; // Memory data word width

parameter ADDRSIZE = 4; // Number of memory address bits

parameter DEPTH = 1《《ADDRSIZE; // DEPTH = 2**ADDRSIZE

output [DATASIZE-1:0] rdata;

input [DATASIZE-1:0] wdata;

input [ADDRSIZE-1:0] waddr, raddr;

input wclken, wclk;

`ifdef VENDORRAM

// instantiation of a vendor‘s dual-port RAM

VENDOR_RAM MEM (.dout(rdata), .din(wdata),

.waddr(waddr), .raddr(raddr),

.wclken(wclken), .clk(wclk));

`else

reg [DATASIZE-1:0] MEM [0:DEPTH-1];

assign rdata = MEM[raddr];

always @(posedge wclk)

if (wclken) MEM[waddr] 《= wdata;

`endif

endmodule

module async_cmp (aempty_n, afull_n, wptr, rptr, wrst_n);

parameter ADDRSIZE = 4;

parameter N = ADDRSIZE-1;

output aempty_n, afull_n;

input [N:0] wptr, rptr;

input wrst_n;

reg direction;

wire high = 1’b1;

wire dirset_n = ~( (wptr[N]^rptr[N-1]) & ~(wptr[N-1]^rptr[N]));

wire dirclr_n = ~((~(wptr[N]^rptr[N-1]) & (wptr[N-1]^rptr[N])) |

~wrst_n);

always @(posedge high or negedge dirset_n or negedge dirclr_n)

if (!dirclr_n) direction 《= 1‘b0;

else if (!dirset_n) direction 《= 1’b1;

else direction 《= high;

//always @(negedge dirset_n or negedge dirclr_n)

//if (!dirclr_n) direction 《= 1‘b0;

//else direction 《= 1’b1;

assign aempty_n = ~((wptr == rptr) && !direction);

assign afull_n = ~((wptr == rptr) && direction);

endmodule

module rptr_empty2 (rempty, rptr, aempty_n, rinc, rclk, rrst_n);

parameter ADDRSIZE = 4;

output rempty;

output [ADDRSIZE-1:0] rptr;

input aempty_n;

input rinc, rclk, rrst_n;

reg [ADDRSIZE-1:0] rptr, rbin;

reg rempty, rempty2;

wire [ADDRSIZE-1:0] rgnext, rbnext;

//---------------------------------------------------------------

// GRAYSTYLE2 pointer

//---------------------------------------------------------------

always @(posedge rclk or negedge rrst_n)

if (!rrst_n) begin

rbin 《= 0;

rptr 《= 0;

end

else begin

rbin 《= rbnext;

rptr 《= rgnext;

end

//---------------------------------------------------------------

// increment the binary count if not empty

//---------------------------------------------------------------

assign rbnext = !rempty ? rbin + rinc : rbin;

assign rgnext = (rbnext》》1) ^ rbnext; // binary-to-gray conversion

always @(posedge rclk or negedge aempty_n)

if (!aempty_n) {rempty,rempty2} 《= 2‘b11;

else {rempty,rempty2} 《= {rempty2,~aempty_n};

endmodule

module wptr_full2 (wfull, wptr, afull_n, winc, wclk, wrst_n);

parameter ADDRSIZE = 4;

output wfull;

output [ADDRSIZE-1:0] wptr;

input afull_n;

input winc, wclk, wrst_n;

reg [ADDRSIZE-1:0] wptr, wbin;

reg wfull, wfull2;

wire [ADDRSIZE-1:0] wgnext, wbnext;

//---------------------------------------------------------------

// GRAYSTYLE2 pointer

//---------------------------------------------------------------

always @(posedge wclk or negedge wrst_n)

if (!wrst_n) begin

wbin 《= 0;

wptr 《= 0;

end

else begin

wbin 《= wbnext;

wptr 《= wgnext;

end

//---------------------------------------------------------------

// increment the binary count if not full

//---------------------------------------------------------------

assign wbnext = !wfull ? wbin + winc : wbin;

assign wgnext = (wbnext》》1) ^ wbnext; // binary-to-gray conversion

always @(posedge wclk or negedge wrst_n or negedge afull_n)

if (!wrst_n ) {wfull,wfull2} 《= 2’b00;

else if (!afull_n) {wfull,wfull2} 《= 2‘b11;

else {wfull,wfull2} 《= {wfull2,~afull_n};

endmodule

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • fifo
    +關(guān)注

    關(guān)注

    3

    文章

    390

    瀏覽量

    43882
  • 異步FIFO
    +關(guān)注

    關(guān)注

    0

    文章

    20

    瀏覽量

    8412
  • 同步FIFO
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    5384
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用SCL編寫FIFO功能塊

    一、 導(dǎo)讀? ? 前幾天一位搞電氣的朋友問S7-1200中如何做個(gè)先入先出的功能,說原來用S7-200SMART的時(shí)候有填表指令和FIFO指令可以實(shí)現(xiàn)該功能,現(xiàn)在S7-1200中找了一圈都沒有
    的頭像 發(fā)表于 02-09 10:27 ?75次閱讀
    使用SCL編寫<b class='flag-5'>FIFO</b>功能塊

    FIFO IP核的使用教程

    在數(shù)字設(shè)計(jì)中,利用FIFO進(jìn)行數(shù)據(jù)處理是非常普遍的應(yīng)用,例如,實(shí)現(xiàn)時(shí)鐘域交叉、低延時(shí)存儲(chǔ)器緩存、總線位寬調(diào)整等。下圖給出了FIFO生成器支持的一種可能配置。
    的頭像 發(fā)表于 01-03 09:36 ?1720次閱讀
    <b class='flag-5'>FIFO</b> IP核的使用教程

    DAC3482內(nèi)部的FIFO作用是什么?

    我現(xiàn)在正在使用DAC3482芯片,想請(qǐng)教一下其內(nèi)部的FIFO作用是什么? FIFO讀寫指針分別由DATACLK和DACCLK(或其分頻)來驅(qū)動(dòng),用于“緩沖”的作用,我有兩種理解: 1.只能緩沖讀寫
    發(fā)表于 12-23 07:06

    使用DAC3482 fifo同步失敗的原因?怎么處理?

    進(jìn)行數(shù)據(jù)采樣,所以設(shè)置為DATACLK的2倍)、240M(DATACLK,輸出到3482芯片)、10M(SCLK,配置3482寄存器的串口驅(qū)動(dòng)時(shí)鐘,輸出到3482)這3個(gè)時(shí)鐘。 FIFO使用雙同步
    發(fā)表于 12-23 06:02

    FIFO Generator的Xilinx官方手冊(cè)

    FIFO作為FPGA崗位求職過程中最常被問到的基礎(chǔ)知識(shí)點(diǎn),也是項(xiàng)目中最常被使用到的IP,其意義是非常重要的。本文基于對(duì)FIFO Generator的Xilinx官方手冊(cè)的閱讀與總結(jié),匯總主要知識(shí)點(diǎn)
    的頭像 發(fā)表于 11-12 10:46 ?737次閱讀
    <b class='flag-5'>FIFO</b> Generator的Xilinx官方手冊(cè)

    FIFO的深度應(yīng)該怎么計(jì)算

    FIFO是FPGA/IC設(shè)計(jì)中經(jīng)常使用到的模塊,它經(jīng)常被用在兩個(gè)模塊之間進(jìn)行數(shù)據(jù)的緩存,以避免數(shù)據(jù)在傳輸過程中丟失。同時(shí)FIFO也經(jīng)常被用在跨時(shí)鐘域處理中。
    的頭像 發(fā)表于 10-25 15:20 ?446次閱讀
    <b class='flag-5'>FIFO</b>的深度應(yīng)該怎么計(jì)算

    Efinity FIFO IP仿真問題 -v1

    Efinity目前不支持聯(lián)合仿真,只能通過調(diào)用源文件仿真。 我們生成一個(gè)fifo IP命名為fifo_sim 在Deliverables中保留Testbench的選項(xiàng)。 在IP的生成目錄下會(huì)有以下
    的頭像 發(fā)表于 10-21 11:41 ?1136次閱讀
    Efinity <b class='flag-5'>FIFO</b> IP仿真問題 -v1

    如何使用FX3同步從屬fifo模式通過FPGA傳輸傳感器數(shù)據(jù)?

    我們正試圖使用 FX3 同步從屬 fifo 模式通過 FPGA 傳輸傳感器數(shù)據(jù)。 USB type-C 接口需要選擇一個(gè)多路復(fù)用器來決定使用哪一邊的 USB。 因此,我們考慮使用 FX3 GPIO
    發(fā)表于 07-17 08:04

    使用FX3同步fifo兩地址線能夠配置成四線程模式嗎?

    使用FX3同步fifo兩地址線能夠配置成四線程模式嗎,也就是兩個(gè)端點(diǎn)輸出,兩個(gè)端點(diǎn)輸入,麻煩大佬回復(fù)一下?。?/div>
    發(fā)表于 07-02 07:45

    具有FIFO的雙異步通信元件TL16C552A數(shù)據(jù)表

    電子發(fā)燒友網(wǎng)站提供《具有FIFO的雙異步通信元件TL16C552A數(shù)據(jù)表.pdf》資料免費(fèi)下載
    發(fā)表于 06-26 11:28 ?0次下載
    具有<b class='flag-5'>FIFO</b>的雙<b class='flag-5'>異步</b>通信元件TL16C552A數(shù)據(jù)表

    同步FIFO異步FIFO區(qū)別介紹

    ,并且間隔時(shí)間長(zhǎng),也就是突發(fā)寫入。那么通過設(shè)置一定深度的FIFO,可以起到數(shù)據(jù)暫存的功能,且使得后續(xù)處理流程平滑。 時(shí)鐘域的隔離:主要用異步FIFO。對(duì)于不同時(shí)鐘域的數(shù)據(jù)傳輸,可以通過FIFO
    的頭像 發(fā)表于 06-04 14:27 ?1817次閱讀
    <b class='flag-5'>同步</b><b class='flag-5'>FIFO</b>和<b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>區(qū)別介紹

    求助,求大神幫忙解答下AN65974同步Slave FIFO的讀時(shí)序

    你好,在AN65974文檔中,我看不懂同步Slave FIFO的讀時(shí)序,你可以給我解讀一下么? 下圖中有我標(biāo)注的我不懂的問題。非常感謝你!......
    發(fā)表于 05-31 06:27

    DMA產(chǎn)生FIFO error interrupt錯(cuò)誤的原因?

    DMA用于接收采集AD轉(zhuǎn)化數(shù)據(jù),而且AD每間隔50us采集一次,DMA配置成單次模式,并收數(shù)長(zhǎng)度50次,未啟用FIFO模式,但是當(dāng)外部中斷非常頻繁時(shí),DMA不知怎么回事,產(chǎn)生了FIFO 錯(cuò)誤,按道理
    發(fā)表于 05-15 06:34

    關(guān)于同步FIFO異步FIFO的基礎(chǔ)知識(shí)總結(jié)

    FIFO是一種先進(jìn)先出數(shù)據(jù)緩存器,它與普通存儲(chǔ)器的區(qū)別是沒有外部讀寫地址線,使用起來非常簡(jiǎn)單,缺點(diǎn)是只能順序讀寫,而不能隨機(jī)讀寫。
    的頭像 發(fā)表于 04-09 14:23 ?3444次閱讀
    關(guān)于<b class='flag-5'>同步</b><b class='flag-5'>FIFO</b>和<b class='flag-5'>異步</b><b class='flag-5'>FIFO</b>的基礎(chǔ)知識(shí)總結(jié)

    如何清除SPI通信中的TX_FIFO和RX_FIFO

    你好, 如何清除 SPI通信中的 TX_FIFO 和 RX_FIFO?是否有任何 API 可以清除接收數(shù)據(jù)緩沖區(qū)。
    發(fā)表于 02-27 07:16