📄 tx_uart_m8.vhd
字号:
-----------------------------------------------------------------------
-- Tx_UART_M8.vhd
-- --------------------------------------------------------------------
-- >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-- --------------------------------------------------------------------
-- Copyright (c) 2005 by Lattice Semiconductor Corporation
-- --------------------------------------------------------------------
--
-- Permission:
--
-- Lattice Semiconductor grants permission to use this code for use
-- in synthesis for any Lattice programmable logic product. Other
-- use of this code, including the selling or duplication of any
-- portion is strictly prohibited.
--
-- Disclaimer:
--
-- This VHDL or Verilog source code is intended as a design reference
-- which illustrates how these types of functions can be implemented.
-- It is the user's responsibility to verify their design for
-- consistency and functionality through the use of formal
-- verification methods. Lattice Semiconductor provides no warranty
-- regarding the use or functionality of this code.
--
-- --------------------------------------------------------------------
--
-- Lattice Semiconductor Corporation
-- 5555 NE Moore Court
-- Hillsboro, OR 97214
-- U.S.A
--
-- TEL: 1-800-Lattice (USA and Canada)
-- 408-826-6000 (other locations)
--
-- web: http://www.latticesemi.com/
-- email: techsupport@latticesemi.com
--
-- --------------------------------------------------------------------
--
-- This is a ultracompact TX UART
-- Address map:
-- 00000110: Data transmit register
-- This will translate the parallel data from a mico8 to
-- a serial UART output.
-- The size of the parallel data (generic paramter 8) can be anything
-- from 5 to 8.
-- One start and stopbit is provided.
-- The generic parameter CLK_DIV is used to set the correct baudrate:
-- baudrate = inputfreq/CLK_DIV
-- This is now fixed to 115200 buad and 40MHz clock.
-- --------------------------------------------------------------------
--
-- Revision History :
-- --------------------------------------------------------------------
-- Ver :| Author :| Mod. Date :| Changes Made:
-- V1.0 :| G.M. :| 06/03/07 :| Release
-- --------------------------------------------------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all, ieee.std_logic_arith.all;
entity TX_UART_M8 is
generic (
CLKFREQ : in integer := 50000000; -- clock frequency in Hz
BAUDRATE : in integer := 9600
);
port (
Clk : in std_logic;
Reset : in std_logic;
WR : in std_logic;
Addr: in std_logic_vector(7 downto 0);
Mico8_Data : in std_logic_vector (7 downto 0);
TXD : out std_logic;
TX_Ack : out std_logic
);
end TX_UART_M8;
architecture Behave of TX_UART_M8 is
signal zWR : std_logic;
constant TXaddress: std_logic_vector (7 downto 0) := "00000110";
signal TxData: std_logic_vector( 7 downto 0);
signal TX_Req : std_logic;
constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1;
constant RTS : std_logic := '0';
type TxState_type is (E_TxState_Waiting, E_TxState_Start, E_TxState_Data, E_TxState_Stop);
signal timecounter : integer range 0 to TIMECOUNTER_SIZE;
signal bitcounter : integer range 0 to 8;
signal TXShiftRegister : std_logic_vector(1 to 8);
signal TxState, nextTxState : TxState_type;
signal StartSending : std_logic;
signal timecounter_pulse : std_logic;
signal sync_RTS : std_logic_vector(3 downto 1);
attribute pgroup : string;
attribute pgroup of Behave : architecture is "TX_UART";
begin
-- The TxState statemachine controls the correct flow for the start, data
-- and stop bit(s).
process (TxState, StartSending, bitcounter)
begin
nextTxState <= TxState;
case TxState is
when E_TxState_Waiting =>
-- Req for sending data received.
if StartSending = '1' then
nextTxState <= E_TxState_Start;
end if;
when E_TxState_Start =>
nextTxState <= E_TxState_Data;
when E_TxState_Data =>
-- Last databit send.
if bitcounter = 8 and StartSending = '0' then
nextTxState <= E_TxState_Waiting;
end if;
when others =>
nextTxState <= E_TxState_Waiting;
end case;
end process;
-- Generate a pulse when timecounter is 0.
timecounter_pulse <= '1' when timecounter = 0 else '0';
-- Sample the inputsignal from physical EIA232 interface into a flipflop.
process (sync_RTS)
begin
sync_RTS(sync_RTS'low) <= RTS;
sync_RTS(sync_RTS'high downto sync_RTS'low+1) <= sync_RTS(sync_RTS'high-1 downto sync_RTS'low);
end process;
process (clk,Reset, WR)
begin
if Reset = '1' then
timecounter <= TIMECOUNTER_SIZE;
TX_Ack <= '0';
StartSending <= '0';
TXShiftRegister <= (others => '1');
TxData <= (others => '0');
zWR <= WR;
TX_Req <= '0';
elsif rising_edge(clk) then
-- Mico8 interface
zWR <= WR;
if ((zWR /= WR) and (WR = '0') and (Addr = TXaddress)) then
TxData(7 downto 0) <= Mico8_Data(7 downto 0);
TX_Req <= '1';
else
TxData(7 downto 0) <= TxData(7 downto 0);
TX_Req <= '0';
end if;
TX_Ack <= '0';
-- Counter to devide the clk input.
if timecounter_pulse = '1' then
timecounter <= TIMECOUNTER_SIZE;
else
timecounter <= timecounter - 1;
end if;
case TxState is
when E_TxState_Waiting =>
-- Req received and ready to transmit data.
if StartSending = '0' and TX_Req = '1' and sync_RTS(sync_RTS'high) = '0' then
-- Load the shiftregister
TXShiftRegister(1 to 8) <= TxData;
TX_Ack <= '1';
StartSending <= '1';
end if;
when E_TxState_Start | E_TxState_Data =>
StartSending <= '0';
-- The shiftregister can shift every timecounter_pulse.
-- This register runs on clk because it must be possible to load
-- external data assynchronous to timecounter_pulse.
if timecounter_pulse = '1' then
TXShiftRegister(TXShiftRegister'low) <= '1';
TXShiftRegister(TXShiftRegister'low+1 to TXShiftRegister'high) <= TXShiftRegister(TXShiftRegister'low to TXShiftRegister'high-1);
end if;
when others =>
StartSending <= '0';
end case;
end if;
end process;
process (clk,Reset)
begin
if Reset = '1' then
TXD <= '1';
TxState <= E_TxState_Waiting;
bitcounter <= 0;
elsif rising_edge(clk) then
if timecounter_pulse = '1' then
TxState <= nextTxState;
case nextTxState is
when E_TxState_Waiting =>
TXD <= '1';
when E_TxState_Start =>
TXD <= '0';
when E_TxState_Data =>
TXD <= TXShiftRegister(8);
if bitcounter = 8 then
bitcounter <= 0;
else
bitcounter <= bitcounter + 1;
end if;
when others =>
TXD <= '1';
end case;
end if;
end if;
end process;
end Behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -