練習十. 通過模塊之間的調用實現自頂向下的設計目的:學習狀態機的嵌套使用實現層次化、結構化設計。
現代硬件系統的設計過程與軟件系統的開發相似,設計一個大規模的集成電路的往往由模塊多層次的引用和組合構成。層次化、結構化的設計過程,能使復雜的系統容易控制和調試。 在Verilog HDL中,上層模塊引用下層模塊與C語言中程序調用有些類似,被引用的子模塊在綜合時作為其父模塊的一部分被綜合,形成相應的電路結構。在進行模塊實例引用時,必須注意的是模塊之間對應的端口,即子模塊的端口與父模塊的內部信號必須明確無誤地一一對應,否則容易產生意想不到的后果。
下面給出的例子是設計中遇到的一個實例,其功能是將并行數據轉化為串行數據送交外部電路編碼,并將解碼后得到的串行數據轉化為并行數據交由CPU處理。顯而易見,這實際上是兩個獨立的邏輯功能,分別設計為獨立的模塊,然后再合并為一個模塊顯得目的明確、層次清晰。
// ----------------?? p_to_s.v ---------------------------------
module? p_to_s(D_in,T0,data,SEND,ESC,ADD_100);
??? output??????? D_in,T0;??????????? // D_in是串行輸出,T0是移位時鐘并給
????????????????????????????????????? // CPU中斷,以確定何時給出下個數據。
??? input?? [7:0] data;?????????????? //并行輸入的數據。
??? input???????? SEND,ESC,ADD_100;?? //SEND、ESC共同決定是否進行并到串
????????????????????????????????????? //的數據轉化。ADD_100決定何時置數。
??? wire????????? D_in,T0;
??? reg [7:0] DATA_Q,DATA_Q_buf;
?
??? assign??????? T0 = ! (SEND & ESC);????? //形成移位時鐘。.
??? assign??????? D_in = DATA_Q[7];???????? //給出串行數據。
?
??? always @(posedge T0 or negedge ADD_100)? //ADD_100下沿置數,T0上沿移位。
????? begin
??????? if(!ADD_100)
????????? DATA_Q = data;
??????? else
????????? begin
????????? DATA_Q_buf = DATA_Q<<1;??????? //DATA_Q_buf作為中介,以令綜合器
????????? DATA_Q??? = DATA_Q_buf;?????????? //能辨明。
????????? end
????? end
endmodule
在p_to_s.v中,由于移位運算雖然可綜合,但是不是簡單的RTL級描述,直接用DATA_Q<=DATA_Q<<1的寫法在綜合時會令綜合器產生誤解。另外,在該設計中,由于時鐘T0的頻率較低,所以沒有象以往那樣采用低電平置數,而是采用ADD_100的下降沿置數。
//--------------------- s_to_p.v ---------------------------
module s_to_p(T1, data, D_out,DSC,TAKE,ADD_101);
?????? output?????? T1;???????????????????? //給CPU中斷,以確定CPU何時取轉化
??????????????????????????????????????????? //得到的并行數據。?????????????
?????? output [7:0] data;????????????????
?????? input?? D_out, DSC, TAKE, ADD_101;? //D_out提供輸入串行數據。DSC、TAKE
?????????????????????????????????????????? //共同決定何時取數。??????????
?????? wire?? [7:0] data;
?????? wire???????? T1,clk2;
?????? reg??? [7:0] data_latch, data_latch_buf;
??????
?????? assign?????? clk2 = DSC? & TAKE ;?? //提供移位時鐘。??????
?????? assign?????? T1 = !clk2;
??????
?????? assign?????? data =? (!ADD_101) ? data_latch : 8'bz;???
?????? always@(posedge clk2)
??????????? begin
?????????????? data_latch_buf = data_latch << 1;?? //data_latch_buf作緩沖
?????????????? data_latch???? = data_latch_buf;?? //,以令綜合器能辯明。
??????????????? data_latch[0] = D_out;
?????????? end
endmodule
將上面的兩個模塊合并起來的sys.v的源代碼:
//------------------- sys.v ---------------------------
`include "./p_to_s.v"
`include "./s_to_p.v"
module sys(D_in,T0,T1, data, D_out,SEND,ESC,DSC,TAKE,ADD_100,ADD_101);
? input???????? D_out,SEND,ESC,DSC,TAKE,ADD_100,ADD_101;
? inout? [7:0]? data;
? output??????? D_in,T0,T1;
?
? p_to_s?? p_to_s(.D_in(D_in),.T0(T0),.data(data),
??????????????? .SEND(SEND),.ESC(ESC),.ADD_100(ADD_100));
? s_to_p?? s_to_p(.T1(T1),.data(data),.D_out(D_out),
????????? .DSC(DSC),.TAKE(TAKE),.ADD_101(ADD_101));
?
endmodule
測試模塊源代碼:
//-------------Top test file for sys.v ------------------
`timescale 1ns/100ps
`include "./sys.v"
module Top;
?reg D_out,SEND,ESC,DSC,TAKE,ADD_100,ADD_101;
?reg[7:0] data_buf;
?wire [7:0] data;
?wire clk2;
?assign? data = (ADD_101) ? data_buf : 8'bz;??
???????????????????????????????? //data在sys中是inout型變量,ADD_101
???????????????????????????????? //控制data是作為輸入還是進行輸出。
assign? clk2 =DSC && TAKE;
initial?
? begin
???? SEND = 0;
???? ESC = 0;
???? DSC = 1;
???? TAKE = 1;
???? ADD_100 = 1;
???? ADD_101 = 1;
? end
initial
? begin
??? data_buf = 8'b10000001;
??? #90 ADD_100 = 0;
??? #100 ADD_100 = 1;
? end
always
? begin
??? #50;
??? SEND = ~SEND;
??? ESC = ~ESC;
? end
initial
? begin
??? #1500 ;
??? SEND = 0;
??? ESC? = 0;
??? DSC? = 1;
??? TAKE = 1;
??? ADD_100 = 1;
??? ADD_101 = 1;
??? D_out = 0;???
??? #1150 ADD_101 = 0;
??? #100 ADD_101 =1;
??? #100 $stop;
? end
always
? begin
??? #50 ;
??? DSC = ~DSC;
??? TAKE = ~TAKE;
? end
always @(negedge clk2) D_out = ~D_out;
sys??? sys(.D_in(D_in),.T0(T0),.T1(T1),.data(data),.D_out(D_out),
????????????? .ADD_101(ADD_101), .SEND(SEND),.ESC(ESC),.DSC(DSC),
?????????????????????????????????? .TAKE(TAKE),.ADD_100(ADD_100));?
endmodule
仿真波形:[[wysiwyg_imageupload:255:]]
練習:設計一個序列發生器。要求根據輸入的8位并行數據輸出串行數據,如果輸入數據在0—127之間則輸出一位0,如果輸入數據在128—255之間則輸出一位1,同步時鐘觸發;并且和范例8的序列檢測器搭接,形成一個封閉系統。編寫測試模塊,并給出仿真波形。
通過模塊之間的調用實現自頂向下的設計
- 模塊(46367)
- 狀態機(27117)
相關推薦
通過無線通信收發模塊實現單片機之間通信的解決方案
與有線數據傳輸相比,無線數據傳輸以成本低廉、適應性好、擴展性好、組網簡單方便、設備維護簡單等特點在工業生產、抄表系統、離散環境下的監控系統、點菜系統等眾多領域得到廣泛的運用。下面通過無線通信收發模塊D21DL來實現兩個單片機之間的通信。
2018-02-28 09:01:04
8762


匯編語言模塊調用C++函數實例
現在編寫一個簡單的應用程序,提示用戶輸入整數,通過移位的方式將其與 2 的幕 (21?2?) 相乘,并用填充前導空格的形式再次顯示每個乘積。輸入-輸出使用 C++。匯編模塊將調用 3 個 C++ 編寫的函數。程序將由 C++ 模塊啟動。
2022-10-11 09:52:20
672

CanTrcv_SetOpMode被哪個模塊調用?在什么場景下調用?
CanTrcv模塊在上電后的初始狀態配置,一般配置初始狀態為SLEEP狀態。而后,CanTrcv模塊的狀態通過其他模塊調用CanTrcv_SetOpMode來切換。
2022-10-31 10:58:09
1693

Linux系統調用的實現與應用
在計算機科學中,系統調用(System Call)是一種操作系統提供的服務,它允許應用程序通過軟件中斷的方式訪問操作系統內核中的函數。這些函數提供了一系列與硬件相關的服務,例如文件系統訪問、進程管理、網絡通信等。應用程序通過系統調用接口來調用這些函數,以便實現各種功能。
2023-06-14 11:46:37
338

Linux內核中系統調用詳解
Linux內核中設置了一組用于實現各種系統功能的子程序,稱為系統調用。用戶可以通過系統調用命令在自己的應用程序中調用它們。從某種角度來看,系統調用和普通的函數調用非常相似。區別僅僅在于,系統調用由操作系統核心提供,運行于核心態;而普通的函數調用由函數庫或用戶自己提供,運行于用戶態。
2023-08-23 10:37:22
577


通過CALL命令調用cmd腳本實現NVM讀取
和具體使用方法1.4 save命令詳解2. 通過CALL命令調用cmd腳本實現NVM讀取2.1 CMD命令腳本和CALL命令詳解2.2 讀取S12G128的片上NVM數...
2021-11-04 07:52:57
通過LabVIEW調用DLL文件,實現USB HID的雙向通信
通過LabVIEW調用DLL文件,實現USB HID的雙向通信。(說明:請不要向我索要LabVIEW源代碼,開發千般辛苦,況且是公司的代碼,我相信大家的水平都比我高,通過下面的入門介紹,相信大家可以
2011-11-30 11:22:57
通過LabVIEW與MATLAB設計模糊參數自整定PID
摘 要:探討在MATLAB中使用FIS編輯器與Simulink相結合的方法構造模糊推理結構,并通過MATLAB Script Node實現LabVIEW與MATLAB的混合編程,設計出具有模糊自整定
2019-04-03 09:40:03
通過vi調用節點,調用vi的問題
通過vi節點,打開前面板,運行vi等等。但是比如說我需要從用戶登錄界面,通過vi調用節點,打開某個試驗界面,同時希望是淡入淡出的效果,也就是通過設置透明度來實現。可是開運行到節點的時候,會咔2、3
2013-08-23 21:41:58
DSP與FPGA之間的通信如何實現
大家好,我現在在畫一塊28335的板子,想實現與FPGA之間的通信,但是不知道該怎樣設計,包括FPGA與DSP連接的引腳、通過內部什么模塊實現數據通信,現在一頭霧水,請大家幫忙。謝謝。
2018-12-03 15:55:34
EDA技術有什么特征?
EDA代表了當今電子設計技術的最新發展方向,它的基本特征是:設計人員按照“自頂向下”的設計方法,對整個系統進行方案設計和功能劃分,系統的關鍵電路用一片或幾片專用集成電路(ASIC)實現,然后采用硬件
2019-10-08 14:25:32
ESD設計與綜合
設計中的ESD分析。外圍和核心電路的I/O布局及其在ESD和Latchup下的應用。在“自底向上”和“自頂向下”兩種方法下進行保護環整合,將涵蓋I/O保護環、ESD保護環、I/O至I/O之間和I/O至
2013-09-04 09:17:26
評論