如何解决UART发送器仅在嵌入式逻辑分析仪运行时起作用
我一直在尝试实现UART,以便在莱迪思MachXO3D板与计算机之间进行通信。目前,我正在尝试从FPGA实现传输。
在硬件上进行测试时,我遇到了一个非常奇怪的问题。如果正常运行,它将运行几秒钟,然后突然停止运行(连接到我的计算机的CH340将报告它正在接收包含0x0的消息)。但是,如果我通过Lattice Diamond软件将逻辑分析仪嵌入到FPGA上,然后运行分析仪,它将在很长一段时间内完美运行。
可悲的是,我没有逻辑分析仪,因此嵌入式逻辑分析仪是我了解实际传输内容的唯一机会。
这些是与我的实现相关的文件:
baud_gen
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
-- Generates 16 ticks per bit
ENTITY baud_gen IS
GENERIC(divider: INTEGER := 13 -- 24M/115200*16
);
PORT(
clk,reset: IN STD_LOGIC;
s_tick: OUT STD_LOGIC
);
END baud_gen;
ARCHITECTURE working OF baud_gen IS
BEGIN
PROCESS(clk)
VARIABLE counter: UNSIGNED(3 DOWNTO 0) := to_unsigned(0,4);
BEGIN
IF clk'EVENT AND clk='1' THEN
IF reset='1' THEN
s_tick <= '0';
counter := to_unsigned(0,4);
ELSIF counter=to_unsigned(divider-1,4) then
s_tick <= '1';
counter:= to_unsigned(0,4);
ELSE
s_tick <= '0';
counter := counter + 1;
END IF;
END IF;
END PROCESS;
END working;
rs232_tx
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY rs232_tx IS
PORT(clk: IN std_logic;
tx: OUT std_logic;
rst: IN std_logic;
fifo_empty: IN std_logic;
fifo_RdEn,fifo_RdClock: OUT std_logic;
fifo_data: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Q: OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END rs232_tx;
ARCHITECTURE working OF rs232_tx IS
TYPE state IS (idle,start,data);
SIGNAL tx_pulse: STD_LOGIC := '1';
SIGNAL s_tick: STD_LOGIC;
SIGNAL pr_state,nx_state: state := idle;
SIGNAL data_val: std_logic_vector(7 DOWNTO 0):=(others=>'0');
SIGNAL data_count: unsigned(2 DOWNTO 0):=to_unsigned(0,3);
BEGIN
process(s_tick,rst)
VARIABLE count: unsigned(3 DOWNTO 0):= to_unsigned(0,4);
BEGIN
IF rising_edge(s_tick) THEN
count := count + to_unsigned(1,4);
IF count = to_unsigned(15,4) THEN
tx_pulse <= '1';
ELSE
tx_pulse <='0';
END IF;
END IF;
END PROCESS;
process(tx_pulse,rst)
BEGIN
IF rising_edge(tx_pulse) THEN
IF rst='1' THEN
pr_state <= idle;
data_val <= (others=>'0');
data_count <= to_unsigned(0,3);
ELSE
pr_state <= nx_state;
CASE pr_state IS
WHEN idle =>
data_count <= to_unsigned(0,3);
WHEN data =>
data_count <= data_count + to_unsigned(1,3);
WHEN start =>
data_val <= fifo_data;
WHEN OTHERS =>
END case;
END IF;
END IF;
END process;
process(fifo_empty,rst,data_count,pr_state,data_count)
BEGIN
case pr_state is
when idle =>
Q <= ('1','1');
fifo_RdEn <= '0';
tx <= '1';
IF fifo_empty='0' AND rst='0' THEN
nx_state <= start;
ELSE
nx_state <= idle;
END IF;
WHEN start =>
Q <= ('1','0');
fifo_RdEn <= '1';
tx <= '0';
nx_state <= data;
WHEN data =>
Q <= ('0','1');
fifo_RdEn <= '0';
tx <= data_val(to_integer(data_count));
if data_count=to_unsigned(7,3) then
nx_state <= idle;
ELSE
nx_state <= data;
end if;
end case;
END process;
fifo_RdClock <= tx_pulse;
baud_gen: ENTITY work.baud_gen
PORT MAP(clk,reset=>'0',s_tick=>s_tick);
END working;
测试台
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY rs232_tx_test IS
GENERIC(clk_period: TIME := 41666666.7 fs;
baud_period: TIME := 8680.55556 ns);
END rs232_tx_test;
ARCHITECTURE working OF rs232_tx_test IS
SIGNAL clk: STD_LOGIC := '0';
SIGNAL tx,fifo_empty,fifo_RdEn,fifo_RdClock: STD_LOGIC;
SIGNAL fifo_data: STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
clk <= NOT clk AFTER clk_period/2;
rst <= '1','0' AFTER 100 ns;
PROCESS
BEGIN
fifo_empty <= '1';
WAIT FOR baud_period;
fifo_empty <= '0';
WAIT FOR baud_period*16;
END PROCESS;
fifo_data <= ('1','1','0','1') WHEN fifo_RdEn='1' ELSE (others=>'0');
dut: ENTITY work.rs232_tx
PORT MAP(clk,tx,fifo_RdClock,fifo_data);
END working;
编辑 我已经在9600 bps的在线速度下测试了另一种UART设计,但同样失败。它可以将恒定字符(在本例中为“ a”)发送到计算机上的终端,然后突然停止发送任何内容。但是,如果我开始收听在Lattice Diamond中生成的软逻辑分析仪,则它可以正常工作并且不会失败。
解决方法
这闻起来像是经典的计时问题。
在评论中,其他人解释了代码中哪些弱点可能会间接导致此问题。我将专注于正在发生的事情。
如前所述,在仿真中,您的代码可以按预期工作。但是,这只是故事的一半。要创建FPGA比特流,构建工具将使用您的代码和其他几个文件,进行综合并进行布局布线。您的计时问题发生在P&R期间。这就是为什么您的仿真不会出现任何错误的原因,因为我假设它是RTL(预置位和布线)仿真。
在P&R期间,工具以最佳方式放置逻辑以适合设备的时序模型,以便所有路径均满足其时序要求。路径时序要求是从“时序约束”文件中的显式语句派生而来,并从您的代码中推断(这就是为什么您的编码风格很重要)的原因。
P&R完成后,这些工具将通过静态时序分析器(STA)工具将构建工件放入其中,并报告构建是否不满足时序要求。
这导致两个问题:
- 该版本是否报告计时错误?
- 您是否有“时间约束”文件-如果不确定,答案是否定的。
调试问题的方法是使用Lattice Diamond生成的时序报告来查看故障发生的位置。 如果没有报告的故障,则表明您的时序模型是错误的,因为缺少适当的时序约束。至少,您需要限制设计中的所有IO,并描述设计中的所有时钟。
以下是一个很好的文档,可以帮助您: https://www.latticesemi.com/-/media/LatticeSemi/Documents/UserManuals/RZ/Timing_Closure_Document.ashx?document_id=45588
使用嵌入式逻辑分析仪时设计工作的原因是在设计中放置了额外的逻辑,这改变了时序模型。 P&R工具以不同的方式对设计进行布局,但幸运的是,设计可以满足其实际时序要求。
正如我经常对我的软件工程师同事说的那样,软件语言创建了一组指令,HDL创建了一组建议。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。