《EDA技術(shù)入門與提高》課件-第9章_第1頁
《EDA技術(shù)入門與提高》課件-第9章_第2頁
《EDA技術(shù)入門與提高》課件-第9章_第3頁
《EDA技術(shù)入門與提高》課件-第9章_第4頁
《EDA技術(shù)入門與提高》課件-第9章_第5頁
已閱讀5頁,還剩136頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論