vhdl锁存器中的RS232发送器模块?

时间:2013-05-24 09:47:11

标签: serial-port vhdl

我正在尝试在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 个答案:

答案 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)

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