0

我正在尝试在 vhdl 中为 UA(R)T 创建一个状态机(仅发送部分)。

我对程序的流程有疑问。我知道 buad rate 部分目前不起作用。我现在正试图让它只用一个时钟工作,然后实现波特率分频器。

当我通过我的测试台运行它时(没什么复杂的,只需为 x 时间分配几个初始值 reset = 1,din = z,baud = y 等),没有任何反应。我的输出 txd 保持在重置阶段设置的初始“1”值,如果我将其设置为“0”,它将在周期内保持不变。

我在设计状态机时遇到的问题是它有两个值,它将转换但不会处于任何状态。

基本上,它应该做的是: reset: txd = 1, count = 1, busy = 0, we = 0 idle: when busy = 1 set shift = init values wait: transition on next clock signal trans: if count < 9,txd = shift(0),如果 count = 9,则 shift shift,busy = 0,count = 0 并返回空闲

我认为我的问题与未正确设置忙音有关。

-- Universal Asynch Receiver Transmitter
---------------------
library ieee;
use ieee.std_logic_1164.all;

entity eds_uart is
   generic (width : positive := 16);
   port ( clk,reset: in std_logic ;
     din_wen: buffer std_logic; -- state machine sets value thus buffer needed
     brd : in std_logic_vector(23 downto 0); -- buad rate dividor
     din : in std_logic_vector(7 downto 0); -- input value
     txd: out std_logic; -- sent data bit
     tx_busy : buffer std_logic -- sent data bit active
     );
end entity eds_uart;

architecture behaviour of eds_uart is
    type state_type is (idle_s, wait_s, transmit_s);  -- three possible states of uat
    signal current_s: state_type; 
    signal tick: std_logic; -- baud rate clock
    signal count: integer := 0; -- count number of characters sent
    signal shift: std_logic_vector(9 downto 0); -- intermediate vector to be shifted

begin
   -- assign tick value based on baud rate 
   -- need to implement divisor
   process(clk, brd) begin
      tick <= clk;
   end process; 

   process(tick, reset, din) begin 
       if (reset = '1') then
           current_s <= idle_s; -- default state
           count <= 0; -- reset character counter
           txd <= '1'; 
           tx_busy <= '0'; 
           din_wen <= '0'; -- able to start sending
       elsif (current_s = idle_s and din_wen = '1') then -- transition when write enable is high
           current_s <= wait_s; -- transition
           tx_busy <= '1';  
           shift <= '1' & din & '0'; -- init shift value
       elsif (current_s = wait_s and rising_edge(tick)) then -- transition on clock signal
            current_s <= transmit_s;
       elsif (current_s = transmit_s and rising_edge(tick)) then -- test transition on clock signal
            if (count < 9) then
                txd <= shift(0); -- output value
                shift <= '0' & shift(9 downto 1); -- shift to next value
                count <= count + 1; -- increment counter
                current_s <= transmit_s; -- dont change state
            elsif (count = 9) then 
                txd <= shift(0); -- send last element
                count <= 0;
                tx_busy <= '0'; -- reset busy signal
                current_s <= idle_s; -- start process again
           end if;
       end if;
   end process;
end architecture behaviour ;
4

1 回答 1

0

评论:

-- state machine sets value thus buffer needed

-- transition when write enable is high

建议您可能期望为din_wen. 如果是这种情况,则该buffer模式对您没有任何好处,因为它只暴露了内部驱动程序的值,而内部驱动程序的值din_wen只会驱动“0”。发布 VHDL-2002,buffer实际上是一个花哨的、可读的版本,out没有早期标准的限制。它没有实现输入端口。更重要的是,如果您在此实体之外有其他信号驱动程序,它不会让您看到外部解析值。

目前尚不清楚为什么您甚至需要din_wen内部驱动,因为它旨在成为导致转换到wait_s状态的控制输入。考虑将其更改为in端口模式并删除重置分配。

风格说明:您正在使用此处描述的同步和异步逻辑的混合来招惹危险。您应该坚持在包装所有同步逻辑rising_edge()的顶级块中进行一次调用的模式。if

于 2014-07-09T21:13:07.283 回答