I've this code:
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;
But it's not working like I need.
What I need:
ModuleENABLE
goes '1' instantly OutENABLE
goes "001" and not at first rising_edge(CLK)
(Now, in this code, if ModuleENABLE goes '1' OutENABLE doesn't change from "000" to "001", it change to "001" after first rising_edge(CLK))rising_edge(CLK)
and OutENABLE
it's updated every CLK
event. (Now, in this code, counter go up when rising_edge(CLK) but OutENABLE it's updated when rising_edge(CLK) and not when CLK goes up and goes down)So I've modified code to do that:
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;
Now code work like I need in ModelSim, but when I synthesize it or compile it and simulate again it doesn't work.
My question is:
What it's wrong with second code and how I can fix it?
If I can't fix second code how I can modify first code to work like I need?
What it's wrong with second code and how I can fix it?
Your synthesis tool is fussy about how the clock and reset lines are connected. You have to use a structure like:
if ModuleRESET = '0' then
...
elsif rising_edge(CLK) then
or the synthesis tool cannot recognise the clock and reset lines.
If I can't fix second code how I can modify first code to work like I need?
You need to move "OutENABLE" outside of the first process, and into a process of its own. From what you've said, OutENABLE should not be a register - it should be a combinatorial function of Counter, ModuleRESET and ModuleENABLE. Try this.
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;