我在VHDL中实现RS-232发送器。 我想使用PS-2键盘输入数据并将其显示在串口终端中。 我有工作的接收器,我知道其余的元件正在与这个发射器分开工作。
我有以下代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity uart is
generic (
CLK_FREQ : integer := 50;
SER_FREQ : integer := 115200
);
port (
clk : in std_logic;
rst : in std_logic;
tx : out std_logic;
tx_req : in std_logic;
tx_data : in std_logic_vector(7 downto 0);
rx_ready : out std_logic;
rx_data : out std_logic_vector(7 downto 0)
);
end uart;
architecture Behavioral of uart is
constant UART_IDLE : std_logic := '1';
constant UART_START : std_logic := '0';
constant RST_LVL : std_logic := '1';
type state is (idle,data,stop);
signal tx_state : state;
signal tx_next_state : state;
signal tx_clk_en : std_logic;
signal tx_data_tmp : std_logic_vector(7 downto 0);
signal tx_data_cnt : std_logic_vector(2 downto 0);
begin
--
tx_clk_gen:process(clk)
variable counter : integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
begin
if clk'event and clk = '1' then
if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 then
tx_clk_en <= '1';
counter := 0;
else
tx_clk_en <= '0';
counter := counter + 1;
end if;
end if;
end process;
tx_process:process(clk, tx_state)
begin
if tx_clk_en = '0' then
tx_next_state <= tx_state;
case tx_state is
when idle =>
if tx_req = '0' then
tx <= '0';
tx_data_tmp <= tx_data;
tx_next_state <= data;
tx_data_cnt <= (others=>'1');
else
tx <= '1';
tx_next_state <= idle;
tx_data_cnt <= (others=>'1');
tx_data_tmp <= (others=>'1');
end if;
when data =>
tx <= tx_data_tmp(0);
if tx_data_cnt = 0 then
tx_next_state <= stop;
tx_data_cnt <= (others=>'1');
tx_data_tmp <=(others=>'1');
else
tx_next_state <= data;
tx_data_tmp <= '0' & tx_data_tmp(7 downto 1);
tx_data_cnt <= tx_data_cnt - 1;
end if;
when stop =>
tx <= '1';
tx_next_state <= idle;
tx_data_cnt <= (others=>'1');
tx_data_tmp <=(others=>'1');
end case;
end if;
end process;
tx_next:process(tx_next_state)
begin
tx_state <= tx_next_state;
end process;
end Behavioral;
在实施设计期间,有一些警告:
One or more signals are missing in the process sensitivity list. To enable synthesis of FPGA/CPLD hardware, XST will assume that all necessary signals are present in the sensitivity list. Please note that the result of the synthesis may differ from the initial design specification. The missing signals are:<tx_clk_en>, <tx_req>, <tx_data>
Found 3-bit latch for signal <tx_data_cnt>. 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.
Found 8-bit latch for signal <tx_data_tmp>. 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.
Found 3-bit latch for signal <tx_next_state>. 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.
Found 1-bit latch for signal <tx>. 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.
请帮帮我。 提前谢谢。
编辑:
我根据您的提示修改了我的代码,现在没有任何警告,但我仍然不确定它是否能正常工作。有人可以在硬件上检查吗?或者只是评论新版本。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity uart is
generic (
CLK_FREQ : integer := 50;
SER_FREQ : integer := 115200
);
port (
clk : in std_logic;
rst : in std_logic;
tx : out std_logic;
tx_req : in std_logic;
tx_data : in std_logic_vector(7 downto 0);
);
end uart;
architecture Behavioral of uart is
constant UART_IDLE : std_logic := '1';
constant UART_START : std_logic := '0';
constant RST_LVL : std_logic := '1';
type state is (idle, active);
signal tx_state : state;
signal tx_next_state : state;
signal tx_clk_en : std_logic;
signal tx_data_packet : std_logic_vector(9 downto 0);
signal tx_data_cnt : std_logic_vector(3 downto 0);
begin
--
tx_clk_gen:process(clk)
variable counter : integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
begin
if clk'event and clk = '1' then
if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 then
tx_clk_en <= '1';
counter := 0;
else
tx_clk_en <= '0';
counter := counter + 1;
end if;
end if;
end process;
tx_reset:process(clk)
begin
if clk'event and clk = '1' then
if rst = '0' then
tx_state <= idle;
else
tx_state <= tx_next_state;
end if;
end if;
end process;
tx_process:process(clk, tx_state, tx_req, tx_clk_en)
begin
if clk'event and clk = '1' then
if tx_clk_en = '0' then
tx_next_state <= tx_state;
case tx_state is
when idle =>
if tx_req = '0' then
tx_data_packet(9) <= '0';
tx_data_packet(8 downto 1) <= tx_data;
tx_data_packet(0) <= '1';
tx_next_state <= active;
tx_data_cnt <= "1010";
else
tx <= '1';
tx_next_state <= idle;
tx_data_cnt <= (others=>'1');
tx_data_packet <= (others=>'1');
end if;
when active =>
tx <= tx_data_packet(0);
if tx_data_cnt = 0 then
tx_next_state <= idle;
tx_data_cnt <= (others=>'1');
tx_data_packet <=(others=>'1');
else
tx_next_state <= active;
tx_data_packet <= '0' & tx_data_packet(9 downto 1);
tx_data_cnt <= tx_data_cnt - 1;
end if;
end case;
else
tx <= '1';
tx_data_packet <= (others=>'1');
tx_data_cnt <= (others=>'1');
end if;
end if;
end process;
end Behavioral;
#
#
嘿伙计们!
我现在有以下代码,我在硬件上进行了测试,但它仍然无法正常工作。你有什么想法吗?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity uart is
generic (
CLK_FREQ : integer := 50;
SER_FREQ : integer := 115200
);
port (
clk : in std_logic;
rst : in std_logic;
rx : in std_logic;
tx : out std_logic;
tx_req : in std_logic;
tx_data : in std_logic_vector(7 downto 0);
);
end uart;
architecture Behavioral of uart is
constant UART_IDLE : std_logic := '1';
constant UART_START : std_logic := '0';
constant RST_LVL : std_logic := '1';
type state is (idle, active);
signal tx_busy :std_logic;
signal tx_state : state;
signal tx_next_state : state;
signal tx_clk_en : std_logic;
signal tx_data_packet : std_logic_vector(8 downto 0);
signal tx_data_cnt : std_logic_vector(3 downto 0);
begin
--
tx_clk_gen:process(clk, tx_req)
variable counter : integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
begin
if rising_edge(clk) then
if tx_busy = '1' then
if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 then
tx_clk_en <= '1';
counter := 0;
else
tx_clk_en <= '0';
counter := counter + 1;
end if;
end if;
end if;
end process;
tx_reset:process(clk)
begin
if rising_edge(clk) then
if rst = '0' then
tx_state <= idle;
else
tx_state <= tx_next_state;
end if;
end if;
end process;
tx_process:process(clk, tx_state, tx_req, tx_clk_en)
begin
if rising_edge(clk) then
case tx_state is
when idle =>
if tx_req = '1' then
tx <= '0';
tx_data_packet(7 downto 0) <= tx_data;
tx_data_packet(8) <= '1';
tx_next_state <= active;
tx_data_cnt <= "1010";
tx_busy <= '1';
else
tx <= '1';
tx_next_state <= idle;
tx_data_cnt <= (others=>'1');
tx_data_packet <= (others=>'1');
end if;
when active =>
if tx_clk_en = '1' then
tx <= tx_data_packet(0);
if tx_data_cnt = 0 then
tx_next_state <= idle;
tx_data_cnt <= (others=>'1');
tx_data_packet <=(others=>'1');
tx <= '1';
tx_busy <= '0';
else
tx_next_state <= active;
tx_data_packet <= '1' & tx_data_packet(8 downto 1);
tx_data_cnt <= tx_data_cnt - 1;
end if;
end if;
end case;
end if;
end process;
答案 0 :(得分:1)
锁存器指示您要计时的非时钟进程,或者覆盖不完整的组合逻辑(例如if
语句没有else
部分)。
我可以在短暂的一瞥中看到前两个代码。
编辑re:编辑:然后编写一个测试平台并进行模拟。它符合您的期望吗?
答案 1 :(得分:0)
猜猜您在if clk'event and clk = '1' then
的最外层失踪rising_edge(clk)
或tx_process
。
tx_next
过程看起来也很奇怪;它实际上没有像现在所写的那样(除了延迟)。