【FGPA】VHDL實驗


 

實驗一 簡單的QUARTUSII實例設計

一、 實驗目的

1、 通過一個簡單的38譯碼器的設計,掌握組合邏輯電路的設計方法。

2、 初步了解QUARTUSII原理圖輸入設計的全過程。

3、 掌握組合邏輯電路的靜態測試方法。

二、 實驗原理

3-8譯碼器三輸入,八輸出。當輸入信號按二進制方式的表示值為N時,輸出端標號為N的輸出端輸出高電平表示有信號產生,而其它則為低電平表示無信號產生。因為三個輸入端能產生的組合狀態有八種,所以輸出端在每種組合中僅有一位為高電平的情況下,能表示所有的輸入組合。其真值表如表1-1所示:

輸入

輸出

A

B

C

D7

D6

D5

D4

D3

D2

D1

D0

0

0

0

0

0

0

0

0

0

0

1

0

0

1

0

0

0

0

0

0

1

0

0

1

0

0

0

0

0

0

1

0

0

0

1

1

0

0

0

0

1

0

0

0

1

0

0

0

0

0

1

0

0

0

0

1

0

1

0

0

1

0

0

0

0

0

1

1

 

0

1

0

0

0

0

0

0

1

1

1

1

0

0

0

0

0

0

0

1-1  -八譯碼器真值表

譯碼器不需要像編碼器那樣用一個輸出端指示輸出是否有效。但可以在輸入中加入一個輸出使能端,用來指示是否將當前的輸入進行有效的譯碼,當使能端指示輸入信號無效或不用對當前信號進行譯碼時,輸出端全為高電平,表示無任何信號。本例設計中沒有考慮使能輸入端,自己設計時可以考慮加入使能輸入端時,程序如何設計。

三、 實驗內容

   在本實驗中,用三個撥動開關來表示三八譯碼器的三個輸入(ABC);用八個LED來表示三八譯碼器的八個輸出(D0-D7)。通過輸入不同的值來觀察輸入的結果與三八譯碼器的真值表(表1-1)是否一致。實驗箱中的撥動開關與FPGA的接口電路如下圖1-1所示,當開關閉合(撥動開關的檔位在下方)時其輸出為低電平,反之輸出高電平。 

1-1  撥動開關與FPGA接口電路

LED燈與FPGA的接口電路如圖1-2所示,當FPGA與其對應的端口為高電平時LED就會發光,反之LED燈滅。

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Sim381 is
    port(A,B,C:in STD_LOGIC;
        Y:out STD_LOGIC_vector(7 downto 0));
end entity Sim381;
architecture tmp of Sim381 is
signal s:STD_LOGIC_vector(2 downto 0);
    begin
        s <= A & B & C ;
        with s select
            Y  <= "00000001" when "000",
                    "00000010" when "001",
                    "00000100" when "010",
                    "00001000" when "011",
                    "00010000" when "100",
                    "00100000" when "101",
                    "01000000" when "110",
                    "10000000" when "111",
                    "00000000" when others;
end architecture tmp;

 

實驗二  基於VHDL格雷碼編碼器設計

一、 實驗目的

1、 了解格雷碼變換的原理。

2、 進一步熟悉QUARTUSII軟件的使用方法和VHDL輸入的全過程。

3、 進一步掌握實驗系統的使用。

二、 實驗原理

格雷(Gray)碼是一種可靠性編碼,在數字系統中有着廣泛的應用。其特點是任意兩個相鄰的代碼中僅有一位二進制數不同,因而在數碼的遞增和遞減運算過程中不易出現差錯。但是格雷碼是一種無權碼,要想正確而簡單的和二進制碼進行轉換,必須找出其規律。

根據組合邏輯電路的分析方法,先列出其真值表再通過卡諾圖化簡,可以很快的找出格雷碼與二進制碼之間的邏輯關系。其轉換規律為:高位同,從高到低看異同,異出1’,同出‘0’。也就是將二進制碼轉換成格雷碼時,高位是完全相同的,下一位格雷碼是‘1’還是‘0’,完全是相鄰兩位二進制碼的“異”還是“同”來決定。下面舉一個簡單的例子加以說明。

假如要把二進制碼10110110轉換成格雷碼,則可以通過下面的方法來完成,方法如圖2-1

 

 

 

2-1  格雷碼變換示意圖

因此,變換出來的格雷碼為11101101

三、 實驗內容

本實驗要求完成的任務是變換12位二進制碼到12位的格雷碼。實驗中用12位撥動開關模塊的K1K12表示8位二進制輸入,用LED模塊的LED1LED12來表示轉換的實驗結果十二位格雷碼。實驗LED亮表示對應的位為‘1’,LED滅表示對應的位為‘0’。通過輸入不同的值來觀察輸入的結果與實驗原理中的轉換規則是否一致。

 

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity GrayCode is
    port(inPort:in std_logic_vector(7 downto 0);
    outPort:out std_logic_vector(7 downto 0)
    );
end GrayCode;
architecture dataFlow of GrayCode is
    begin
    outPort(7) <= inPort(7);
    u1:for i in 0 to 6 generate
            outPort(i) <= (inPort(i) xor inPort(i+1));
    end generate u1;
end dataFlow;

 

實驗三  加法計數器設計

一、 實驗目的

1、 了解二進制計數器的工作原理。

2、 進一步熟悉QUARTUSII軟件的使用方法和VHDL輸入。

3、 時鍾在編程過程中的作用。

二、 實驗原理

二進制計數器中應用最多、功能最全的計數器之一,含異步清零和同步使能的加法計數器的具體工作過程如下:

在時鍾上升沿的情況下,檢測使能端是否允許計數,如果允許計數(定義使能端高電平有效)則開始計數,否則一直檢測使能端信號。在計數過程中再檢測復位信號是否有效(低電平有效),當復位信號起作用時,使計數值清零,繼續進行檢測和計數。其工作時序如圖3-1所示:

 

 

 

       

3-1  計數器的工作時序

三、 實驗內容

本實驗要求完成的任務是在時鍾信號的作用下,通過使能端和復位信號來完成加法計數器的計數。實驗中時鍾信號使用數字時鍾源模塊的1HZ信號,用一位撥動開關K1表示使能端信號,用復位開關S1表示復位信號,用LED模塊的LED1LED11來表示計數的二進制結果。實驗LED亮表示對應的位為‘1’,LED滅表示對應的位為‘0’。通過輸入不同的值模擬計數器的工作時序,觀察計數的結果。實驗箱中的撥動開關、與FPGA的接口電路,LED燈與FPGA的接口電路以及撥動開關、LEDFPGA的管腳連接在實驗一中都做了詳細說明,這里不在贅述。

數字時鍾信號模塊的電路原理如圖3-2所示。

 

library ieee;
use ieee.std_logic_1164.all ;
use ieee.std_logic_arith.all ;
use ieee.std_logic_unsigned.all ;

entity Cnt_11 is port(
    clk , reset , En : IN std_logic ;
    CQ : OUT std_logic_vector( 10 downto 0 )
);
end Cnt_11 ;

architecture Behaving of Cnt_11 is
Begin
        Process ( clk , reset , En )
                variable tmp : std_logic_vector( 10 downto 0 ) ;
        Begin 
                if reset = '1' then                                --異步復位
                        tmp := ( others => '0' ) ;
                elsif Rising_Edge( clk ) then                 --上升沿
                        if En = '1' then                             --En始能端為1
                                if tmp < 10 then                     --在0~9時能+1
                                        tmp := tmp + 1 ;
                                else                                    --否則清空
                                        tmp := ( others => '0' ) ; 
                                end if ;
                        end if ;
                end if ;
                
                --賦值給CQ
                CQ <= tmp ;
        End Process ;
End Behaving ;

 

 

實驗四  數碼管動態顯示電路的設計

一、 實驗目的

1、 了解數碼管的工作原理。

2、 學習七段數碼管顯示譯碼器的設計。

3、 學習VHDLCASE語句及多層次設計方法。

二、 實驗原理

七段數碼管是電子開發過程中常用的輸出顯示設備。在實驗系統中使用的是兩個四位一體、共陰極型七段數碼管。其單個靜態數碼管如下圖4-1所示。

4-1  靜態七段數碼管

由於七段數碼管公共端連接到GND(共陰極型),當數碼管的中的那一個段被輸入高電平,則相應的這一段被點亮。反之則不亮。四位一體的七段數碼管在單個靜態數碼管的基礎上加入了用於選擇哪一位數碼管的位選信號端口。八個數碼管的abcdefghdp都連在了一起,8個數碼管分別由各自的位選信號來控制,被選通的數碼管顯示數據,其余關閉。

三、 實驗內容

本實驗要求完成的任務是在時鍾信號的作用下,通過輸入的鍵值在數碼管上顯示相應的鍵值。在實驗中時,數字時鍾選擇1KHZ作為掃描時鍾,用四個撥動開關做為輸入,當四個撥動開關置為一個二進制數時,在數碼管上顯示其十六進制的值。實驗箱中的撥動開關與FPGA的接口電路,以及撥動開關FPGA的管腳連接在實驗一中都做了詳細說明,這里不在贅述。數碼管顯示模塊的電路原理如圖4-2所示。

4-2  數字時鍾信號模塊電路原理

library IEEE;        
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity Digit_Show is  
  port( clk    :  in   std_logic;                      
        Input  :  in   std_logic_vector(3 downto 0);  
        Digit  :  out  std_logic_vector(7 downto 0)  
       );       
end Digit_Show; 

architecture Behaving of Digit_Show is 
begin  
    --0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;
    -- 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , A , B , C , D , E , F ;
    process(Input,clk)
      begin
        if  Rising_Edge(clk) then 
            case  Input  is 
                 when  "0000" =>         Digit <="00111111";     -- 0x3f '0'
                 when  "0001" =>         Digit <="00000110";    -- 0x06 '1'
                 when  "0010" =>         Digit <="01011011";    -- 0x5B '2'
                 when  "0011" =>         Digit <="01001111";    -- 0x4F '3'
                 when  "0100" =>         Digit <="01100110";     -- 0x66 '4'
                 when  "0101" =>         Digit <="01101101";  -- 0x6D '5'
                 when  "0110" =>         Digit <="01111101";    -- 0x7D '6'
                 when  "0111" =>         Digit <="00000111";    -- 0x07 '7'
                 when  "1000" =>         Digit <="01111111";    -- 0x7F '8'
                 when  "1001" =>         Digit <="01101111";    -- 0x6F '9'
                 when  "1010" =>         Digit <="01110111";    -- 0x77 'A'
                 when  "1011" =>         Digit <="01111100";    -- 0x7C 'B'
                 when  "1100" =>         Digit <="00111001";    -- 0x39 'C'
                 when  "1101" =>         Digit <="01011110";    -- 0x5E 'D'
                 when  "1110" =>         Digit <="01111001";    -- 0x79 'E'
                 when  "1111" =>         Digit <="01110001";    -- 0x71 'F'
                 when  others => null;    
            end  case;
        end if ;
  end  process; 
end  Behaving;  

 

 

實驗五  基於FSM的計數器設計

一、 實驗目的

1、 熟悉VHDLFSM編程。

2、 熟悉FSM的工作原理。

3、 進一步了解實驗系統的硬件結構。

二、 實驗原理

根據FSM原理,設計十進制計數器狀態機,然后根據三進程方法編程。

FSM原理圖如圖5-1所示。

 

 

  

5-1 實驗原理圖

 

Moore狀態機編程結構圖如圖5-2所示。

 

 

5-2 Moore狀態機結構

三、 實驗內容

本實驗要求完成的任務是在時鍾信號的作用下,通過使能端和復位信號來完成加法計數器的計數。實驗中時鍾信號使用數字時鍾源模塊的1HZ信號,用一位撥動開關K1表示使能端信號,用復位開關S1表示復位信號,用LED模塊的LED1LED11來表示計數的二進制結果。實驗LED亮表示對應的位為‘1’,LED滅表示對應的位為‘0’。通過輸入不同的值模擬計數器的工作時序,觀察計數的結果。實驗箱中的撥動開關、與FPGA的接口電路,LED燈與FPGA的接口電路以及撥動開關、LEDFPGA的管腳連接在實驗一中都做了詳細說明,這里不在贅述。

 

library ieee;
use ieee.std_logic_1164.all ; 
entity FSM_Cnt is 
        port( clk , inp , reset : in std_logic;
                outp : out std_logic_vector( 9 downto 0 ) );
end entity ;

architecture behave of FSM_Cnt is 
    type state is( s0 , s1 , s2 , s3 , s4 , s5 ,s6 , s7 , s8 , s9 ) ; 
    signal cur_s , next_s : state ;
    
begin
    main_process : process ( clk , reset )
    begin 
        if reset = '1' then
            cur_s <= s0 ;
        elsif clk'event and clk = '1' then
            cur_s <= next_s ;
        end if;
    end process ;
    
    state_trans : process ( cur_s , inp )
    begin
        case cur_s is 
            when s0 => if inp = '0' then
                    next_s <= s1 ;end if;
            when s1 => if inp = '0' then
                    next_s <= s2 ;end if;
            when s2 => if inp = '0' then
                    next_s <= s3 ;end if;
            when s3 => if inp = '0' then
                    next_s <= s4 ;end if;
            when s4 => if inp = '0' then
                    next_s <= s5 ;end if;
            when s5 => if inp = '0' then
                    next_s <= s6 ;end if;
            when s6 => if inp = '0' then
                    next_s <= s7 ;end if;
            when s7 => if inp = '0' then
                    next_s <= s8 ;end if;
            when s8 => if inp = '0' then
                    next_s <= s9 ;end if;
            when s9 => if inp = '1' then
                    next_s <= s0 ;end if;
            when others => next_s <= s0 ;
        end case ;
    end process ;
    
    output_process : process ( cur_s )
    begin
        case cur_s is
            when s0 => outp <= "0000000001" ;
            when s1 => outp <= "0000000010" ;
            when s2 => outp <= "0000000100" ;
            when s3 => outp <= "0000001000" ;
            when s4 => outp <= "0000010000" ;
            when s5 => outp <= "0000100000" ;
            when s6 => outp <= "0001000000" ;
            when s7 => outp <= "0010000000" ;
            when s8 => outp <= "0100000000" ;
            when s9 => outp <= "1000000000" ;
        end case ;
    end process ;
end behave ;
            

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM