一 前言
這一周連續兩場線下面試,緊接着又是微信視頻面試,從連續三天的面試中,收獲頗豐!
存在的問題:
一是對項目細節模糊;
二是IC基礎知識薄弱;
具體表現是,在面試過程中,如被問到DDR3和千兆以太網的知識,講不清楚,如DDR3的IP的輸入數據位寬和時鍾之類,DDR3的架構,標注項目系統框圖的時鍾和數據流等 ,用Verilog實現1.2*2.8的代碼,小數1.2用八位無符號二進制位表示,不能准確寫出來,還有問CRC32的原理也懵了;這些都是對項目細節理解不夠;對於IC基礎知識薄弱,就反映在做數字IC的筆試中,發現很多基礎,如亞穩態,跨時鍾域處理的方法,奇偶分頻,建立時間和保持時間;都沒有熟練寫出Verilog代碼來,能夠准確說出他們的定義,解決方法等
二 筆試題(廣州一家IC設計公司)
1. 比較同步復位與異步復位的區別,異步復位的同步釋放改怎么處理?
復位最基本的目的就是使電路(主要是觸發器)進入一個能穩定操作的確定狀態(主要是觸發器在在某個確定的狀態),主要表現為下面兩點:
①使電路在復位后從確定的初始狀態運行:
·上電的時候,為了避免上電后進入隨機狀態而使電路紊亂,這個時候你就需要上電復位了。
·有時候,電路在某個狀態下,你想或者別人要求你從電路的初始狀態開始進行延時你的電路功能,這個時候你就要對你的電路進行復位,讓它從最初的狀態開始運行。
②使電路從錯誤狀態回到可以控制的確定狀態:
(1)同步復位
同步復位是指復位信號在時鍾有效沿到來時才復位電路。因此同步復位的復位信號受到時鍾信號的控制。Verilog代碼和電路如下
always @(posedge clk)
優點:
1).有利於仿真器的仿真;
2).有利於靜態時序分析工具的分析;
3).由於只在時鍾有效電平到來時才有效,所以可以濾除高於時鍾頻率的復位毛刺。
缺點:
1).由於大多數的邏輯器件的目標庫內的 DFF 都只有異步復位端口,倘若采用同步復位的話,綜合器就會在寄存器的數據輸入端口插入組合邏輯,這樣就會一方面額外增加 FPGA 內部的邏輯資源,另一方面也增加了相應的組合邏輯門時延。
2).復位信號的有效時長必須大於時鍾周期,才能真正被系統識別並完成復位任務。同時還要考慮諸如時鍾偏移、組合邏輯路徑延時、復位延時等因素(所以復位信號有時需要脈沖展寬,用以保證時鍾有效期間有足夠的復位寬度)
3).同步復位依賴於時鍾,如果電路中的時鍾信號出現問題,無法完成復位。
(2)異步復位
異步復位觸發器則是在設計觸發器的時候加入了一個復位引腳,也就是說復位邏輯集成在觸發器里面。(一般情況下)低電平的復位信號到達觸發器的復位端時,觸發器進入復位狀態,直到復位信號撤離。Verilog代碼和電路如下always @(posedge clk or negedge rst_n)
優點:
1). ASIC庫或FPGA器件的DFF都提供異步復位端口,無需多加的邏輯資源產生;
2).設計相對簡單
3).復位信號不依賴於時鍾,產生和響應都很方便。
缺點:
1) .屬於異步邏輯,復位釋放接近時鍾有效沿時容易使得觸發器的輸出進入亞穩態;
2) 可能因為噪聲或者毛刺造成虛假復位信號;
3) 靜態時序分析困難,靜態時序分析一般是針對同步設計,基於時鍾周期分析時序;
4) 對於 DFT設計,如果復位信號不是直接來自於 I/O 引腳,在 DFT 掃描和測試時,復位信號必須被禁止,因此需要額外的同步電路。
(3)異步復位的同步釋放
異步復位的同步釋放電路也稱為復位同步器,這個方法是將外部輸入的異步復位信號進行處理,產生另外一個適合用於后面電路的復位信號,這個處理后的復位信號能夠異步復位電路中的觸發器,又不會存在撤離問題.異步復位同步釋放就是在復位信號到來的時候不受時鍾信號的同步,而是在復位信號釋放的時候受到時鍾信號的同步。

1 module system_ctrl 2 //==================<端口>================================================== 3 ( 4 //globel clock ---------------------------------- 5 input wire clk , //時鍾,50Mhz 6 input wire rst_n , //復位,低電平有效 7 //user interface -------------------------------- 8 input wire a , //輸入信號 9 output reg b //輸出信號 10 ); 11 12 //========================================================================== 13 //== 異步復位的同步化設計 14 //========================================================================== 15 reg sys_rst_n_r; 16 reg sys_rst_n; 17 18 always @(posedge clk or negedge rst_n) begin 19 if(!rst_n) begin 20 sys_rst_n_r <= 0; 21 sys_rst_n <= 0; 22 end 23 else begin 24 sys_rst_n_r <= 1; 25 sys_rst_n <= sys_rst_n_r; 26 end 27 end 28 29 always @(posedge clk or negedge sys_rst_n) begin 30 if(!sys_rst_n) 31 b <= 0; 32 else 33 b <= a; 34 end 35 36 37 38 endmodule
電路結構圖如下:
理解:將外部信號進行同步處理(sys_rst_n),作為后面電路的復位信號(帶復位端的觸發器b~reg0)
2. 什么是時鍾偏移(Clockskew),負時鍾偏移,正時鍾偏移?
jitter:由於晶振本身穩定性,電源以及溫度變化等原因造成了時鍾頻率的變化,就是jitter,指的是時鍾周期的變化。指兩個時鍾周期之間存在的差值,這個誤差是在時鍾發生器內部產生的,和晶振或者PLL內部電路有關,布線對其沒有影響。由於跟晶振本身的工藝有關,所以在設計中無法避免它能帶來的影響,通產只能在設計中留有一定的margin。
Clockskew指同樣的時鍾產生的多個子時鍾信號之間的延時差異。skew通常是時鍾相位上的不確定。由於時鍾源到達不同寄存器所經歷路徑的驅動和負載的不同,時鍾邊沿的位置有所差異,因此就帶來了skew。完成布局布線后,物理路徑延時是固定的,所以在設計中考慮到時鍾偏移,就可以避免偏移帶來的影響。
時鍾偏斜是一個時鍾信號沿着同一個時鍾網絡到達源寄存器與目的寄存器的時間差。負時鍾偏斜,即當目標寄存器時鍾早於源寄存器時鍾到達時,時鍾偏斜稱為負時鍾偏斜。
當源寄存器時鍾早於目的寄存器時鍾到達時,時鍾偏斜稱為正時鍾偏斜。
參考資料:李銳博恩,《高性能FPGA系統——時序設計與分析》
3. 什么是亞穩態,如何防止?
觸發器無法在某一個規定時間段內產生一個確定的狀態(即既不是高電平1也不是低電平0)。
原因:由於觸發器的建立時間和保持時間不滿足,當觸發器進入亞穩態,使得無法預測該單元的輸出,也無法預測何時輸出才能穩定到某個正確的電平上。在這個穩定期間,觸發器輸出一些中間級電平,或者可能處於振盪狀態,這種不穩定是會沿着信號通道的各個觸發器級聯傳播。
消除:兩級或多級寄存器同步。理論上亞穩態不能完全消除,只能降低,一般采用兩級觸發器同步就可以大大降低亞穩態發生的概率,再加多級觸發器改善不大。
如何消除亞穩態?
(1降低系統時鍾;
(2)用反應更快的D觸發器,鎖存器;
(3)引入同步機制;
(4)改善時鍾質量,用邊沿變化快速的時鍾信號消除;
4. 什么是setup時間和hold時間,描述區別並簡單畫出示意圖?
建立時間:指在觸發器的時鍾信號上升沿到來以前,數據穩定不變的時間。如果建立的時間不滿足要求那么數據將不能在這個時鍾上升沿被穩定的打入觸發器
保持時間:是指在觸發器的時鍾信號上升沿到來以后,數據穩定不變的時間。如果保持時間不滿足要求那么數據同樣也不能被穩定的打入觸發器。
(setup time不受系統時鍾頻率影響)
因為觸發器內部數據的形成是需要一定的時間的,如果不滿足建立和保持時間,D觸發器將進入亞穩態。
5、時序約束的基本概念和基本策略?
時序約束主要包括周期約束,偏移約束,靜態時序約束。
通過附加時序約束可以綜合布線工具調整映射和布局布線,使設計達到時序要求。
附加時序約束的一般策略是先附加全局約束,然后對快速和慢速例外路徑附加專門約束,首先定義設計的所有時鍾,對各時鍾域內的同步元件進行分組,對分組附加時序偏移約束,對全組合邏輯的 PAD to PAD 路徑附加約束。附加專門約束時,首先約束分組之間的路徑,然后約束快慢速例外路徑和周期路徑,以及其他特殊路徑。
6.描述跨時鍾域設計會出現的問題及解決辦法,多比特信號,單比特信號?
(一)問題
1 亞穩態問題
2數據丟失
這個現象經常出現在由快時鍾域到慢時鍾域時,由於信號保持時間過短,作為采集方的慢時鍾域有可能采集不到該信號,造成數據丟失。
3.數據聚和錯誤
意思就是信號通過不同路徑傳輸后重新聚合到一起使用。
參考資料:https://www.jianshu.com/p/05b434313997
(二)解決方法
單bit: (1)雙D觸發器打拍同步; (2)脈沖展寬處理(https://www.cnblogs.com/rouwawa/p/7501319.html)
多bit: (1)格雷碼+雙D觸發器打拍; (2)DMUX數據使能選通設計;
(3)異步握手協議 (4)異步FIFO或RAM
(三)對各種方法解釋
(1)格雷碼+雙D觸發器
多bit信號轉換為格雷碼,再用雙D觸發器打拍。為什么不直接打兩拍,而先轉換格雷碼:不同信號路徑延時不同,信號打兩拍之后可能出現不同狀態。例如00->11,直接打拍可能變成00->10->11。而格雷碼相鄰狀態只有1bit變換,即使路徑延時不同,狀態也不會出錯。例如00->11格雷碼是00->10,打拍可能變成00->00->10,只會出現某個狀態多延時一拍而已,不會出錯。注意:格雷碼作同步時必須是2^N個狀態。
其他的方法,如異步握手協議,有很多資料和博客解釋,如微信公眾號達爾聞說的求職系列75,咸魚FPGA博客;
7.描述ASIC設計流程及工具
1.規格制定
芯片規格也像功能列表一樣,是客戶向芯片公司提出的設計要求,包括芯片需要達到的具體功能和性能方面的要求。
2.詳細設計
根據客戶提出的規格要求,拿出設計解決方案和具體時間架構,划分模塊功能。
3.HDL編碼
使用硬件描述語言(VHDL,Verilog HDL)。
4.仿真驗證
工具:Mentor公司的Modelsim,Synopsys的VCS,還有Cadence的NC-Verilog均可以對RTL級代碼進行驗證。
5.邏輯綜合
邏輯綜合就是把設計實現的HDL代碼翻譯成門級網表netlist。綜合需要設定約束條件,就是你希望綜合出來的電路在面積、時序等目標參數上達到的標准。邏輯綜合需要基於特定的綜合庫,不同的庫中,門電路基本標准單元的面積,時序參數是不一樣的。
6.STA(靜態時序分析)state timing analysis
從時序上對電路進行驗證,檢查電路是否存在建立時間(setup time)和保持時間(hold time)的違例。
工具:Synopsys的prime time。
7.形式驗證
從功能上對綜合后的網表進行驗證。常用的等價性檢查方法,以功能驗證后的HDL設計為參考,對比綜合后的網表功能,他們是否在功能上存在等價性。
工具:Synopsys的Formality。
8. 異步FIFO設計
異步FIFO是一種FIFO設計,數據從一個時鍾域進入到FIFO,在另一個時鍾域讀取數據,並且兩個時鍾域是異步。
異步FIFO的用於將數據從一個時鍾域安全准確地傳遞到另一個時鍾域。
1)傳遞多個異步信號
將多個信號從一個時鍾域同步到另一個時鍾域,並確保所有的信號都同步到新時鍾域中的同一時鍾周期這是一個關鍵問題。 FIFO在設計中用於將多位數據從一個時鍾域安全地傳遞到另一個時鍾域。 通過一個時鍾域中的控制信號將數據存入FIFO緩存中,並通過來自第二時鍾域的控制信號將數據從同一FIFO緩存的另一個端口中讀取並刪除。
IFO設計的難點在於生成FIFO指針以及FIFO上的滿和空狀態確定。
滿(寫滿標志判斷),空(讀空標志判斷)
1.1) 同步FIFO指針
對於同步FIFO設計(在同一時鍾域中執行FIFO讀寫操作),一種實現方式是對FIFO的寫入和讀取次數進行計數,遞增
(以FIFO寫入但不讀取) ),遞減(在FIFO讀取但無寫入時)或保持(無寫入和讀或同時進行寫入和讀取操作)FIFO計數
值。 當FIFO計數器達到預定的最大值時,FIFO為滿,而當FIFO計數器為零時,FIFO為空。
1.2) 異步FIFO指針
寫指針總是指向下一個要寫的字;因此,在復位時,兩個指針都設置為零,這也恰好是下一個要寫入的FIFO字位置。在FIFO寫入操作中,將數據寫入指針所指向的位置,然后將寫指針遞增以指向要寫入的下一個位置。同樣,讀取指針始終指向要讀取的當前FIFO字。再次復位時,兩個指針均復位為零,FIFO為空,而讀指針指向無效數據(因為FIFO為空且聲明了空標志)。一旦第一個數據被寫入FIFO,寫入指針就會遞增,清空標志,並且在尋址第一個FIFO存儲字內容的讀指針會立即將第一個有效數據驅動到FIFO數據輸出端口,由接收端讀取。讀指針始終指向要讀取的下一個FIFO字意味着,接收端不必使用兩個時鍾周期來讀取數據。如果接收端在讀取FIFO數據之前必須先遞增讀指針,則接收端必須先用一個周期等FIFO輸出數據字,再用一個周期將數據字捕獲到接收端,這回浪費一倍的時間。
當讀寫指針相等時,FIFO為空。當兩個指針在復位操作期間都復位為零時,或者在從FIFO讀取了最后一個字的情況下,讀指針趕上了寫指針,就會發生這種情況。
當指針再次相等時,也就是說,當寫指針跑了一圈並追上讀指針時,FIFO為滿。
那么問題來了,當指針相等時,FIFO到底為空還是滿?
區分是滿還是空可以為每個指針添加一個額外的位。當寫指針增加到最終FIFO地址之后,寫指針將使未使用的MSB標志位遞增,同時將其余位置回零,如下圖所示(FIFO使用了帶MSB標志位的指針)。讀取指針也是如此。如果兩個指針的MSB不同,則意味着寫指針比讀指針多跑了一圈。如果兩個指針的MSB相同,則意味着兩個指針的圈數一致相同。
使用n位指針(其中n-1是訪問整個FIFO緩存所需的地址位數),當兩個指針(包括MSB)相等時,FIFO為空。當兩個
指針(MSB除外)相等時,FIFO已滿。即讀寫指針相同,FIFO為空。最高位不同,其余位為相同,FIFO為滿。
1)格雷碼
關於格雷碼,任何兩個相鄰數之間的編碼距離僅為1(從一個格雷計數到下一個格雷計數,只能改變一位)。其次,最有用的格雷碼計數器的深度必須是2的冪. 這意味着本文描述的技術。用於制作2^n深度的FIFO。
比較空滿時,需要讀寫地址進行判斷,二者屬於跨時鍾域,需要進行打拍的同步處理,為避免亞穩態,采用格雷碼,因為格雷碼相鄰只有一位變化,這樣同步多位時更不容易產生問題。
格雷碼公式:
gray = (binary>>1) ^ binary;
格雷碼特點:“讀寫的最高2位不同,其余位相同”時,處於寫滿狀態。
1 //------------寫時鍾域------------// 2 //寫時鍾域內,寫數據進FIFO,並將寫指針加1 3 assign w_addr = w_pointer[POINTER_WIDTH-2:0]; 4 always@(posedge w_clk or negedge w_rstn)begin 5 if(w_en & (!full))begin 6 fifo_mem[w_addr]<=w_data; 7 end 8 end 9 //寫指針計數器 10 always@(posedge w_clk or negedge w_rstn)begin 11 if(!w_rstn)begin 12 w_pointer<=0; 13 end 14 else if(w_en & (!full))begin 15 w_pointer <= w_pointer+1; 16 end 17 else begin 18 w_pointer<=w_pointer; 19 end 20 end 21 22 //-------------------- 23 24 //------------讀時鍾域------------// 25 //讀時鍾域內,把FIFO內的數據取出,並將讀指針加1 26 assign r_addr = r_pointer[POINTER_WIDTH-2:0]; 27 always@(posedge r_clk or negedge r_rstn)begin 28 if(!r_rstn)begin 29 r_data<='h0; 30 end 31 else if(r_en & (!empty))begin 32 r_data<= fifo_mem[r_addr]; 33 end 34 end 35 //讀指針計數器 36 always@(posedge r_clk or negedge r_rstn)begin 37 if(!r_rstn)begin 38 r_pointer<=0; 39 end 40 else if(r_en & (!empty))begin 41 r_pointer <= r_pointer+1; 42 end 43 else begin 44 r_pointer<=r_pointer; 45 end 46 end 47 //-------------------- 48 49 //--------------------指針同步---------- 50 //將格雷碼寫指針同步到讀時鍾域 51 //再將轉換后的指針經過兩級觸發器同步 52 assign w_gray_pointer = w_pointer^[w_pointer>>1]; 53 always@(posedge r_clk or negedge r_rstn)begin 54 if(!r_rstn)begin 55 {w_pointer_d1,w_pointer_d2} <=0; 56 end 57 else begin 58 {w_pointer_d1,w_pointer_d2} <= {w_pointer_d1,w_gray_pointer}; 59 end 60 61 end 62 //將格雷碼讀指針打兩拍同步到寫時鍾域 63 //讀指針->格雷碼 64 assign r_gray_pointer = r_pointer^[r_pointer>>1]; 65 //將格雷碼讀指針打兩拍同步到寫時鍾域 66 always@(posedge w_clk or negedge w_rstn)begin 67 if(!w_rstn)begin 68 {w_pointer_d1,w_pointer_d2} <=0; 69 end 70 else begin 71 {r_pointer_d1,r_pointer_d2} <= {r_pointer_d1,r_gray_pointer}; 72 end 73 74 end 75 //--------------------指針同步---------- 76 77 //判斷空滿 78 assign full = ( 79 (r_pointer_d2[POINTER_WIDTH-1] != w_gray_pointer[POINTER_WIDTH-1])&& //最高位不同 80 (r_pointer_d2[POINTER_WIDTH-2] != w_gray_pointer[POINTER_WIDTH-2])&& //次高位不同 81 (r_pointer_d2[POINTER_WIDTH-3:0] != w_gray_pointer[POINTER_WIDTH-3:0])&& //其他低位不同 82 ); 83 assign empty = (w_pointer_d2 == r_gray_pointer); 84 85 endmodule
10. 時序分析基礎
時序分析模型
系統時鍾需要滿足如下關系:
1)建立時間裕量
注釋:其中T為時鍾周期,Tcq為觸發器時鍾端到輸出端Q的延時,Tgate或Tdelay為組合邏輯延時。Tsu為建立時間,由於時鍾源到達不同寄存器所經歷路徑的驅動和負載的不同,時鍾邊沿的位置有所差異,因此就帶來了skew。
所有的一切Tskew都是如下:
所以,Tskew有可能為正,也有可能為負,負的話就有利於滿足保持時間,正的話就有利於滿足建立時間;
2)保持時間裕量
與上面1)的解釋相同,Th為保持時間。
總結:建立時間裕量何保持時間裕量是時序分析的兩個基礎公式,常用於IC筆試題的分析中。
3)例題
下面為聯發科一道筆試題,利用上面的公式
11. verilog中不可綜合的語句
不可綜合verilog語句
(1)initial
只能在test bench中使用,不能綜合。
(2)events
event在同步test bench時更有用,不能綜合。
(3)real
不支持real數據類型的綜合。
(4)time
不支持time數據類型的綜合。
(5)force 和release
不支持force和release的綜合。
(6)assign 和deassign
不支持對reg 數據類型的assign或deassign進行綜合,支持對wire數據類型的assign或deassign進行綜合。
(7) fork join
不可綜合,可以使用非塊語句達到同樣的效果。
(8) primitives
支持門級原語的綜合,不支持非門級原語的綜合。
(9) table
不支持UDP 和table的綜合。
(10) 敏感列表里同時帶有posedge和negedge
如:always @(posedge clk or negedge clk) begin...end
這個always塊不可綜合。
(11) 同一個reg變量被多個always塊驅動
(12) 延時
以#開頭的延時不可綜合成硬件電路延時,綜合工具會忽略所有延時代碼,但不會報錯。
如:a=#10 b;
這里的#10是用於仿真時的延時,在綜合的時候綜合工具會忽略它。也就是說,在綜合的時候上式等同於a=b;
(13) 與X、Z的比較
可能會有人喜歡在條件表達式中把數據和X(或Z)進行比較,殊不知這是不可綜合的,綜合工具同樣會忽略。所以要確保信號只有兩個狀態:0或1。