0

我正在尝试在 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

4

4 回答 4

1

描述寄存器的进程在灵敏度列表中应该只有一个信号 clk(如果使用异步复位,也可能是复位信号),因为寄存器只对单个事件敏感,即时钟沿。

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;
于 2013-05-24T10:05:18.477 回答
1

看看你的“shiftstate”过程,它负责驾驶“准备好”。当 'reset' 不是 1 并且 'start' 不是 1 时,它是如何驱动 'ready' 的?您还没有告诉它,因此在这些情况下它保持“准备就绪”不变。这就是'latch'的意思:这个过程需要记住之前的'ready'是什么,并保持不变;因此,您的代码会推断出记忆。确保在所有分支中都驱动“就绪”;您可以使用顶部的默认分配轻松完成此操作。

话虽如此,您的代码还有多个其他问题。是否有人在另一个线程中建议您不应该在 if 语句中进行上升沿检测?还是那是别人?回去再读一遍。

于 2013-05-24T10:50:32.093 回答
0

尝试填充 if 语句的所有可能性,以便每次运行程序都知道哪个值对应于变量。if 语句几乎总是与 else 或 elsif 选项一起使用以不产生闩锁。

于 2013-12-09T07:40:43.010 回答
0

当一个进程被允许从开始到结束而驱动输出没有被分配一个值时,就会发生锁存器。也就是说,如果您的流程中有任何条件语句,并且您的输出是在这些条件语句中驱动的,那么很有可能永远不会驱动输出。为避免这种情况,最好在流程的开头放置一条并发语句,以确保至少设置一次输出。这将告诉您的合成器不要创建锁存器。

于 2015-08-01T23:09:23.550 回答