试图在VHDL中使用缓冲区 - 无法正常工作

时间:2014-11-25 14:49:07

标签: vhdl

我的代码在编译时会产生以下错误:

错误: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;

2 个答案:

答案 0 :(得分:0)

旧式VHDL:Buffer端口必须连接到Buffer端口(不是Out端口)一直到层次结构。这背后的原因在VHDL的早期有意义,但ASIC和FPGA技术已经发展,合成技术也在不断发展。

旧式解决方案:所以在实体中设置out端口(您还没有发布足够的代码,因此我无法对其进行命名,但它是下一级别的层次结构)一个buffer端口。

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

较新的VHDL:在VHDL-2002中,此限制已被取消,因此如果您在编译时选择--std=vhdl2002或等效选项,这应该有效。

最新的VHDL:由于Buffer的教学质量如此之差,造成了如此多的混乱,如果您选择--std=vhdl2008out端口现在只允许读取驱动值与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_outstudent_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;

我们可以模拟:

four_bit_counter_tb (图片可点击)

您可以看到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期间。