數字IC前端學習筆記:鎖存器的綜合

相關閱讀

數字IC前端專欄https://blog.csdn.net/weixin_45791458/category_12173698.html?spm=1001.2014.3001.5482


? ? ? ? 鎖存器是一種時序邏輯,與寄存器相比面積更小,但它的存在會使靜態時序分析(STA)變得更加復雜,因此懂得什么樣的設計會綜合出鎖存器是很重要的,本文就將對此進行詳細介紹。?

顯式鎖存器

? ? ? ? 顯式鎖存器指的是在連續賦值語句或組合邏輯always結構中,將信號顯式賦值給自己時出現的鎖存器,一般顯式鎖存器是有意為之的。

連續賦值語句

最直觀的鎖存器

圖1 D型鎖存器

// 例1
module NonLatch1 (input wire d,input wire en,output wire q,output wire qbar
);wire set, rst;assign set =  !(en &  d);assign rst =  !(en & !d);assign q    = !(set & qbar);assign qbar = !(rst & q);endmodule

? ? ? ? 圖2是例1在Design Compiler 2024中的綜合結果,可以看出,即使可以綜合,綜合工具并沒有推斷出D鎖存器,而是綜合為存在組合環(Combinational Loop)或者說反饋的結構。

圖2 例1的綜合結果

使用條件操作符

// 例2
module NonLatch2 (input wire d,input wire en,output wire q,output wire qbar
);assign q = en ? d : q;assign qbar = !q;
endmodule

????????圖3是例2的綜合結果,可以看出,綜合工具也沒有推斷出D鎖存器,而是綜合為存在組合環(Combinational Loop)或者說反饋的多路選擇器。?

圖3 例2的綜合結果

always結構

? ? ? ? 需要注意的是,這里指的是組合邏輯always結構,而不是邊沿控制的時序邏輯always塊,對于后者,綜合工具會推斷出觸發器而不是鎖存器。

使用條件操作符

// 例3
module Latch1 (input wire d,input wire en,output reg q,output reg qbar
);always @(*) beginq = en ? d : q;qbar = !q;endendmodule

????????圖4是例3的綜合結果,可以看出,綜合工具將其綜合為D鎖存器。?

圖4?例3的綜合結果

使用if-else語句

// 例4
module Latch2 (input wire d,input wire en,output reg q,output reg qbar
);always @(*) beginif (en) beginq = d; qbar = ~d;endelse beginq = q; qbar = qbar;endendendmodule

????????圖5是例4的綜合結果,可以看出,綜合工具將其綜合為D鎖存器,但與圖4有一點區別,原因是發生了在優化過程中發生了相位反轉和寄存器合并。??

圖5?例4的綜合結果

隱式鎖存器

? ? ? ? 隱式鎖存器指的是在always結構中,沒有將自己顯式賦值給自己,但由于意料之外的因素出現的鎖存器。

不完整的敏感列表

// 例5
module NonLatch3 (input wire a,input wire b,input wire c,output reg y
);always @(a) beginy = a & b & c;endendmodule

? ? ? ? 例5使用組合邏輯always結構描述了一個三輸入與門,但敏感列表中只有a而不含b和c,這導致了只有a發生變化時才會激活always結構。對于以前的綜合工具,這會導致鎖存器的產生;對于現在的綜合工具,其對組合邏輯always結構的綜合不依賴敏感列表,因此不會有鎖存器產生,但這會導致前/后仿真的不一致,因為對于仿真工具根據敏感列表進行判斷,因此行為就像是鎖存器。

????????圖6是例5的綜合結果,可以看出,綜合工具將其綜合為三輸入與門。?

圖6?例5的綜合結果

????????實際上,由于不完整的敏感列表帶來的風險如此巨大,Verilog 2001標準新加了一個*通配符來形成一個完整的敏感列表。使用通配符意味著always結構中RHS表達式、函數和任務調用的參數、case語句的case expression和case item、if語句的expression信號將自動加入敏感列表,如例6所示。?

// 例6
module NonLatch4 (input wire a,input wire b,input wire c,output reg y
);always @(*) beginy = a & b & c;endendmodule

不完整的if語句

// 例7
module Latch3 (input wire a,input wire b,output reg y
);always @(*) beginif (a) y = b;endendmodule

? ? ? ? 例7中的if語句缺少else分支,即當a為0時輸出保持不變(這其實與例4等價,只不過例4是顯式賦值),這是一個鎖存器的行為,圖7是例7的綜合結果,可以看出,綜合工具將其綜合為D鎖存器。?

圖7?例7的綜合結果

解決方法1

? ? ? ? 保持if語句完整且在每個分支中對所有信號的賦值,如例8所示。

// 例8
module NonLatch5 (input wire a,input wire b,output reg y
);always @(*) beginif (a) y = b;else   y = 1'b0;endendmodule

解決方法2

? ? ? ? 在always結構的開頭對所有信號賦初值,如例9所示。

// 例9
module NonLatch6 (input wire a,input wire b,output reg y
);always @(*) beginy = 1'b0;if (a) y = b;endendmodule

不完整的case語句

// 例10
module Latch4 (input wire [1:0] sel,input wire a,input wire b,output reg y
);always @(*) begincase (sel)2'b00: y = 1'b0;2'b01: y = 1'b1;endcase
endendmodule

? ? ? ? 與例7類似,例10中的case語句缺少case item,即當sel[1]為1時輸出保持不變,這是一個鎖存器的行為,圖8是例10的綜合結果,可以看出,綜合工具將其綜合為D鎖存器。?

圖8?例10的綜合結果

解決方法1

????????保持case語句完整且在每個分支中對所有信號的賦值(或者干脆使用case default),如例11所示。

// 例11
module NonLatch7 (input wire [1:0] sel,input wire a,input wire b,output reg y
);always @(*) begincase (sel)2'b00: y = a;2'b01: y = b;2'b01: y = 1'b1;2'b01: y = 1'b0;// default: y = 1'b0;endcase
endendmodule

解決方法2

????????在always結構的開頭對所有信號賦初值,如例12所示。

// 例12
module NonLatch8 (input wire [1:0] sel,input wire a,input wire b,output reg y
);always @(*) beginy = 1'b0;case (sel)2'b00: y = a;2'b01: y = b;endcase
endendmodule

根本原因

? ? ? ? 以上這些無意間綜合出的鎖存器產生的根本原因是出現了在某些情況下需要保持信號值不變的需求,而又使用了組合邏輯always結構,因此只能使用鎖存器實現功能。

? ? ? ? 思考一個問題:如果不使用本文提到的這些解決方法,不完整的if語句和case語句一定會綜合出鎖存器嗎?例13會綜合出鎖存器嗎?

// 例12
module Latch_or_Not (input wire sel,input wire a,input wire b,output reg y
);reg [1:0] sel_with_constraint;always @(*) beginif (sel) sel_with_constraint = 2'b00;else     sel_with_constraint = 2'b01;
endalways @(*) beginy = 1'b0;case (sel_with_constraint)2'b00: y = a;2'b01: y = b;endcase
endendmodule

????????圖9是例13的綜合結果,如果這與你想的不一樣,想想鎖存器產生的根本原因,而不是孤立地看待if語句和case語句。

圖9 例13的綜合結果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80103.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80103.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80103.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LVGL源碼學習之渲染、更新過程(2)---無效區域的處理

LVGL版本:8.1 往期回顧: LVGL源碼學習之渲染、更新過程(1)---標記和激活 區域合并 在前面的代碼分析中,發現標記無效區域的工作其實很繁瑣,雖然大部分區域因為包含關系被剔除,但仍可能存在相互交叉的區域&#xff0c…

01 dnsmasq 中 dns服務

前言 這里我們主要是 來看一下 dns 服務器這邊的相關業務處理 通常來說 在我們日常生活中 還是經常會需要使用 dns 的情況, 主要是更加友好的去給一個主機命名一個別名 比如 現在我的應用在服務器 192.168.220.133 但是我不想記這個生硬的 ip, 我可能更期望記錄一個域名, …

最優化方法Python計算:有約束優化應用——線性Lasso回歸分類器

利用線性Lasso模型類LineLassoModel類(見博文《最優化方法Python計算:有約束優化應用——線性Lasso回歸預測器》)及分類器類Classification(見博文《最優化方法Python計算:無約束優化應用——線性回歸分類器》&#xf…

Python基礎學習-Day20

目錄 奇異值分解(SVD)的輸入和輸出奇異值的應用實際案例1. 問題分析2. 解決方案:對測試集應用相同的變換3. 為什么不能對測試集單獨做 SVD?4. 代碼示例:訓練集和測試集的 SVD 降維6. 實際操作中的注意事項 奇異值分解&…

2025年 全新 AI 編程工具 Cursor 安裝使用教程

一、Cursor 軟件下載 首選,登錄Cursor官網,進行軟件下載,官網下載地址如下: Cursor AI IDE 下載 二、Cursor軟件安裝配置 此處以Windows10系統安裝為例,下載完成之后,右鍵安裝包,以管理員身份…

[vue]error:0308010C:digital envelope routines::unsupported

npm run dev 報錯: \node_modules\webpack\hot\dev-server.jsnode:internal/crypto/hash:71 this[kHandle] new _Hash(algorithm, xofLen); Error: error:0308010C:digital envelope routines::unsupported opensslErrorStack: [ error:03000086:digital env…

開放的力量:新零售生態的共贏密碼

當某頭部生鮮平臺向供應商開放銷售預測系統后,合作伙伴的庫存周轉率竟提升12%——這個反常識的案例,正在重塑商業競爭的底層邏輯。 生態共建三板斧 ▌模塊化設計:像搭積木一樣開放 ? 樂高式API架構:30%接口支持自由組合&#xff…

深入理解Spring緩存注解:@Cacheable與@CacheEvict

在現代應用程序開發中,緩存是提升系統性能的重要手段。Spring框架提供了一套簡潔而強大的緩存抽象,其中Cacheable和CacheEvict是兩個最常用的注解。本文將深入探討這兩個注解的工作原理、使用場景以及最佳實踐。 1. Cacheable注解 基本概念 Cacheable…

[python] 函數3-python內置函數

一 內置函數 導入:import builtins 1.1 查看內置函數 大寫字母開頭的一般是內置變量小寫的一般是內置函數 import builtins print(dir(builtins)) 1.2 abs() 求絕對值 print(abs(-10)) 1.3 sum()求和 不能直接用純數字,因為不是可迭代對象 運算時只要一個是浮點數,結果就…

QT異步線程通信

在使用 QThreadPool 提交任務后,如果你需要知道任務何時完成,并且需要使用任務的執行結果,可以通過以下幾種方式來實現: 1. 使用信號和槽 QRunnable 提供了一個 finished() 信號,當任務執行完成后會發出。你可以在任…

利用并行處理提高LabVIEW程序執行速度

在 LabVIEW 編程中,提升程序執行速度是優化系統性能的關鍵,而并行處理技術則是實現這一目標的有力武器。通過合理運用并行處理,不僅能加快程序運行,還能增強系統的穩定性和響應能力。下面將結合實際案例,深入探討如何利…

機器學習第三講:監督學習 → 帶答案的學習冊,如預測房價時需要歷史價格數據

機器學習第三講:監督學習 → 帶答案的學習冊,如預測房價時需要歷史價格數據 資料取自《零基礎學機器學習》。 查看總目錄:學習大綱 關于DeepSeek本地部署指南可以看下我之前寫的文章:DeepSeek R1本地與線上滿血版部署&#xff1…

Open CASCADE學習|實現裁剪操作

1. 引言 Open CASCADE (簡稱OCC) 是一個功能強大的開源幾何建模內核,廣泛應用于CAD/CAM/CAE領域。裁剪操作作為幾何建模中的基礎功能,在模型編輯、布爾運算、幾何分析等方面有著重要作用。本文將全面探討Open CASCADE中的裁剪操作實現原理、應用場景及具…

【redis】分片方案

Redis分片(Sharding)是解決單機性能瓶頸的核心技術,其本質是將數據分散存儲到多個Redis節點(實例)中,每個實例將只是所有鍵的一個子集,通過水平擴展提升系統容量和性能。 分片的核心價值 性能提…

RGB矩陣照明系統詳解及WS2812配置指南

RGB矩陣照明系統詳解及WS2812配置指南 一、RGB矩陣照明簡介 RGB矩陣照明是一種強大的功能,允許使用外部驅動器驅動的RGB LED矩陣為鍵盤增添絢麗的燈光效果。該系統與RGBLIGHT功能無縫集成,因此您可以使用與RGBLIGHT相同的鍵碼來控制它,操作…

[250509] x-cmd 發布 v0.5.11 beta:x ping 優化、AI 模型新增支持和語言變量調整

目錄 X-CMD 發布 v0.5.11 beta📃Changelog🧩 ping🧩 openai🧩 gemini🧩 asdf🧩 mac? 升級指南 X-CMD 發布 v0.5.11 beta 📃Changelog 🧩 ping 調整 x ping 默認參數為 bing.com&a…

嵌入式開發學習日志Day17

第十一章 結構體與共用體 一、結構體 1、結構體 一般形式 【struct 標識符】 結構體中的標識符一般首字母大寫; 【.】結構體成員運算符; 優先級 1 級 結合方向:從左至右; 【->】:指向結構體成員運算符&#x…

發那科機器人5(異常事件和程序備份加載+ROBOGUIDE離線仿真)

發那科機器人5(異常事件和程序備份加載+ROBOGUIDE離線仿真) 一,異常事件和程序備份加載1,常見異常事件2,零點復歸介紹3,程序備份-加載(未整理)二,`ROBOGUIDE`離線仿真1,仿真軟件簡介及安裝步驟(未整理)2,機器人==導入與工具==與==工件添加==2.1,機器人導入(未整…

青少年編程與數學 02-019 Rust 編程基礎 01課題、環境準備

青少年編程與數學 02-019 Rust 編程基礎 01課題、環境準備 一、Rust核心特性應用場景開發工具社區與生態 二、Rust 和 Python 比較1. **內存安全與并發編程**2. **性能**3. **零成本抽象**4. **跨平臺支持**5. **社區與生態系統**6. **錯誤處理**7. **安全性**適用場景總結 三、…

Java反射 八股版

目錄 一、核心概念闡釋 1. Class類 2. Constructor類 3. Method類 4. Field類 二、典型應用場景 1. 框架開發 2. 單元測試 3. JSON序列化/反序列化 三、性能考量 四、安全與訪問控制 1. 安全管理器限制 2. 打破封裝性 3. 安全風險 五、版本兼容性問題 六、最佳…