加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • ?1 概述
    • 2 樣例
    • 3 常用編寫
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

VHDL快速語法入門

03/04 10:30
3915
閱讀需 24 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

?1 概述

HDL(VHSIC Hardware Description Language)是一種硬件描述語言,主要用于描述數(shù)字電路和系統(tǒng)的結(jié)構(gòu)、行為和功能。它是一種用于硬件設(shè)計(jì)的標(biāo)準(zhǔn)化語言,能夠幫助工程師們更好地描述和設(shè)計(jì)數(shù)字電路,并且廣泛應(yīng)用于FPGA和ASIC設(shè)計(jì)中。

在VHDL中,一個(gè)設(shè)計(jì)被描述為一個(gè)實(shí)體(entity),它包含了輸入輸出端口的描述。實(shí)體也包含了該設(shè)計(jì)的行為(behavior)的描述。 此外,VHDL還包括了標(biāo)準(zhǔn)庫(standard library)和數(shù)學(xué)運(yùn)算庫(numeric package)等。

VHDL的基本語法包括關(guān)鍵字、標(biāo)識(shí)符、注釋、數(shù)據(jù)類型(如std_logic、integer等)、變量聲明、信號(hào)聲明、過程語句、并行操作符等。

以下是VHDL的一些基本特性和語法:

實(shí)體聲明(Entity Declaration):實(shí)體(entity)是一個(gè)設(shè)計(jì)的接口和規(guī)范,描述了設(shè)計(jì)的輸入和輸出信號(hào)。在實(shí)體聲明中,可以指定設(shè)計(jì)的接口和端口類型。

架構(gòu)(Architecture):架構(gòu)是實(shí)體的行為和功能描述。它包括了組件實(shí)例化、信號(hào)聲明、過程語句等。在架構(gòu)中,可以描述設(shè)計(jì)的邏輯和數(shù)據(jù)流動(dòng)。

信號(hào)(Signal)和變量(Variable):在VHDL中,信號(hào)用于描述設(shè)計(jì)中的數(shù)據(jù)傳輸,而變量通常用于描述局部的數(shù)據(jù)存儲(chǔ)。信號(hào)和變量的作用在于描述設(shè)計(jì)中的數(shù)據(jù)流動(dòng)和數(shù)據(jù)處理。

過程(Process):過程描述了設(shè)計(jì)中的行為和邏輯。過程可以包括對(duì)信號(hào)和變量的操作、時(shí)序邏輯的描述等。

循環(huán)(Loop):VHDL中也包括了循環(huán)語句,用于描述設(shè)計(jì)中的重復(fù)操作。

總的來說,VHDL是一門強(qiáng)大的硬件描述語言,能夠幫助工程師們進(jìn)行數(shù)字電路的設(shè)計(jì)和描述。通過VHDL,工程師們可以更好地理解和描述設(shè)計(jì)的結(jié)構(gòu)和行為,從而實(shí)現(xiàn)復(fù)雜的數(shù)字系統(tǒng)設(shè)計(jì)。雖然VHDL的語法可能對(duì)初學(xué)者來說有一定的復(fù)雜性,但一旦熟悉了其基本特性和語法,將會(huì)成為非常有用的工具。

library IEEE;
use IEEE.std_logic_1164.all;

entity ExampleModule is
port(
clk, reset : in std_logic;
input1, input2 : in std_logic_vector(7 downto 0);
output1 : out std_logic_vector(7 downto 0)
);
end ExampleModule;

architecture Behavioral of ExampleModule is
component SubModule is
port(
a, b : in std_logic_vector(7 downto 0);
c : out std_logic_vector(7 downto 0)
);
end component;

signal intermediate : std_logic_vector(7 downto 0);
begin
SubModule_inst : SubModule
port map(
a => input1,
b => input2,
c => intermediate
);

process(clk, reset)
begin
if reset = '1' then
output1 <= (others => '0');
elsif rising_edge(clk) then
output1 <= intermediate;
end if;
end process;
end Behavioral;

2 樣例

按鍵消抖

設(shè)計(jì)文件:

library ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.ALL;

entity debouncing is
    generic(N: integer := 10);
    port(	clk: in std_logic;
			rst: in std_logic;
			u: in std_logic;
			delay : in std_logic_vector(N-1 downto 0);
			y: out std_logic);
end debouncing;

architecture arch of debouncing is
	type state_type is (zero, wait0, wait1, one);
	signal state, state_n: state_type;
	
	signal cnt, cnt_n: unsigned(N-1 downto 0);
begin
    -- state register
    process(clk,rst)
    begin
        if (rst='1') then
            state <= zero;
            cnt <= (others => '0');
        elsif (rising_edge(clk)) then
            state <= state_n;
            cnt <= cnt_n;
        end if;
    end process;
    -- next-state/output logic
    process(state,u,cnt,delay)
    begin
        state_n <= state;
        cnt_n <= (others => '0');
        
        case state is
        when zero =>
            y <= '0';
            if u= '1' then
                state_n <= wait0;
            end if;
            
        when wait0 =>
            
            y <= '0';
            
            -- check next state
            if u = '0' then
                state_n <= zero;
            elsif cnt = unsigned(delay) then
                state_n <= one;
            end if;
            
            -- increment counter
            cnt_n <= cnt + 1;
            
        when wait1 =>
            
            y <= '1';
            
            -- check next state
            if u = '1' then
                state_n <= one;
            elsif cnt = unsigned(delay) then
                state_n <= zero;
            end if;
            
            -- increment counter
            cnt_n <= cnt + 1;
            
        when one =>
            y <= '1';
            if u= '0' then
                state_n <= wait1;
            end if;
        end case;
    end process;
end arch;

按鍵消抖仿真文件:

ibrary ieee;
use ieee.std_logic_1164.all;
use IEEE.NUMERIC_STD.ALL;

entity debouncing_tb is
end debouncing_tb;

architecture tb of debouncing_tb is
    
    constant N: integer := 8;
    signal delay: std_logic_vector(N-1 downto 0);
    signal u, y,z : std_logic;
    
    signal clk, rst : std_logic;
    -- Clock period definitions
    constant Ts : time := 10 ns;

begin

    db0 : entity work.debouncing
    generic map(N => N)
    port map (clk => clk,
              rst => rst,
              delay => delay,
              u => u,
              y => y);
              
   -- Clock process definitions
   process
   begin
	clk <= '0';
	wait for Ts/2;
	clk <= '1';
	wait for Ts/2;
   end process;


    stimuli : process
    begin
        rst <= '1';
        u <= '0';
        delay <= (others => '0');
        
        wait for 5*Ts;
        
        rst <= '0';
        delay <= std_logic_vector(to_unsigned(20,N));
        
        u <= '1';
        wait for 3*Ts;
        
        u <= '0';
        wait for 5*Ts;
        
        u <= '1';
        wait for 10*Ts;
        
        u <= '0';
        wait for 3*Ts;
        
        u <= '1';
        wait for 25*Ts;
        
        u <= '0';
        wait for 2*Ts;
        
        u <= '1';
        wait for 5*Ts;
        
        u <= '0';
        wait for 25*Ts;
                
        wait;
    end process;

end tb;


3 常用編寫

時(shí)序邏輯:
在 VHDL 中,時(shí)序邏輯指的是描述在特定時(shí)鐘信號(hào)的邊沿或狀態(tài)變化下發(fā)生的操作。時(shí)序邏輯可以包括使用 rising_edge 或 falling_edge 函數(shù)來檢測(cè)時(shí)鐘信號(hào)的上升沿或下降沿,以及使用 wait for 語句來控制時(shí)序行為。下面是一個(gè)簡(jiǎn)單的示例,說明了時(shí)序邏輯的基本用法:

architecture Behavioral of ExampleModule is
begin
  process (clk)
  begin
    if rising_edge(clk) then
      -- 在時(shí)鐘上升沿執(zhí)行的操作
      -- 例如,更新寄存器、執(zhí)行狀態(tài)轉(zhuǎn)移等
    end if;
  end process;
end architecture Behavioral;

在這個(gè)例子中,我們定義了一個(gè)處理時(shí)鐘信號(hào) clk 的過程。使用 if rising_edge(clk) then 表示當(dāng)檢測(cè)到時(shí)鐘信號(hào)的上升沿時(shí)執(zhí)行操作。在這個(gè)邏輯塊中,你可以更新寄存器、執(zhí)行狀態(tài)轉(zhuǎn)移等與時(shí)鐘相關(guān)的操作。這種時(shí)序邏輯的描述允許你根據(jù)特定時(shí)鐘信號(hào)的變化來控制設(shè)計(jì)的行為。

時(shí)序邏輯在數(shù)字電路設(shè)計(jì)中非常重要,因?yàn)樗軌虼_保設(shè)計(jì)在特定時(shí)鐘信號(hào)的控制和同步下正確運(yùn)行。通過使用時(shí)序邏輯,可以將設(shè)計(jì)的行為明確地與時(shí)鐘信號(hào)進(jìn)行關(guān)聯(lián),從而實(shí)現(xiàn)可靠的同步邏輯。

VHDL組合邏輯:
在 VHDL 中,組合邏輯是指在不涉及時(shí)鐘信號(hào)的條件下,根據(jù)輸入直接計(jì)算輸出的邏輯部分。通常,組合邏輯描述了在給定輸入條件下的輸出行為,而且輸出立即對(duì)輸入進(jìn)行響應(yīng),不依賴于時(shí)鐘的邊沿。以下是一個(gè)簡(jiǎn)單的示例,說明了組合邏輯的基本用法:

-- 一個(gè)簡(jiǎn)單的 2:1 多路選擇器的組合邏輯
entity Mux2x1 is
  port (
    sel: in std_logic;
    a, b: in std_logic;
    y: out std_logic
  );
end entity Mux2x1;

architecture Behavioral of Mux2x1 is
begin
  process (sel, a, b)
  begin
    if sel = '0' then
      y <= a;
    else
      y <= b;
    end if;
  end process;
end architecture Behavioral;

在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為 Mux2x1 的實(shí)體,該實(shí)體具有三個(gè)輸入端口 sel、a 和 b 以及一個(gè)輸出端口 y。在 Behavioral 架構(gòu)中的處理過程中,我們使用 if 語句來根據(jù)輸入信號(hào) sel 的值選擇輸出的值。這是一個(gè)典型的組合邏輯,因?yàn)檩敵?y 的值是僅僅依賴于當(dāng)前輸入信號(hào)的狀態(tài)而計(jì)算出來的,不涉及時(shí)鐘或者時(shí)序控制。

組合邏輯在數(shù)字電路設(shè)計(jì)中很常見,它描述了電路在給定輸入下的輸出行為,沒有涉及時(shí)鐘控制或時(shí)序邏輯。

case語句:
當(dāng)需要根據(jù)輸入的不同值采取不同的操作時(shí),可以使用VHDL中的case語句。下面是一個(gè)簡(jiǎn)單的VHDL case語句的示例:

process (input)
begin
  case input is
    when "00" =>
      -- 對(duì)輸入為 "00" 執(zhí)行的操作
      output <= "0000";
    when "01" =>
      -- 對(duì)輸入為 "01" 執(zhí)行的操作
      output <= "0011";
    when "10" =>
      -- 對(duì)輸入為 "10" 執(zhí)行的操作
      output <= "1100";
    when others =>
      -- 對(duì)其他輸入情況下執(zhí)行的操作
      output <= "1111";
  end case;
end process;

在這個(gè)例子中,我們?cè)谝粋€(gè)process中使用了case語句來根據(jù)輸入的不同情況執(zhí)行相應(yīng)的操作。當(dāng)輸入信號(hào)input的值滿足某個(gè)條件時(shí),對(duì)應(yīng)的輸出output會(huì)被賦予相應(yīng)的值。 “when others” 表示當(dāng)輸入值不滿足前面列舉的情況時(shí)執(zhí)行的操作。

這個(gè)例子展示了VHDL中使用case語句進(jìn)行條件判斷和執(zhí)行不同操作的方法。

狀態(tài)機(jī)

在 VHDL 中實(shí)現(xiàn)狀態(tài)機(jī)(state machine)通常是通過組合邏輯和時(shí)序邏輯相結(jié)合的方式來完成的。狀態(tài)機(jī)描述了一個(gè)系統(tǒng)在不同狀態(tài)下的行為,通常會(huì)隨著輸入信號(hào)的變化而轉(zhuǎn)換狀態(tài)。下面是一個(gè)簡(jiǎn)單的示例,說明了一個(gè)基本的有限狀態(tài)機(jī)在 VHDL 中的實(shí)現(xiàn):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity SimpleFSM is
  Port ( clk : in STD_LOGIC;
         reset : in STD_LOGIC;
         input : in STD_LOGIC;
         output : out STD_LOGIC);
end SimpleFSM;

architecture Behavioral of SimpleFSM is
  type state_type is (s0, s1, s2, s3);
  signal state, next_state : state_type;
begin
  process (clk, reset)
  begin
    if reset = '1' then
      state <= s0; -- 在復(fù)位時(shí)將狀態(tài)設(shè)置為初始狀態(tài)
    elsif rising_edge(clk) then
      state <= next_state; -- 在時(shí)鐘的上升沿根據(jù)下一個(gè)狀態(tài)進(jìn)行狀態(tài)更新
    end if;
  end process;

  process (state, input)
  begin
    case state is
      when s0 =>
        if input = '1' then
          next_state <= s1; -- 根據(jù)輸入信號(hào)轉(zhuǎn)移至下一個(gè)狀態(tài)
        else
          next_state <= s0; -- 如果輸入信號(hào)不滿足條件,保持在當(dāng)前狀態(tài)
        end if;
      when s1 =>
        if input = '0' then
          next_state <= s2;
        else
          next_state <= s1;
        end if;
      when s2 =>
        if input = '1' then
          next_state <= s3;
        else
          next_state <= s2;
        end if;
      when s3 =>
        next_state <= s0;
      when others =>
        next_state <= s0;
    end case;
  end process;
end Behavioral;

在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為 SimpleFSM 的實(shí)體,該實(shí)體包括了時(shí)鐘信號(hào) clk、復(fù)位信號(hào) reset、輸入信號(hào) input 和輸出信號(hào) output。狀態(tài)機(jī)的行為由 state 和 next_state 信號(hào)來描述。在第一個(gè) process 中,我們根據(jù)時(shí)鐘信號(hào)和復(fù)位信號(hào)來更新 state 的值,以此來控制狀態(tài)的轉(zhuǎn)移。在第二個(gè) process 中,我們根據(jù)當(dāng)前的狀態(tài)和輸入信號(hào)來計(jì)算下一個(gè)狀態(tài) next_state。這個(gè)狀態(tài)機(jī)描述了一個(gè)簡(jiǎn)單的輸入序列檢測(cè)過程,根據(jù)輸入序列的不同,狀態(tài)機(jī)將在不同的狀態(tài)間轉(zhuǎn)移。這是一個(gè)基本的有限狀態(tài)機(jī)的例子,通過狀態(tài)的轉(zhuǎn)移來實(shí)現(xiàn)不同的行為。

時(shí)鐘信號(hào)編寫:
a)占空比為50%

constant PERIOD : time := <value>;  --定義時(shí)鐘周期

--使用after語句
CLK <= not CLK after PERIOD/2;

--使用wait語句
constant PERIOD : time := <value>;
CLK <= '0';
wait for PERIOD/2;
CLK <= '1';
wait for PERIOD/2;

b)非50%占空比

constant DUTY_CYCLE : real := <value_0.01_to_0.99>; --定義占空比系數(shù)
constant PERIOD : time := <value>;  --定義時(shí)鐘周期


--使用after語句


CLK <= '1' after (PERIOD - (PERIOD * DUTY_CYCLE)) when CLK = '0'
  else '0' after (PERIOD * DUTY_CYCLE);


--使用wait語句

CLK <= '0';
wait for (PERIOD - (PERIOD * DUTY_CYCLE));
CLK <= '1';
wait for (PERIOD * DUTY_CYCLE);

c)差分端口占空比為50%

constant PERIOD : time := <value>;   --設(shè)置時(shí)鐘周期

--使用after語句

CLK_P <= not CLK_P after PERIOD/2;
CLK_N <= not CLK_N after PERIOD/2;
--使用wait語句
CLK_P <= '0';
CLK_N <= '1';
wait for PERIOD/2;
CLK_P <= '1';
CLK_N <= '0';
wait for PERIOD/2;

延時(shí):

constant SIM_TIME : time := 10 ms;  --設(shè)置仿真時(shí)間SIM_TIME, 時(shí)間為10ms
<signal_name> <= <signal_value> after SIM_TIME;  --信號(hào)在SIM_TIME后進(jìn)行賦值

wait on <signal_name>;   --延時(shí)到信號(hào)有變化

wait until falling_edge(<signal_name>); --延時(shí)到信號(hào)的下降沿到來
                        
wait until rising_edge(<signal_name>);  --延時(shí)到信號(hào)的上升沿到來

wait until <signal_name> = <value>;   --延時(shí)到信號(hào)變化到指定值

循環(huán):
a) loop語句

loop
   CLK <= not CLK;
   wait for PERIOD/2;
   if <signal_name = <value> then
      exit;
   end if;
end loop;

b) for語句

for <variable_name> in <lower_limit> to <upper_limit> loop
   <statement>;
   <statement>;
end loop;

c)while語句

while <condition> loop
   <statement>;
   <statement>;
end loop;

 

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
25LC256-I/ST 1 Microchip Technology Inc 32K X 8 SPI BUS SERIAL EEPROM, PDSO8, 4.40 MM, ROHS COMPLIANT, PLASTIC, TSSOP-8

ECAD模型

下載ECAD模型
$2.62 查看
SST25VF080B-50-4I-S2AE-T 1 Microchip Technology Inc IC FLASH 2.7V PROM, Programmable ROM

ECAD模型

下載ECAD模型
$1.45 查看
LAN8720AI-CP-ABC 1 Microchip Technology Inc Ethernet Transceiver

ECAD模型

下載ECAD模型
$1.26 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

lee
lee

從數(shù)字出發(fā),走進(jìn)圖像世界,聆聽音頻的美妙旋律。從電路出發(fā),實(shí)現(xiàn)美妙的算法,展示代碼的美奐。從知識(shí)到實(shí)現(xiàn),歡迎大家關(guān)注公眾號(hào)FPGA開源工作室。