1. 程式人生 > >【VHDL】VHDL設計一個分頻器

【VHDL】VHDL設計一個分頻器

1. 實驗任務

  • 嘗試用兩種或以上方式設計並實現一個分頻器

2. 如何實現

  1. 二進位制分頻器的設計

    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    use ieee.std_logic_unsigned.all;
    ENTITY DIV IS 
    generic (N:integer :=2);--進行2的N次冪分頻
    PORT (fin:in std_logic;
    fout:out std_logic);
    end entity DIV;
    
    architecture behav of DIV is
    signal count :std_logic_vector
    (N-1 downto 0); begin process (fin) begin if(fin'event and fin='1') then count<=count+1;--計數值加一 end if; end process; fout<=count(N-1); end ;
  2. 偶分頻器(佔空比為50%)

    Library ieee;
    Use ieee.std_logic_1164.all;
    Use ieee.std_logic_unsigned.all;
    Use ieee.std_logic_arith.all;
    
    Entity fdiv is
      generic
    (N: integer:=6); --rate=N,N是偶數 port( clkin: IN std_logic; clkout: OUT std_logic ); End fdiv; Architecture a of fdiv is signal cnt: integer range 0 to n-1; Begin process(clkin) --計數 begin if(clkin'event and clkin='1') then if(cnt<n-1) then cnt <= cnt+1
    ; else cnt <= 0; end if; end if; end process; process(cnt) --根據計數值,控制輸出時鐘脈衝的高、低電平 begin if(cnt<n/2) then clkout <= '1'; else clkout <= '0'; end if; end process; End a;
  3. 奇分頻器(佔空比為50%)

    Library ieee;
    Use ieee.std_logic_1164.all;
    Use ieee.std_logic_unsigned.all;
    Use ieee.std_logic_arith.all;
    
    Entity fdiv is
      generic(N: integer:=5);        --rate=N,N是奇數
      port(
            clkin: IN std_logic;
            clkout: OUT std_logic
            );
    End fdiv;
    architecture a of fdiv is
      signal cnt1, cnt2: integer range 0 to N-1;
    begin
      process(clkin)
      begin
          if(clkin‘event and clkin=’1‘) then  --上升沿計數
              if(cnt1<N-1) then
                  cnt1 <= cnt1+1;
              else
               cnt1 <= 0;
           end if;
          end if;
      end process;
      process(clkin)
      begin
        if(clkin‘event and clkin=’0‘) then  --下降沿計數
            if(cnt2<N-1) then
                cnt2 <= cnt2+1;
            else
             cnt2 <= 0;
            end if;
        end if;
      end process;
    
      clkout <= '1' when cnt1<(N-1)/2 or cnt2<(N-1)/2 else
                      '0';
    
    end a;
    
  4. 使用LPM 和繪圖方式來實際N分頻器
      選擇Tools中的MegaWizard Plug-In Manager命令,選擇Creat a new custom megafunction variation,定製一個新的模版,在左側欄中選擇算術項Arthmetic下的LPM_COUNTER,進而一步步配置,得到一定位數,預製功能可定製的LPM計數器。
      
      
      二進位制分頻器可視作一個n位的計數器和一個D觸發器相連線,當計數器溢位時,D觸發器翻轉,從而構成分頻器。
      LPM_COUNTER配置好之後,可以編寫D觸發器,或者使用系統提供的D觸發器。
      最後通過原件例化語句或者畫圖的方式將兩者連線在一起。

    • D觸發器
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    
    ENTITY DDFF IS
    PORT (CLK_D,D:IN STD_LOGIC;
              Q:OUT STD_LOGIC);
    END;
    
    ARCHITECTURE bhv OF DDFF IS
    SIGNAL Q1:STD_LOGIC;
    BEGIN 
    PROCESS (CLK_D,Q1) BEGIN
            IF CLK_D'EVENT AND CLK_D='1' THEN Q1<=D;
            END IF;
    END PROCESS;
    Q<=Q1;
    END bhv;
    • LPM_COUNTER(具有同步載入、非同步清零、加減控制)N進位制計數器
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    use ieee.std_logic_unsigned.all;
    ENTITY CNT4BIT IS 
    generic (N:integer :=4);--進行2的N次冪分頻
    PORT (
    CLK,RST,ENA,SLD,UD:IN STD_LOGIC;
    DIN:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
    COUT:OUT STD_LOGIC;
    DOUT:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
    END ENTITY CNT4BIT;
    
    ARCHITECTURE behav OF CNT4BIT IS
    SIGNAL TRANS :STD_LOGIC;
    
    component LPM_MD 
    port(
    aclr,clk_en,clock,sload,updown:in std_logic;
    data:in std_logic_vector(3 downto 0);
    cout:out std_logic;
    q:out std_logic_vector(3 downto 0));
    end component;
    
    component DDFF
    PORT (CLK_D,D:IN STD_LOGIC;
              Q:OUT STD_LOGIC);
    END component ;
    
    begin 
    U1:LPM_MD PORT MAP(sload=>SLD,
    clk_en=>ENA,
    aclr=>RST,
    cout=>TRANS,
    clock=>CLK,
    data=>DIN,
    updown=>UD,
    q=>DOUT);
    
    U2:DDFF port map(
    CLK_D=>CLK,
    D=>TRANS,
    Q=>COUT
    );
    
    END ARCHITECTURE behav;

3. 實驗結果

  • 模擬波形圖

  • LPM_DIV(16分頻分頻器)