2017-05-19 77 views
0

我使用RS232接口的參考分量從https://reference.digilentinc.com/reference/programmable-logic/nexys-2/start和示例代碼是:從RS232接收數據時,VHDL

------------------------------------------------------------------------- 
-- main.vhd 
------------------------------------------------------------------------- 
-- Author: Dan Pederson 
--   Copyright 2004 Digilent, Inc. 
------------------------------------------------------------------------- 
-- Description:  This file tests the included UART component by 
--     sending data in serial form through the UART to 
--     change it to parallel form, and then sending the 
--     resultant data back through the UART to determine if 
--     the signal is corrupted or not. When the serial 
--     information is converted into parallel information, 
--     the data byte is displayed on the 8 LEDs on the 
--     system board. 
-- 
--     NOTE: Not all mapped signals are used in this test. 
--     The signals were mapped to ease the modification of 
--     test program.   
------------------------------------------------------------------------- 
-- Revision History: 
--  07/30/04 (DanP) Created 
--  05/26/05 (DanP) Modified for Pegasus board/Updated commenting style 
--  06/07/05 (DanP) LED scancode display added 
------------------------------------------------------------------------- 

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 

------------------------------------------------------------------------- 
-- 
--Title: Main entity 
-- 
--Inputs: 3 : RXD 
--     CLK 
--     RST 
-- 
--Outputs: 1 : TXD 
--     LEDS      
-- 
--Description: This describes the main entity that tests the included 
--    UART component. The LEDS signals are used to 
--    display the data byte on the LEDs, so it is set equal to 
--    the dbOutSig. Technically, the dbOutSig is the scan code 
--    backwards, which explains why the LEDs are mapped 
--    backwards to the dbOutSig. 
-- 
------------------------------------------------------------------------- 
entity DataCntrl is 
    Port ( TXD  : out std_logic := '1'; 
      RXD  : in std_logic := '1'; 
      CLK  : in std_logic; 
      LEDS : out std_logic_vector(7 downto 0) := "11111111"; 
      RST  : in std_logic := '0'); 
end DataCntrl; 

architecture Behavioral of DataCntrl is 

------------------------------------------------------------------------- 
-- Local Component, Type, and Signal declarations.        
------------------------------------------------------------------------- 

------------------------------------------------------------------------- 
-- 
--Title: Component Declarations 
-- 
--Description: This component is the UART that is to be tested. 
--    The UART code can be found in the included 
--    RS232RefComp.vhd file. 
-- 
------------------------------------------------------------------------- 
component RS232RefComp 
    Port ( TXD  : out std_logic := '1'; 
      RXD  : in std_logic;     
      CLK  : in std_logic;       
      DBIN : in std_logic_vector (7 downto 0); 
      DBOUT : out std_logic_vector (7 downto 0); 
      RDA  : inout std_logic;       
      TBE  : inout std_logic := '1';    
      RD  : in std_logic;       
      WR  : in std_logic;       
      PE  : out std_logic;       
      FE  : out std_logic;       
      OE  : out std_logic;           
      RST  : in std_logic := '0');     
end component; 
------------------------------------------------------------------------- 
-- 
--Title: Type Declarations 
-- 
--Description: There is one state machine used in this program, called 
--    the mainState state machine. This state machine controls 
--    the flow of data around the UART; allowing for data to be 
--    changed from serial to parallel, and then back to serial. 
-- 
------------------------------------------------------------------------- 
    type mainState is (
     stReceive, 
     stSend); 
------------------------------------------------------------------------- 
-- 
--Title: Local Signal Declarations 
-- 
--Description: The signals used by this entity are described below: 
-- 
--    -dbInSig : This signal is the parallel data input 
--        for the UART 
--    -dbOutSig : This signal is the parallel data output 
--        for the UART 
--    -rdaSig  : This signal will get the RDA signal from 
--        the UART 
--    -tbeSig  : This signal will get the TBE signal from 
--        the UART 
--    -rdSig  : This signal is the RD signal for the UART 
--    -wrSig  : This signal is the WR signal for the UART 
--    -peSig  : This signal will get the PE signal from 
--        the UART 
--    -feSig  : This signal will get the FE signal from 
--        the UART 
--    -oeSig  : This signal will get the OE signal from 
--        the UART 
-- 
--    The following signals are used by the main state machine 
--    for state control: 
--    
--    -stCur, stNext 
-- 
------------------------------------------------------------------------- 
    signal dbInSig : std_logic_vector(7 downto 0); 
    signal dbOutSig : std_logic_vector(7 downto 0); 
    signal rdaSig : std_logic; 
    signal tbeSig : std_logic; 
    signal rdSig : std_logic; 
    signal wrSig : std_logic; 
    signal peSig : std_logic; 
    signal feSig : std_logic; 
    signal oeSig : std_logic; 

    signal stCur : mainState := stReceive; 
    signal stNext : mainState; 

------------------------------------------------------------------------ 
-- Module Implementation 
------------------------------------------------------------------------ 

begin 

------------------------------------------------------------------------ 
-- 
--Title: LED definitions 
-- 
--Description: This series of definitions allows the scan code to be 
--    displayed on the LEDs on the FPGA system board. Because the 
--    dbOutSig is the scan code backwards, the LEDs must be 
--    defined backwards from the dbOutSig. 
-- 
------------------------------------------------------------------------ 
    LEDS(7) <= dbOutSig(0); 
    LEDS(6) <= dbOutSig(1); 
    LEDS(5) <= dbOutSig(2); 
    LEDS(4) <= dbOutSig(3); 
    LEDS(3) <= dbOutSig(4); 
    LEDS(2) <= dbOutSig(5); 
    LEDS(1) <= dbOutSig(6); 
    LEDS(0) <= dbOutSig(7); 
------------------------------------------------------------------------- 
-- 
--Title:  RS232RefComp map 
-- 
--Description: This maps the signals and ports in main to the 
--    RS232RefComp. The TXD, RXD, CLK, and RST of main are 
--    directly tied to the TXD, RXD, CLK, and RST of the 
--    RS232RefComp. The remaining RS232RefComp ports are 
--    mapped to internal signals in main. 
-- 
------------------------------------------------------------------------- 
    UART: RS232RefComp port map ( TXD  => TXD, 
            RXD  => RXD, 
            CLK  => CLK, 
            DBIN => dbInSig, 
            DBOUT => dbOutSig, 
            RDA  => rdaSig, 
            TBE  => tbeSig, 
            RD  => rdSig, 
            WR  => wrSig, 
            PE  => peSig, 
            FE  => feSig, 
            OE  => oeSig, 
            RST  => RST); 
------------------------------------------------------------------------- 
-- 
--Title: Main State Machine controller 
-- 
--Description: This process takes care of the Main state machine 
--    movement. It causes the next state to be evaluated on 
--    each rising edge of CLK. If the RST signal is strobed, 
--    the state is changed to the default starting state, which 
--    is stReceive. 
-- 
------------------------------------------------------------------------- 
    process (CLK, RST) 
     begin 
      if (CLK = '1' and CLK'Event) then 
       if RST = '1' then 
        stCur <= stReceive; 
       else 
        stCur <= stNext; 
       end if; 
      end if; 
     end process; 
------------------------------------------------------------------------- 
-- 
--Title: Main State Machine 
-- 
--Description: This process defines the next state logic for the Main 
--    state machine. The main state machine controls the data 
--    flow for this testing program in order to send and 
--    receive data. 
-- 
------------------------------------------------------------------------- 
    process (stCur, rdaSig, dboutsig) 
     begin 
      case stCur is 
------------------------------------------------------------------------- 
-- 
--Title: stReceive state 
-- 
--Description: This state waits for the UART to receive data. While in 
--    this state, the rdSig and wrSig are held low to keep the 
--    UART from transmitting any data. Once the rdaSig is set 
--    high, data has been received, and is safe to transmit. At 
--    this time, the stSend state is loaded, and the dbOutSig 
--    is copied to the dbInSig in order to transmit the newly 
--    acquired parallel information. 
-- 
------------------------------------------------------------------------- 
       when stReceive => 
        rdSig <= '0'; 
        wrSig <= '0'; 

        if rdaSig = '1' then 
         dbInSig <= dbOutSig; 
         stNext <= stSend; 
        else 
         stNext <= stReceive; 
        end if;   
------------------------------------------------------------------------- 
-- 
--Title: stSend state 
-- 
--Description: This state tells the UART to send the parallel 
--    information found in dbInSig. It does this by strobing 
--    both the rdSig and wrSig signals high. Once these 
--    signals have been strobed high, the stReceive state is 
--    loaded. 
-- 
------------------------------------------------------------------------- 
       when stSend => 
        rdSig <= '1'; 
        wrSig <= '1'; 

        stNext <= stReceive; 
      end case; 
     end process; 
end Behavioral; 

在以上代碼的基礎上,我努力使自己的狀態機,它允許我從一行終端接收幾個字節到一個緩衝區,改變狀態並將這些字節從一個緩衝區發送到我的電腦上的一個終端。 我從計數器開始計數接收字節的數量。我最終不知道發生了什麼,因爲櫃檯不是隨意改變它的值。我是VHDL新手,任何建議將不勝感激。

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 
use IEEE.NUMERIC_STD.ALL; 

entity DataCntrl is 
    Port ( TXD  : out std_logic := '1'; 
      RXD  : in std_logic := '1'; 
      CLK  : in std_logic; 
      LED : out std_logic_vector(7 downto 0) := "00000000"; 
      RST  : in std_logic := '0'); 
end DataCntrl; 

architecture Behavioral of DataCntrl is 


component RS232RefComp 
    Port ( TXD  : out std_logic := '1'; 
      RXD  : in std_logic;     
      CLK  : in std_logic;       
      DBIN : in std_logic_vector (7 downto 0); 
      DBOUT : out std_logic_vector (7 downto 0); 
      RDA  : inout std_logic;       
      TBE  : inout std_logic := '1';    
      RD  : in std_logic;       
      WR  : in std_logic;       
      PE  : out std_logic;       
      FE  : out std_logic;       
      OE  : out std_logic;           
      RST  : in std_logic := '0');     
end component; 

    type mainState is (
     stReceive, stA, 
     stRereceive); 

    signal dbInSig : std_logic_vector(7 downto 0); 
    signal dbOutSig : std_logic_vector(7 downto 0); 
    signal rdaSig : std_logic; 
    signal tbeSig : std_logic; 
    signal rdSig : std_logic; 
    signal wrSig : std_logic; 
    signal peSig : std_logic; 
    signal feSig : std_logic; 
    signal oeSig : std_logic; 

    signal stCur : mainState := stReceive; 
    signal stNext : mainState; 


begin 


    UART: RS232RefComp port map ( TXD  => TXD, 
            RXD  => RXD, 
            CLK  => CLK, 
            DBIN => dbInSig, 
            DBOUT => dbOutSig, 
            RDA  => rdaSig, 
            TBE  => tbeSig, 
            RD  => rdSig, 
            WR  => wrSig, 
            PE  => peSig, 
            FE  => feSig, 
            OE  => oeSig, 
            RST  => RST); 

    process (CLK, RST) 
     begin 
      if (CLK = '1' and CLK'Event) then 
       if RST = '1' then 
        stCur <= stReceive; 
       else 
        stCur <= stNext; 
       end if; 
      end if; 
     end process; 

    process (stCur, rdaSig, dboutsig) 
    variable Send: std_logic :='0'; 
    variable Count: integer :=0; 
     variable Jol: integer :=0; 
     begin 
     Jol:=Count; 
     Led<=std_logic_vector(to_unsigned(Jol,8)); 
      case stCur is 

       when stReceive => 
        rdSig <= '0'; 
        wrSig <= '0'; 

        if rdaSig = '1' then 
        Send:='0'; 
         dbInSig <= dbOutSig; 
        if(Count=4) then 
         dbInSig <= "11101111"; 
        stNext <= stA; 

         else 
         stNext <= stRereceive; 
         end if; 
        else 
         stNext <= stReceive; 
        end if;   

       when stRereceive => 
        rdSig <= '1'; 
        if(Send='0') then 
        Count:=Count+1; 
        Send:='1'; 
        end if; 
        stNext <= stReceive; 

       when stA=> 
        wrSig <= '1'; 
        rdSig <= '1'; 


      end case; 
     end process; 
end Behavioral; 
+0

我認爲的一個例子。 –

+1

不要同時使用包std_logic_arith和numeric_std,並且注意use子句的順序很重要。函數to_unsigned在numeric_std中使用的無符號聲明與std_logic_arith中的無符號聲明不同,充其量不是便攜式的。您不提供缺少測試臺和Rs232RefComp的[最小,完整和可驗證示例](https://stackoverflow.com/help/mcve)。您的Count計數器不是時鐘同步的,並且可以在'stCur','rdaSig'或'dboutsig'之一的事件中以'stRereceive'狀態遞增。 – user1155120

+0

Lol,這位來自Agillent的Dan Pederson在2004年仍然使用'STD_LOGIC_ARITH'。即使在大公司,一些專業人士仍然生活在90年代。 – JHBonarius

回答

0

所以,看看你的計算器增量代碼:

process (stCur, rdaSig, dboutsig) 
    [...] 
    variable Count: integer := 0; 
begin 
    [...] 
    case stCur is 
     [...] 
     when stRereceive => 
      [...] 
      if(Send='0') then 
       Count:=Count+1; 

讓我們來分析一下,我們在這裏看到。

  1. count是一個變量。
  2. count在組合過程中增加。

[讓我們省去了你的敏感名單是殘缺不全]

當你說「計數器不改變其值由一個」,我想,你希望它由一個每個時鐘週期(或相當於增加)。但爲了能夠增加先前的值,計數器必須保持以前的值。這意味着需要寄存器。但是,寄存器需要時鐘輸入。因此,在無時鐘組合處理中,沒有寄存器被推斷爲

然後:請勿將變量用於註冊值。只有很少的情況下你應該使用變量,而這不是其中之一。

這裏是你的意思是UART並不RS232一個計時計數處理

architecture rtl of ent is 
    signal count : unsigned(3 downto 0) := (others => '0'); 
begin 
    clk_proc : process (clk) 
    begin 
     if rising_edge(clk) then 
      if [condition] then 
       count <= count + 1; 
      end if; 
      if reset = '1' then 
       count <= (others => '0'); 
      end if; 
     end if; 
    end process;