我的代码在编译时会产生以下错误:
错误:HDLC编译器:439 - " E:/ ELECTRONIC ENGINEERING 2 / DIGITAL / Resit_Year / Assignment_7_seg / 4_Bit_Counter / Bit_Counter / counter_tb.vhd"第47行:模式缓冲区的正式端口count_out不能与模式输出的实际端口count_out相关联 错误:模拟器:777 - 库工作中顶级VHDL设计单元counter_tb的静态细化失败
不知道如何解决这个问题。
完整代码:
-----------------------------------------------------------------------------------
entity Four_Bit_Counter is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
pause : in STD_LOGIC;
count_out : buffer STD_LOGIC_VECTOR (3 downto 0);
student_id : buffer STD_LOGIC_VECTOR (3 downto 0) );
end Four_Bit_Counter;
----------------------------------------------------------------------------------
architecture Behavioral of Four_Bit_Counter is
signal temp_count : std_logic_vector(3 downto 0) := "0000" ;
signal slow_clock : std_logic ;
signal clock_divider : std_logic_vector(1 downto 0) := "00";
variable cout_out : std_logic_vector(3 downto 0):= "0000";
begin
---------------------------------------------------------------------------------
clock_division : process (clock, clock_divider)
begin
if
clock'event and clock = '1' then
clock_divider <= clock_divider + 1;
end if;
slow_clock <= clock_divider(1);
end process;
--------------------------------------------------------------------------------
counting : process(reset, pause, slow_clock, temp_count)
begin
if reset = '1' then
temp_count <= "0000";
elsif pause = '1' then
temp_count <= temp_count;
else
if slow_clock'event and slow_clock= '1' then
if temp_count < 15 then
temp_count <= temp_count + 1;
else
temp_count <= "0000";
end if;
end if;
end if;
count_out <= temp_count;
end process;
----------------------------------------------------------------------------------
student : process (reset, pause, slow_clock, temp_count)
begin
IF (cout_out = "0010") THEN
student_id <= "0010";
ELSIF (cout_out = "0011") THEN
student_id <= "0001";
ELSIF (cout_out = "0100") THEN
student_id <= "0000";
ELSIF (cout_out = "0101") THEN
student_id <= "0000";
ELSIF (cout_out = "0110") THEN
student_id <= "1001";
ELSIF (cout_out = "0111") THEN
student_id <= "0011";
ELSIF (cout_out = "1000") THEN
student_id <= "0010";
ELSIF (cout_out = "1001") THEN
student_id <= "0110";
ELSE student_id <= "1000";
END IF;
end process student;
--student_id <= "0010" when count_out >= "0001" else
--"0001" when count_out >= "0011" else
--"0000" when count_out >= "0101" else
--"0000" when count_out >= "0111" else
--"1001" when count_out >= "1000" else
--"0011" when count_out >= "1001" else
--"0000" when count_out >= "1011" else
--"0110" when count_out >= "1100" else
--"1000";
end Behavioral;
答案 0 :(得分:0)
旧式VHDL:Buffer
端口必须连接到Buffer
端口(不是Out
端口)一直到层次结构。这背后的原因在VHDL的早期有意义,但ASIC和FPGA技术已经发展,合成技术也在不断发展。
旧式解决方案:所以在实体中设置out
端口(您还没有发布足够的代码,因此我无法对其进行命名,但它是下一级别的层次结构)一个buffer
端口。
解决方法:如果您不允许更改更高级别的端口类型,则可以将缓冲区端口连接到信号,并将该信号分配给out
端口。
较新的VHDL:在VHDL-2002中,此限制已被取消,因此如果您在编译时选择--std=vhdl2002
或等效选项,这应该有效。
最新的VHDL:由于Buffer
的教学质量如此之差,造成了如此多的混乱,如果您选择--std=vhdl2008
,out
端口现在只允许读取驱动值与buffer
端口类似,因此您只需将buffer
端口替换为out
个端口。
答案 1 :(得分:0)
让设计先行
设计规范存在多种问题,因此在将用法显示为模式buffer
之前,似乎更容易使其正常工作。
&#34;完整代码:&#34;缺少上下文子句:
-- missing context clause:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
(Synopsys软件包std_logic_unsigned提供&#34; +&#34;运算符[std_logic_vector,整数返回std_logic_vector],对于某些VHDL分析器可能需要-fexplicit或等效的命令行标志。对于等于运算符有两种可能的解释& #34; =&#34;签名相同。)
在架构行为中不评估count_out
和student_id
,它们可以声明为模式out
。除非您打算取消temp_count
(其中count_out
可以保留模式buffer
,否则我们稍后会这样做。)
entity four_bit_counter is
port (
clock: in std_logic;
reset: in std_logic;
pause: in std_logic;
count_out: out std_logic_vector (3 downto 0);
student_id: out std_logic_vector (3 downto 0)
);
end entity four_bit_counter;
正如Brian指出的那样,层次结构中的下一级应该具有直接连接端口模式buffer
,用于four_bit_counter
模式端口buffer
。目前还不清楚为什么你在测试台上有端口(&#34; _tb&#34;在&#34; E:/ ELECTRONIC ENGINEERING 2 / DIGITAL / Resit_Year / Assignment_7_seg / 4_Bit_Counter / Bit_Counter / counter_tb.vhd& #34;),它没有证据。
cout_out
应该是signal
而不是variable
。它没有被使用,可以被淘汰:
-- variable cout_out: std_logic_vector(3 downto 0):= "0000";
-- signal cout_out: std_logic_vector(3 downto 0):= "0000";
cout_out
在流程student
中进行了评估,但似乎应该在流程temp_count
中将其重命名为counting
的导线,因此我们可以将temp_count
替换为cout_out
。流程student
的敏感度列表也应仅包含temp_count
:
student:
process (temp_count) -- (reset, pause, slow_clock, temp_count)
begin
if temp_count = "0010" then
student_id <= "0010";
elsif temp_count = "0011" then
student_id <= "0001";
elsif temp_count = "0100" then
student_id <= "0000";
elsif temp_count = "0101" then
student_id <= "0000";
elsif temp_count = "0110" then
student_id <= "1001";
elsif temp_count = "0111" then
student_id <= "0011";
elsif temp_count = "1000" then
student_id <= "0010";
elsif temp_count = "1001" then
student_id <= "0110";
else
student_id <= "1000";
end if;
end process student;
pause
也存在设计问题:
counting:
process(reset, pause, slow_clock, temp_count)
begin
if reset = '1' then
temp_count <= "0000";
elsif pause = '1' then
temp_count <= temp_count;
else
看起来pause
应该是同步的。 reset
是异步的,将使用包含temp_count
计数器的触发器的清除输入。这些触发器的D输入是递增器(+ 1
)。在多路复用器中添加异步控制,在增量器和当前值之间进行选择本质上是一种启用,应该同步表示:
counting:
process (reset, slow_clock, temp_count) -- (reset, pause, slow_clock, temp_count)
begin
if reset = '1' then
temp_count <= "0000";
-- elsif pause = '1' then
-- temp_count <= temp_count;
-- else
-- if slow_clock'event and slow_clock = '1' then
elsif slow_clock'event and slow_clock = '1' and pause = '0' then
if temp_count < 15 then
temp_count <= temp_count + 1;
else
temp_count <= "0000";
end if;
end if;
-- end if;
count_out <= temp_count;
end process;
(我还使用elsif
代替else if
折叠了if语句级别。
因此,通过这些更改,设计可以成功分析和阐述。 (计算"00"
的默认值以使增量clock_divider <= clock_divider + 1;
正常工作)。
添加测试台:
library ieee;
use ieee.std_logic_1164.all;
entity four_bit_counter_tb is
end entity;
architecture foo of four_bit_counter_tb is
signal clock: std_logic := '0';
signal reset: std_logic;
signal pause: std_logic;
signal count_out: std_logic_vector (3 downto 0);
signal student_id: std_logic_vector (3 downto 0);
begin
DUT:
entity work.four_bit_counter
port map (
clock => clock,
reset => reset,
pause => pause,
count_out => count_out,
student_id => student_id
);
CLK:
process
begin
wait for 10 ns;
clock <= not clock;
if Now > 1.53 us then
wait;
end if;
end process;
STIMULIS:
process
begin
wait for 20 ns;
pause <= '0';
reset <= '1';
wait for 20 ns;
reset <= '0';
wait for 140 ns;
pause <= '1';
wait for 40 ns;
pause <= '0';
wait;
wait;
end process;
end architecture;
我们可以模拟:
您可以看到pause
的调用延长了temp_count
的{{1}}周期。
您可能还注意到temp_count = "0001"
始终已定义,count_out
的默认值。
将count_out重新转换为模式缓冲区
所以,您可以设置temp_count
模式缓冲区,取消count_out
的声明,并将temp_count
替换为实际temp_count
中其他地方的count_out
,它会工作。请注意,所提供的测试平台并不关心four_bit_counter
的模式,因为它没有连接到任何端口信号。
所以我这样做了,将count_out
重命名为count_out
:
count
结果是一样的。没有任何端口的测试台不受影响。对于任何理由和供应商允许您的测试平台有端口并且library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity four_bit_counter is
port (
clock: in std_logic;
reset: in std_logic;
pause: in std_logic;
count: buffer std_logic_vector (3 downto 0) := "0000";
student_id: out std_logic_vector (3 downto 0)
);
end entity four_bit_counter;
architecture behavioral of four_bit_counter is
signal slow_clock: std_logic;
signal clock_divider: std_logic_vector(1 downto 0) := "00";
begin
clock_division:
process (clock, clock_divider)
begin
if clock'event and clock = '1' then
clock_divider <= clock_divider + 1;
end if;
slow_clock <= clock_divider(1);
end process;
counting:
process (reset, slow_clock)
begin
if reset = '1' then
count <= "0000";
elsif slow_clock'event and slow_clock = '1' and pause = '0' then
if count < 15 then
count <= count + 1;
else
count <= "0000";
end if;
end if;
end process;
student:
process (count)
begin
if count = "0010" then
student_id <= "0010";
elsif count = "0011" then
student_id <= "0001";
elsif count = "0100" then
student_id <= "0000";
elsif count = "0101" then
student_id <= "0000";
elsif count = "0110" then
student_id <= "1001";
elsif count = "0111" then
student_id <= "0011";
elsif count = "1000" then
student_id <= "0010";
elsif count = "1001" then
student_id <= "0110";
else
student_id <= "1000";
end if;
end process;
end architecture behavioral;
已连接,它必须是模式缓冲区。
请注意,已添加重命名的count
的默认值。这主要是为了方便。测试平台在count
的下一个下降沿之后生成reset
,并且Synopsys包std_logic_unsigned调用std_logic_arith。&#34; =&#34;在初始执行流程clock
期间。