📄 txmitt.vhd
字号:
LIBRARY IEEE;
USE IEEE.Std_Logic_1164.all;
USE IEEE.Std_Logic_Unsigned.all;
ENTITY Txmitt IS
PORT (
Reset : IN STD_LOGIC; --全局复位
Clk16X : IN STD_LOGIC; -- 全局时钟
THR : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--发送缓冲寄存器
ThrWRn_re : IN STD_LOGIC; --发送缓冲寄存器写使能
SOUT : OUT STD_LOGIC; --串行输出信号
DataBits : IN STD_LOGIC_VECTOR(1 DOWNTO 0); --数据的长度设置
StopBits : IN STD_LOGIC_VECTOR(1 DOWNTO 0); --数据停止位的设置
ParityEnable: IN STD_LOGIC; --奇偶校验使能
ParityEven : IN STD_LOGIC; --奇或偶校验选择信号
ParityStick : IN STD_LOGIC;
TxBreak : IN STD_LOGIC;
THRE : OUT STD_LOGIC; --THR状态标志
TEMT : OUT STD_LOGIC --THR和TSR为空
);
END Txmitt;
ARCHITECTURE Txmitt_arch OF Txmitt IS
SIGNAL TxOutput : STD_LOGIC;
SIGNAL TSR : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL TxParity_r : STD_LOGIC;
SIGNAL ThrEmpty : STD_LOGIC;
SIGNAL TsrEmpty : STD_LOGIC;
SIGNAL TxInStartState : STD_LOGIC;
SIGNAL TxInShiftState : STD_LOGIC;
SIGNAL TxInStopState : STD_LOGIC;
SIGNAL TxInStartState1 : STD_LOGIC; -- TxInStartState delayed 1 Clk16X clock
SIGNAL TxInShiftState1 : STD_LOGIC; -- TxInShiftState delayed 1 Clk16X clock
SIGNAL TxInStopState1 : STD_LOGIC; -- TxInStopState delayed 1 Clk16X clock
-- Transmitter Clock Enable Signals
SIGNAL TxClkEnA : STD_LOGIC;
SIGNAL TxClkEnB : STD_LOGIC;
SIGNAL TxCNT_r : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL Count_vr : STD_LOGIC_VECTOR(3 DOWNTO 0);
-- State Machine Definition
type state_typ IS (start, shift, parity, stop_1bit, stop_2bit, stop_halfbit);
SIGNAL Tx_State : state_typ;
ATTRIBUTE SYN_KEEP : integer;
ATTRIBUTE SYN_KEEP OF TxOutput, TxCNT_r, TSR, TxParity_r : SIGNAL IS 1;
ATTRIBUTE SYN_KEEP OF TsrEmpty, ThrEmpty : SIGNAL IS 1;
ATTRIBUTE OPT : string;
ATTRIBUTE OPT OF TxOutput, TxCNT_r, TSR, TxParity_r : SIGNAL IS "KEEP";
ATTRIBUTE OPT OF TsrEmpty, ThrEmpty : SIGNAL IS "KEEP";
begin
--------------------------------------------------------------------------------
-- 发送器状态机
--------------------------------------------------------------------------------
Shift_Data_Proc: PROCESS(Reset, CLK16X)
begin
IF (Reset='1') THEN
TxCNT_r <= (others=>'0');
TSR <= (others=>'0');
TxOutput <= '1';
TxParity_r <= '1';
Tx_State <= start;
ELSIF rising_edge(Clk16X) THEN
CASE Tx_State IS
WHEN start =>
IF (ThrEmpty='0') and (TxClkEnA='1') THEN
-- Load data from THR to TSR
TSR <= THR;
-- TxParity_r initialization:
-- set it WHEN odd parity IS selected(ParityEven='0')
-- clear it WHEN even parity IS selected(ParityEven='1')
TxParity_r <= not ParityEven;
TxOutput <= '0'; -- start bit='0'
TxCNT_r <= (others=>'0');
Tx_State <= shift;
else
TxOutput <= '1';
END IF;
WHEN shift =>
IF (TxClkEnA='1') THEN
-- Shift serial data OUT
TSR <= '0' & TSR(7 DOWNTO 1);
TxParity_r <= TxParity_r xor TSR(0);
TxOutput <= TSR(0); -- output Data bits
TxCNT_r <= TxCNT_r + 1;
IF ((Databits="00" and TxCNT_r=4) OR
(Databits="01" and TxCNT_r=5) OR
(Databits="10" and TxCNT_r=6) OR
(Databits="11" and TxCNT_r=7)) THEN
IF (ParityEnable='0') THEN
Tx_State <= stop_1bit;
else
Tx_State <= parity;
END IF;
END IF;
END IF;
WHEN parity =>
IF (TxClkEnA='1') THEN
-- Output 1 parity bit
IF (ParityStick='0') THEN
TxOutput <= TxParity_r; -- output Parity bit
else
TxOutput <= not ParityEven; -- forced parity bit
END IF;
Tx_State <= stop_1bit;
END IF;
WHEN stop_1bit =>
IF (TxClkEnA='1') THEN
-- Output 1 bit OF StopBits
TxOutput <= '1';
IF (StopBits="00") THEN -- 1 stop bit
Tx_State <= start;
ELSIF (StopBits="01") THEN -- 1.5 stop bits(for 5-bit data only)
Tx_State <= stop_halfbit;
else -- 2 stop bits(for 6,7,8-bit data)
Tx_State <= stop_2bit;
END IF;
END IF;
WHEN stop_2bit =>
IF (TxClkEnA='1') THEN
-- Output 2nd bit OF 2 Stopbits
TxOutput <= '1';
Tx_State <= start;
END IF;
WHEN stop_halfbit =>
IF (TxClkEnB='1') THEN -- half bit
TxOutput <= '1';
Tx_State <= start;
END IF;
WHEN others =>
Tx_State <= Start;
END CASE;
END IF;
END PROCESS Shift_Data_Proc;
--------------------------------------------------------------------------------
-- 产生TsrEmpty和ThrEmpty 信号
--------------------------------------------------------------------------------
-- TsrEmpty : 当TSR为空的时候设置
TsrEmpty_Proc: PROCESS(Clk16X, Reset)
begin
IF (Reset='1') THEN
TsrEmpty <= '1';
ELSIF rising_edge(Clk16X) THEN
IF (TxInStopState='1') and (TxInStopState1='0') THEN
-- Set TsrEmpty flag to '1' WHEN StopBit(s) IS transmitted
TsrEmpty <= '1';
ELSIF (TxInShiftState='1') and (TxInShiftState1='0') THEN
-- Reset TsrEmpty flag to '0' WHEN data IS transferred from THR to TSR
TsrEmpty <= '0';
END IF;
END IF;
END PROCESS TsrEmpty_Proc;
-- ThrEmpty : 当THR为空的时候设置
ThrEmpty_Proc: PROCESS(Clk16X, Reset)
begin
IF (Reset='1') THEN
ThrEmpty <= '1';
ELSIF rising_edge(Clk16X) THEN
IF (ThrWRn_re='1') THEN
ThrEmpty <= '0'; -- 当CPU写THR的时候复位ThrEmpty 到'0'
ELSIF (TxInShiftState='1') and (TxInShiftState1='0') THEN
ThrEmpty <= '1';――当数据从THR传输到TSR中的时候设置ThrEmpty为1
END IF;
END IF;
END PROCESS ThrEmpty_Proc;
--------------------------------------------------------------------------------
-- 延迟信号的沿检测
--------------------------------------------------------------------------------
Delay_Signals_Proc: PROCESS(Clk16X, Reset)
begin
IF (Reset='1') THEN
TxInStartState1 <= '1';
TxInShiftState1 <= '1';
TxInStopState1 <= '1';
ELSIF rising_edge(Clk16X) THEN
TxInStartState1 <= TxInStartState;
TxInShiftState1 <= TxInShiftState;
TxInStopState1 <= TxInStopState;
END IF;
END PROCESS Delay_Signals_Proc;
--------------------------------------------------------------------------------
-- 发送状态机的指示信号
--------------------------------------------------------------------------------
TxInShiftState_Proc: PROCESS(Clk16X, Reset)
begin
IF (Reset='1') THEN
TxInShiftState <= '0';
ELSIF rising_edge(Clk16X) THEN
IF (Tx_State=shift) THEN
TxInShiftState <= '1';
else
TxInShiftState <= '0';
END IF;
END IF;
END PROCESS TxInShiftState_Proc;
TxInStopState_Proc: PROCESS(Clk16X, Reset)
begin
IF (Reset='1') THEN
TxInStopState <= '0';
ELSIF rising_edge(Clk16X) THEN
IF (Tx_State=stop_1bit) THEN
TxInStopState <= '1';
else
TxInStopState <= '0';
END IF;
END IF;
END PROCESS TxInStopState_Proc;
TxInStartState_Proc: PROCESS(Clk16X, Reset)
begin
IF (Reset='1') THEN
TxInStartState <= '0';
ELSIF rising_edge(Clk16X) THEN
IF (Tx_State=start) THEN
TxInStartState <= '1';
else
TxInStartState <= '0';
END IF;
END IF;
END PROCESS TxInStartState_Proc;
--------------------------------------------------------------------------------
-- 产生TxClkEnA/TxClkEnB信号
--------------------------------------------------------------------------------
-- 发送器工作在输入频率的1/16,TxClkEnA, TxClkEnB 是发送状态机时钟使能信号
TxCLK_Proc: PROCESS(Reset, Clk16X)
begin
IF (Reset='1') THEN
Count_vr <= (others => '1');
TxClkEnA <= '0';
TxClkEnB <= '0';
ELSIF rising_edge(Clk16X) THEN
IF (Count_vr="0000") THEN
TxClkEnA <= '1';
else
TxClkEnA <= '0';
END IF;
-- TxClkEnB用来产生1.5的停止位
IF (Count_vr="1000") THEN
TxClkEnB <= '1';
else
TxClkEnB <= '0';
END IF;
IF (TxInStartState='1') and (TxInStartState1='0') THEN
Count_vr <= "0011"; -- Offset to the 2 cycle's delay
else
Count_vr <= Count_vr + 1;
END IF;
END IF;
END PROCESS TxCLK_Proc;
--------------------------------------------------------------------------------
-- 产生THRE/TEMT标志
--------------------------------------------------------------------------------
THRE <= ThrEmpty;
-- 当THR和TSR都为空的时候,将Transmitter Empty Indicator 设置为'1' ,当THR或TSR其中有一个字符的时候置为0
TEMT <= '1' WHEN (ThrEmpty='1') and (TsrEmpty='1') else '0';
--------------------------------------------------------------------------------
-- Serial Data Output
--------------------------------------------------------------------------------
-- If Break Control bit IS set to 1, the serial output IS forced to Zero
SOUT <= '0' WHEN (TxBreak='1') else TxOutput;
END Txmitt_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -