VHDL中几个TX和RX数据引脚的说明
我已经做了一段时间的VHDL,但我仍然是一个初学者。 我有一个UART代码,它工作得很好,但无法理解几个引脚的用法 请向我解释以下PIN的用法VHDL中几个TX和RX数据引脚的说明,vhdl,Vhdl,我已经做了一段时间的VHDL,但我仍然是一个初学者。 我有一个UART代码,它工作得很好,但无法理解几个引脚的用法 请向我解释以下PIN的用法 txReady\u o、rxNewData\u o、rxDataAck\u i library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --------------------------------------------------------------------
txReady\u o、rxNewData\u o、rxDataAck\u i
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-------------------------------------------------------------------------------
-- Entity
-------------------------------------------------------------------------------
entity uart_mod is
generic (CLK_FREQ : integer := 18500000;
BAUDRATE : integer := 115200);
port (
-- general ports
clk_i : in std_logic;
rst_i : in std_logic;
-- tx ports
tx_o : out std_logic; -- transmit data line
txData_i : in std_logic_vector(7 downto 0); -- data to transmit
txReady_o : out std_logic; -- transmit ready flag
txStart_i : in std_logic; -- start transmission signal
-- rx ports
rx_i : in std_logic; -- receive data line
rxData_o : out std_logic_vector(7 downto 0); -- received data
rxNewData_o : out std_logic; -- new data received flag
rxDataAck_i : in std_logic; -- acknowledge of received data signal
rxErr_o : out std_logic); -- receive error
end uart_mod;
-------------------------------------------------------------------------------
-- Architecture
-------------------------------------------------------------------------------
architecture Behavioral of uart_mod is
-----------------------------------------------------------------------------
-- Constants
-----------------------------------------------------------------------------
-- sample values
constant BIT_COUNT_DIV1 : integer := CLK_FREQ/BAUDRATE - 1;
constant BIT_COUNT_DIV2 : integer := CLK_FREQ/BAUDRATE/2 - 1;
constant BIT_COUNT_DIV4 : integer := CLK_FREQ/BAUDRATE/4 - 1;
constant MAX_BIT_ERROR : integer := BIT_COUNT_DIV2/3; -- 33% errors allowed
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- tx signals
signal txWaitCnt : integer range 0 to BIT_COUNT_DIV1;
signal txBitCnt : integer range 0 to 7;
type txStates is (idle, startBit, dataBit, stopBit);
signal txState : txStates;
-- rx signals
signal rxInput : std_logic_vector(7 downto 0);
signal rxTrigger : std_logic;
signal rxSync : std_logic;
signal rxWeight : integer range 0 to 5;
signal sampleCnt : integer range 0 to BIT_COUNT_DIV2 + BIT_COUNT_DIV4;
signal dataCnt : integer range 0 to 8;
signal highCnt : integer range 0 to BIT_COUNT_DIV2;
type rxStates is (idle, startBit, waitState, dataBit, stopBit, resetCycle);
signal rxState : rxStates;
type rxAckStates is (idle, waitAck);
signal rxAckState : rxAckStates;
-- debug signals
signal txState_as_vector : std_logic_vector(3 downto 0);
signal rxState_as_vector : std_logic_vector(3 downto 0);
signal rxAckState_as_vector : std_logic_vector(1 downto 0);
begin
-----------------------------------------------------------------------------
-- Transmit FSM
-----------------------------------------------------------------------------
txMonitor : process (clk_i)
begin
if rising_edge(clk_i) then
-- sync reset
if rst_i = '1' then
txState <= idle;
tx_o <= '1';
txReady_o <= '1';
txBitCnt <= 0;
txWaitCnt <= 0;
else
-- debug signal
txState_as_vector <= std_logic_vector(to_unsigned(txStates'pos(txState), 4));
case txState is
when idle =>
---------------------------------------------------------------------
-- State 0: Idle and wait for tx request
---------------------------------------------------------------------
if txStart_i = '1' then
tx_o <= '0';
txReady_o <= '0';
txState <= startBit;
end if;
when startBit =>
-------------------------------------------------------------------
-- State 1: Send startbit
-------------------------------------------------------------------
-- check if max cnt value is reached
if txWaitCnt < BIT_COUNT_DIV1 then
txWaitCnt <= txWaitCnt + 1;
else
txWaitCnt <= 0;
txState <= dataBit;
tx_o <= txData_i(txBitCnt);
end if;
when dataBit =>
-------------------------------------------------------------------
-- State 2: Send data bits
-------------------------------------------------------------------
-- check if max cnt value is reached
if txWaitCnt < BIT_COUNT_DIV1 then
txWaitCnt <= txWaitCnt + 1;
else
txWaitCnt <= 0;
-- check if all bits are transmitted
if txBitCnt < 7 then
txBitCnt <= txBitCnt + 1;
tx_o <= txData_i(txBitCnt + 1);
else
txBitCnt <= 0;
txState <= stopBit;
tx_o <= '1';
end if;
end if;
when stopBit =>
-------------------------------------------------------------------
-- State 3: Send stop bit
-------------------------------------------------------------------
-- check if max cnt value is reached
if txWaitCnt < BIT_COUNT_DIV1 then
txWaitCnt <= txWaitCnt + 1;
else
txWaitCnt <= 0;
txReady_o <= '1';
txState <= idle;
end if;
end case;
end if;
end if;
end process txMonitor;
-----------------------------------------------------------------------------
-- 3-of-5 rx sample filter with shifter
-----------------------------------------------------------------------------
process (clk_i) is
begin -- process
if rising_edge(clk_i) then
-- sync reset
if rst_i = '1' then
rxWeight <= 0;
rxInput <= (others => '0');
else
-- increase or decrease rxWeight
if rx_i = '1' and rxWeight < 5 then
rxWeight <= rxWeight + 1;
elsif rx_i = '0' and rxWeight > 0 then
rxWeight <= rxWeight - 1;
end if;
-- rx shifter with respect to rxWeight
if rxWeight > 2 then
rxInput <= rxInput(6 downto 0) & '1';
else
rxInput <= rxInput(6 downto 0) & '0';
end if;
end if;
end if;
end process;
-----------------------------------------------------------------------------
-- Receive FSM
-----------------------------------------------------------------------------
rxMonitor : process (clk_i)
begin
if rising_edge(clk_i) then
-- sync reset
if rst_i = '1' then
-- initial state
rxState <= idle;
-- reset signals
rxTrigger <= '0';
rxSync <= '0';
-- reset output ports
rxErr_o <= '0';
rxData_o <= (others => '0');
-- reset counter
sampleCnt <= 0;
highCnt <= 0;
dataCnt <= 0;
else
-- debug signal
rxState_as_vector <= std_logic_vector(to_unsigned(rxStates'pos(rxState), 4));
case rxState is
when idle =>
-------------------------------------------------------------------
-- State 0: Idle and wait for a falling edge (start bit)
-------------------------------------------------------------------
-- check rx input for a falling edge
if rxInput(1 downto 0) = "10" then
rxState <= startBit;
sampleCnt <= 1;
end if;
when startBit =>
-------------------------------------------------------------------
-- State 1: Check if falling edge results in a start bit
-------------------------------------------------------------------
-- sample 3/4 bit
if sampleCnt < (BIT_COUNT_DIV2 + BIT_COUNT_DIV4) then
sampleCnt <= sampleCnt + 1;
-- sum up bit errors
if rxInput(0) = '1' then
if highCnt > MAX_BIT_ERROR then
rxErr_o <= '1';
rxState <= resetCycle;
else
highCnt <= highCnt + 1;
end if;
end if;
else
-- start bit detected
rxState <= waitState;
sampleCnt <= 0;
highCnt <= 0;
end if;
when waitState =>
-------------------------------------------------------------------
-- State 2: Wait for bit/2 and try to sync if there is a stable edge
-------------------------------------------------------------------
if sampleCnt < BIT_COUNT_DIV2 then
-- increase counter
sampleCnt <= sampleCnt + 1;
-- try to sync
if rxSync = '0' then
if rxInput = "00001111" or rxInput = "11110000" then
sampleCnt <= BIT_COUNT_DIV4 + 4;
rxSync <= '1';
end if;
end if;
else
-- wait time reached
sampleCnt <= 0;
rxSync <= '0';
-- check if all data bits are sampled
if dataCnt < 8 then
rxState <= dataBit;
else
dataCnt <= 0;
rxState <= stopBit;
end if;
end if;
when dataBit =>
-------------------------------------------------------------------
-- State 3: Receive a data bit
-------------------------------------------------------------------
if sampleCnt < BIT_COUNT_DIV2 then
sampleCnt <= sampleCnt + 1;
if rxInput(0) = '1' then
highCnt <= highCnt + 1;
end if;
else
sampleCnt <= 0;
highCnt <= 0;
rxState <= waitState;
dataCnt <= dataCnt + 1;
-- sampling complete, check highCnt
if (BIT_COUNT_DIV2 - highCnt) <= MAX_BIT_ERROR then
-- '1' was sampled
rxData_o(dataCnt) <= '1';
elsif highCnt <= MAX_BIT_ERROR then
-- '0' was sampled
rxData_o(dataCnt) <= '0';
else
-- sample error
rxErr_o <= '1';
rxState <= resetCycle;
end if;
end if;
when stopBit =>
-------------------------------------------------------------------
-- State 4: Receive the stop bit
-------------------------------------------------------------------
if sampleCnt < BIT_COUNT_DIV2 then
sampleCnt <= sampleCnt + 1;
if rxInput(0) = '0' then
if highCnt > MAX_BIT_ERROR then
-- stop bit error
rxErr_o <= '1';
rxState <= resetCycle;
else
highCnt <= highCnt + 1;
end if;
end if;
else
-- stop bit detected
rxState <= resetCycle;
rxTrigger <= '1';
end if;
when resetCycle =>
-------------------------------------------------------------------
-- State 5: cycle to reset flags and counters
-------------------------------------------------------------------
highCnt <= 0;
rxTrigger <= '0';
rxErr_o <= '0';
rxState <= idle;
end case;
end if;
end if;
end process rxMonitor;
-----------------------------------------------------------------------------
-- Acknowledge handshake
-----------------------------------------------------------------------------
ackProcess : process (clk_i) is
begin -- process ackProcess
if rising_edge(clk_i) then
-- sync reset
if rst_i = '1' then
rxAckState <= idle;
else
-- debug signal
rxAckState_as_vector <= std_logic_vector(to_unsigned(rxAckStates'pos(rxAckState), 2));
case rxAckState is
when idle =>
-------------------------------------------------------------------
-- State 0: Wait for new received data
-------------------------------------------------------------------
-- check if rx data is available
if rxTrigger = '1' then
rxAckState <= waitAck;
end if;
when waitAck =>
-------------------------------------------------------------------
-- State 1: Wait for a external ackowlede
-------------------------------------------------------------------
if rxDataAck_i = '1' then
rxAckState <= idle;
end if;
end case;
end if;
end if;
end process ackProcess;
rxNewData_o <= '1' when rxAckState = waitAck else '0';
end Behavioral;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
-------------------------------------------------------------------------------
--实体
-------------------------------------------------------------------------------
实体uart_mod为
通用(时钟频率:整数:=18500000;
波特率:整数:=115200);
港口(
--一般港口
clk_i:标准逻辑中;
rst_i:标准逻辑中;
--发送端口
tx_o:输出标准逻辑——传输数据线
txData_i:标准逻辑向量(7到0);--要传输的数据
txReady_o:out std_逻辑;--传输就绪标志
txStart_i:在std_逻辑中;--启动传输信号
--接收端口
rx_i:在标准逻辑中;--接收数据线
rxData_o:out std_logic_vector(7到0);--接收到的数据
rxNewData_o:out std_logic;--新数据接收标志
rxDataAck_i:在标准逻辑中;——接收数据信号的确认
rxErr(输出标准逻辑);--接收错误
结束uart_mod;
-------------------------------------------------------------------------------
--建筑
-------------------------------------------------------------------------------
uart_mod的体系结构是
-----------------------------------------------------------------------------
--常数
-----------------------------------------------------------------------------
--样本值
常量位计数除法1:整数:=时钟频率/波特率-1;
常量位计数DIV2:整数:=CLK\u FREQ/BAUDRATE/2-1;
常量位计数DIV4:整数:=CLK\u FREQ/BAUDRATE/4-1;
常量最大位错误:整数:=位计数DIV2/3;--允许33%的错误
-----------------------------------------------------------------------------
--信号
-----------------------------------------------------------------------------
--发送信号
信号txWaitCnt:整数范围0到位\u计数\u DIV1;
信号txBitCnt:整数范围0至7;
txStates类型为(空闲、启动位、数据位、停止位);
信号txState:txStates;
--接收信号
信号rxInput:std_逻辑_向量(7到0);
信号发生器:标准逻辑;
信号rxSync:std_逻辑;
信号rxWeight:整数范围0到5;
信号采样:整数范围0至位计数2+位计数4;
信号数据Cnt:整数范围0到8;
信号highCnt:整数范围0至位\u计数\u DIV2;
rxStates类型为(idle、startBit、waitState、dataBit、stopBit、resetCycle);
信号rxState:rxStates;
rxAckStates类型为(空闲、等待);
信号rxAckState:rxAckStates;
--调试信号
信号txState_作为_向量:标准逻辑_向量(3到0);
信号rxState_as_向量:标准逻辑_向量(3到0);
信号rxAckState_作为_向量:标准逻辑_向量(1到0);
开始
-----------------------------------------------------------------------------
--传输有限状态机
-----------------------------------------------------------------------------
txMonitor:过程(clk_i)
开始
如果上升沿(clk_i),则
--同步复位
如果rst_i='1',则
txState
-------------------------------------------------------------------
--状态0:空闲并等待下降沿(起始位)
-------------------------------------------------------------------
--检查rx输入是否有下降沿
如果rxInput(1到0)=“10”,则
rxState对动词SHOUT的自由解释撇开不谈,对提供的VHDL设计规范的检查表明,txReady_o
、rxNewData_o
和rxDataAck_i
信号是时钟的一部分(clk_i
)同步握手操作两个并行接口,用于发送和接收串行发送或串行接收的数据
我有一个UART代码,它工作得很好,但无法理解几个引脚的用法
除了想知道如何在不使用接口的情况下确定代码工作外,每个并行发送和接收接口都使用双信号握手。(不,这不是串行流量控制)
用于传输的双信号握手
变送器表示可以通过断言txReady\u o
接受新数据。当待传输的数据在txData_i
上可用时,输入txStart_i
被断言,直到txReady_o
被反断言(在下一个clk_i上升沿之后,请参见tx_监视器
过程,案例tx_状态
,空闲时)
用于接收的双信号握手
接收器用rxNewData\u o
表示接收到的数据值,然后从rxData\u o
端口读取数据,断言rxData\u i
rxNewData\u o
作为类似于txReady\u o
的结果被取消断言,请参见过程ackProcess
<当rxNewData\u o
被反断言时,code>rxDataAck\u i
也应该被反断言
请注意,您可以指定从检测到的停止位到下一个第一个接收到的数据位(在开始位之后)读取rxData\u o
的时间。没有单独的输出缓冲区或输出FIFO。请停止对我们大喊大叫!用大写字母写东西很烦人,因为它真的很难读懂,而且它被认为是对你的听众大喊大叫,这简直是粗鲁无礼。别这样!现在就确定你的标题它只是一个标题,不像叫喊我在这里,我甚至不知道如何首先确定它-事实上,所有的大写字母都被认为是叫喊是普遍的-这不是一件那么具体的事情。所有的论坛都不赞成所有的帽子。第二:你可以编辑你的文章并修改标题!非常感谢,答案非常有用。伊安