實驗1 在MAX10 FPGA上實作組合邏輯
實驗前的準備工作:參照講義步驟安裝Quartus,Modelsim和System Builder。閱讀材料:1)推薦的檔案組織形式;2)Verilog 1:概述和Verilog 2:重點是assign語句。
參考資源:友晶網站上的關于DE10-Lite實驗闆的資源:使用者手冊,工具和案例。
http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=218&No=1021&PartNo=4
Part 0. 使用System
Bulider、Quartus和Modelsim的設計流程
A. 使用System Builder建立工程檔案
在使用者手冊的第4章介紹了System Builder,它是一個windows平台的工具。用來生成Quartus工程檔案和配置設定DE10-Lite實驗闆的I/O引腳。
(1)
運作DE10_Lite_SystemBuilder.exe
(2)
輸入工程名稱和勾選在工程裡用到I/O裝置。
如圖1所示,在這裡我們設定工程名是majority,勾選了LED,按鍵,撥動開關,7段數位管這些I/O裝置。然後單擊Generate按鈕,将生成的檔案儲存到工程目錄。當成功生成工程檔案後,退出SystemBuilder.
圖 1 SystemBuilder界面
如圖2所示,在工程目錄中,Systembuilder生成了一系列工程檔案。
圖 2 SystemBuilder生成的工程檔案
其中majority.v是頂層設計的Verilog檔案模闆(如圖3所示)。SystemBilder已經在這個模闆裡把端口聲明和引腳配置設定完成,帶來很大的便利。可以更叫專注于功能描述。
//=======================================================
//
This code is generated by Terasic System Builder
//=======================================================
module majority(
////////////
SEG7 //////////
output
[7:0] HEX0,
output
[7:0] HEX1,
output
[7:0] HEX2,
output
[7:0] HEX3,
output
[7:0] HEX4,
output
[7:0] HEX5,
////////////
KEY //////////
input
[1:0] KEY,
////////////
LED //////////
output
[9:0] LEDR,
////////////
SW //////////
input
[9:0] SW
);
//=======================================================
//
REG/WIRE declarations
//=======================================================
//=======================================================
//
Structural coding
//=======================================================
endmodule
圖3 Verilog模闆檔案
在這個案例裡,我們描述基本的邏輯門組成的電路功能。如同書中3.6節描述的那樣(Digital Design- A System Approach).我們使用撥動開關作為電路的輸入,使用LED作為電路的輸出。
B.
使用Quartus Prime編譯和程式設計
l 運作Quartus Prime并打開之前用SystemBuilder建立的工程檔案。
l 選擇File> Open Project,在工程目錄,選擇majority.qpf.
l 在Project Navigator視窗輕按兩下majority實體名,打開其Verilog設計檔案。
l 在majority.v的功能描述部分,添加下面一條語句。
assign LEDR[1] =
(SW[0]&SW[1])|(SW[0]&SW[2])|(SW[1]&SW[2]);
這裡隻有當3個撥動開關有至少2個都是1時,LED才被點亮。實驗闆上LED的電路如圖4所示。
圖 4
LED電路
l 當完成Verilog代碼編輯後,選擇Processing > Start
Compliation。此處應該0個錯誤。
l 選擇Tools > Programmer。通過USB電纜連接配接DE10-Lite實驗闆和電腦。如圖5所示,在Hardware Setup那裡設定為USB-Blaster[USB-0],如果沒有,可能是驅動沒有安裝。确定majority.sof檔案顯示在下方清單并且已勾選Programe/Configure.然後單擊Start按鈕。
圖 5
程式設計視窗
現在,可以在實驗闆上驗證這個邏輯門電路的設計。通過撥動SW[2]、SW[1]和SW[0],觀察LEDR[1]的亮滅,其中隻有在兩個或兩個以上開關推上去時,LEDR[1]亮,反之則滅。
C.
使用Testbench在ModelSim裡仿真
使用功能仿真和時序仿真來仿真設計是一種功能強大的調試技術。它比把設計的電路下載下傳到FPGA裡來調試好太多了。因為:1)在功能仿真裡,可以像觀察I/O端口一樣觀察電路的内部信号;2)使用testbench節省了每次下載下傳驗證所需的下載下傳時間。
我們将使用testbench來做電路的功能仿真。雖然可以手繪波形激勵,但最好的方法是編寫testbench産生電路的輸入并監視輸出。
圖6列出了邏輯門電路的testbench内容。
module tb_majority;
reg [2:0] count;
wire [7:0] HEX5;
wire [7:0] HEX4;
wire [7:0] HEX3;
wire [7:0] HEX2;
wire [7:0] HEX1;
wire [7:0] HEX0;
wire [9:0] LEDR;
wire [9:0] SW;
assign SW[2:0] = count;
majority maj1(.HEX0(HEX0),
.HEX1(HEX1),
.HEX2(HEX2),
.HEX3(HEX3),
.HEX4(HEX4),
.HEX5(HEX5),
.KEY(KEY),
.LEDR(LEDR),
.SW(SW)
);
initial
begin
count
= 3'b0;
repeat(8)
begin
#100
$display("in
= %b, out = %b",count,LEDR[1]);
count
= count + 1'b1;
end
end
endmodule
圖6 testbench
Testbench檔案不能綜合成實際的電路,隻是用來做仿真。是以,它可以使用不可綜合的Verilog語句,如延時#,display,initial等。testbench例化被測試的子產品,産生輸入激勵并監視輸出。在ModelSim裡,波形檢視器是一個很友善的檢測電路響應的工具。
ModelSim裡功能仿真步驟如下:
1) 在majority.v同目錄下,建立tb_majority.v檔案,并編輯。
2) 在Quartus工程目錄,建立一個名為Simulation的子目錄,用來存儲仿真檔案。
3) 運作ModelSime。
4) 選擇File > New > Project打開建立工程對話框。設定路徑(如前所述)和工程名。其它設定預設不修改。單擊OK。
5) 在Add Items to the Project視窗,添加majority.v和tb_majority.v檔案,選擇Reference from current
location.
6) 選擇Compile > Compile All。此處應該0錯誤。
7) 單擊Simulate > Start Simulation,選擇Desing >
work > tb_majority。
8) 檢視仿真波形。選擇View > Wave。然後,在Objects視窗選擇count,右擊,選擇Add Wave。這樣就把count信号添加到波形視窗。再展開LEDR信号,把LEDR[1]添加到波形視窗。這樣在波形視窗就可以看到邏輯門電路的輸入/出信号。
9) 執行仿真可以通過菜單操作:Simulate > Run > Run 100或者在指令視窗輸入run執行。這樣将使仿真運作100個時間機關,預設是100ps。如圖7所示,是仿真運作800ps的波形。
圖 7 仿真波形
在ModelSim的控制視窗,也可以看到testbench的輸出資訊,如圖8所示,其輸入/出資訊通圖7波形顯示結果。
圖 8
控制台視窗資訊
Part 1. 在DE10-Lite實驗闆上實作基本的組合邏輯門電路
參照Part 0的設計,建立一個工程,實作邏輯門電路的可以,可以使用2-4輸入的與門、與非門、或門和或非門。也可以用按鍵直接操控LED和7段數位管。這裡需要注意,DE10-Lite上的7段數位管是共陽極的連接配接。下載下傳驗證。并編寫testbench測試。
圖 9 共陽7段數位管
這裡決定用KEY[1]和KEY[0]相與後驅動LEDR1和HEX0,設計代碼和testbench如下:
//=======================================================
//
This code is generated by Terasic System Builder
//=======================================================
module part2(
////////////
SEG7 //////////
output
[7:0] HEX0,
output
[7:0] HEX1,
output
[7:0] HEX2,
output
[7:0] HEX3,
output
[7:0] HEX4,
output
[7:0] HEX5,
////////////
KEY //////////
input
[1:0] KEY,
////////////
LED //////////
output
[9:0] LEDR,
////////////
SW //////////
input
[9:0] SW
);
//=======================================================
//
REG/WIRE declarations
//=======================================================
//=======================================================
//
Structural coding
//=======================================================
assign LEDR[1] = (KEY[0]&KEY[1]);
assign HEX0 =
~(KEY[1]&KEY[0])?8'b0100_0000:8'b1111_1111;
endmodule
測試代碼:
module tb_part2;
reg [1:0] count;
wire [7:0] HEX0;
wire [7:0] HEX1;
wire [7:0] HEX2;
wire [7:0] HEX3;
wire [7:0] HEX4;
wire [7:0] HEX5;
wire [1:0] KEY;
wire [9:0] SW;
wire [9:0] LEDR;
assign KEY = count;
part2 p1(.HEX0(HEX0),
.HEX1(HEX1),
.HEX2(HEX2),
.HEX3(HEX3),
.HEX4(HEX4),
.HEX5(HEX5),
.KEY(KEY),
.LEDR(LEDR),
.SW(SW)
);
initial
begin
count = 2'b00;
repeat(4)
begin
#100
$display("in = %b, out = %b",count,LEDR[1]);
count = count +1'b1;
end
end
endmodule
仿真結果如圖10所示:
圖 10
part 2 仿真結果
圖 11
監視輸出
Part 2. 為 4 位開關輸入實作組合邏輯十進制 7 段顯示
設計一個組合邏輯電路,用SW[3]-SW[0]作輸入,HEX1,HEX0作輸出。使數位管根據輸入顯示00、01、02、。。。、13、14、15。另外4個數位管HEX5-HEX2關閉。
按以下步驟完成:
1) 寫出真值表(輸入是SW[4]-SW[0],輸出是HEX1和HEX0的每段);
2) 卡諾圖化簡;
3) 使用assign語句描述7段數位管每一段的邏輯表達式;
4) 用testbench測試輸入的16種情況;
5) 編譯并下載下傳驗證。
後面會學習使用其它描述方式描述真值表,比如case語句,就不需要推導數位管每一段的邏輯表達式。
參考代碼如下:
//=======================================================
// This code is generated by Terasic System
Builder
//=======================================================
module
lab1_part2(
//////////// SEG7 //////////
output [7:0] HEX0,
output [7:0] HEX1,
output [7:0] HEX2,
output [7:0] HEX3,
output [7:0] HEX4,
output [7:0] HEX5,
//////////// KEY //////////
input [1:0] KEY,
//////////// LED //////////
output [9:0] LEDR,
//////////// SW //////////
input [9:0] SW
);
//=======================================================
// REG/WIRE declarations
//=======================================================
//=======================================================
// Structural coding
//=======================================================
assign
HEX1[6] = 1'b1;
assign
HEX1[5] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX1[4] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX1[3] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX1[2] = 1'b0;
assign
HEX1[1] = 1'b0;
assign
HEX1[0] = SW[3]&SW[2] | SW[3]&SW[1];
assign
HEX0[6] = ~SW[3]&~SW[2]&~SW[1] |
~SW[3]&SW[2]&SW[1]&SW[0]
|
SW[3]&~SW[2]&SW[1];
assign
HEX0[5] = SW[3]&SW[2]&~SW[1] |
~SW[3]&~SW[2]&SW[0] |
~SW[3]&~SW[2]&SW[1] |
~SW[3]&SW[1]&SW[0] |
~SW[2]&SW[1]&SW[0];
assign
HEX0[4] = SW[0] | ~SW[3]&SW[2]&~SW[1] |
SW[3]&SW[2]&SW[1];
assign
HEX0[3] = ~SW[3]&SW[2]&~SW[1]&~SW[0] |
~SW[3]&~SW[2]&~SW[1]&SW[0] |
~SW[3]&SW[2]&SW[1]&SW[0] |
SW[3]&SW[2]&SW[1]&~SW[0] |
SW[3]&~SW[2]&SW[1]&SW[0];
assign
HEX0[2] = SW[3]&SW[2]&~SW[1]&~SW[0] |
~SW[3]&~SW[2]&SW[1]&~SW[0];
assign
HEX0[1] = ~SW[3]&SW[2]&~SW[1]&SW[0] |
SW[3]&SW[2]&SW[1]&SW[0] |
~SW[3]&SW[2]&SW[1]&~SW[0];
assign
HEX0[0] = ~SW[3]&~SW[2]&~SW[1]&SW[0] |
~SW[3]&SW[2]&~SW[1]&~SW[0] |
SW[3]&SW[2]&SW[1]&~SW[0] |
SW[3]&~SW[2]&SW[1]&SW[0];
//turn
off HEX5-HEX2
assign
HEX5 = 8'b1111_1111;
assign
HEX4 = 8'b1111_1111;
assign
HEX3 = 8'b1111_1111;
assign HEX2
= 8'b1111_1111;
endmodule
測試代碼如下:
module tb_p2;
reg [3:0]
count;
wire
[9:0] SW;
wire
[1:0] KEY;
wire
[9:0] LEDR;
wire
[6:0] HEX5,HEX4,HEX3,HEX2,HEX1,HEX0;
assign
SW[3:0] = count;
lab1_part2
p1(.KEY(KEY),
.SW(SW),
.LEDR(LEDR),
.HEX5(HEX5),
.HEX4(HEX4),
.HEX3(HEX3),
.HEX2(HEX2),
.HEX1(HEX1),
.HEX0(HEX0)
);
initial
begin
count = 4'd0;
repeat(16)
begin
#100
$display("in = %b, out =
%b",count,{HEX1,HEX0});
count = count + 1'b1;
end
end
endmodule
仿真結果如圖12所示,類似之前列出的真值表,對應16種SW的組合,生成相應的HEX1和HEX0的狀态.
圖12
仿真結果
評分标準:
1) 共60分,其中,Part 1占25分,Part 2占35分;
2) 10分,設計Part 1和Part 2的Verilog代碼;
3) 10分,Part 2的真值表,卡諾圖,邏輯表達式;
4) 20分,Part 1和Part 2的testbench及仿真結果。
References:
1.University of California, Davis
Department
of Electrical and Computer Engineering
EEC180
DIGITAL SYSTEMS II Spring 2021
Lab 1:
Implementing Combinational Logic in the MAX10 FPGA