目錄
- 第一章 什么是IP核?
- 第二章 什么是LPM?
- 第一節 設置LPM_COUNTER模塊參數
- 第二節 仿真
- 第三章 什么是PLL?
- 第一節 設置ALTPLL(嵌入式鎖相環)模塊參數
- 第二節 仿真
- 第四章 什么是RAM?
- 第一節 RAM_1PORT的調用
- 第二節 配置RAM_1PORT
- 第三節 RAM_2PORT的調用
- 第四節 配置RAM_2PORT
- 第五章 什么是FIFO?
- 第一節 FIFO模塊參數配置
- 第二節 配置FIFO
- 參考文獻
第一章 什么是IP核?
IP核就是知識產權核或知識產權模塊的意思,在EDA技術開發中具有十分重要的地位。美國著名的Dataquest咨詢公司將半導體產業的IP定義為“用于ASIC或FPGA中的預先設計好的電路功能模塊”。IP主要分為軟IP、固IP和硬IP。軟IP是用Verilog/VHDL等硬件描述語言描述的功能塊,但是并不涉及用什么具體電路元件實現這些功能。固IP是完成了綜合的功能塊。硬IP提供設計的最終階段產品——掩膜。[1]
第二章 什么是LPM?
LPM即參數化模塊庫(Library of Parameterized Modules),是Altera 公司FPGA/CPLD設計軟件Quartus II自帶的一些宏功能模塊,如:鎖相環(PLLs), LVDS,數字信號處理(DSP) 模塊等。這些功能是對Altera器件的優化,設計者在用這些模塊時,不耗用器件的邏輯資源(Logic Cell)。[2]
第一節 設置LPM_COUNTER模塊參數
-
新建項目,點擊
IP Catalog
,在搜索框內輸入counter,點擊LPM_COUNTER
,然后將其保存為myLPM_counter.v
,點擊Ok開始配置
-
基礎設置
-
設置輸入并點擊NEXT。
-
多次點擊NEXT,出現如下界面后選擇需要文件,點擊Finish完成配置,在彈出界面點擊Yes
第二節 仿真
- 新建Verilog HDL File,然后寫入代碼,生成需要的模型,將其保存為
Updown_counter10.v
module Updown_counter10 (aclr,cp_en,cp,updown,co,q);input aclr;input cp_en;input cp;input updown;output co;output [3:0] q;myLPM_counter myLPM_counter_inst(.aclr(aclr),.clk_en(cp_en),.clock(cp),.updown(updown),.cout(co),.q (q));
endmodule
文件目錄如下
- 設置LPM_COUNTER,修改
myLPM_counter.qip
文件下的myLPM_counter.v
,使其符合期望
`timescale 1 ps / 1 ps
module myLPM_counter (aclr,clk_en,clock,sclr,updown,cout,q);input aclr;input clk_en;input clock;input sclr;input updown;output cout;output [3:0] q;wire sub_wire0;wire [3:0] sub_wire1;wire cout = sub_wire0;wire [3:0] q = sub_wire1[3:0];lpm_counter LPM_COUNTER_component (.clk_en (clk_en),.clock (clock),
// .sclr (sclr),.updown (updown),.cout (sub_wire0),.q (sub_wire1),.aclr (1'b0),.aload (1'b0),.aset (1'b0),.cin (1'b1),.cnt_en (1'b1),.data ({4{1'b0}}),.eq (),.sclr(1'b0),.sload (1'b0),.sset (1'b0));defparamLPM_COUNTER_component.lpm_direction = "UNUSED",LPM_COUNTER_component.lpm_modulus = 10,LPM_COUNTER_component.lpm_port_updown = "PORT_USED",LPM_COUNTER_component.lpm_type = "LPM_COUNTER",LPM_COUNTER_component.lpm_width = 4;
endmodule
- 開始完整編譯,編譯通過后,新建
University Program VWF
進行仿真
- 仿真
觀察仿真結果發現,結果與預期相同
第三章 什么是PLL?
PLL即鎖相環 (phase locked loop)是一種利用相位同步產生的電壓,去調諧壓控振蕩器以產生目標頻率的負反饋控制系統。根據自動控制原理,這是一種典型的反饋控制電路,利用外部輸入的參考信號控制環路內部振蕩信號的頻率和相位,實現輸出信號頻率對輸入信號頻率的自動跟蹤,一般用于閉環跟蹤電路。是無線電發射中使頻率較為穩定的一種方法,主要有VCO(壓控振蕩器)和PLL IC (鎖相環集成電路),壓控振蕩器給出一個信號,一部分作為輸出,另一部分通過分頻與PLL IC所產生的本振信號作相位比較,為了保持頻率不變,就要求相位差不發生改變,如果有相位差的變化,則PLL IC的電壓輸出端的電壓發生變化,去控制VCO,直到相位差恢復,達到鎖相的目的。能使受控振蕩器的頻率和相位均與輸入信號保持確定關系的閉環電子電路。[3]
第一節 設置ALTPLL(嵌入式鎖相環)模塊參數
-
選擇ALTPLL,與第二章第一節相同的處理方法,在IP Catalog中搜索
PLL
,選擇ALTPLL在點擊左下角的Add
按鈕將其保存為mypll.v
文件并開始配置
-
根據選擇的芯片設置合適的晶振,ep4ce115f29c7的晶振為50MHZ,使用時鐘頻率選擇50MHZ,模式為正常
-
以下配置默認即可
-
設置時鐘
c0:設置100MHZ,將時鐘倍頻,占空比設置50%
c1:25MHZ,選擇分頻,且相位偏移90°,占空比50%
c2:5MHZ,占空比為25%
c3:先分頻再倍頻,75MHZ,占空比50%
目前只選擇4個時鐘,第5個時鐘不啟用 -
多次點擊next,直到出現此界面,勾選
mypll_inst.v
文件和mypll_bb.v
文件
第二節 仿真
- 新建
Verilog HDL File
,寫入下面的模型代碼,保存為test_IP.v
module test_IP(input clk , // 時鐘信號input rst_n , // 上電復位低有效output c0 ,output c1 ,output c2 ,output c3 ,output locked
);// PLL
mypll mypll_inst (.areset ( ~rst_n ), // IP復位高有效.inclk0 ( clk ), // 輸入時鐘.c0 ( c0 ), // 輸出時鐘.c1 ( c1 ), // 輸出時鐘.c2 ( c2 ), // 輸出時鐘.c3 ( c3 ), // 輸出時鐘.locked ( locked ) // 時鐘輸出鎖--鎖定不穩定時鐘輸出
);endmodule
以及測試代碼test_tb.v
`timescale 1ns/1ps
module test_tb();reg clk ;reg rst_n ;wire c0 ;wire c1 ;wire c2 ;wire c3 ;//例化要仿真的文件
test_IP u_test_IP(.clk (clk ),//時鐘信號.rst_n (rst_n ),//上電復位低有效.c0 (c0 ),.c1 (c1 ),.c2 (c2 ),.c3 (c3 ),.locked (locked )
);always #10 clk = ~clk;//產生50M仿真時鐘integer i = 0,j = 0;//用于產生地址,寫入數據initial beginclk = 1'b1;rst_n = 1'b1;#200.1;rst_n = 1'b0;//主動產生上電復位#200;rst_n = 1'b1;#20000;$stop;
endendmodule
- 進行完整編譯,編譯通過后開始仿真
- 仿真
觀察仿真結果發現與預期相同
第四章 什么是RAM?
RAM即隨機存取存儲器(英語:Random Access Memory,縮寫:RAM),也叫主存,是與CPU直接交換數據的內部存儲器。它可以隨時讀寫(刷新時除外),而且速度很快,通常作為操作系統或其他正在運行中的程序的臨時數據存儲介質。RAM工作時可以隨時從任何一個指定的地址寫入(存入)或讀出(取出)信息。它與ROM的最大區別是數據的易失性,即一旦斷電所存儲的數據將隨之丟失。RAM在計算機和數字系統中用來暫時存儲程序、數據和中間結果。[4]
第一節 RAM_1PORT的調用
-
搜索
RAM
選擇RAM_1PORT
并添加保存為RAM_1PORT.v
-
設置位寬和數據深度
-
多次點擊NEXT直到出現此界面,并勾選
RAM_1PORT_inst.v
和RAM_1PORT_bb.v
第二節 配置RAM_1PORT
- 新建Verilog HDL File,寫入模型的代碼
module RAM_1port_test(input clk ,//時鐘信號input rst_n ,//上電復位低有效input rden ,input wren ,input [7:0] address ,input [7:0] data ,output [7:0] q
);//RAM_1portRAM_1PORT RAM_1PORT_inst (.aclr ( ~rst_n ),.address ( address ),.clock ( clk ),.data ( data ),.rden ( rden ),.wren ( wren ),.q ( q ));
endmodule
以及測試的代碼
`timescale 1ns/1ps
module RAM_1port_test_tb();reg clk ;reg rst_n ;reg rden ;reg wren ;reg [7:0] address ;reg [7:0] data ;wire [7:0] q ;//例化要仿真的文件
RAM_1port_test u_RAM_1port_test(.clk (clk ),//時鐘信號.rst_n (rst_n ),//上電復位低有效.rden (rden ),.wren (wren ),.address (address ),.data (data ),.q (q )
);always #10 clk = ~clk;//產生50M仿真時鐘integer i = 0,j = 0;//用于產生地址,寫入數據initial beginclk = 1'b1;rst_n = 1'b1;#200.1;rst_n = 1'b0;//主動產生上電復位
//RAM_1PORTwren = 1'b0;//復位有效,賦初值rden = 1'b0;data = 0;address = 0;#200;rst_n = 1'b1;#200;//wren 50Mfor(i=0;i<256;i=i+1)beginwren = 1'b1;//高電平有效address = i;data = i+1;#20;endwren = 1'b0;//寫完拉低#100;//rden 100Mfor(j=0;j<256;j=j+1)beginrden = 1'b1;address = j;#20;endrden = 1'b0;//讀完拉低#200;$stop;
endendmodule
- 完全編譯
第三節 RAM_2PORT的調用
- 同樣,找到RAM_2PORT并添加,保存為
RAM_2port.v
- 配置讀寫模塊
- 配置數據深度為1024
- 選擇讀寫時鐘分開
- 讀出數據設置為q,同樣選擇復位清零
- 多次點擊next直到出現此界面,選擇
RAM_2port_inst.v
及RAM_2port_bb.v
第四節 配置RAM_2PORT
- 同樣編譯模型代碼和測試代碼
test_IP.v
module test_IP(input clk ,//時鐘信號input rst_n ,//上電復位低有效input [7:0] data ,input [7:0] rdaddress ,input rden ,input [7:0] wraddress ,input wrclock ,input wren ,output [7:0] q);// //RAM_2portRAM_2port RAM_2port_inst (.data ( data ),.rd_aclr ( ~rst_n ),.rdaddress ( rdaddress ),.rdclock ( clk ),.rden ( rden ),.wraddress ( wraddress ),.wrclock ( wrclock ),.wren ( wren ),.q ( q ));endmodule
測試代碼test_tb.v
`timescale 1ns/1ps
module test_tb();reg clk ;reg rst_n ;reg [7:0] data ;reg [7:0] rdaddress ;reg rden ;reg [7:0] wraddress ;reg wrclock ;reg wren ;wire [7:0] q ;//例化要仿真的文件
test_IP u_test_IP(.clk (clk ),//時鐘信號.rst_n (rst_n ),//上電復位低有效.data (data ),.rdaddress (rdaddress ),.rden (rden ),.wraddress (wraddress ),.wrclock (clk ),.wren (wren ),.q (q )
);always #10 clk = ~clk;//產生50M仿真時鐘integer i = 0,j = 0;//用于產生地址,寫入數據initial beginclk = 1'b1;rst_n = 1'b1;#200.1;rst_n = 1'b0;//主動產生上電復位wren = 1'b0;//復位有效,賦初值rden = 1'b0;rdaddress = 0;wraddress = 0;data = 0;#200;rst_n = 1'b1;#200;//wren 50Mfor(i=0;i<256;i=i+1)beginwren = 1'b1;//高電平有效wraddress = i;data = i+1;#20;endwren = 1'b0;//寫完拉低#100;//rden 100Mfor(j=0;j<256;j=j+1)beginrden = 1'b1;rdaddress = j;#20;endrden = 1'b0;//讀完拉低#200;$stop;
endendmodule
- 完整編譯通過
第五章 什么是FIFO?
FIFO( First Input First Output)簡單說就是指先進先出。由于微電子技術的飛速發展,新一代FIFO芯片容量越來越大,體積越來越小,價格越來越便宜。作為一種新型大規模集成電路,FIFO芯片以其靈活、方便、高效的特性,逐漸在高速數據采集、高速數據處理、高速數據傳輸以及多機處理系統中得到越來越廣泛的應用。[5]
第一節 FIFO模塊參數配置
1.在IP Catelog搜索FIFO,選擇FIFO并添加,保存為fifo.v
- 選擇讀寫使用同一個時鐘
- 配置SCFIFO
- 默認即可,點擊next
- 默認即可
- 勾選
fifo_inst.v
和fifo_bb.v
第二節 配置FIFO
- 與前面相同,新建Verilog HDL File,寫入如下代碼并保存
模型代碼:
module test_IP(input clk ,//時鐘信號input rst_n ,//上電復位低有效input [7:0] data ,input rdreq ,input wrreq ,output empty ,output full ,output [7:0] q ,output [7:0] usedw );// //FIFOfifo fifo_inst (.aclr ( ~rst_n ),.clock ( clk ),.data ( data ),.rdreq ( rdreq ),.wrreq ( wrreq ),.empty ( empty ),.full ( full ),.q ( q ),.usedw ( usedw ));
endmodule
測試代碼:
`timescale 1ns/1ps
module test_tb();reg clk ;reg rst_n ;reg wrreq ;reg rdreq ;reg [7:0] data ;wire [7:0] q ;wire empty ;wire full ;wire usedw ;//例化要仿真的文件
test_IP u_test_IP(.clk (clk ),//時鐘信號.rst_n (rst_n ),//上電復位低有效.data (data ),.rdreq (rdreq ),.wrreq (wrreq ),.empty (empty ), .full (full ), .q (q ), .usedw (usedw )
);always #10 clk = ~clk;//產生50M仿真時鐘integer i = 0,j = 0;//用于產生地址,寫入數據initial beginclk = 1'b1;rst_n = 1'b1;#200.1;rst_n = 1'b0;//主動產生上電復位rdreq = 1'b0;wrreq = 1'b0;data = 0;#200;rst_n = 1'b1;#200;//wrreq 50Mfor(i=0;i<256;i=i+1)beginwrreq = 1'b1;//高電平有效data = {$random};#20;endwrreq = 1'b0;//寫完拉低#100;//rdreq 100Mfor(j=0;j<256;j=j+1)beginrdreq = 1'b1;#20;endrdreq = 1'b0;#200;$stop;
endendmodule
- 全部編譯通過
參考文獻
[1] 潘松·EDA技術與Verilog HDL·北京:清華大學出版社,2010
[2] LPM(FPGA參數化模塊庫) -百度百科
[3] 鎖相環(無線電術語)-百度百科
[4] 楊頌華,馮毛官,孫萬蓉,初秀琴,胡力山編著·數字電子技術基礎:西安電子科技大學出版社,2016.07
[5] FIFO存儲器 -百度百科
[6] Quartus基本IP核調用及仿真
[7] 羅杰.Verilog HDL 與FPGA數字系統設計 第二版[M].機械工業出版社:北京,2022:198-210.