2014-11-25 21 views
-2

我的代码编译时产生以下错误:试图使用VHDL缓冲区 - 不工作

错误:HDLCompiler:439 - “E:/电子工程2/DIGITAL/Resit_Year/Assignment_7_seg/4_Bit_Counter/Bit_Counter/counter_tb.vhd” 47号线:模拟器:模式缓冲区的正式端口count_out不能用的模式出来 ERROR实际端口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

旧风格的VHDL:Buffer端口都必须连接到Buffer端口(未Out端口)一路上扬的层次结构。在VHDL的早期阶段,这个原因是有道理的,但ASIC和FPGA技术已经发展,合成技术也有所发展。

旧样式解决方案:因此请在实体中创建out端口(您尚未发布足够的代码,因此我无法命名它,但它是层次结构中的下一级),也有buffer端口。

解决方法:如果您不允许在更高级别更改端口类型,则可以将缓冲区端口连接到信号,并将该信号分配给端口out

较新的VHDL:在VHDL-2002中,此限制已被消除,因此如果在编译时选择--std=vhdl2002或同等选项,则此功能应起作用。

最新VHDL:由于Buffer已经如此糟糕教它创造了这么多的困惑,如果你选择--std=vhdl2008out港口现在允许读取驾驶价值就像buffer端口,因此你可以简单地用out口更换你buffer端口。

+1

IEEE Std 1076-2008 6.5.2接口对象声明,注7 - 尽管模式输出端口与模式缓冲区的端口具有相同的语义,但它们之间存在重要的设计文档区分。目的是模式输出端口应该只读取被动活动,即用于在监视器或属性或断言检查器中用于验证的功能。如果读取输出端口的值以实现描述的算法行为,则该端口应该是模式缓冲区。 *应*具有推荐权重(不是强制性的)。 – user1155120 2014-11-26 00:27:32

+0

换句话说,你*可以*用'out'替换'buffer' ......但你可能*不应该*。感谢您的澄清。 – 2014-11-26 00:52:05

+0

*应该*表示建议对于2008年的标准是新的,并且对设计描述的合法性没有任何影响。注7可以忽略,建议不可测试。标准并不意味着提供样式要求。另一方面是综合供应商支持的做法? – user1155120 2014-11-26 05:56:52

0

正确的设计工作第一

有多种事情不对的设计规范,所以它似乎更容易得到它显示为模式buffer使用前正常工作。

“的完整代码:” 丢失上下文子句:

-- missing context clause: 
library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 

(Synopsys的std_logic_unsigned提供 “+” 运算符[std_logic_vector,整数返回std_logic_vector],可能需要一些-fexplicit或等效的命令行标志VHDL分析器。有等于运算符“=”具有相同签名的两种可能的解释。)

无论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; 

布赖恩指出的下一级层次结构中应该有一个直接连接的端口模式buffer的模式bufferfour_bit_counter端口。不清楚为什么你在测试平台上有端口(“E:/ ELECTRONIC ENGINEERING 2/DIGITAL/Resit_Year/Assignment_7_seg/4_Bit_Counter/Bit_Counter/counter_tb.vhd”中的“_tb”),这并不是明证。

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进行评估,但似乎它应该改名过程counting连接到temp_count电线,这样我们可以为cout_out替代temp_count。过程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; 

(I也折叠if语句级别,使用elsif代替else 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; 

我们可以模拟:

four_bit_counter_tb (图片可点击)

你可以看到,pause调用拉伸temp_count周期为temp_count = "0001"

您可能还注意到count_out总是定义,有一个为temp_count的默认值。

重新转换到count_out模式缓冲区

所以,你可以让count_out模式缓冲区,消除temp_count声明和实体four_bit_counter取代temp_countcount_out其他地方,它会工作。注意提供的测试台不关心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的默认值。这主要是为了方便。在clock的下一个下降沿之后,测试台生成reset,而Synopsys软件包std_logic_unsigned在初始执行过程student期间调用std_logic_arith。“=”。