1. 程式人生 > 其它 >mips cache verilog實現_例項解析Verilog綜合出鎖存器的問題

mips cache verilog實現_例項解析Verilog綜合出鎖存器的問題

技術標籤:mips cache verilog實現verilog adc程式碼verilog always語法verilog case語句verilog coding styleverilog reg賦初值

fec87a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg

八月の

00c97a8d-9c1a-eb11-8da9-e4434bdf6706.gif 01c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

時間一晃,夏和秋開始交替

有的人準備迎接碩果

而我,在夏天的尾巴焦頭爛額

望著窗外的天,享受吹來的風

仍不知心裡愁緒是真,還是假

逃離秋招季的焦慮

緩緩心情,也好好努力

這篇文章通過實際的Design Compiler綜合來精解Verilog程式碼生成latch的問題。

下面哪種寫法會產生latch?為什麼?

程式碼如下:

A.

always  @(*)beginif(d)a = b;end

B

always  @(*)beginif(d)  a = b;else  a = a;end

C

always @ (b or d)  case(d)    2’b00: a=b>>1;    2’b11: c=b>>1;    default:      begin        a=b;        c=b;      endendcase

D

always @(b or d)begin  a=b;  c=b;  case(d)    2’b00: a=b>>1;    2’b11: c=b>>1;  endcaseend

E

[email protected]
(bor d)begin case(d) //synopsys full_case 2’b00: a=b>>1; 2’b11: c=b>>1; endcaseend

程式碼A:

是一個always語句塊構成的組合邏輯,其中缺少else分支

當d=1'b0時,綜合工具會預設保持a的值,即生成鎖存器。

module code_a(        input d,        input b,        output reg a);        [email protected](*) begin                if(d) a =b ;        endendmodule

02c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

綜合出的電路圖如上所示,TLATX1就是所使用的標準單元庫的鎖存器的名字。

04c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

05c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

程式碼B:

module code_b(        input d,        input b,        output reg a);        [email protected](*) begin                if(d) a =b ;                else  a =a ;        endendmodule

程式碼B雖然補全了else分支語句。但是,其程式碼依然有保持功能,即會生成鎖存器。

08c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

也就是說,組合邏輯是否會生成鎖存器,其根本原因是該組合邏輯存在保持功能!

程式碼C:

module code_c(        input [1:0] d,        input [1:0] b,        output reg [1:0] a,        output reg [1:0] c);        [email protected](b or d ) begin                case(d)                         2'b00:a = b >>1 ;                         2'b11:c = b >>1 ;                         default:begin                                 a = b ;                                 c = b ;                         end                endcase        endendmodule

程式碼C在always語句塊內使用了case語句,並且case語句中含有default分支。但是,我們可以發現,

d=2’b00時,沒有說明c的賦值;d=2’b01時,沒有說明a的賦值;

0ac97a8d-9c1a-eb11-8da9-e4434bdf6706.png

從上面的綜合結果可以看出,綜合出來4 個鎖存器。
d=2’b00時,儲存c的值;d=2’b01時,儲存a的值

程式碼D

module code_d(        input [1:0]d,        input [1:0]b,        output reg [1:0]a,        output reg [1:0]c);        [email protected](b or d ) begin                       a = b ;                c = b ;                case(d)                         2'b00:a = b >>1 ;                         2'b11:c = b >>1 ;                endcase        endendmodule

程式碼D和程式碼C的不同是,它在always語句塊的開始,對a和c進行了預設賦值。

這就類似於軟體裡面的初始化,當然只是類似而已。

0dc97a8d-9c1a-eb11-8da9-e4434bdf6706.png

從上面的綜合結果,我們可以看出來,沒有生成任何時序邏輯。

程式碼E

module code_e(  input [1:0] d,  input [1:0] b,  output reg [1:0] a,  output reg [1:0] c);  [email protected](b or d ) begin    case(d) //synopsys full_case      2'b00:a = b >>1 ;      2'b11:c = b >>1 ;    endcase  endendmodule

使用了//synopsys full_case 選項,

該選項:

1、防止綜合工具將case語句綜合成不必要的優先順序電路,增大硬體開銷

2、和default語句類似,補全case語句沒有列出的情況。

3、但是//synopsys full_case會造成工具之間的移植性問題,改程式碼依然綜合出了鎖存器

10c97a8d-9c1a-eb11-8da9-e4434bdf6706.png

由上圖我們可以看出,對於2 位元的右移位“>> ” a[1]和c[1]恆等於1’b0 但是程式碼C 卻使用了4 個鎖存器,這是一個比較詭異的事情!

12c97a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg

14c97a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg

往期精彩

數字IC筆試題(1) ——復旦微2017

數字IC筆試題(2) ——匯頂設計驗證2018

數字IC筆試題(3) ——Cadence前端設計2018

數字IC筆試題(4) ——Nvidia前端設計2018

數字IC筆試題(5) ——全志科技數字前端

數字IC筆試題(6) ——樂鑫科技數字晶片2020

數字IC筆試題(7) ——樂鑫科技數字晶片2017

字IC筆試題(8) ——樂鑫科技數字晶片2020(續)

數字IC筆試題(9) ——匯頂設計驗證2019(續)

數字IC筆試題(10) ——卓勝微電子2020

數字IC筆試題(11)——卓勝微電子2020(續)

數字IC筆試題(12)——上海南芯2019秋招筆試預測題

數字IC筆試題(13)——大疆2019 FPGA校招筆試

15c97a8d-9c1a-eb11-8da9-e4434bdf6706.png 16c97a8d-9c1a-eb11-8da9-e4434bdf6706.gif

前瞻性的眼光,

和持之以恆地學習~

17c97a8d-9c1a-eb11-8da9-e4434bdf6706.jpeg 18c97a8d-9c1a-eb11-8da9-e4434bdf6706.png