Прием данных с RS232, vhdl

Я использую эталонный компонент интерфейса RS232 из https://reference.digilentinc.com/reference/programmable-logic/nexys-2/start и пример кода:

-------------------------------------------------------------------------
-- 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;

person tech2nick    schedule 19.05.2017    source источник
comment
Я думаю, вы имеете в виду uart, а не RS232.   -  person old_timer    schedule 19.05.2017
comment
Не используйте оба пакета, std_logic_arith и numeric_std, и обратите внимание на порядок использования предложений. Объявление unsigned, используемое функцией to_unsigned в numeric_std, отличается от объявления unsigned в std_logic_arith, в лучшем случае оно не переносимо. Вы не предоставляете минимальный, полный и проверяемый пример, в котором отсутствует как тестовая среда, так и Rs232RefComp. Ваш счетчик Count не синхронизирован с часами и может увеличиваться по событию одного из stCur, rdaSig или dboutsig в состоянии stRereceive.   -  person    schedule 19.05.2017
comment
Лол, этот Дэн Педерсон из Agilent все еще использует STD_LOGIC_ARITH в 2004 году. Кажется, даже в крупных компаниях некоторые профессионалы все еще живут в 90-х.   -  person JHBonarius    schedule 22.05.2017


Ответы (1)


Итак, взгляните на свой код увеличения счетчика:

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 увеличивается в комбинаторном процессе.

[упустим, что ваш список конфиденциальности неполный]

Когда вы говорите, что «счетчик меняет свое значение не на единицу», я предполагаю, что вы хотите, чтобы он увеличивался на единицу каждый такт (или сопоставимо). Но чтобы иметь возможность увеличивать предыдущее значение, счетчик должен удерживать это предыдущее значение. Это означает, что регистры необходимы. Однако регистры требовали ввода часов. Таким образом, в комбинаторном процессе без часов никакие регистры не выводятся.

Затем: не используйте переменные для зарегистрированных значений. Есть очень немного ситуаций, в которых вы должны использовать переменные, и это не одна из них.

Вот пример синхронизированного счетчика

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;
person JHBonarius    schedule 22.05.2017