數(shù)器設(shè)計(jì)詳解:從JK觸發(fā)器狀態(tài)表到Verilog仿真全流程)
簡介一份面向數(shù)字電子線路課程的實(shí)驗(yàn)指導(dǎo)文檔圍繞計(jì)數(shù)器邏輯功能與設(shè)計(jì)展開適合高校電類專業(yè)學(xué)生及數(shù)字電路學(xué)習(xí)者閱讀。內(nèi)容覆蓋同步/異步、二進(jìn)制/十進(jìn)制/任意進(jìn)制、加法/減法/可逆計(jì)數(shù)器等基礎(chǔ)分類重點(diǎn)講解反饋歸零法和反饋置數(shù)法設(shè)計(jì)任意進(jìn)制計(jì)數(shù)器并結(jié)合74HC161、74HC390等中規(guī)模集成芯片以簡易數(shù)字鐘為例呈現(xiàn)六十進(jìn)制、二十四進(jìn)制計(jì)數(shù)器的級聯(lián)構(gòu)建方法。資源共1個(gè)docx文件大小207KB文檔包含實(shí)驗(yàn)?zāi)康摹x器設(shè)備、預(yù)習(xí)要求、原理說明、芯片結(jié)構(gòu)圖與引腳圖、實(shí)驗(yàn)步驟和思考題等完整環(huán)節(jié)既可作為實(shí)驗(yàn)預(yù)習(xí)資料也可在設(shè)計(jì)接線時(shí)提供方法與思路參考。已有288人學(xué)習(xí)該資源適合需要完成同類數(shù)字電路實(shí)驗(yàn)并希望深入理解計(jì)數(shù)功能與設(shè)計(jì)方法的讀者。1. 2-5 計(jì)數(shù)器是什么先把這個(gè)邏輯功能翻譯成電路術(shù)語拿到“數(shù)字電子線路基礎(chǔ)2-5 計(jì)數(shù)器邏輯功能和設(shè)計(jì)”這個(gè)題目時(shí)最容易踩的坑是把它當(dāng)成一個(gè)簡單的“從 2 數(shù)到 5 再停下來”的計(jì)數(shù)器。實(shí)際上數(shù)字電路里說 2-5 計(jì)數(shù)器通常指一個(gè)同步計(jì)數(shù)器讓狀態(tài)按 2→3→4→5→2 循環(huán)每來一個(gè)時(shí)鐘上升沿前進(jìn)一次本質(zhì)是一個(gè)模 4 計(jì)數(shù)器只是有效狀態(tài)從 2 開始、到 5 結(jié)束。這種序列控制邏輯在電子鐘分頻、步進(jìn)電機(jī)換相、交通燈時(shí)序和簡單狀態(tài)機(jī)里非常常見。適合的人群是正在上數(shù)字電子線路課的初學(xué)者以及想做課程設(shè)計(jì)但不想只抄仿真圖的硬件新人。這篇文章的目標(biāo)很直接幫你把“邏輯功能”拆成狀態(tài)表再用 JK 觸發(fā)器設(shè)計(jì)出可復(fù)現(xiàn)的電路最后用仿真驗(yàn)證它真的在循環(huán)而不是停在某個(gè)非法狀態(tài)里出不來。2. 狀態(tài)設(shè)計(jì)2→3→4→5→2 的循環(huán)怎么變成狀態(tài)表2.1 三比特編碼2、3、4、5 到底對應(yīng)哪一組 Q2Q1Q0數(shù)字電路的計(jì)數(shù)器最終要落到觸發(fā)器的 Q 端上。2-5 這個(gè)序列里一共有四個(gè)有效狀態(tài)理論上兩個(gè)觸發(fā)器就夠了但兩個(gè)觸發(fā)器只能表示 0 到 3如果直接把 2、3、4、5 當(dāng)作數(shù)值兩個(gè)觸發(fā)器根本裝不下 4 和 5。因此常見做法是用三個(gè)觸發(fā)器 Q2、Q1、Q0把狀態(tài)編碼成三位二進(jìn)制計(jì)數(shù)序號計(jì)數(shù)值Q2 Q1 Q0020 1 0130 1 1241 0 0351 0 14回到 20 1 0注意這里的狀態(tài)編碼不是連續(xù)的 000→001→010→011而是 010→011→100→101 循環(huán)。為什么要這樣編碼因?yàn)檫@樣最直觀地對應(yīng)輸出數(shù)值Q2Q1Q0 本身就是二進(jìn)制數(shù)010 等于十進(jìn)制 2011 等于 3100 等于 4101 等于 5。后續(xù)接數(shù)碼管顯示或者接比較器判斷數(shù)值時(shí)不需要再額外做復(fù)雜的算術(shù)轉(zhuǎn)換。剩下的 000、001、110、111 四個(gè)狀態(tài)是非法狀態(tài)。設(shè)計(jì)時(shí)我一般不會(huì)直接忽略它們否則仿真跑得通、上電后可能卡在 000 或者 111 里永遠(yuǎn)進(jìn)不了循環(huán)。真正可靠的計(jì)數(shù)器設(shè)計(jì)必須把非法狀態(tài)也拉回到合法狀態(tài)這就是后面要說的自啟動(dòng)設(shè)計(jì)。2.2 把狀態(tài)轉(zhuǎn)換寫成激勵(lì)表JK 觸發(fā)器對每個(gè)翻轉(zhuǎn)需要什么輸入有了狀態(tài)編碼下一步是列出狀態(tài)轉(zhuǎn)換關(guān)系。每來一個(gè)時(shí)鐘上升沿電路從當(dāng)前狀態(tài)跳到下一狀態(tài)。四個(gè)合法轉(zhuǎn)換是010→011011→100100→101101→010。再用 JK 觸發(fā)器的特性逐位分析。JK 觸發(fā)器的行為是J1、K0 時(shí)置位為 1J0、K1 時(shí)清零為 0J1、K1 時(shí)翻轉(zhuǎn)J0、K0 時(shí)保持。所以對于某一位 Q如果它要從 0 變 1那 J 必須為 1如果要從 1 變 0那 K 必須為 1如果保持原值則 J 和 K 中至少有一個(gè)為 0具體是 00 還是 10 還是 01 都可以通常填 X 表示任意。下面是三個(gè)觸發(fā)器的完整性激勵(lì)表當(dāng)前狀態(tài)下一狀態(tài)J2 K2J1 K1J0 K00100110 XX 01 X0111001 XX 1X 1100101X 00 X1 X101010X 11 XX 1以 011→100 這行為例Q2 從 0 變 1所以 J21Q1 從 1 變 0所以 K11Q0 從 1 變 0所以 K01。其他位填 X這不代表引腳可以懸空而是說化簡時(shí)可以靈活選擇 0 或 1用來湊最簡邏輯式。2.3 先把可運(yùn)行的計(jì)數(shù)器模塊搭出來一個(gè) Verilog 最小框架狀態(tài)表寫完我先不急著化簡而是用 Verilog 把 JK 觸發(fā)器和計(jì)數(shù)器骨架搭出來。這樣做的好處是后面每一步化簡出的方程都可以直接替換進(jìn)代碼里跑仿真不會(huì)等到接線完才發(fā)現(xiàn)邏輯矛盾。先寫一個(gè)行為級 JK 觸發(fā)器module jk_ff ( input wire clk, input wire rst_n, input wire j, input wire k, output reg q ); always (posedge clk or negedge rst_n) begin if (!rst_n) begin q 1b0; end else begin case ({j, k}) 2b10: q 1b1; // J1,K0 置位 2b01: q 1b0; // J0,K1 清零 2b11: q ~q; // J1,K1 翻轉(zhuǎn) default: q q; // 保持 endcase end end endmodule這段代碼里的 case 語句直接對應(yīng) JK 觸發(fā)器的四種行為。注意 default 分支不能省略否則 j/k 為 00 時(shí) q 的行為在仿真里可能沒有定義綜合時(shí)也容易多出鎖存器或不定態(tài)。再寫計(jì)數(shù)器頂層module counter_2_5 ( input wire clk, input wire rst_n, output wire [2:0] q ); wire j2, k2, j1, k1, j0, k0; wire [2:0] q; // 先臨時(shí)用最保守的激勵(lì)保持為低后面用卡諾圖化簡結(jié)果替換 assign j2 1b0; assign k2 1b0; assign j1 1b0; assign k1 1b0; assign j0 1b0; assign k0 1b0; jk_ff u2 (.clk(clk), .rst_n(rst_n), .j(j2), .k(k2), .q(q[2])); jk_ff u1 (.clk(clk), .rst_n(rst_n), .j(j1), .k(k1), .q(q[1])); jk_ff u0 (.clk(clk), .rst_n(rst_n), .j(j0), .k(k0), .q(q[0])); endmodule復(fù)位后三個(gè)觸發(fā)器輸出都是 000所以計(jì)數(shù)器會(huì)先從 000 跳到 010再進(jìn)入 2→3→4→5 循環(huán)。這里把復(fù)位統(tǒng)一做成低電平異步復(fù)位所有觸發(fā)器在一個(gè)復(fù)位信號控制下回到 000避免不同觸發(fā)器復(fù)位時(shí)間不一致導(dǎo)致狀態(tài)錯(cuò)位。下一步就是使用激勵(lì)表求出這六根線 j2、k2、j1、k1、j0、k0 的表達(dá)式。3. 從狀態(tài)表到邏輯圖卡諾圖化簡和接線3.1 用卡諾圖圈 JK 激勵(lì)J2、K2、J1 怎么圈最少卡諾圖是手算組合邏輯最快的方法。我以 J2 為例演示化簡過程。J2 只在當(dāng)前狀態(tài) 011 時(shí)為 1其他合法狀態(tài)為 0 或 X非法狀態(tài)里 110、111 是 X000、001 我們暫時(shí)希望它是 0。按 Q2Q1 作行、Q0 作列可得到下面的三變量卡諾圖J2 的卡諾圖 Q00 Q01 Q2Q100 0 0 Q2Q101 0 1 Q2Q111 X X Q2Q110 X X卡諾圖圈“1”和“X”時(shí)盡量圈 2、4、8 個(gè)相鄰格。這張圖里 011 這個(gè) 1 與 111 這個(gè) X 相鄰可以圈成一行化簡結(jié)果是 Q1·Q0。所以 J2 Q1·Q0。K2 的卡諾圖同樣處理K2 需要在 Q2Q1Q0101 時(shí)為 1為了讓非法狀態(tài) 110、111 也能被清回合法狀態(tài)K2 要在這兩個(gè)非法狀態(tài)也為 1圈出來就是 Q2·(Q1Q0)。3.2 六條激勵(lì)方程和自啟動(dòng)校驗(yàn)按同樣的卡諾圖方法把所有激勵(lì)項(xiàng)圈完得到一組可以直接接線使用的方程信號化簡表達(dá)式作用位說明J2Q1·Q0只有 Q1、Q0 同時(shí)為 1 時(shí)把 Q2 置 1K2Q2·(Q1Q0)Q2 為 1 且 Q1 或 Q0 為 1 時(shí)把 Q2 清 0J1~Q1·(~Q2Q0)讓 Q1 在狀態(tài) 000、001、101 時(shí)置 1K1~Q2·Q1·Q0從 011 轉(zhuǎn)到 100 時(shí)把 Q1 清 0J0Q2 XOR Q1兩個(gè)高位不同時(shí)讓 Q0 置 1K0Q0Q0 為 1 時(shí)下一個(gè)周期必翻轉(zhuǎn)這組方程和上一章激勵(lì)表的合法狀態(tài)完全一致同時(shí)還處理了非法狀態(tài)。比如 000 狀態(tài)下J1 為 1、K1 為 0一個(gè)時(shí)鐘脈沖后 Q1 變 1狀態(tài)變成 010也就是回到計(jì)數(shù)值 2。111 狀態(tài)下 J2、K2 同時(shí)為 1Q2 翻轉(zhuǎn)成 0J0、K0 同時(shí)為 1Q0 翻轉(zhuǎn)成 0Q1 保持 1于是也落到 010。四個(gè)非法狀態(tài)都會(huì)在 1 到 2 個(gè)時(shí)鐘周期內(nèi)回到合法循環(huán)里這就是自啟動(dòng)。寫一小段 Python 腳本可以快速驗(yàn)證狀態(tài)轉(zhuǎn)移def jk_next(q, j, k): if j and not k: return 1 if k and not j: return 0 if j and k: return 1 - q return q def next_state(q2, q1, q0): j2 q1 and q0 k2 q2 and (q1 or q0) j1 (not q1) and ((not q2) or q0) k1 (not q2) and q1 and q0 j0 q2 ^ q1 k0 q0 return ( jk_next(q2, j2, k2), jk_next(q1, j1, k1), jk_next(q0, j0, k0), ) seen {} for s in range(8): q2 (s 2) 1 q1 (s 1) 1 q0 s 1 path [] while (q2, q1, q0) not in path: path.append((q2, q1, q0)) q2, q1, q0 next_state(q2, q1, q0) print(f初始 {path[0]} - 第一步 {path[1] if len(path)1 else } 循環(huán)長度 {len(path)})這段腳本把八個(gè)狀態(tài)全部跑一遍如果每個(gè)狀態(tài)的路徑最終都能落進(jìn) 010→011→100→101 這個(gè)環(huán)就說明自啟動(dòng)沒問題。參數(shù)上要注意Python 里的 and/or 返回的是布爾值JK 觸發(fā)器的 q 是 0 或 1所以在 jk_next 里直接返回 0/1不會(huì)出現(xiàn) None 或字符串問題。3.3 邏輯圖接線從觸發(fā)器輸出到 2-5 輸出端得到激勵(lì)方程后實(shí)際接線就是把門電路連接到三個(gè) JK 觸發(fā)器的 J/K 端。J2 用一只二輸入與門輸入接 Q1 和 Q0K2 用一只二輸入或門接 Q1、Q0再和 Q2 相與J1 需要兩只門組合先讓 Q2 取反后與 Q0 相或再與 Q1 的反相相與K1 是三輸入與門J0 用異或門K0 直接接 Q0。整體是簡單的 SSI 門電路不需要鎖存器或額外寄存器。輸出端不需要二次譯碼因?yàn)?Q2Q1Q0 本身就是二進(jìn)制編碼的 2、3、4、5。若你想接數(shù)碼管需要再送 BCD 轉(zhuǎn)七段譯碼器因?yàn)閿?shù)碼管驅(qū)動(dòng)要求的是 8421 BCD 碼而不是原始三位二進(jìn)制碼。進(jìn)位信號則可取 K2 的輸出因?yàn)槊慨?dāng) Q2 被清零時(shí)就意味著狀態(tài)要從 5 回到 2這個(gè)時(shí)刻就是一輪循環(huán)結(jié)束。4. 仿真驗(yàn)證讓計(jì)數(shù)器按預(yù)期跑完一輪循環(huán)4.1 最小測試平臺(tái)時(shí)鐘、復(fù)位和一輪 2→3→4→5→2邏輯圖畫得對不對最快的方法是跑行為仿真。測試平臺(tái)最小化到只要三樣?xùn)|西時(shí)鐘發(fā)生器、復(fù)位信號、計(jì)數(shù)器實(shí)例。下面是一個(gè)完整的 testbenchmodule tb_counter_2_5; reg clk 0; reg rst_n 0; wire [2:0] q; counter_2_5 uut ( .clk(clk), .rst_n(rst_n), .q(q) ); always #5 clk ~clk; // 時(shí)鐘周期 10ns always (posedge clk) begin if (rst_n) $display(t%0t q%b %d, $time, q, q); end initial begin $dumpfile(counter_2_5.vcd); $dumpvars(0, tb_counter_2_5); #10 rst_n 1; // 復(fù)位釋放等待第一個(gè)上升沿 repeat (8) (posedge clk); $finish; end endmodule這里時(shí)鐘用 always #5 clk ~clk生成 10ns 周期的方波。復(fù)位保持 10ns即一個(gè)完整時(shí)鐘周期后才釋放確保電源和復(fù)位建立穩(wěn)定。repeat(8) 表示觀察八個(gè)時(shí)鐘沿足夠覆蓋 000→010→011→100→101→010 兩輪循環(huán)。$display 會(huì)在每個(gè)時(shí)鐘上升沿后打印當(dāng)前 Q 值方便對照狀態(tài)表。4.2 跑仿真并讀結(jié)果四個(gè)邊沿對應(yīng)四個(gè)狀態(tài)如果使用免費(fèi)的 Verilog 仿真工具命令行方式如下iverilog -s tb_counter_2_5 -o counter_tb.out counter_2_5.v tb_counter_2_5.v vvp counter_tb.out也可以換成自己熟悉的圖形化仿真器把 counter_2_5.v 和 testbench 一起加進(jìn)工程即可。運(yùn)行后打印結(jié)果應(yīng)該是時(shí)鐘邊沿序號Q2 Q1 Q0十進(jìn)制值第 1 個(gè)上升沿0 1 02第 2 個(gè)上升沿0 1 13第 3 個(gè)上升沿1 0 04第 4 個(gè)上升沿1 0 15第 5 個(gè)上升沿0 1 02注意如果在第 1 個(gè)上升沿看到的是 011先別急著改代碼檢查復(fù)位釋放時(shí)間。由于復(fù)位釋放后電路首先把 000 拉到 010這個(gè)跳變發(fā)生在復(fù)位釋放后的第一個(gè)上升沿正好對應(yīng)“2”。如果復(fù)位釋放與時(shí)鐘同時(shí)發(fā)生可能會(huì)看到復(fù)位競爭把第一個(gè)狀態(tài)吃掉這個(gè)問題后面單獨(dú)講。4.3 波形檢查時(shí)重點(diǎn)看哪幾個(gè)信號時(shí)鐘沿、復(fù)位釋放、毛刺打開波形文件后我習(xí)慣先看三個(gè)東西。第一是復(fù)位釋放位置是否在時(shí)鐘低電平區(qū)間不要在時(shí)鐘上升沿附近釋放復(fù)位第二是 Q 端變化是否都在上升沿后出現(xiàn)若某個(gè) Q 在時(shí)鐘低電平期間變了通常說明組合邏輯存在競爭冒險(xiǎn)第三是 J/K 信號本身有沒有毛刺尤其要觀察 J1 和 K1因?yàn)檫@兩個(gè)信號用了取反和或門門延遲不匹配時(shí)容易在時(shí)鐘沿附近出現(xiàn)極窄的尖峰。波形里還有一個(gè)容易被忽略的細(xì)節(jié)Q2 從 1 變 0 的時(shí)刻應(yīng)該和 Q1 從 0 變 1 基本同步因?yàn)?J0 依賴 Q2 XOR Q1兩個(gè)高位翻轉(zhuǎn)時(shí)間相差太大會(huì)讓 Q0 多翻一次。如果發(fā)現(xiàn) Q0 出現(xiàn)雙脈沖就要回到卡諾圖檢查是否把 J0 化簡得太大或者給 K0 增加一個(gè)小的濾波電容。5. 計(jì)數(shù)器設(shè)計(jì)避坑五個(gè)常見翻車點(diǎn)5.1 上電停在非法狀態(tài)計(jì)數(shù)器不進(jìn)循環(huán)現(xiàn)象仿真時(shí)把復(fù)位釋放后狀態(tài)一直是 000 或 111看不到 2→3→4→5 的序列。原因電路沒有做自啟動(dòng)設(shè)計(jì)非法狀態(tài)各自形成死循環(huán)比如 111→111。解決把非法狀態(tài)在激勵(lì)表里顯式處理至少要保證 000 和 111 能進(jìn)入合法環(huán)。本文先前的方程已經(jīng)在 000、001、110、111 上都做了跳轉(zhuǎn)處理如果你自己化簡時(shí)把非法狀態(tài)全部當(dāng)作 X 圈掉就可能得到非自啟動(dòng)電路。5.2 觸發(fā)器的復(fù)位方式不統(tǒng)一狀態(tài)錯(cuò)位一個(gè)周期現(xiàn)象板子實(shí)測時(shí)有時(shí)從 2 開始有時(shí)從 3 開始每上電結(jié)果都不一樣。原因某些觸發(fā)器用了異步復(fù)位另一些用了同步置數(shù)復(fù)位釋放的瞬間三位的恢復(fù)時(shí)間不一致。解決所有觸發(fā)器統(tǒng)一接同一個(gè)低電平復(fù)位并在復(fù)位釋放后預(yù)留至少一個(gè)完整時(shí)鐘周期再開始計(jì)數(shù)。不要在復(fù)位信號上串聯(lián)電阻或電容那只會(huì)讓沿更鈍。5.3 JK 同時(shí)為 1 造成的翻轉(zhuǎn)毛刺和競爭冒險(xiǎn)現(xiàn)象波形圖上 Q 端在同一個(gè)時(shí)鐘沿出現(xiàn)快速 0→1→0 的跳動(dòng)。原因某個(gè)位從 0 變 1 時(shí)J 和 K 同時(shí)為 1觸發(fā)器實(shí)際發(fā)生翻轉(zhuǎn)而相鄰位的組合邏輯還在變化造成二次翻轉(zhuǎn)。解決設(shè)計(jì)激勵(lì)方程時(shí)盡量讓“置位”和“清零”兩支路徑互斥避免 JK1 出現(xiàn)在關(guān)鍵轉(zhuǎn)換上。如果電路已經(jīng)焊好不方便改可以在 J/K 輸入端加同步寄存器讓激勵(lì)信號和時(shí)鐘嚴(yán)格同源同沿。5.4 把 Q2Q1Q0 直接當(dāng)十進(jìn)制輸出數(shù)碼管亂碼現(xiàn)象LED 或數(shù)碼管顯示的不是 2、3、4、5而是跳出一堆亂碼。原因大多數(shù)七段數(shù)碼管需要 BCD 碼而 Q2Q1Q0 是以 010、011、100、101 編碼的原始狀態(tài)直接接上去當(dāng)然對不上。解決接一個(gè) BCD 七段譯碼器或者用單片機(jī)讀 Q 后再查表輸出。若只想驗(yàn)證邏輯功能用三只 LED 分別顯示 Q2、Q1、Q0 就夠了010 燈亮狀態(tài)就是計(jì)數(shù)值 2。5.5 復(fù)位時(shí)間太短上電瞬間就把 2 漏掉現(xiàn)象示波器看到計(jì)數(shù)器啟動(dòng)后第一個(gè)狀態(tài)是 3而不是 2。原因復(fù)位信號寬度小于一個(gè)時(shí)鐘周期電路還沒從 000 跳到 010第一次有效上升沿就把它當(dāng)成了 010 本身直接推進(jìn)到 011。解決復(fù)位低電平至少要維持兩個(gè)時(shí)鐘周期以上并在時(shí)鐘低電平中段釋放。上電復(fù)位電路可以用施密特觸發(fā)器反相器加 RC 延遲RC 時(shí)間常數(shù)取時(shí)鐘周期的 10 倍以上。6. 進(jìn)階用法把一個(gè)固定序列計(jì)數(shù)器變成可預(yù)置分頻器6.1 加一個(gè)置數(shù)端計(jì)數(shù)器就能從指定位置重新開始固定 2→3→4→5 的計(jì)數(shù)器再往上走一步就是加置數(shù)端。常見做法是把撥碼開關(guān)預(yù)置到 010當(dāng) LD 信號有效時(shí)在下一個(gè)時(shí)鐘沿把 Q2、Q1、Q0 分別裝入預(yù)設(shè)值。這樣不但能隨時(shí)讓狀態(tài)回到 2還能通過改變預(yù)置數(shù)改變起始位置把一個(gè)固定序列計(jì)數(shù)器變成可編程的分頻器。比如預(yù)置 100 時(shí)計(jì)數(shù)序列變成 4→5→2→3輸出脈沖密度不變但相位整體移動(dòng)了。實(shí)際使用時(shí)LD 信號要和時(shí)鐘同步否則仍然會(huì)出現(xiàn)上一章說的競爭問題。6.2 用級聯(lián)和進(jìn)位輸出擴(kuò)展計(jì)數(shù)范圍單個(gè)計(jì)數(shù)器只有 4 拍。要做更長定時(shí)把低位計(jì)數(shù)器的進(jìn)位輸出接到高位計(jì)數(shù)器的時(shí)鐘端就得到級聯(lián)結(jié)構(gòu)。低位從 5 跳回 2 時(shí)K2 產(chǎn)生一個(gè)低脈沖經(jīng)過簡單整形后送給高位時(shí)鐘高位計(jì)數(shù)器加 1。這樣兩級級聯(lián)后周期為 16 個(gè)低位周期輸出頻率是輸入時(shí)鐘的十六分之一。級聯(lián)時(shí)要注意高位時(shí)鐘觸發(fā)沿低位進(jìn)位信號翻轉(zhuǎn)沿不能太緩建議用上升沿觸發(fā)的邊沿檢測電路整形后再接高位。6.3 一次系統(tǒng)性自檢腳本模擬八個(gè)周期驗(yàn)證自啟動(dòng)最后分享一個(gè)我常用的收尾動(dòng)作把設(shè)計(jì)好的電路在軟件里做一次全狀態(tài)遍歷。做法是把上一章的 Python 腳本擴(kuò)展一下從 8 個(gè)狀態(tài)分別運(yùn)行 8 個(gè)時(shí)鐘周期斷言最終都進(jìn)入 010→011→100→101 環(huán)。只要這個(gè)斷言過了綜合和接線再出問題基本可以排除邏輯功能錯(cuò)誤。固定序列計(jì)數(shù)器最怕的不是門電路復(fù)雜而是某些“想當(dāng)然能忽略”的非法狀態(tài)在斷電上電時(shí)偷偷接管電路。我習(xí)慣把這套自檢腳本留在工程目錄里每次改完激勵(lì)方程都跑一遍給自己留一張后悔藥。希望這篇從狀態(tài)表到仿真、再到實(shí)物排錯(cuò)的筆記能幫你少走一圈彎路也希望你能把這套自啟動(dòng)的思路用在你手頭的下一個(gè)序列控制電路上。本文還有配套的精品資源點(diǎn)擊獲取