⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhdl design urat .txt

📁 用VHDL编写的URAT程序
💻 TXT
字号:

--
-- Copyright (c) 1992,1993,1994, Exemplar Logic Inc. All rights reserved.
--
----------------------------------------------------------------
--
-- This design implements a UART. 
--
-- 
--     Version 1.1 : Original Creation
--     Version 1.2 : Modified to std_logic types
--     Version 2.1 : Extended reset to be more effective.
--                   Introduced OTHERS clause.
------------------------------------------------------------------

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

ENTITY uart IS
    PORT (clkx16 : IN    std_logic; -- Input clock. 16x bit clock
            read : IN    std_logic; -- Received data read strobe
           write : IN    std_logic; -- Transmit data write strobe
       rx : IN    std_logic; -- Receive  data line
    reset : IN    std_logic; -- clear dependencies
       tx : OUT   std_logic; -- Transmit data line
           rxrdy : OUT   std_logic; -- Received data ready to be read
           txrdy : OUT   std_logic; -- Transmitter ready for next byte
       parityerr : OUT   std_logic; -- Receiver parity error
      framingerr : OUT   std_logic; -- Receiver framing error
         overrun : OUT   std_logic; -- Receiver overrun error 
     data : INOUT std_logic_vector(0 TO 7)); -- Bidirectional data bus
END uart;

ARCHITECTURE exemplar OF uart IS
    -- Transmit data holding register
    SIGNAL      txhold : std_logic_vector(0 TO 7);

    -- Transmit shift register bits
    SIGNAL       txreg : std_logic_vector(0 TO 7);
    SIGNAL      txtag2 : std_logic; -- tag bits for detecting 
    SIGNAL      txtag1 : std_logic; --    empty shift reg
    SIGNAL    txparity : std_logic; -- Parity generation register

    -- Transmit clock and control signals
    SIGNAL       txclk : std_logic;     -- Transmit clock: 1/16th of clkx16
    SIGNAL      txdone : std_logic; -- '1' when shifting of byte is done
    SIGNAL paritycycle : std_logic; -- '1' on next to last shift cycle
    SIGNAL   txdatardy : std_logic;     -- '1' when data is ready in txhold

    -- Receive shift register bits
    SIGNAL      rxhold : std_logic_vector(0 TO 7);-- Holds received data for read
    SIGNAL       rxreg : std_logic_vector(0 TO 7);-- Receive data shift register
    SIGNAL    rxparity : std_logic; -- Parity bit of received data
    SIGNAL   paritygen : std_logic; -- Generated parity of received data
    SIGNAL      rxstop : std_logic; -- Stop bit of received data

    -- Receive clock and control signals
    SIGNAL       rxclk : std_logic; -- Receive data shift clock
    SIGNAL      rxidle : std_logic;     -- '1' when receiver is idling
    SIGNAL   rxdatardy : std_logic;     -- '1' when data is ready to be read

BEGIN 

make_txclk:
    PROCESS (reset, clkx16)
 VARIABLE cnt  : std_logic_vector(2 DOWNTO 0);
    BEGIN
 -- Toggle txclk every 8 counts, which divides the clock by 16
 IF reset='1' THEN
     txclk <= '0' ;
     cnt := (OTHERS=>'0') ;
 ELSIF clkx16'event AND clkx16='1' THEN
     IF (cnt = "000") THEN 
         txclk <= NOT txclk; 
     END IF;
     cnt := cnt + "001"; -- Use the exemplar_1164 "+" on std_logic_vector
 END IF;
    END PROCESS;

make_rxclk:
    PROCESS  (reset, clkx16) 
 VARIABLE rxcnt : std_logic_vector(0 TO 3); -- Count of clock cycles
 VARIABLE rx1   : std_logic; -- rx delayed one cycle
 VARIABLE hunt  : boolean; -- Hunting for start bit 
    BEGIN
 IF reset='1' THEN
     -- Reset all generated signals and variables
     hunt := FALSE ;
     rxcnt := (OTHERS=>'0') ;
     rx1 := '0' ;
     rxclk <= '0' ;
 ELSIF clkx16'EVENT AND clkx16 = '1' THEN

     -- rxclk = clkx16 divided by 16 
     rxclk <= rxcnt(0);

     -- Hunt=TRUE when we are looking for a start bit:
     --  A start bit is eight clock times with rx=0 after a falling edge

     IF (rxidle = '1' AND rx = '0' AND rx1 = '1') THEN
                -- Start hunting when idle and falling edge is found
         hunt := TRUE;
     END IF ;
     IF rxidle = '0' OR rx = '1' THEN
         -- Stop hunting when shifting in data or a 1 is found on rx
         hunt := FALSE;
     END IF;
     rx1 := rx; -- rx delayed by one clock for edge detection
   -- (Must be assigned AFTER reference)

     -- Increment count when not idling or when hunting
     IF (rxidle = '0' OR hunt) THEN
         -- Count clocks when not rxidle or hunting for start bit
         rxcnt := rxcnt + "0001";
     ELSE
         -- hold at 1 when rxidle and waiting for falling edge
         rxcnt := "0001";
     END IF;
 END IF ;
    END PROCESS;

-- transmit shift register:
txshift:
    PROCESS (reset, txclk)
    BEGIN
 IF reset='1' THEN
     txreg <= (OTHERS=>'0') ; 
     txtag1 <= '0' ;
     txtag2 <= '0' ;
            txparity <= '0' ;
     tx <= '0' ;
 ELSIF txclk'event AND txclk = '1' THEN 
     IF (txdone AND txdatardy) = '1'  THEN
         -- Initialize registers and load next byte of data
         txreg    <= txhold; -- Load tx register from txhold
         txtag2   <= '1';    -- Tag bits for detecting 
         txtag1   <= '1';    --    when shifting is done
         txparity <= '1';    -- Parity bit.Initializing to 1==odd parity
         tx       <= '0';    -- Start bit
     ELSE
         -- Shift data
         txreg <= txreg(1 TO 7) & txtag1;
         txtag1        <= txtag2;
         txtag2    <= '0';

         -- Form parity as each bit goes by
         txparity      <= txparity XOR txreg(0);

         -- Shift out data or parity bit or stop/idle bit
         IF txdone = '1' THEN
      tx <= '1'; -- stop/idle bit
         ELSIF paritycycle = '1' THEN
      tx <= txparity; -- Parity bit
         ELSE
          tx <= txreg(0); --Shift data bit
         END IF;
     END IF ;
 END IF;
    END PROCESS;

    -- paritycycle = 1 on next to last cycle (When txtag2 has reached txreg(1))
    --   (Enables putting the parity bit out on tx)
    paritycycle <= txreg(1) AND NOT (txtag2 OR txtag1 OR 
         txreg(7) OR txreg(6) OR txreg(5) OR 
         txreg(4) OR txreg(3) OR txreg(2));

    -- txdone = 1 when done shifting (When txtag2 has reached tx)
    txdone <= NOT (txtag2 OR txtag1 OR
    txreg(7) OR txreg(6) OR txreg(5) OR txreg(4) OR 
    txreg(3) OR txreg(2) OR txreg(1) OR txreg(0));

rx_proc:  -- Shift data on each rxclk when not idling
    PROCESS (reset, rxclk) 
    BEGIN
 IF reset='1' THEN
     rxreg <= (OTHERS=>'0') ;
            rxparity <= '0' ;
            paritygen <= '0' ;
            rxstop <= '0' ;
 ELSIF rxclk'event AND rxclk = '1' THEN
     IF rxidle = '1' THEN 
         -- Load all ones when idling
         rxreg <= (OTHERS=>'1');
         rxparity <= '1';
         paritygen <= '1'; -- Odd parity
         rxstop <= '0';
     ELSE
         -- Shift data when not idling
         -- bug in assigning to slices
         -- rxreg (0 TO 6) <= rxreg (1 TO 7);
         -- rxreg(7) <= rxparity;
         rxreg <= rxreg (1 TO 7) & rxparity;
         rxparity <= rxstop;
         paritygen <= paritygen XOR rxstop;-- Form parity as data shifts by
         rxstop <= rx;
     END IF ;
        END IF;
    END PROCESS;

    
async:  -- rxidle requires async preset since it is clocked by rxclk and  
        -- its value determines whether rxclk gets generated 
    PROCESS ( reset, rxclk )
    BEGIN
        IF reset = '1' THEN
           rxidle <= '0';
        ELSIF rxclk'EVENT and rxclk = '1' THEN
           rxidle <= NOT rxidle AND NOT rxreg(0);
        END IF;
    END PROCESS async;

txio: -- Load txhold and set txdatardy on falling edge of write
 -- Clear txdatardy on falling edge of txdone
    PROCESS (reset, clkx16)
 VARIABLE wr1,wr2: std_logic; -- write signal delayed 1 and 2 cycles
 VARIABLE txdone1: std_logic;        -- txdone signal delayed one cycle
    BEGIN
 IF reset='1' THEN
     txdatardy <= '0' ;
     wr1 := '0' ;
     wr2 := '0' ;
     txdone1 := '0' ;
 ELSIF clkx16'event AND clkx16 = '1' THEN
     IF wr1 = '0' AND wr2= '1' THEN
         -- Falling edge on write signal. New data in txhold latches
         txdatardy  <= '1';
     ELSIF txdone = '0' AND txdone1 = '1' THEN
         -- Falling edge on txdone signal. Txhold has been read.
         txdatardy  <= '0';
     END IF;

     -- Delayed versions of write and txdone signals for edge detection
         wr2 := wr1;
     wr1 := write;
     txdone1 := txdone;
 END IF ;
    END PROCESS;

rxio:
    PROCESS (reset, clkx16)
 VARIABLE rd1, rd2 : std_logic; -- Read input delayed 1 and 2 cycles
 VARIABLE rxidle1  : std_logic; -- rxidle signal delayed 1 cycle
    BEGIN
 IF reset='1' THEN
     overrun <= '0' ;
     rxhold <= (OTHERS=>'0') ;
     parityerr <= '0' ;
            framingerr <= '0' ;
     rxdatardy <= '0' ;
     rd1 := '0' ;
            rd2 := '0' ;
     rxidle1 := '0' ;
 ELSIF clkx16'event AND clkx16 = '1' THEN

     -- Look for rising edge on idle and update output registers
     IF rxidle = '1' AND rxidle1 = '0' THEN
         IF rxdatardy = '1' THEN
          -- Overrun error if previous data is still there
      overrun <= '1';
         ELSE
      -- No overrun error since holding register is empty
      overrun <= '0';

      -- Update holding register
      rxhold <= rxreg;

      -- paritygen = 1 if parity error
      parityerr <= paritygen;

      -- Framingerror if stop bit is not 1
      framingerr <= NOT rxstop;

      -- Signal that data is ready for reading
      rxdatardy <= '1';
         END IF;
     END IF;
     rxidle1 := rxidle; -- rxidle delayed 1 cycle for edge detect

     --  Clear error and data registers when data is read
     IF (NOT rd2 AND rd1) = '1' THEN
         rxdatardy  <= '0';
         parityerr  <= '0';
         framingerr <= '0';
         overrun    <= '0';
     END IF;
     rd2 := rd1; -- Edge detect for read
     rd1 := read; -- (Must be assigned AFTER reference)
     IF reset = '1' THEN 
         rxdatardy <= '0'; 
     END IF;
 END IF ;
    END PROCESS;

    -- Drive data bus only during read
    data <= rxhold WHEN read = '1' ELSE (OTHERS=>'Z') ;

    -- Latch data bus during write
    txhold <= data WHEN write = '1' ELSE txhold;

    -- Receive data ready output signal
    rxrdy <= rxdatardy;

    -- Transmitter ready for write when no data is in txhold
    txrdy <= NOT txdatardy;

    -- Run-time simulation check for transmit overrun
    ASSERT write = '0' OR txdatardy = '0'
 REPORT "Transmitter overrun error" SEVERITY WARNING;

END exemplar;

  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -