版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第9章VHDL設(shè)計實例9.1SPI接口的VHDL實現(xiàn)9.2URAT接口的VHDL實現(xiàn)9.3ASK調(diào)制解調(diào)器的VHDL實現(xiàn)9.1SPI接口的VHDL實現(xiàn)
SPI(SerialPeripheralInterface)即串行外圍接口,由Motorola公司提出。目前SPI接口主要應(yīng)用在EEPROM、Flash、實時時鐘、A/D轉(zhuǎn)換器、數(shù)字信號處理器和數(shù)字信號解碼芯片上,作為與CPU之間進行同步串行數(shù)據(jù)傳輸?shù)慕涌?,速度可達(dá)到Mb/s級別。在FPGA器件上實現(xiàn)了SPI接口后,就可以代替CPU,直接控制這些外圍器件。9.1.1SPI接口介紹
SPI接口是以主從方式工作的,這種模式通常有一個主控器件和一個或多個從屬器件,其接口包括以下4種信號:
(1)?MOSI:主控器件數(shù)據(jù)輸出,從屬器件數(shù)據(jù)輸入;
(2)?MISO:主控器件數(shù)據(jù)輸入,從屬器件數(shù)據(jù)輸出;
(3)?SCLK:時鐘信號,由主控器件產(chǎn)生;
(4)?:從屬器件使能信號,由主控器件控制。
點對點的通信連接關(guān)系如圖9.1所示。在點對點的通信中,SPI接口不需要進行尋址操作,且為全雙工通信。圖9.1點對點的通信連接關(guān)系多個從屬器件的系統(tǒng)如圖9.2所示。在多個從屬器件的系統(tǒng)中,每個從屬器件需要獨立地使能信號,硬件上比點對點的系統(tǒng)要稍微復(fù)雜一些。
SPI接口的核心是兩個移位寄存器,傳輸?shù)臄?shù)據(jù)為8位,在主控器件產(chǎn)生的從屬器件使能信號和移位時鐘脈沖SCLK的作用下,按位傳輸,數(shù)據(jù)的高位在前,低位在后。如圖9.3所示,在SCLK的下降沿上數(shù)據(jù)改變,同時一位數(shù)據(jù)被存入移位寄存器。圖9.2一主多從的SPI接口圖9.3SPI接口通信時序圖9.4SPI接口內(nèi)部核心硬件結(jié)構(gòu)SPI接口內(nèi)部核心硬件結(jié)構(gòu)如圖9.4所示。9.1.2移位寄存器編程
SPI接口的核心是一個8位的同步移位寄存器。為了實現(xiàn)全雙工的SPI接口,在移位寄存器向外發(fā)送數(shù)據(jù)時,同時也在接收數(shù)據(jù)。移位寄存器的VHDL描述如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.NUMERIC_STD.ALL;
ENTITYshift_rIS-------------ENTITY---------------------
PORT(
clk:INSTD_LOGIC;
--系統(tǒng)時鐘輸入
rst:INSTD_LOGIC;--復(fù)位信號輸入
sclk:INSTD_LOGIC;--移位寄存器移位時鐘輸入
shift_reload:INSTD_LOGIC;
--移位寄存器發(fā)送數(shù)據(jù)加載信號
shift_in:INSTD_LOGIC;--移位寄存器輸入
shift_out:OUTSTD_LOGIC;--移位寄存器輸出
datain:INSTD_LOGIC_VECTOR(7DOWNTO0);
--移位寄存器發(fā)送參數(shù)接口
dataout:OUTSTD_LOGIC_VECTOR(7DOWNTO0)
--移位寄存器接收數(shù)據(jù)接口
);
ENDshift_r;
ARCHITECTUREbehvOFshift_rIS
SIGNALshift_clk:STD_LOGIC;
SIGNALsck_r1:STD_LOGIC;
SIGNALsck_r2:STD_LOGIC;
SIGNALsck_r3:STD_LOGIC;
SIGNALshift_reg:STD_LOGIC_VECTOR
(7DOWNTO0);
BEGIN
shift_clk<=NOTsck_r1ANDsck_r2;
flop_proc:PROCESS(clk)----------Shiftregister---------
BEGIN
IF(clk'eventANDclk='1')THEN
sck_r2<=sck_r1;--移位寄存器時鐘信號同步
sck_r1<=sclk;
ENDIF;
ENDPROCESS;
sr_proc:PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
IF(rst='0')THEN
shift_reg<="00000000";--同步復(fù)位
ELSE
IF(Shift_reload='1')THEN--運行時不加載
shift_reg<=datain;
--加載從CPU發(fā)送的數(shù)據(jù)
ELSIF(shift_finish='1')THEN
dataout<=shift_reg;
ELSIF(shift_clk='1')THEN
shift_re<=shift_reg(6DOWNTO0)&shift_in;
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
shift_out<=shift_reg(7);
ENDbehv;
在移位寄存器的VHDL描述中,利用了PROCESS過程中的信號賦值特點,第一次使用信號sck_r1和sck_r2,生成了如圖9.5所示的三級寄存器結(jié)構(gòu)。圖9.5生成的三級寄存器結(jié)構(gòu)使用第一級寄存器將輸入信號sclk與clk同步,使用第二級寄存器和第三級寄存器產(chǎn)生一個clk周期的信號的延遲,通過對寄存器輸出信號進行取反和相與操作,得到寬度為一個clk信號周期的脈沖信號shift_clk。shift_clk信號發(fā)生波形圖如圖9.6所示。圖9.6shift_clk信號發(fā)生波形圖圖9.7實體shift_r的仿真波形實體shift_r的仿真波形如圖9.7所示。通過仿真波形可知,由datain端口輸入需要發(fā)送的8位數(shù)據(jù)“AA”,在shift_reload信號為高時,該數(shù)據(jù)導(dǎo)入移位寄存器shift_reg中,并在sclk的每個上升沿將“AA”信號以從高到低的順序一位一位地移到shift_out端口,同時將shift_in端口的信號移入移位寄存器shift_reg中,當(dāng)移位結(jié)束時,在shift_finish信號的作用下,將shift_reg中的數(shù)據(jù)通過dataout接口輸出。仔細(xì)研究仿真波形后可以發(fā)現(xiàn),shift_out信號的有效信號在sclk信號的上升沿后兩個系統(tǒng)時鐘周期內(nèi)就發(fā)生了變化,當(dāng)sclk信號頻率比較低時,shift_out信號的保持時間將不足以滿足穩(wěn)定傳輸信號的要求,不符合SPI接口的時序規(guī)范,所以需要添加輸出信號保持模塊。帶信號輸出保持的移位寄存器VHDL描述如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.NUMERIC_STD.ALL;
ENTITYshift_rIS
PORT(
clk:INSTD_LOGIC;--系統(tǒng)時鐘輸入
rst:INSTD_LOGIC; --復(fù)位信號輸入
sclk:INSTD_LOGIC; --移位寄存器移位時鐘輸入
shift_reload:INSTD_LOGIC;
--移位寄存器發(fā)送數(shù)據(jù)加載信號
shift_finish:INSTD_LOGIC;
--移位寄存器數(shù)據(jù)發(fā)送完畢信號
shift_in:INSTD_LOGIC;--移位寄存器輸入
shift_out:OUTSTD_LOGIC;--移位寄存器輸出
datain:INSTD_LOGIC_VECTOR(7DOWNTO0);
--移位寄存器發(fā)送參數(shù)接口
dataout:OUTSTD_LOGIC_VECTOR(7DOWNTO0)
--移位寄存器接收數(shù)據(jù)接口
);
ENDshift_r;
ARCHITECTUREbehvOFshift_rIS
SIGNALshift_clk:STD_LOGIC;
SIGNALshift_clk_neg:STD_LOGIC;
SIGNALsck_r1:STD_LOGIC;
SIGNALsck_r2:STD_LOGIC;
SIGNALshift_reg:STD_LOGIC_VECTOR(7DOWNTO0);
BEGIN
shift_clk<=NOTsck_r2ANDsck_r1;
shift_clk_neg<=NOTsck_r1ANDsck_r2;
flop_proc:PROCESS(clk)
BEGIN
IF(clk‘eventANDclk='1')THEN
sck_r2<=sck_r1;
--移位寄存器時鐘信號同步
sck_r1<=sclk;
ENDIF;
ENDPROCESS;
sr_proc:PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
IF(rst='0')THEN
shift_reg<="00000000";
--同步復(fù)位
ELSE
IF(shift_reload='1')THEN
shift_reg<=datain;
--加載數(shù)據(jù)
ELSIF(shift_finish='1')THEN
dataout<=shift_reg;
ELSIF(shift_clk='1')THEN
shift_reg<=shift_reg(6DOWNTO0)&shift_in;
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
sig_hold:PROCESS(clk)
BEGIN
IF(clk‘eventANDclk='1')THEN
IF(rst='0')THEN
shift_out<='0';
ELSE
IF(shift_reload='1')OR(shift_clk_neg='1')THEN
shift_out<=shift_reg(7);
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
ENDbehv;圖9.8帶信號保持的移位寄存器的仿真波形該模塊的仿真波形如圖9.8所示。由仿真結(jié)果可知,帶信號保持的移位寄存器的輸出信號在sclk引腳信號的下降沿才進行跳變,符合SPI接口標(biāo)準(zhǔn)的要求。
實體shift_r實現(xiàn)了SPI接口的基本收/發(fā)功能,但是還無法作為一個完整的SPI接口使用,需要添加大量的控制邏輯功能,例如SPI主從選擇、SCLK信號發(fā)生、SCLK信號相位選擇和發(fā)送/接收中斷信號發(fā)生等重要的功能。9.1.3SPI主從選擇模塊編程
根據(jù)SPI接口的規(guī)范,SPI主機的接口引腳MISO為串行數(shù)據(jù)輸入引腳,而SPI從機的接口引腳MISO為串行數(shù)據(jù)輸出引腳,同樣MOSI引腳在SPI主機和從機上的功能也是不同的。SCLK引腳在主機和從機上的功能雖然相同,但是信號的方向卻不同,SPI主機的SCLK引腳輸出同步時鐘信號,而SPI從機的SCLK引腳輸入同步時鐘信號。為了讓SPI接口能實現(xiàn)主機和從機的選擇功能,需要一個主從選擇模塊,該模塊將使用到三態(tài)門,其VHDL描述如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.NUMERIC_STD.ALL;
ENTITYm_s_selIS----------------ENTITY------------
PORT(
mosi:INOUTSTD_LOGIC;--主出從入
miso:INOUTSTD_LOGIC;--主入從出
sclk:INOUTSTD_LOGIC;--SPI時鐘
master_sel:INSTD_LOGIC;--主從選擇位
shift_in:OUTSTD_LOGIC;--移位寄存器輸入信號shift_out:INSTD_LOGIC; --移位寄存器輸出信號
shift_clk:OUTSTD_LOGIC; --移位寄存器時鐘
sclk_gen:INSTD_LOGIC; --SPI時鐘發(fā)生模塊輸出的時鐘信號
);
ENDm_s_sel;
ARCHITECTUREbehvOFm_s_selIS
BEGIN
PROCESS(master_sel,shift_out,miso,mosi,sclk_gen,sclk)
--注意需要填入所有輸入信號,以避免出現(xiàn)不必要的鎖存器
BEGIN
IF(master_sel='1')THEN
shift_in<=miso;
miso<='Z';
mosi<=shift_out;
shift_clk<=sclk_gen;
sclk<=sclk_gen;
ELSE
shift_in<=mosi;
mosi<='Z';
miso<=shift_out;
shift_clk<=sclk;
sclk<='Z';
ENDIF;
ENDPROCESS;
ENDbehv;
編譯綜合后,生成的RTL圖如圖9.9所示。圖9.9主從選擇模塊的RTL圖在該模塊中共使用了三個三態(tài)門,在VHDL描述中,通過向inout端口置“Z”就可以添加一個三態(tài)門。對主從選擇模塊進行仿真,波形圖如圖9.10所示。圖9.10主從選擇模塊仿真結(jié)果從主從選擇模塊仿真波形圖中可以看出,當(dāng)master_sel端口被置為“1”時,處于SPI主機模式,sclk端口輸出信號和移位寄存器的時鐘引腳shift_clk的信號由本機內(nèi)部時鐘信號發(fā)生器的輸出引腳sclk_gen提供,移位寄存器的輸入引腳shift_in的信號由miso引腳提供,移位寄存器輸出引腳shift_out的信號通過mosi引腳輸出。
當(dāng)master_sel端口被置為“0”時,處于SPI從機模式,移位寄存器的時鐘引腳shift_clk的信號由sclk引腳提供,移位寄存器的輸入引腳shift_in的信號由mosi引腳提供,移位寄存器輸出引腳shift_out的信號通過miso輸出。9.1.4時鐘信號發(fā)生模塊
當(dāng)SPI端口處于主機模式時,需要根據(jù)發(fā)送數(shù)據(jù)的速度要求,由SCLK端口向從機輸出頻率可選的時鐘信號,時鐘發(fā)生模塊的功能就在于此。依據(jù)以上功能要求,時鐘信號發(fā)生模塊的VHDL描述如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.NUMERIC_STD.ALL;
ENTITYsclk_generateIS-----------ENTITY-------------
PORT(
clk:INSTD_LOGIC;--系統(tǒng)時鐘輸入端口sclk_set:INSTD_LOGIC_VECTOR(1DOWNTO0);
--時鐘選擇位輸入端口
sclk_gen:OUTSTD_LOGIC; --SPI同步時鐘輸出端口
sclk_en:INSTD_LOGIC;--同步時鐘使能信號輸入端口
sclk_pol:INSTD_LOGIC
--空閑時,SPI時鐘的輸出信號狀態(tài)
);
ENDsclk_generate;
ARCHITECTUREbehvOFsclk_generateIS
SIGNALclk_count:STD_LOGIC_VECTOR(4DOWNTO0);
SIGNALsclk_dvd2:STD_LOGIC;
BEGIN
PROCESS(clk)
BEGIN
IF(clk‘eventANDclk='1')THEN
IF(sclk_en='0')THEN
clk_count<="00000";
sclk_dvd2<=sclk_pol;
ELSE
IF(clk_count="00000")THEN
IF(sclk_set="00")THEN
clk_count<="00011";
ELSIF(sclk_set="01")THEN
clk_count<="00111";
ELSIF(sclk_set="10")THEN
clk_count<="01111";
ELSIF(sclk_set="11")THEN
clk_count<="11111";
ENDIF;
sclk_dvd2<=NOTsclk_dvd2;
ELSE
clk_count<=STD_LOGIC_VECTOR(unsigned(clk_count)-1);
ENDIF;
ENDIF;
sclk_gen<=sclk_dvd2;
ENDIF;
ENDPROCESS;
ENDbehv;
時鐘信號發(fā)生模塊的仿真波形如圖9.11所示。圖9.11時鐘信號發(fā)生模塊的仿真波形由圖9.11可知,當(dāng)sclk_en信號為低時,輸出信號sclk_gen保持為低;當(dāng)sclk_en信號為高時,時鐘信號發(fā)生模塊根據(jù)sclk_set端口的設(shè)置,對clk信號進行分頻,由sclk_gen端口輸出不同頻率的時鐘信號。sclk_set端口設(shè)置與分頻比之間的關(guān)系如表9.1所示。
表9.1sclk_set端口設(shè)置與分頻比之間的關(guān)系sclk_set分頻比“00”8∶1“01”16∶1“10”32∶1“11”64∶19.1.5SPI接口控制管理模塊
完整的SPI接口除了內(nèi)核之外,還需要有實現(xiàn)內(nèi)部數(shù)據(jù)交流和設(shè)置的寄存器控制管理模塊,以確定SPI接口工作模式。本例中使用4個8位的寄存器,其地址和功能如表9.2所示。
表9.2SPI接口寄存器功能分配
(1)?Data_reg寄存器——寄存器地址為“0”的8位寄存器,用于存儲SPI接收的或需要發(fā)送的數(shù)據(jù)內(nèi)容,硬件實現(xiàn)中實際上由兩個不同的8位數(shù)據(jù)寄存器組成,當(dāng)外部芯片讀取地址0的數(shù)據(jù)時,讀出的是SPI接口器件收到的數(shù)據(jù)內(nèi)容,外部芯片也可向地址0寫入數(shù)據(jù),寫入的數(shù)據(jù)將通過SPI接口發(fā)送出去。
(2)?CTL寄存器——寄存器地址為“1”的8位寄存器,用于存儲SPI接口的控制參數(shù),其中包含以下6個控制參數(shù)位。
①?TX_ON位:位地址是“0”,用于設(shè)置作為主設(shè)備時,啟動SPI發(fā)送過程。當(dāng)TX_ON位被置為“1”時,啟動SPI發(fā)送時序,發(fā)送過程結(jié)束后,該位被自動清零。②MSTEN位:位地址是“1”,用于設(shè)置SPI接口的主從模式。當(dāng)MSTEN位被置為“1”時,當(dāng)前SPI接口工作于主模式;當(dāng)MSTEN位被置為“0”時,當(dāng)前SPI接口工作于從模式。
③CLKPOL位:位地址是“3”,用于設(shè)置作為主設(shè)備時,時鐘同步信號SCLK的默認(rèn)狀態(tài)。當(dāng)CLKPOL位被置為“1”時,SCLK默認(rèn)狀態(tài)下為高;當(dāng)CLKPOL位被置為“0”時,SCLK默認(rèn)狀態(tài)下為低。
④Phase位:位地址是“4”,用于設(shè)置時鐘同步信號作用的相位。當(dāng)Phase位被置為“1”時,SPI接口在SCLK下降沿讀取數(shù)據(jù);當(dāng)Phase位被置為“0”時,SPI接口在SCLK上升沿讀取數(shù)據(jù)。⑤CLK_Sel位:該控制寄存器包含兩位,位地址為“6”和“5”,“6”為高位,“5”為低位,用于設(shè)置SPI的時鐘分頻器,分頻比與時鐘發(fā)生模塊的相同。
⑥IRQEN位:位地址是“7”,中斷信號允許位。當(dāng)IRQEN位被置為“1”時,允許SPI接口在接收/發(fā)送完數(shù)據(jù)后發(fā)出中斷控制信號;當(dāng)IRQEN位被置為“0”時,屏蔽中斷信號。
(3)?STATUS寄存器——寄存器的地址為“2”,用于保存SPI接口的運行狀態(tài)。該寄存器包含以下4個狀態(tài)寄存器。
①SLVSEL位:位地址為“0”,該位只讀,用于標(biāo)示SPI模塊的主從狀態(tài)。當(dāng)SLVSEL位被置為“1”時,表示SPI工作于從屬狀態(tài);當(dāng)SLVSEL位被置為“0”時,表示SPI工作于主機狀態(tài)。②TXRUN位:位地址為“1”,該位只讀。當(dāng)SPI模塊處于主機模式時,TXRUN位如果被置為“1”,則表示SPI模塊正處于接收或發(fā)送過程中。
③OverRun位:位地址為“6”,該位可讀/寫。當(dāng)SPI接口正在發(fā)送數(shù)據(jù)時,如果用戶向傳輸寄存器DOUT寫數(shù)據(jù),則OverRun位將被置為“1”,表示發(fā)生傳輸過載錯誤,發(fā)生錯誤后,需要從內(nèi)部總線手動復(fù)位。
④IRQ位:位地址為“7”,為中斷激活位,可讀/寫。作為主模塊時當(dāng)發(fā)送完成后,或者作為從模塊時接收到一個字節(jié)后,IRQ位將被置為“1”,中斷位置1后,需要由內(nèi)部總線手動置零。
(4)?SEL寄存器——寄存器的地址為“3”,用于保存從接口選擇位和傳輸位寬選擇位。
①?SSEL位:位地址為“0~4”,用于在作為SPI組模塊時,選擇與之通信的從模塊。
②?BIT_CTR位:位地址為“5~7”,用于設(shè)置SPI傳輸字的位寬,“000”表示8位,“001”~“111”表示1~7位。
SPI接口模塊的另一側(cè)采用并行接口,通過CLK信號進行同步,使用CHIP_SEL引腳作為片選,“WRITE”引腳作為寫使能信號,對寄存器進行寫入。
SPI控制管理模塊的VHDL描述如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
--使用IEEE標(biāo)準(zhǔn)中的1164邏輯類型
USEIEEE.NUMERIC_STD.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;--使用+和-操作
ENTITYControllerIS---------ENTITY-----------------
PORT(
clk:INSTD_LOGIC;--系統(tǒng)時鐘輸入
data_in:INSTD_LOGIC_VECTOR(7DOWNTO0);
--系統(tǒng)8位數(shù)據(jù)輸入接口shift_clk_in:INSTD_LOGIC;
--移位寄存器時鐘信號輸入端口
shift_clk_out:OUTSTD_LOGIC;
--移位寄存器時鐘信號輸出端口
shift_reg_in:OUTSTD_LOGIC_VECTOR
(7DOWNTO0);
--移位寄存器待發(fā)送數(shù)據(jù)輸入接口
shift_reg_out:INSTD_LOGIC_VECTOR
(7DOWNTO0);
--移位寄存器接收數(shù)據(jù)輸出接口shift_reg_load:OUTSTD_LOGIC;
--移位寄存器待發(fā)送數(shù)據(jù)導(dǎo)入信號引腳
mst_sel:OUTSTD_LOGIC;--器件主從選擇引腳
wr:INSTD_LOGIC;--寫寄存器信號引腳
RD:INSTD_LOGIC;--讀寄存器信號引腳
addr:INSTD_LOGIC_VECTOR(1DOWNTO0); ?--寄存器讀/寫地址輸入端口
data_out:OUTSTD_LOGIC_VECTOR(7DOWNTO0);
--數(shù)據(jù)輸出信號TX_Finish:OUTSTD_LOGIC;
--數(shù)據(jù)發(fā)送完畢信號輸出端口
SCLK_gen_en:OUTSTD_LOGIC;
--同步時鐘信號發(fā)生使能控制信號輸出端口
SCLK_POL:OUTSTD_LOGIC;
--同步時鐘相位控制信號輸出端口
sclk_set:OUTSTD_LOGIC_VECTOR(1DOWNTO0); --同步時鐘頻率控制信號輸出端口
SSEL:OUTSTD_LOGIC_VECTOR(4DOWNTO0) --作為主機時,從機選擇輸出位
);ENDController;
ARCHITECTUREbehvOFControllerIS
SIGNALMsten:STD_LOGIC;
SIGNALshift_done:STD_LOGIC;
SIGNALslvsel:STD_LOGIC;
SIGNALshift_run:STD_LOGIC;
SIGNALdata_reg:STD_LOGIC_VECTOR(7DOWNTO0);
SIGNALTX_ON:STD_LOGIC;
SIGNALTX_ON_reg:STD_LOGIC;
SIGNALTX_Start:STD_LOGIC;
SIGNALTXRUN:STD_LOGIC;SIGNALPhase:STD_LOGIC;
SIGNALBIT_count:STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALCLKpol:STD_LOGIC;
SIGNALclk_sel:STD_LOGIC_VECTOR(1DOWNTO0);
SIGNALoverrun:STD_LOGIC;
SIGNALIRQEN:STD_LOGIC;
SIGNALIRQ:STD_LOGIC;
SIGNALBIT_ctr:STD_LOGIC_VECTOR(2DOWNTO0);
SIGNALSCLK_out:STD_LOGIC;
SIGNALSCLK_out_reg:STD_LOGIC;SIGNALIRQ_clr:STD_LOGIC;
SIGNALshift_finish:STD_LOGIC;
BEGIN
SCLK_CTRL:process(TXRUN,Msten)
BEGIN
IF(Msten='1')THEN
SCLK_gen_en<=TXRUN;
ELSE
SCLK_gen_en<='0';
ENDIF;
ENDPROCESS;PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
shift_clk_out<=sclk_out;
IF(Phase='1')THEN
SCLK_out<=shift_clk_in;
ELSE
SCLK_out<=NOTshift_clk_in;
ENDIF;
ENDIF;
ENDPROCESS;PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
mst_sel<=Msten;
slvsel<=NOTMsten;
sclk_set<=CLK_sel;
SCLK_POL<=CLKpol;
IRQ<=shift_doneANDIRQEN;
ENDIF;
ENDPROCESS;PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
IF(IRQ_clr='0')THEN
shift_done<='0';
ELSIF(shift_finish='1')THEN
shift_done<='1';
ENDIF;
ENDIF;
ENDPROCESS;PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
IF(wr='1')THEN
IF(addr="00")THEN
IF(shift_run='1')THEN
overrun<='1';
ELSE
shift_reg_in<=data_in;
TX_Start<='1';
ENDIF;
IRQ_clr<='1';
ELSIF(addr="01")THEN
TX_Start<='0';
Msten<=data_in(1);
CLkpol<=data_in(3);
Phase<=data_in(4);
CLK_sel<=data_in(6DOWNTO5);
IRQEN<=data_in(7);
IRQ_clr<='1';
ELSIF(addr="10")THEN
TX_Start<='0';
overrun<=data_in(6);
IRQ_clr<=data_in(7);
ELSIF(addr="11")THEN
TX_Start<='0';
IRQ_clr<='1';
SSEL<=data_in(4DOWNTO0);
BIT_ctr<=data_in(7DOWNTO5);
ELSE
TX_Start<='0';
TX_Start<='0';IRQ_clr<='1';
ENDIF;
ELSE
TX_Start<='0';
ENDIF;
ENDIF;
shift_reg_load<=TX_Start;
ENDPROCESS;
PROCESS(CLK)
BEGIN
IF(clk'eventANDclk='1')THEN
IF(RD='1')THEN --讀取控制寄存器值
IF(addr="00")THEN
data_out<=shift_reg_out;
ELSIF(addr=“01”)THEN
data_out<=IRQEN&CLK_sel&Phase&CLKpol&'0'&Msten&TX_ON;
ELSIF(addr="10")THEN
data_out<=IRQ&overrun&"0000"&TXRUN&slvsel;
ELSIF(addr="11")THEN
data_out<=BIT_CTR&SSEL;ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
IF(Msten='1')THEN --主設(shè)備
IF(TX_Start='1'ANDTXRUN='0'ANDBIT_count="0000")THEN
IF(BIT_ctr="000")THEN
BIT_count(3)<='1';
ELSE
BIT_count(3)<='0';
ENDIF;
shift_finish<='0';
BIT_count(2DOWNTO0)<=BIT_ctr;
TXRUN<='1';
ELSIF(SCLK_out='1'ANDSCLK_out_reg='0'ANDBIT_count/="0000")THEN
BIT_count<=BIT_count-"0001";
ELSIF(TXRUN='1'ANDBIT_count="0000")THEN
TXRUN<='0';
shift_finish<='1';
ENDIF;
ELSE --從設(shè)備
IF(BIT_count="0000"ANDTXRUN='0')THEN
IF(BIT_ctr="000")THEN
BIT_count(3)<='1';
ELSE
BIT_count(3)<='0';
ENDIF;
BIT_count(2DOWNTO0)<=BIT_ctr;
shift_finish<='0';
TXRUN<='1';
ELSIF(SCLK_out='1'ANDSCLK_out_reg='0'AND
BIT_count/="0000")THEN
BIT_count<=BIT_count-'1';
ELSIF(TXRUN='1'ANDBIT_count="0000")THEN
TXRUN<='0';
shift_finish<='1';
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(clk)
BEGIN
IF(clk'eventANDclk='1')THEN
SCLK_out_reg<=SCLK_out;
TX_ON<=data_in(0);
ENDIF;
TX_finish<=shift_finish;
ENDPROCESS;
ENDARCHITECTURE;
SPI接口控制管理模塊的仿真波形如圖9.12所示。
由仿真結(jié)果可知,通過讀/寫信號、地址接口和數(shù)據(jù)輸入接口可以對內(nèi)部的寄存器進行操作,同時控制shift_reg_load引腳發(fā)出啟動脈沖,觸發(fā)SPI接口進行數(shù)據(jù)導(dǎo)入并進行收/發(fā),當(dāng)設(shè)置的一定位長的數(shù)據(jù)收/發(fā)完畢時,能置位IRQ,發(fā)出中斷信號。圖9.12SPI接口控制管理模塊的仿真波形9.1.6頂層設(shè)計VHDL描述
完成了各個模塊的VHDL描述后,接下來要使用頂層設(shè)計將這些模塊連接起來,形成一個完整的SPI接口。頂層設(shè)計VHDL描述如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
--使用IEEE標(biāo)準(zhǔn)中的1164邏輯類型
USEIEEE.NUMERIC_STD.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
--使用+和-操作
USEWORK.ALL; --使用WORK庫
ENTITYSPI_PORTIS
PORT(
clk:INSTD_LOGIC;
reset:INSTD_LOGIC;
data_in:INSTD_LOGIC_VECTOR(7DOWNTO0);
data_out:OUTSTD_LOGIC_VECTOR(7DOWNTO0);
wr:INSTD_LOGIC;
rd:INSTD_LOGIC;
SCLK:INOUTSTD_LOGIC;
MISO:INOUTSTD_LOGIC;
MOSI:INOUTSTD_LOGIC;
);ENDSPI_PORT;
ARCHITECTUREbehavOFSPI_PORTIS
SIGNALshift_data_in:STD_LOGIC_VECTOR(7DOWNTO0);
SIGNALshift_data_out:STD_LOGIC_VECTOR(7DOWNTO0);
SIGNALsclk_set:STD_LOGIC_VECTOR(1DOWNTO0);
SIGNALshift_clk:STD_LOGIC;
SIGNALshift_reg_load:STD_LOGIC;
SIGNALshift_out:STD_LOGIC;
SIGNALshift_in:STD_LOGIC;SIGNALmst_sel:STD_LOGIC;
SIGNALsclk_gen:STD_LOGIC;
SIGNALsclk_en:STD_LOGIC;
SIGNALsclk_pol:STD_LOGIC;
SIGNALshift_finish:STD_LOGIC;
COMPONENTcontroller
PORT(
clk:INSTD_LOGIC;--系統(tǒng)時鐘輸入
data_in:INSTD_LOGIC_VECTOR(7DOWNTO0);
--系統(tǒng)8位數(shù)據(jù)輸入接口
shift_clk_in:INSTD_LOGIC;
--移位寄存器時鐘信號輸入端口
shift_clk_out:OUTSTD_LOGIC;
--移位寄存器時鐘信號輸出端口
shift_reg_in:OUTSTD_LOGIC_VECTOR(7DOWNTO0);
--移位寄存器待發(fā)送數(shù)據(jù)輸入接口
shift_reg_out:INSTD_LOGIC_VECTOR(7DOWNTO0);
--移位寄存器接收數(shù)據(jù)輸出接口
shift_reg_load:OUTSTD_LOGIC;
--移位寄存器待發(fā)送數(shù)據(jù)導(dǎo)入信號引腳
mst_sel:OUTSTD_LOGIC;
--器件主從選擇引腳wr:INSTD_LOGIC;--寫寄存器信號引腳
rd:INSTD_LOGIC;--讀寄存器信號引腳
addr:INSTD_LOGIC_VECTOR(1DOWNTO0);
--寄存器地址信號輸入端口
data_out:OUTSTD_LOGIC_VECTOR(7DOWNTO0); --數(shù)據(jù)輸出端口
TX_finish:OUTSTD_LOGIC;--發(fā)送完成信號輸出端口
SCLK_gen_en:OUTSTD_LOGIC;
--同步時鐘信號發(fā)生使能控制信號輸出端口
SCLK_POL:OUTSTD_LOGIC;
--同步時鐘相位控制信號輸出端口sclk_set:OUTSTD_LOGIC_VECTOR(1DOWNTO0)
--同步時鐘頻率控制信號輸出端口
);
ENDCOMPONENT;
COMPONENTsclk_generate
PORT(
clk:INSTD_LOGIC;--系統(tǒng)時鐘輸入端口
sclk_set:INSTD_LOGIC_VECTOR(1DOWNTO0); --時鐘選擇位輸入端口
sclk_gen:OUTSTD_LOGIC;--SPI同步時鐘輸出端口
sclk_en:INSTD_LOGIC;--同步時鐘使能信號輸入端口
sclk_pol:INSTD_LOGIC
--空閑時,SPI時鐘的輸出信號狀態(tài)
);
ENDCOMPONENT;
COMPONENTm_s_sel
PORT(
mosi:INOUTSTD_LOGIC;--主出從入
miso:INOUTSTD_LOGIC;--主入從出
sclk:INOUTSTD_LOGIC; --SPI時鐘
master_sel:INSTD_LOGIC; --主從選擇位shift_in:OUTSTD_LOGIC;--移位寄存器輸入信號
shift_out:INSTD_LOGIC;--移位寄存器輸出信號
shift_clk:OUTSTD_LOGIC;--移位寄存器時鐘
sclk_gen:INSTD_LOGIC;
--SPI時鐘信號發(fā)生模塊輸出的時鐘信號
);
ENDCOMPONENT;
COMPONENTshift_r
PORT(
clk:INSTD_LOGIC; --系統(tǒng)時鐘輸入
rst:INSTD_LOGIC; --復(fù)位信號輸入sclk:INSTD_LOGIC; --移位寄存器移位時鐘輸入
shift_reload:INSTD_LOGIC;
--移位寄存器發(fā)送數(shù)據(jù)加載信號
shift_finish:INSTD_LOGIC;
--移位寄存器數(shù)據(jù)發(fā)送完成信號
shift_in:INSTD_LOGIC; --移位寄存器輸入
shift_out:OUTSTD_LOGIC;--移位寄存器輸出
datain:INSTD_LOGIC_VECTOR(7DOWNTO0);
--移位寄存器發(fā)送參數(shù)接口
dataout:OUTSTD_LOGIC_VECTOR(7DOWNTO0)?
--移位寄存器接收數(shù)據(jù)接口
);
ENDCOMPONENT;
BEGIN
U1:shift_r
PORTMAP(
clk=>clk,rst=>rst,sclk=>shift_clk_out,shift_reload
=>shift_reg_load,shift_finish=>TX_finish,shift_in=>
shift_in,shift_out=>shift_out,
datain=>shift_reg_in,
dataout=>shift_reg_out
);
U2:m_s_sel
PORTMAP(
mosi=>MOSI,miso=>MISO,sclk=>SCLK,master_sel
=>mst_sel,shift_in=>shift_in,shift_out=>shift_out,
shift_clk=>shift_clk_in,
sclk_gen=>sclk_gen
);
U3:sclk_generate
PORTMAP(
clk=>clk,sclk_set=>sclk_set,sclk_gen=>sclk_gen,
sclk_en=>SCLK_gen_en,sclk_pol=>SCLK_POL
);
U4:controller
PORTMAP(
clk=>clk,data_in=>data_in,shift_clk_in=>shift_clk,
shift_clk_out=>clk,shift_reg_in=>datain,shift_reg_
out=>dataout,shift_reg_load=>shift_reload,mst_sel
=>master_sel,wr=>wr,rd=>rd,addr=>addr,
data_out=>data_out,TX_finish=>shift_finish,
SCLK_gen_en=>sclk_en,SCLK_POL=>sclk_pol,
sclk_set=>sclk_set
);
ENDARCHITECTUREbehav;
通過頂層設(shè)計將4個模塊連接起來,連接關(guān)系如圖9.13所示。至此,完成了SPI接口的VHDL設(shè)計。圖9.13頂層設(shè)計的結(jié)構(gòu)9.2URAT接口的VHDL實現(xiàn)
9.2.1UART接口介紹
UART(UniversalAsynchronousReceiver/Transmitter)即通用異步收/發(fā)傳輸器,工作于數(shù)據(jù)鏈路層。它包含了RS-232、RS-422、RS-485串口通信和紅外(IrDA)等。UART協(xié)議作為一種低速通信協(xié)議,廣泛應(yīng)用于通信領(lǐng)域等各種場合。
異步串口通信協(xié)議作為UART的一種,工作原理是將傳輸數(shù)據(jù)的每個字符一位接一位地傳輸。其工作時序如圖9.14所示。圖9.14UART接口工作時序圖9.14中各位的含義如下:
起始位:先發(fā)出一個邏輯“0”的信號,表示傳輸字符的開始。
數(shù)據(jù)位:是傳輸?shù)膬?nèi)容,緊接著起始位之后。根據(jù)UART協(xié)議規(guī)定,數(shù)據(jù)位的個數(shù)可以是4、5、6、7、8等,構(gòu)成一個字符。通常情況下采用ASCII編碼。從最低位開始傳送,靠自身的時鐘控制定位。
奇偶校驗位:用于校驗數(shù)據(jù)位傳輸?shù)恼_性,所有數(shù)據(jù)位加上這一位后,使得“1”的位數(shù)應(yīng)為偶數(shù)(偶校驗)或奇數(shù)(奇校驗),以此來判斷資料傳送是否成功。停止位:是一個字符數(shù)據(jù)的結(jié)束標(biāo)志,可以是1位、1.5位、2位的高電平。
空閑位:處于邏輯“1”狀態(tài),表示當(dāng)前線路上沒有資料傳送。
波特率是衡量資料傳送速率的指針,表示每秒鐘傳送的二進制位數(shù)。例如,資料傳送速率為960字符/秒,而每一個字符包含起始位、數(shù)據(jù)位、奇偶校驗位和停止位共10位,則其傳送的波特率為10×960=9600位/秒,即波特率為9600。在UART通信中,必須保證通信雙方的波特率相同,否則無法正常通信。
本實例將采用自頂向下的方式,對UART接口進行設(shè)計,首先是頂層的模塊劃分。9.2.2UART頂層的模塊劃分和VHDL描述
根據(jù)UART通信的要求,初步將UART接口分為UART接收模塊、UART發(fā)送模塊和波特率控制模塊。UART接收模塊負(fù)責(zé)接收UART輸入信號,一個字節(jié)接收完畢后,將數(shù)據(jù)內(nèi)容由并行輸出接口輸出。UART發(fā)送模塊負(fù)責(zé)向外傳輸UART串行信號,將并行數(shù)據(jù)接口輸入的內(nèi)容轉(zhuǎn)換為符合UART傳輸規(guī)范的串行信號輸出。波特率控制模塊根據(jù)設(shè)置生成對應(yīng)的波特率信號,指導(dǎo)發(fā)送和接收模塊工作。
UART接口的頂層VHDL描述如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYtopIS
PORT(
clk:INSTD_LOGIC;--系統(tǒng)時鐘輸入端口
reset:INSTD_LOGIC;--硬件復(fù)位信號輸入端口
rxd:INSTD_LOGIC;--UART接收信號輸入端口xmit_cmd_p_in:INSTD_LOGIC;--控制信號端口
baud_set_wr:INSTD_LOGIC;--波特率設(shè)置寫控制端口
rec_ready:OUTSTD_LOGIC;--接收完成信號輸出端口
txd_out:OUTSTD_LOGIC;--UART發(fā)送端口
txd_done_out:OUTSTD_LOGIC;
--發(fā)送完成信號輸出端口
baud_set:INSTD_LOGIC_VECTOR(7DOWNTO0); --波特率設(shè)置端口
txdbuf_in:INSTD_LOGIC_VECTOR(7DOWNTO0);
--待發(fā)送數(shù)據(jù)輸入端口
rec_buf:OUTSTD_LOGIC_VECTOR(7DOWNTO0));
--接收數(shù)據(jù)輸出端口
ENDtop;
ARCHITECTUREBehavOFtopIS
COMPONENTUART_Receiver--UART接收模塊
PORT(
bclkr:INSTD_LOGIC;--波特率時鐘輸入端口
resetr:INSTD_LOGIC;--硬件復(fù)位輸入端口
rxdr:INSTD_LOGIC;--UART接收端口
r_ready:OUTSTD_LOGIC;
--接口完成信號輸出端口
rbuf:OUTSTD_LOGIC_VECTOR(7DOWNTO0)
--接收數(shù)據(jù)輸出端口
);
ENDCOMPONENT;
COMPONENTUART_Transfer--UART發(fā)送模塊
PORT(
bclkt:INSTD_LOGIC;--波特率時鐘輸入端口
resett:INSTD_LOGIC;--硬件復(fù)位輸入端口
xmit_cmd_p:INSTD_LOGIC;--數(shù)據(jù)輸入控制位
txdbuf:INSTD_LOGIC_VECTOR(7DOWNTO0);
--待發(fā)送數(shù)據(jù)輸入接口
txd:OUTSTD_LOGIC;--UART接收端口
txd_done:OUTSTD_LOGIC
--發(fā)送完成信號輸出端口
);
ENDCOMPONENT;
COMPONENTbaud
PORT(
--波特率控制模塊
clk:INSTD_LOGIC;--系統(tǒng)時鐘輸入端口
resetb:INSTD_LOGIC;--硬件復(fù)位信號輸入端口
baud_set:INSTD_LOGIC_VECTOR(7DOWNTO0);
--波特率設(shè)置端口
baud_set_wr:INSTD_LOGIC;
--波特率設(shè)置寫控制端口
bclk:OUTSTD_LOGIC--波特率時鐘輸出端口
);
ENDCOMPONENT;
SIGNALb:STD_LOGIC;
BEGIN--頂層映射
u1:baudPORTMAP(clk=>clk,
resetb=>reset,
bclk=>b,
baud_set=>baud_set,
baud_set_wr=>baud_set_wr
);
u2:UART_ReceiverPORTMAP(bclkr=>b,
resetr=>reset,
rxdr=>rxd,
r_ready=>rec_ready,
rbuf=>rec_buf
);
u3:UART_TransferPORTMAP(bclkt=>b,
resett=>reset,
xmit_cmd_p=>xmit_cmd_p_in,
txdbuf=>txdbuf_in,
txd=>txd_out,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國北斗衛(wèi)星應(yīng)用行業(yè)營銷創(chuàng)新戰(zhàn)略制定與實施研究報告
- 2025-2030年中國汽車經(jīng)銷行業(yè)全國市場開拓戰(zhàn)略制定與實施研究報告
- 2025-2030年中國桑拿洗浴行業(yè)資本規(guī)劃與股權(quán)融資戰(zhàn)略制定與實施研究報告
- 2025-2030年中國控制線纜組件行業(yè)開拓第二增長曲線戰(zhàn)略制定與實施研究報告
- 自動噴水滅火系統(tǒng)的維護管理標(biāo)準(zhǔn)
- 拜師儀式主持詞
- 購置冬裝方式選擇的調(diào)查研究
- 家裝電梯知識培訓(xùn)課件
- 2024年一年級語文教學(xué)設(shè)計(合集篇)
- 廣東日化用品項目資金申請報告
- 天津市部分區(qū)2023-2024學(xué)年高一上學(xué)期期末練習(xí)生物試題【含答案解析】
- 稀土鋁合金電纜項目招商引資方案
- 人教版六年級數(shù)學(xué)下冊全冊分層作業(yè)設(shè)計含答案
- 面點專業(yè)職業(yè)生涯規(guī)劃與管理
- 紀(jì)梵希服裝營銷方案
- 滬教版小學(xué)語文古詩(1-4)年級教材
- 農(nóng)耕研學(xué)基地可行性方案
- 《太陽能光伏技術(shù)》課件
- 2024年職業(yè)素養(yǎng)與商務(wù)禮儀培訓(xùn)資料
- 兒科課件:急性細(xì)菌性腦膜炎
- 柜類家具結(jié)構(gòu)設(shè)計課件
評論
0/150
提交評論