天天看點

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫

文章目錄

  • 2021秋招筆試(1)_樂鑫
    • 1、FIFO測試
      • **1)題目**:
      • 2)分析
      • 3)解析
    • 2、按鍵識别、消抖
      • 1)題目
      • 2)分析
    • 3、用Verilog 實作 CRC-8 的串行計算,G(D) = D8 + D2 + D + 1,計算流程如下
    • 4、setup/hold time 和 溫度/電壓關系
      • 知識補充:
    • 5、NAND 和 NOR Flash 的差別
    • 6、驗證
    • 7、優化
    • 8、異步設計中對跨時鐘處理的信号,功能驗證時一般要考慮
    • 9、欲産生序列信号 11010111,則至少需要(3)級觸發器
    • 10 FIFO 深度計算
    • FIFO
        • 場景1:fa>fb with no idle cycles in both write and read
        • 場景2:fa>fb with two clock cycle delay between two successive read and write
        • 場景3:fa > fb with idle cycles in both write and read
        • 場景4:fa > fb with duty cycles given for wr_enb and rd_enb.
        • 場景5:fa < fb with no idle cycles in both write and read
        • 場景6:fa < fb with idle cycles in both write and read
        • 場景7:fa = fb with no idle cycles in both write and read
        • 場景8:fa = fb with idle cycles in both write and read
        • 場景9:Data rates are given,read and write random(important!!!)
        • 下面來計算FIFO最小深度
    • 補充1
    • 補充2
    • 補充3

2021秋招筆試(1)_樂鑫

參考:

  • https://mp.weixin.qq.com/s/0C1gkOuknTFJe8y0oH19dw
  • https://blog.csdn.net/DengFengLai123/article/details/106757235
  • https://blog.csdn.net/zhangningning1996/article/details/106795689

1、FIFO測試

1)題目:

請根據下面的設計描述,盡可能多的列出你所能想到的測試點:

一個異步FIFO,rdata和wdata均為8位資料,FIFO深度為16,當rst_n輸入為低時,FIFO被複位,當wclk的上升沿采樣到wr為高時,資料被寫入FIFO,當rclk的上升沿采樣到rd為高時,FIFO輸出資料。此外,當FIFO為空時,empty信号輸出為高,當FIFO滿時,full信号輸出為高。

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫

2)分析

[7:0] rdata,wdata;
reg[7:0] mem[15:0];
rst_n = 0 複位
[email protected](posedge wclk) begin
	if(wr && !full)
		mem[wr_ptr] <= wdata;
end


[email protected](posedge rclk) begin
	if(rd && !empty)
		rdata <= mem[wr_ptr];
end
           

是以應該有兩方面測試:

  • 1、FIFO的功能
    • FIFO
    • 讀、寫(在對應使能端是否正确變化)
    • 空、滿信号生成、判斷
    • 讀空、寫滿處理
  • 2、異步複位:異步機制中的幾個元件
    • 格雷碼轉換
    • 兩級觸發器同步

3)解析

根據題目,主要有兩個一級測試點

1、FIFO 基本功能 2、異步處理

對于 FIFO 的基本功能,可以使用黑盒用例 進行 端到端測試,通過注入特定序列的輸入檢測輸出是否符合預期。有以下二級測試點

  • 1、寫端口時序行為與描述一緻,檢查資料在wr被采樣時候正确寫入
  • 2、讀端口……………………,………………rd ……………………
  • 3、FIFO 能保證先進先出
  • 4、空信号能正确産生
  • 5、滿信号能正确産生
  • 6、檢查在寫滿、讀空之後,是否有做讀寫保護防止資料覆寫(白盒可檢查memory 資料)
  • 7、…………………………………………………防止空滿信号錯亂(白盒可檢查指針,内部計數器)
  • 8、檢查能否被正常複位,複位之後各輸出信号初始狀态(複位值)是否正常。

對于異步處理,必須要進行白盒測試,假設内部實作是經典的異步FIFO實作,則有以下二級測試點:

  • 1、格雷碼轉換邏輯的正确性
  • 2、跨時鐘域傳輸,是否進行同步器打拍處理,以及指針信号經過同步器打拍延時對功能帶來的影響(理論上沒有影響)
  • 3、頻率不同對FIFO讀寫的影響,覆寫讀快寫慢和讀慢寫快(理論上沒有影響)

2、按鍵識别、消抖

1)題目

請實作對4x4矩陣式鍵盤的按鍵識别,假設每次都是單按鍵輸入,需要有去抖功能(持續20ms以上被認為是有效鍵值),子產品時鐘頻率為1kHz,要求用狀态機實作,定義狀态,畫出狀态轉移圖,并用verilog完整描述該識别子產品。矩陣式鍵盤電路結構參見下圖,其中行線1 ~ 4由識别子產品控制輸出,列線5 ~ 8為識别子產品的輸入

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫

2)分析

要求:狀态機實作、定義狀态、畫出狀态轉移圖,Verilog描述

注意:題目中的輸入、輸出是相對于識别子產品(右下角黃色)而言的

兩部分工作:

  • 1、方法:如何判斷按鍵,消抖
    • 判斷按鍵:确定(x,y)坐标:
      • 先将輸入置0或置1,檢查輸出,确定有按鍵按下 —— 行線1 ~ 4 置0(識别子產品的輸出 是 該子產品的輸入),檢查列線 5 ~ 8 中哪一個為低電平,則該列有按鍵按下
      • 再用控制變量法确定坐标 —— 行線 1 ~ 4 分别置 0111、1011、1101、1110,若某一個數(如0111)的輸出 5 ~ 8 檢測到(1011)低電平,則确定坐标 0111_1011 為第一行、第三列位置(注意第5号線是最右邊一列)
    • 消抖:根據要求的有效按鍵值,計算需要的時鐘周期數 (如 1kHz,周期1ms,20ms即為20個周期)
  • 2、Verilog實作
IDLE:初始狀态,或 1 ~ 4(in)為低電平時,5~8(out)未檢測到低電平,out=4'b0,
s1:1~4為低電平 4'b0000 時,有按鍵按下,5~8檢測到低電平
	若持續20ms,則列号确定,轉到下一狀态;
	若小于20ms,則回到IDLE狀态。
s2:确定有按鍵按下時, 1~4 置為4'b0111,監測輸出,如5 ~ 8号線為0111、1011、1101、1110,則确定按鍵位置,轉為done狀态;否則,轉到s3
s3:………………………………………………………………4'b1011,……………………………………………………,……………………;…………………… s4
s4:………………………………………………………………4'b1101,……………………………………………………,……………………;…………………… s5
s5:………………………………………………………………4'b1110,……………………………………………………,……………………;由于已經确定有按鍵按下,是以肯定會确定出位置
done:已經識别出按鍵,且消抖,輸出結果。轉到IDLE狀态。

此處題目沒有額外要求,也可将 in[3:0] 和 out[3:0] 編碼,得到輸出 code[3:0] ,對應16個按鍵
           
module key_detect
#(parameter data_width = 4)
(
    input clk,rst_n,
    input[data_width-1:0] in,
    output[data_width-1:0] out);
    
    reg[2:0] current_state;
    reg[2:0] next_state;
    reg[4:0] cnt;
    
    
    [email protected](posedge clk or negedge rst_n) begin
        if(!rst_n)
            current_state <= 3'b0;
        else
            current_state <= next_state;
        
    end
    
    reg valid;
    reg en;
    [email protected](current_state or in) begin
            next_state = current_stata;
            out = 0;
        	valid = 1'b0;
        case(current_state)
            3'b000:begin
                in = 4'b0000;
                if(out != 4'1111)
                    next_state = 3'b001;
                else
                    next_state = 3'b000;
            end
            3'b001:begin	// 按鍵消抖子產品
                valid = 1'b1
                if(!en)
                    next_state = 3'b000;		// 按鍵抖動,回到IDLE狀态
                else
                    next_state = 3'b010;		// 按鍵按下,到下一狀态
            end
            3'b010:begin
                in = 4'0111
                if(out == 4'1111) 
                    next_state = 3'b011;
                else 
                    next_state = 3'b110;
            end       
            3'b011:begin
                in = 4'b1011;
                if(out == 4'1111) 
                    next_state = 3'b100;
                else 
                    next_state = 3'b110;
            end   
            3'b100:begin
                in = 4'b1101;
                if(out == 4'1111) 
                    next_state = 3'b101;
                else 
                    next_state = 3'b110;
            end    
            3'b101:begin
                in = 4'b1110;
                next_state = 3'b110;
            end        
            3'b110:
                next_state = 3'b000;
                
        end
    
    
    [email protected](posedge clk or negedge rst_n) begin
        if(!rst_n)
            cnt <= 0;
        	en <= 0;
        else if(valid)begin
            if(cnt < 4'd10)begin
            	cnt <= cnt + 1'b1;
            	en <= 0;
            end
        	else
                begin
            		cnt <= cnt;
            		en <= 1;
                end
        end
        else begin
            cnt <= 0;
        	en <= 0;
        end
    end
            
            // 然後根據 in 和 out 就可以确定位置,如 {in,out}=0111_1011,确定是第一行第二個按鈕
            //
            // 若要求對輸出編碼,且輸出端口中有 output[data_width-1:0] code,
            [email protected](in or out)
                case({in,out})
                    8'b0111_0111:code=3;  // 5号線對應最右邊列
            	    8'b0111_1011:code=2;
                    8'b0111_1101:code=1;
                    8'b0111_1110:code=0;
                    8'b1011_0111:code=7;
                    8'b1011_1011:code=6;
                    8'b1011_1101:code=5;
                    8'b1011_1110:code=4;
                    8'b1101_0111:code=11;
                    8'b1101_1011:code=10;
                    8'b1101_1101:code=9;
                    8'b1101_1110:code=8;
                    8'b1110_0111:code=15;
                    8'b1110_0111:code=14;
                    8'b1110_0111:code=13;
                    8'b1110_0111:code=12;
                    default code=0;
                endcase
endmodule
           

3、用Verilog 實作 CRC-8 的串行計算,G(D) = D8 + D2 + D + 1,計算流程如下

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫
module crc_8
(#parameter data_width = 32)
(	input clk,
    input rst_n,
    input data,
    input data_vlid,
    input crc_start,
    output crc_out,
    output crc_valid);
    
    reg[7:0] shift_reg;
    reg[4:0] cnt;
    reg[2:0] cnt_out;
    reg flag;
    
    assign crc_out = shift_reg[cnt_out];
    
    // 圖中結構實作,資料輸入、移位
    [email protected](posedge clk or negedge rst_n) begin
        if(!rst_n)
            shift_reg <= 8'hff;
        else if(!crc_start)
            shift_reg <= 8'hff;
        else if(data_valid)begin
            shift_reg[0] <= data ^ shift_reg[7];
            shift_reg[1] <= data ^ shift_reg[7] ^ shift_reg[0];
            shift_reg[2] <= data ^ shift_reg[7] ^ shift_reg[1];
            shift_reg[3] <= shift_reg[2];
            shift_reg[4] <= shift_reg[3];
            shift_reg[5] <= shift_reg[4];
            shift_reg[6] <= shift_reg[5];
            shift_reg[7] <= shift_reg[6];
        end
    end
    
    // 計數,32bit輸出串行輸入
    [email protected](posedge clk or negedge rst_n)begin
        if(!rst_n)
            cnt <= 5'd0;
        else if(cnt == 5'd31 && data_valid == 1'b1)
            cnt <= 5'd0;
        else if(data_valid)
            cnt <= cnt + 1'b1;
        else
            cnt <= cnt;
    end
     
    // 輸入結束表示 flag
    [email protected](posedge clk or negedge rst_n)begin
        if(!rst_n)
            flag <= 1'b0;
        else if(cnt == 5'd31 && data_valid == 1'b1)
            flag <= 1'b1;
        else
            flag <= 1'b0;
    end
     
    // 在資料輸入完成之後,再串行輸出
    [email protected](posedge clk or negedge rst_n)begin
        if(!rst_n)
            cnt_out <= 3'd0;
        else if(flag)
            cnt_out <= 3'd7;
        else if(cnt_out > 3'd0)
            cnt_out <= cnt_out - 1'b1;
        else
            cnt_out <= 3'd7;
    end
        
    [email protected](posedge clk or negedge rst_n)begin
        if(!rst_n)
            crc_valid <= 1'b0;
        else if(flag == 1'b1 || cnt_out > 3'd0)
            crc_valid <= 1'b1;
        else 
            crc_valid <= 1'b0;
    end
                    
    endmodule			
           

4、setup/hold time 和 溫度/電壓關系

一批IC樣品在測試中發現有setup或者hold時序問題,現取A,B,C,D四種樣品進行測試。A降溫後停止工作,則可能是==(setup(40nm以下工藝)/(hold(40nm以上工藝))問題。B升溫後停止工作,則可能是(hold(40nm以下工藝)/(setup(40nm以上工藝))問題。C降壓後停止工作,則可能是(setup)問題。D升壓後停止工作,則可能是(hold)==問題。

知識補充:

溫度升高:會使載流子速率降低(散射、碰撞機率增大),也會使Vth降低。但兩者的影響大小不同

  • 40nm以上的工藝,升溫對于 Vth的影響可以忽略,載流子速率對電流影響占主導
  • 40nm以下的工藝,升溫使得Vth 顯著降低,載流子速率影響不大

電壓影響:

  • 升壓,電流增大,延時小
  • 降低,電流減小,延時大

setup/hold time問題

  • setup問題:時序關鍵路徑總時延過大
  • hold 問題:………………總時延過小

5、NAND 和 NOR Flash 的差別

1、NAND 中常存在壞塊

2、NAND 容量可以做到很大

3、NAND 寫入速度比較快

4、NOR 讀出速度比較快

6、驗證

動态驗證:modelsim 仿真、後仿 (驗證結果依賴于向量輸入,動态改變)

靜态驗證:形式驗證、STA (不依賴于具體測試用例)

7、優化

面積優化:邏輯優化、資源共享、串行化

時序優化:寄存器配平、流水線設計、關鍵路徑優化

8、異步設計中對跨時鐘處理的信号,功能驗證時一般要考慮

信号高電平有效還是低電平有效

信号變化的最小寬度 (低頻采高頻場景下,功能仿真可以仿真出漏采現象)

時鐘頻率 (不同時鐘頻率的跨時鐘域是否有頻率不同導緻的功能與預期不一緻)

9、欲産生序列信号 11010111,則至少需要(3)級觸發器

至少:用8個狀态的狀态機,其輸出為 序列,即可産生

若用移位寄存器,則:

  • 3個,110 ->101 -> 010 -> 101 ,重複,不行
  • 4個,……………… 1111 ->1111 ,重複,不行
  • 5個, 不重複,可行。 是以用移位寄存器産生該序列要 5 個觸發器

10 FIFO 深度計算

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫

考慮最大資料情況:

  • 在module A,B 啟動後的 10us内,module A一直在傳輸資料,共有 2us 有效資料,需要存儲 1280Mbit/s * 2us = 2560 bits;
  • 第11us,module A 傳輸資料 1280Mbit/s * 1us = 1280 bits, moduleB 讀取640Mbits/s * 1us = 640 bits, 需要存儲 640 bits
  • 此時總共需要存儲 2560 + 640 = 3200 bits

考慮讀取

前15us 共寫入 1280Mbits * 3 us = 3840 bits, 讀取 5us * 640 Mbits/s = 3200 bits,需要存儲 640 bits

綜合考慮

最大需要存儲 3200 Mbits,深度需要 3200/32 = 100 ,選 最接近的 128 合适。

FIFO

【題目】we need to employ an asynchronous FIFO between two modules working at different clock domains.FIFO is required, only when you are slow at reading and fast in writing to buffer. The design (size) of the FIFO should be in such a way that, the FIFO can store all the data which si not read by the slower module.

(1) please calculate the minimum FIFO depth for the following cases respectively.

(2) Use verilog to implement a FIFO for any one of the cases

Case1: fA > fB with no idle cycles in both write and read.

Writing frequency = fA = 80MHz

Reading freqency = fB = 50MHz

Burst Length = No. of data items to be transferred = 120.

There are no idle cycles in both reading and writing which means that, all the items in the burst will be writen and read in consecutive clock cycles.

Case2: fA > fB with idle cycles in both write and read

Writing frequency = fA = 80MHz

Reading frequency = fB = 50MHz

Burst Length = No.of data items to be transferred = 120.

No. of idle cycles between two successive writes is = 1.

No. of idle cycles between two successive reads is = 3.

Case3: fA > fB with duty cycles given for wr_enb and rd_enb.

Writing frequency = fA = 80MHz

Reading frequency = fB = 50MHz

Burst Length = No.of data items to be transferred = 120.

Duty cycle of wr_enb(write enable) = 50% = 1/2

Duty cycle of rd_enb(read enable) = 25% = 1/4

Case4: fA < fB with idle cycles in both write and read(duty cycles of wr_enb and rd_enb can also be given in these type of questions).

Writing frequency = fA = 30MHz

Reading frequency = fB = 50MHz

Burst Length = No.of data items to be transferred = 120.

No. of idle cycles between two successive writes is = 1.

No. of idle cycles between two successive reads is = 3.

參考連結:https://blog.csdn.net/persistlzy/article/details/108393561

【解析】

資料突發長度(burst length)

首先考慮一種場景,假如子產品A不間斷的往FIFO中寫資料,子產品B同樣不間斷的從FIFO中讀資料,不同的是子產品A寫資料的時鐘頻率要大于子產品B讀資料的時鐘頻率,那麼在一段時間内總是有一些資料沒來得及被讀走,如果系統一直在工作,那麼那些沒有被讀走的資料會越累積越多,那麼FIFO的深度需要是無窮大的,是以隻有在突發資料傳輸過程中讨論FIFO深度才是有意義的。

也就是說一次傳遞一包資料完成後再去傳遞下一包資料,把一段時間内傳遞的資料個數稱為burst length。在維基百科中,burst transmission是這樣解釋的:In telecommunication, a burst transmission or data burst is the broadcast of a relatively high-bandwidth transmission over a short period。

知道burst length過後,通過上述讨論大概就知道FIFO的最小深度與burst rate, burst size, read and write frequency等因素有關。要确定FIFO的深度,關鍵在于計算出在突發讀寫這段時間内有多少個資料沒有被讀走。也就是說FIFO的最小深度就等于沒有被讀走的資料個數。

在讨論之前我們假定子產品A向FIFO寫資料的時鐘頻率為fa,子產品B從FIFO讀資料的時鐘頻率為fb。

場景1:fa>fb with no idle cycles in both write and read

假設:

寫資料時鐘頻率fa=80MHz

讀資料時鐘頻率fb=50MHz

突發長度= number of data to be transferred = 120

在突發傳輸過程中,資料都是連續讀寫的

那麼:

寫一個資料所需要的時間 = 1/80MHz = 12.5ns

突發傳輸中,寫完所有資料所需要的時間 = 120*12.5ns = 1500ns

讀一個資料所需要的時間 = 1/50MHz = 20ns

是以寫完所有的突發傳輸資料需要花費1500ns

在1500ns内能夠讀走的資料個數 = 1500ns/20ns = 75

是以在1500ns内還沒有被讀走的資料個數 = 120-75 = 45

是以FIFO的最小深度為45

場景2:fa>fb with two clock cycle delay between two successive read and write

場景2在場景1的基礎上增加了一個假設,即讀比寫慢兩拍。這種假設是真正存在的,在異步FIFO設計中,我們需要去判斷FIFO的空滿來保證邏輯的正确性,判斷空滿标志需要去比較讀寫指針,而讀指針與寫指針處在不同的時鐘域中,我們需要采用格雷碼和兩級同步寄存器去降低亞穩态的機率,而兩級同步必然會導緻空滿标志位的判斷至少延遲2個cycle。對于空标志位來說,将寫指針同步到讀時鐘域至少需要花費2個時鐘,而在同步這段時間内有可能還會寫入新的資料,是以同步後的寫指針一定小于或等于(當且僅有同步時間内沒有新資料寫入的情況下才會等于)目前的寫指針,是以此時判斷不一定是真空;同理,對于滿标志位來說,将讀指針同步到讀時鐘域至少需要花費2個時鐘,而在同步這段時間内有可能還會讀出新的資料,是以同步後的讀指針一定小于或等于目前讀指針,是以此時判斷并不一定是真滿。

通過上述讨論可以知道場景2的FIFO最小深度應該比場景1的FIFO最小深度45略大。

場景3:fa > fb with idle cycles in both write and read

假設:

寫資料時鐘頻率fa=80MHz

讀資料時鐘頻率fb=50MHz

突發長度= number of data to be transferred = 120

每隔1個cycle寫一次

每隔3個cycle讀一次

那麼:

每隔1個cycle寫一次,意味着2個cycle才寫一個資料

每隔3個cycle讀一次,意味着4個cycle才讀一個資料

寫一個資料所需要的時間 = 21/80MHz = 25ns

突發傳輸中,寫完所有資料所需要的時間 = 12025ns = 3000ns

讀一個資料所需要的時間 = 4*1/50MHz = 80ns

是以寫完所有的突發傳輸資料需要花費3000ns

在3000ns内能夠讀走的資料個數 = 3000ns/80ns = 37.5

是以在3000ns内還沒有被讀走的資料個數 = 120-37.5 = 82.5

是以FIFO的最小深度為83

場景4:fa > fb with duty cycles given for wr_enb and rd_enb.

假設:

寫資料時鐘頻率fa=80MHz

讀資料時鐘頻率fb=50MHz

突發長度= number of data to be transferred = 120

寫使能信号占整個burst時間比重為1/2

讀使能信号占整個burst時間比重為1/4

那麼:

場景4與場景3描述不一緻,但情形是一緻的,是以FIFO的最小深度也為83

場景5:fa < fb with no idle cycles in both write and read

假設:

寫資料時鐘頻率fa=40MHz

讀資料時鐘頻率fb=50MHz

突發長度= number of data to be transferred = 120

在突發傳輸過程中,資料都是連續讀寫的

那麼:

由于讀資料比寫資料要快,是以FIFO隻起到過時鐘域的作用,FIFO的最小深度為1即可

場景6:fa < fb with idle cycles in both write and read

假設:

寫資料時鐘頻率fa=40MHz

讀資料時鐘頻率fb=50MHz

突發長度= number of data to be transferred = 120

每隔1個cycle寫一次

每隔3個cycle讀一次

那麼:

每隔1個cycle寫一次,意味着2個cycle才寫一個資料

每隔3個cycle讀一次,意味着4個cycle才讀一個資料

寫一個資料所需要的時間 = 21/40MHz = 50ns

突發傳輸中,寫完所有資料所需要的時間 = 12050ns = 6000ns

讀一個資料所需要的時間 = 4*1/50MHz = 80ns

是以寫完所有的突發傳輸資料需要花費6000ns

在6000ns内能夠讀走的資料個數 = 6000ns/80ns = 75

是以在6000ns内還沒有被讀走的資料個數 = 120-75 = 45

是以FIFO的最小深度為45

場景7:fa = fb with no idle cycles in both write and read

假設:

寫資料時鐘頻率fa=50MHz

讀資料時鐘頻率fb=50MHz

突發長度= number of data to be transferred = 120

那麼:

如果讀寫時鐘同源并且無相位差,那麼可以不需要FIFO;否則FIFO的最小深度為1

場景8:fa = fb with idle cycles in both write and read

假設:

寫資料時鐘頻率fa=50MHz

讀資料時鐘頻率fb=50MHz

突發長度= number of data to be transferred = 120

每隔1個cycle寫一次

每隔3個cycle讀一次

那麼:

每隔1個cycle寫一次,意味着2個cycle才寫一個資料

每隔3個cycle讀一次,意味着4個cycle才讀一個資料

寫一個資料所需要的時間 = 21/50MHz = 40ns

突發傳輸中,寫完所有資料所需要的時間 = 12040ns = 4800ns

讀一個資料所需要的時間 = 4*1/50MHz = 80ns

是以寫完所有的突發傳輸資料需要花費4800ns

在4800ns内能夠讀走的資料個數 = 4800ns/80ns = 60

是以在4800ns内還沒有被讀走的資料個數 = 120-60 = 60

是以FIFO的最小深度為60

場景9:Data rates are given,read and write random(important!!!)

在前面幾種場景中,我們給的條件都是每隔幾個時鐘讀寫一次,這種周期性讀寫在實際中很常見。但是在工程設計中還存在這樣一種情形,隻給出資料在一段時間内的讀寫速率,怎麼讀寫完全随機,這種情況我們需要考慮最壞的一種情況避免資料丢失。在最壞的情形中,讀寫的速率應該相差最大,也就是說需要找出最大的寫速率和最小的讀速率。

假設:

寫資料時鐘頻率fa=80MHz

讀資料時鐘頻率fb=50MHz

在寫時鐘周期内,每100個周期就有40個資料寫入FIFO

在讀時鐘周期内,每10個周期可以有8個資料讀出FIFO

那麼:

首先這裡沒有給出資料的突發長度,從假設中可以得出每100個周期就有40個資料寫入FIFO,這裡可能就有人會說突發長度就是40個資料,其實不是這樣的,因為資料是随機寫入FIFO的,我們需要考慮做壞的情形,即寫速率最大的情形,隻有如下圖背靠背的情形才是寫速率最高的情形,burst length為80

注意:這裡需要驗證一下是否有解,即寫入burst資料時間必須大于等于讀出burst資料時間,不然資料就會越累積越多,使得FIFO的深度必須為無窮大。首先寫入80個資料需要的時間 = 1/80MHz*(80100/40)=2500ns,讀出80個資料需要的時間 = 1/50MHz(80*10/8)=2000ns,由于寫入burst資料時間大于對出burst資料時間,是以有解。

下面來計算FIFO最小深度

連續寫入80個資料最快所需要時間 = 1/80MHz * 80 = 1000ns

從FIFO中讀出一個資料至少所需時間 = (1/50MHz) * (10/8) = 25ns

那麼在1000ns内能夠讀出的資料 = 1000ns/25ns = 40

在1000ns内沒有讀出的資料 = 80 - 40 = 40

是以FIFO的最小深度為40

【總結】

從上面分析來看,求FIFO的最小深度主要有以下要點:

在求解之前需要驗證一下在允許的最大時間長度内寫入的資料量是否等于讀出的資料量,保證有解;

求FIFO深度需要考慮最壞的情形,讀寫的速率應該相差最大,也就是說需要找出最大的寫速率和最小的讀速率;

不管什麼場景,要确定FIFO的深度,關鍵在于計算出在突發讀寫這段時間内有多少個資料沒有被讀走;

由于FIFO空滿标志位的判斷延遲,在實際應用中需要預留一些餘量。

下面我們來推導一下FIFO深度的求解公式,假設:

寫時鐘頻率為fwr

讀時鐘頻率為frd

在寫時鐘周期内,每m個周期内就有n個資料寫入FIFO

在讀時鐘周期内,每x個周期内可以有y個資料讀出FIFO

那麼:

首先必須滿足(1/fwr)(m/n) ≥ (1/frd)(x/y)

”背靠背“的情形下是FIFO讀寫的最壞情形,burst長度 B = 2*n

寫完burst長度資料最快所需時間 T = (1/fwr) * B

從FIFO中讀出一個資料至少需要時間 t= (1/frd) * (x/y)

在T時間内能夠從都走的資料個數 = T/t = B * (frd/fwr) * (y/x)

在T時間内還沒有讀走的資料個數 = B - B * (frd/fwr) * (y/x)

是以FIFO的最小深度為 B - B * (frd/fwr) * (y/x)

注意保留一些餘量**

補充1

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫

補充2

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫
2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫

補充3

2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫
2021秋招筆試(1)_樂鑫2021秋招筆試(1)_樂鑫

繼續閱讀