如何在moduleEN-VHDL上设置值

如何在moduleEN-VHDL上设置值,vhdl,counter,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; architectu

我有以下代码:

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;
现在代码可以像我在ModelSim中需要的那样工作,但当我合成它或编译它并再次模拟时,它就不起作用了

我的问题是:

  • 第二个代码有什么问题,我怎么能修复它

  • 如果我无法修复第二个代码,我如何修改第一个代码以使其按需要工作

第二个代码有什么问题,我如何修复它

您的合成工具对时钟和复位线的连接方式很挑剔。您必须使用以下结构:

        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;
过程(时钟、模块设置)
开始
如果ModuleRESET='0',则

计数器我没有很好地解释我需要从这个代码中得到什么。第一个代码正在工作,但不是我所需要的。我已经在我的问题中更新了我需要什么(你可以在Strong中找到它),你能再检查一下吗?我得到两个错误:Controller中的net OutENABLE(2到0)的多个非三态驱动程序;控制器中网络可路由(2到0)的未解析三态驱动程序;当我试图编译代码时。这意味着在两个进程中都有对OutENABLE的赋值。很抱歉是我的错。更正了。现在代码正在运行。但我在模拟中有个错误。例如,当OutENABLE处于状态“010”时,它有时会在1ns的时间内随机转到“000”,然后转到“100”,然后再回到“010”。很高兴它能为您工作。OutENABLE现在由一些组合逻辑生成,但当计数器增加时,您不会立即得到答案:仍然存在传播延迟,这说明了您在模拟器中看到的情况以及暂时无效的状态(“故障”)。避免这种情况的方法是将OutENABLE设置为寄存器,就像初始解决方案一样,在这种情况下,OutENABLE在到达时钟边缘之前不会更改。
    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;