VHDL - 时钟边沿外值的编码错误
VHDL - coding error of value outside the clock edge
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity RAM_controler is
port(
clk_50 : in std_logic;
clk_baud : in std_logic;
main_reset : in std_logic;
enable: in std_logic; --active high write enable
in_data : in std_logic_vector(7 downto 0);
W_order : out std_logic;
R_order : out std_logic;
Data_OUT : out std_logic_vector(7 downto 0);
Write_Address_OUT: out std_logic_vector(7 downto 0);
Read_Address_OUT: out std_logic_vector(7 downto 0)
);
end entity RAM_controler;
architecture Behavioral of RAM_controler is
type state is (reset,operation);
signal state_reg,next_state_reg : state;
signal write_address : std_logic_vector(W-1 downto 0):="00000000";
signal next_write_address : std_logic_vector(W-1 downto 0):="00000000";
begin
state_change : process(clk_50, main_reset)
begin
if (main_reset = '1') then
state_reg <= reset;
elsif (rising_edge(clk_50)) then
state_reg <= operation;
read_counter <= next_read_counter;
write_address<= next_write_address;
read_address <= next_read_address;
end if;
end process;
writecounter : process(clk_baud, main_reset,enable)
begin
if (main_reset='1') then
next_write_address <= "00000000";
Data_OUT <= "ZZZZZZZZ";
W_order <='0';
Write_Address_OUT <="ZZZZZZZZ";
elsif (rising_edge(clk_baud) and enable='1' ) then
W_order <='1';
Data_OUT <= in_data;
Write_Address_OUT <= write_address;
if (write_address = "11111111") then
next_write_address <= "00000000";
else
next_write_address <= write_address+1;
end if;
else
W_order <='0';
Write_Address_OUT <= "ZZZZZZZZ";
next_write_address <= write_address+1;
end if;
end process;
end Behavioral;
以上代码描述了 RAM 控制器。
做题的部分是"elsif (rising_edge(clk_baud) and enable='1' ) then"。
错误:无法在 RAM_controler.vhd 为 "Write_Address_OUT" 进行内部注册,因为它不会在时钟边沿
之外保持其值
我不知道为什么那个点是错误的。
有没有人给我提意见?
谢谢!
您代码中的最终 else
实际上应该是:
elsif (rising_edge(clk_baud) and enable='0' ) then
如果您正在编写顺序逻辑代码,坚持使用模板是明智的。这是一个带有异步复位的时序逻辑模板,所有综合工具都应该理解它:
process(clock, async_reset) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if async_reset ='1' then -- or '0' for an active low reset
-- set/reset the flip-flops here
-- ie drive the signals to their initial values
elsif rising_edge(clock) then -- or falling_edge(clock)
-- put the synchronous stuff here
-- ie the stuff that happens on the rising or falling edge of the clock
end if;
-- never put anything here
end process;
所以enable不应该在sensitivity列表中,也不应该在异步复位和时钟测试的同一个if语句中测试。
您收到此错误的原因:
Error : Can`t inter register for "Write_Address_OUT" at
RAM_controler.vhd because it does not hold its value outside the clock
edge
是因为您代码中的最后三个赋值:
W_order <='0';
Write_Address_OUT <= "ZZZZZZZZ";
next_write_address <= write_address+1;
可以发生在时钟的下降沿,或者(因为您的灵敏度列表中也有 enable)完全独立于任何时钟。逻辑合成器无法合成具有这种行为的逻辑。如果你坚持使用模板,你就不会 运行 陷入这种问题(并且它会让你更仔细地思考你期望合成器合成什么逻辑)。
所以,我会像这样编写您的 writecounter 过程:
writecounter : process(clk_baud, main_reset)
begin
if (main_reset='1') then
next_write_address <= "00000000";
Data_OUT <= "ZZZZZZZZ";
W_order <='0';
Write_Address_OUT <="ZZZZZZZZ";
elsif rising_edge(clk_baud) then
if enable='1' then
W_order <='1';
Data_OUT <= in_data;
Write_Address_OUT <= write_address;
if (write_address = "11111111") then
next_write_address <= "00000000";
else
next_write_address <= write_address+1;
end if;
else
W_order <='0';
Write_Address_OUT <= "ZZZZZZZZ";
next_write_address <= write_address+1;
end if;
end if;
end process;
不过,我要强调的是,我的代码与您的代码行为并不完全相同。我不知道你的设计意图,所以我只能猜测你的意图。如果您想要其他一些行为,那么您将不得不实施它。无论您的设计意图如何,我关于坚持使用模板的建议仍然很重要。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity RAM_controler is
port(
clk_50 : in std_logic;
clk_baud : in std_logic;
main_reset : in std_logic;
enable: in std_logic; --active high write enable
in_data : in std_logic_vector(7 downto 0);
W_order : out std_logic;
R_order : out std_logic;
Data_OUT : out std_logic_vector(7 downto 0);
Write_Address_OUT: out std_logic_vector(7 downto 0);
Read_Address_OUT: out std_logic_vector(7 downto 0)
);
end entity RAM_controler;
architecture Behavioral of RAM_controler is
type state is (reset,operation);
signal state_reg,next_state_reg : state;
signal write_address : std_logic_vector(W-1 downto 0):="00000000";
signal next_write_address : std_logic_vector(W-1 downto 0):="00000000";
begin
state_change : process(clk_50, main_reset)
begin
if (main_reset = '1') then
state_reg <= reset;
elsif (rising_edge(clk_50)) then
state_reg <= operation;
read_counter <= next_read_counter;
write_address<= next_write_address;
read_address <= next_read_address;
end if;
end process;
writecounter : process(clk_baud, main_reset,enable)
begin
if (main_reset='1') then
next_write_address <= "00000000";
Data_OUT <= "ZZZZZZZZ";
W_order <='0';
Write_Address_OUT <="ZZZZZZZZ";
elsif (rising_edge(clk_baud) and enable='1' ) then
W_order <='1';
Data_OUT <= in_data;
Write_Address_OUT <= write_address;
if (write_address = "11111111") then
next_write_address <= "00000000";
else
next_write_address <= write_address+1;
end if;
else
W_order <='0';
Write_Address_OUT <= "ZZZZZZZZ";
next_write_address <= write_address+1;
end if;
end process;
end Behavioral;
以上代码描述了 RAM 控制器。
做题的部分是"elsif (rising_edge(clk_baud) and enable='1' ) then"。
错误:无法在 RAM_controler.vhd 为 "Write_Address_OUT" 进行内部注册,因为它不会在时钟边沿
之外保持其值我不知道为什么那个点是错误的。
有没有人给我提意见?
谢谢!
您代码中的最终 else
实际上应该是:
elsif (rising_edge(clk_baud) and enable='0' ) then
如果您正在编写顺序逻辑代码,坚持使用模板是明智的。这是一个带有异步复位的时序逻辑模板,所有综合工具都应该理解它:
process(clock, async_reset) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if async_reset ='1' then -- or '0' for an active low reset
-- set/reset the flip-flops here
-- ie drive the signals to their initial values
elsif rising_edge(clock) then -- or falling_edge(clock)
-- put the synchronous stuff here
-- ie the stuff that happens on the rising or falling edge of the clock
end if;
-- never put anything here
end process;
所以enable不应该在sensitivity列表中,也不应该在异步复位和时钟测试的同一个if语句中测试。
您收到此错误的原因:
Error : Can`t inter register for "Write_Address_OUT" at RAM_controler.vhd because it does not hold its value outside the clock edge
是因为您代码中的最后三个赋值:
W_order <='0';
Write_Address_OUT <= "ZZZZZZZZ";
next_write_address <= write_address+1;
可以发生在时钟的下降沿,或者(因为您的灵敏度列表中也有 enable)完全独立于任何时钟。逻辑合成器无法合成具有这种行为的逻辑。如果你坚持使用模板,你就不会 运行 陷入这种问题(并且它会让你更仔细地思考你期望合成器合成什么逻辑)。
所以,我会像这样编写您的 writecounter 过程:
writecounter : process(clk_baud, main_reset)
begin
if (main_reset='1') then
next_write_address <= "00000000";
Data_OUT <= "ZZZZZZZZ";
W_order <='0';
Write_Address_OUT <="ZZZZZZZZ";
elsif rising_edge(clk_baud) then
if enable='1' then
W_order <='1';
Data_OUT <= in_data;
Write_Address_OUT <= write_address;
if (write_address = "11111111") then
next_write_address <= "00000000";
else
next_write_address <= write_address+1;
end if;
else
W_order <='0';
Write_Address_OUT <= "ZZZZZZZZ";
next_write_address <= write_address+1;
end if;
end if;
end process;
不过,我要强调的是,我的代码与您的代码行为并不完全相同。我不知道你的设计意图,所以我只能猜测你的意图。如果您想要其他一些行为,那么您将不得不实施它。无论您的设计意图如何,我关于坚持使用模板的建议仍然很重要。