我正在尝试在vhdl中为Spartan编写RS232发送器模块。根据Xilinx的模拟,它似乎工作正常,但是当我尝试在设备上部署它时,它根本不起作用。我发现它可能是锁存器的问题,但不知怎的,我无法确定它们。我使用50 Mhz时钟,传输比特率为115200 bs。
这是我的vhdl代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_arith.all; -- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity nadajnikRS is
Port ( start : in STD_LOGIC;
reset : in STD_LOGIC;
clk : in STD_LOGIC;
DI : in STD_LOGIC_VECTOR(7 downto 0);
RS_TX : out STD_LOGIC;
busy : out STD_LOGIC);
end nadajnikRS;
architecture Behavioral of transRS is
signal register : STD_LOGIC_VECTOR(8 downto 0) := (others => '1' );
signal counter : INTEGER range 0 to 9 := 0;
signal baud_clk : STD_LOGIC := '0';
signal ready : STD_LOGIC := '0';
type states is (working, free);
signal state: states := free;
signal baud_counter : INTEGER range 0 to 220 := 215;
begin
baud_clock: process (clk)
begin
if rising_edge(clk) then
if (ready = '1') then
if (baud_counter < 218) then
if (baud_counter = 217) then
baud_clk <= '1';
end if;
baud_counter <= baud_counter+1;
else
baud_counter <= 0;
baud_clk <= '0';
end if;
else
baud_counter <= 0;
end if;
end if;
end process baud_clock;
shiftregister : process (baud_clk)
begin
if rising_edge(baud_clk) then
if (state = free) then
RS_TX <= '0';
register (7 downto 0) <= DI;
else
RS_TX <= register(0);
register <= '1' & register(8 downto 1);
end if;
end if;
end process shiftregister;
bitcounter : process (baud_clk)
begin
if rising_edge(baud_clk) then
counter <= counter + 1;
if (counter = 10) then
counter <= 1;
end if;
end if;
end process bitcounter;
shiftstate: process (reset, counter, start)
begin
if (reset = '1') then
ready <= '0';
end if;
if (start = '1') then
ready <= '1';
state <= free;
end if;
if (counter = 1 ) then
state <= working;
elsif (counter = 10) then
state <= free;
end if;
end process;
statemachine : process (state)
begin
case state is
when working => busy <= '1';
when free => busy <= '0' ;
end case;
end process statemachine;
end Behavioral;
在综合过程中,我收到两个闩锁警告:
Xst:737 - Found 1-bit latch for signal <ready>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
Xst:737 - Found 1-bit latch for signal <state_0>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
我尝试通过添加额外的if语句来消除它们,但似乎没有任何效果。 我将不胜感激任何帮助, Ghaad
答案 0 :(得分:1)
描述寄存器的过程应该在灵敏度列表中只有一个信号clk(如果使用异步复位,也可能是复位信号),因为寄存器只对单个事件敏感,即时钟边沿。 / p>
因此,您的过程敏感度列表baud_clock: process (clk,ready)
和shiftregister : process (baud_clk, state)
已经表明您遇到了问题。
在描述寄存器时,请务必确保if(rising_edge(clk))
围绕所有描述的逻辑。一个简单的注册过程应如下所示:
process(clk) begin
-- NO LOGIC HERE
if(rising_edge(clk)) then
if(reset='1') then
-- Synchronous reset logic here.
else
-- All other logic here.
end if;
end if;
-- NO LOGIC HERE
end process;
答案 1 :(得分:1)
查看您的“shiftstate”流程,该流程负责推动“准备就绪”。当'reset'不是1时,它如何驱动'ready','start'不是1?你没有告诉它,所以它在那些情况下保持“准备好”不变。这就是'闩锁'的意思:这个过程需要记住之前的'准备',并保持相同;因此你的代码推断出一个记忆。确保在所有分支中驱动“就绪”;您可以使用顶部的默认分配轻松完成此操作。
话虽如此,您的代码还有其他多个问题。有人在另一个帖子中建议你不应该在if语句中进行上升沿检测吗?还是那个人?回去再读一遍。
答案 2 :(得分:0)
尝试填充if语句的所有可能性,以便每次运行时程序都知道哪个值对应于变量。如果语句几乎总是使用else或elsif选项而不生成锁存器..
答案 3 :(得分:0)
当允许进程从开始到结束而没有为驱动输出分配值时,可能发生锁存。也就是说,如果您的流程中有任何条件语句,并且您的输出是在这些条件语句中驱动的,那么很可能永远不会驱动输出。为避免这种情况,最好在流程开始时放置并发语句,以确保输出至少设置一次。这将告诉你的合成器不要创建一个锁存器。