如何在moduleEN上设置值 - VHDL

时间:2015-04-29 10:34:37

标签: vhdl counter

我有这段代码:

library IEEE;

use IEEE.std_logic_1164.all;

entity Controller is
port (
    CLK : in std_logic;
    OutENABLE : out std_logic_vector (2 downto 0);
    ModuleRESET : in std_logic;
    ModuleENABLE : in std_logic
);
end Controller;

architecture Controller_archi of Controller is
    signal Counter : integer range 0 to 4200 := 0;

    begin
        process (CLK, ModuleRESET)
        begin
            if ModuleRESET = '0' then
                OutENABLE <= (others => '0');
                Counter <= 0;
            elsif rising_edge(CLK) then
                if ModuleENABLE = '1' then
                    Counter <= Counter + 1;
                    case Counter is
                        when 0 =>
                            OutENABLE <= "001";
                        when 450 =>
                            OutENABLE <= "010";
                        when 900 =>
                            OutENABLE <= "100";
                        when 1350 =>
                            OutENABLE <= "001";
                            Counter <= 0;
                        when others =>
                    end case;
                else
                    OutENABLE <= "000";
                end if;
            end if;
        end process;

end Controller_archi;

但它并不像我需要的那样工作。

我需要什么:

  • ModuleENABLE立即变为'1'时OutENABLE变为“001”而不是最初rising_edge(CLK) (现在,在此代码中,如果ModuleENABLE变为'1',则OutENABLE不会从“000”变为“001”,在第一次rising_edge(CLK)之后变为“001”
  • rising_edge(CLK)OutENABLE每次CLK事件更新时,计数器就会上升。 (现在,在这段代码中,计数器在rising_edge(CLK)时上升但在OUT_ABLE时它会在rising_edge(CLK)时更新,而不是在CLK上升和下降时更新

所以我修改了代码来做到这一点:

library IEEE;
use IEEE.std_logic_1164.all;

entity Controller is
port (
    CLK : in std_logic;
    OutENABLE : out std_logic_vector (2 downto 0);
    ModuleRESET : in std_logic;
    ModuleENABLE : in std_logic
);
end Controller;

architecture Controller_archi of Controller is
    signal Counter : integer range 0 to 4200 := 0;

    begin
        process (CLK, ModuleENABLE, ModuleRESET)
        begin
            if ModuleRESET = '0' then
                OutENABLE <= (others => '0');
                Counter <= 0;
            elsif ModuleENABLE = '1' then
                if rising_edge(CLK) then
                    Counter <= Counter + 1;
                end if;
                    case Counter is
                        when 0 =>
                            OutENABLE <= "001";
                        when 450 =>
                            OutENABLE <= "010";
                        when 900 =>
                            OutENABLE <= "100";
                        when 1350 =>
                            OutENABLE <= "001";
                            Counter <= 0;
                        when others =>
                    end case;
             else
                 Counter <= 0;
                 OutENABLE <= "000";
             end if;
        end process;

end Controller_archi;

现在代码工作就像我在ModelSim中所需要的那样,但是当我合成它或编译它并再次模拟它时它不起作用。

我的问题是:

  • 第二个代码有什么问题以及如何修复它?

  • 如果我无法修复第二个代码,我怎么能修改第一个代码才能像我需要的那样工作?

1 个答案:

答案 0 :(得分:1)

  

第二个代码有什么问题以及如何修复它?

您的综合工具对于如何连接时钟和复位线非常挑剔。你必须使用如下结构:

        if ModuleRESET = '0' then
           ...
        elsif rising_edge(CLK) then

或综合工具无法识别时钟和复位线。

  

如果我无法修复第二个代码,我怎么能修改第一个代码才能像我需要的那样工作?

您需要在第一个流程之外移动“OutENABLE”,并进入自己的流程。根据你的说法,OutENABLE不应该是一个寄存器 - 它应该是Counter,ModuleRESET和ModuleENABLE的组合函数。试试这个。

    process (CLK, ModuleRESET)
    begin
        if ModuleRESET = '0' then
            Counter <= 0;
        elsif rising_edge(CLK) then
            if ModuleENABLE = '1' then
                Counter <= Counter + 1;
                case Counter is
                    when 1350 =>
                       Counter <= 0;
                    when others =>
                       null;
                end case;
            end if;
        end if;
    end process;

    process (Counter, ModuleRESET, ModuleEnable)
    begin
        OutENABLE <= "000";
        if ModuleRESET = '1' and ModuleENABLE = '1' then
            case Counter is
                when 0 .. 449 =>
                    OutENABLE <= "001";
                when 450 .. 899 =>
                    OutENABLE <= "010";
                when 900 .. 1349 =>
                    OutENABLE <= "100";
                when others =>
                    OutENABLE <= "001";
            end case;
        end if;
    end process;