基于VHDL的UA(R)T状态机
我正在尝试用vhdl为UA(R)T(仅发送部分)创建一个状态机 我对程序的流程有问题。我知道buad费率部分目前不起作用。我正在尝试让它在目前只使用一个时钟工作,然后将实现波特率除法器 当我在我的测试台上运行它时(没有什么复杂的,只需为x时间分配两个初始值reset=1,din=z,baud=y,等等),什么都没有发生。我的输出txd保持在重置阶段设置的初始“1”值,如果我将其设置为“0”,则在循环中保持相同 我在设计状态机时遇到的问题是,它有两个值可以转换,但不会处于任何状态 基本上,它应该做的是: 重置:txd=1,计数=1,忙=0,we=0 空闲:忙时=1设置移位=初始值 等待:下一时钟信号转换 trans:如果计数小于9,则txd=移位(0),移位 如果计数=9,忙=0,计数=0 然后回到空闲状态 我认为我的问题与忙信号设置不当有关基于VHDL的UA(R)T状态机,vhdl,state-machine,hardware-programming,Vhdl,State Machine,Hardware Programming,我正在尝试用vhdl为UA(R)T(仅发送部分)创建一个状态机 我对程序的流程有问题。我知道buad费率部分目前不起作用。我正在尝试让它在目前只使用一个时钟工作,然后将实现波特率除法器 当我在我的测试台上运行它时(没有什么复杂的,只需为x时间分配两个初始值reset=1,din=z,baud=y,等等),什么都没有发生。我的输出txd保持在重置阶段设置的初始“1”值,如果我将其设置为“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 ;
——通用异步收发信机
---------------------
图书馆ieee;
使用ieee.std_logic_1164.all;
实体eds_uart是
通用(宽度:正:=16);
端口(时钟,复位:在标准逻辑中;
din_wen:buffer std_logic;--状态机设置所需缓冲区的值
brd:在标准逻辑向量(23到0)中--buad速率除法器
din:标准逻辑向量(7到0);--输入值
txd:out std_logic;--发送的数据位
tx_忙:缓冲区标准逻辑——发送数据位激活
);
终端实体eds_uart;
eds_uart的体系结构行为是
类型状态_类型为(空闲、等待、传输);--uat的三种可能状态
信号电流:状态类型;
信号勾号:标准逻辑;——波特率时钟
信号计数:整数:=0;--计数发送的字符数
信号移位:标准逻辑向量(9到0);--要移位的中间向量
开始
--根据波特率分配刻度值
--需要实现除数
流程(clk、brd)开始
勾选评论:
-- state machine sets value thus buffer needed
及
建议您可能希望为dinu wen
提供额外的外部驱动程序。如果是这种情况,buffer
模式对您没有任何好处,因为它只公开了dinu wen
的内部驱动程序的值,该驱动程序只驱动“0”。在VHDL-2002之后,buffer
实际上是out
的一个奇特的可读版本,没有早期标准的限制。它不实现输入端口。更重要的是,如果在该实体之外有其他信号驱动器,则它不允许您查看外部解析值
不清楚为什么您甚至需要在内部驱动dinu wen
,因为它是一个控制输入,会导致转换到wait_s
状态。考虑在端口模式中将其更改为<代码>,并删除重置赋值。
风格说明:这里所描述的同步和异步逻辑的混合使用,正在引起危险。您应该坚持在顶级if
块中调用rissing\u edge()
,该块包含所有同步逻辑。您似乎没有将dinu wen
设置为'1'
任何位置。这正是问题所在。谢谢并切换了时钟的使用。
-- transition when write enable is high