Reputation: 17
library IEEE;
use IEEE.std_logic_1164.all;
entity INCUBATOR2 is
port(temperature: in std_logic_vector(7 downto 0);
CLK,RESET: in std_logic;
on_cooler,on_heater: out std_logic;
CRS:out std_logic_vector(3 downto 0));
end entity INCUBATOR2;
architecture ARCH of INCUBATOR2 is
TYPE STATE_TYPE_left IS (S1, S2, S3);
SIGNAL STATE,NEXT_STATE : STATE_TYPE_left;
TYPE STATE_TYPE_right IS (S_OUT,S_1, S_2, S_3);
SIGNAL cooler_STATE,cooler_NEXT_STATE : STATE_TYPE_right;
begin
--T<= temprature;
REG: process (clk, reset) begin
if reset='1' then
STATE <= S1 ;
cooler_STATE<=S_OUT;
elsif clk'event and clk='1' then
STATE <= NEXT_STATE ;
cooler_STATE<=cooler_NEXT_STATE;
end if ;
end process REG ;
CMB:process(STATE,temperature ,cooler_STATE)
begin
case STATE is
when S1 =>
if(temperature > "00100011" ) then
NEXT_STATE<=S2;
elsif(temperature < "00001111") then
NEXT_STATE<= S3;
end if;
--cooler_NEXT_STATE<=S_OUT;
when S2 =>
if(temperature < "00011001" ) then
NEXT_STATE<=S1;
end if;
case cooler_STATE is
when S_OUT=>
if(temperature>"00100011") then
cooler_NEXT_STATE<=S_1;
end if;
when S_1=>
if(temperature>"00101000") then
cooler_NEXT_STATE<=S_2;
elsif(temperature<"00011001") then
cooler_NEXT_STATE<=S_OUT;
end if;
when S_2=>
if(temperature>"00101101") then
cooler_NEXT_STATE<=S_3;
elsif(temperature<"00100011") then
cooler_NEXT_STATE<=S_1;
end if;
when S_3=>
if(temperature<"00101000") then
cooler_NEXT_STATE<=S_2;
end if;
end case;
when S3 =>
if(temperature>"00011110" ) then
NEXT_STATE<=S1;
end if;
--cooler_NEXT_STATE<=S_OUT;
end case;
end process CMB;
-- with STATE select
-- heater<= '0' when S1|S2,
-- '1' when S3;
-- cooler<= '0' when S1|S3,
-- '1' when S2;
-- label if( cooler='1') generate
-- modul: COOLER port map(temprature=>T,CRS=>CRS,clk=>clk,reset=>reset);
--end generate;
OUTPUT : process(STATE,cooler_STATE)
begin
case STATE is
when S1 =>
on_heater<='0';
on_cooler<='0';
when S2 =>
on_cooler<='1';
on_heater<='0';
case cooler_STATE is
when S_OUT =>
CRS<="0000";
when S_1 =>
CRS<="0100";
when S_2 =>
CRS<="0110";
when S_3 =>
CRS<="1000";
when others=>
CRS<="0000";
end case;
when S3 =>
on_heater<='1';
on_cooler<='0';
end case;
end process OUTPUT;
end ARCH;
and here is the testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity incubator_tb is
end entity;
architecture testbench of incubator_tb is
component INCUBATOR2 is
port(temperature: in std_logic_vector(7 downto 0);
CLK,RESET: in std_logic;
on_cooler,on_heater: out std_logic;
CRS:out std_logic_vector(3 downto 0));
end component INCUBATOR2;
signal CLK, reset: std_logic;
signal on_cooler,on_heater:std_logic;
signal temperature:std_logic_vector(7 downto 0);
signal CRS: std_logic_vector(3 downto 0);
begin
modul: INCUBATOR2 port map(
temperature => temperature, clk => clk, reset => reset,
on_cooler => on_cooler,on_heater=>on_heater,CRS=>CRS);
stim: process
begin
temperature <= "00100110";
clk <= '0';
reset <= '1';
wait for 20 ns;
temperature <= "00100110";
clk <= '1';
reset <= '0';
wait for 20 ns;
reset <= '0';
clk <= '0';
temperature <= "00001010";
wait for 20 ns;
reset <= '0';
clk <= '1';
temperature <= "00001010";
wait for 20 ns;
reset <= '0';
clk <= '0';
temperature <= "00100110";
wait for 20 ns;
--clk <= '1';
reset <= '0';
clk <= '1';
temperature <= "00100110";
wait for 20 ns;
reset <= '0';
clk <= '1';
temperature <= "00101010";
wait for 20 ns;
wait;
end process;
end architecture testbench;
as in the picture below shows that the outputs of some inputs are being calculated wrong and on_heater never activates...(it is supposed to switch to 1 when the temperature is a)
can anyone tell me that where am i doing wrong?im so confused any help would be really appreciated.
Upvotes: 0
Views: 606
Reputation: 482
Since you are only supposed to design the right-hand state machine (the cooler), you should concentrate on that separate to the left-hand state machine (the main controller).
Talk to your colleague who's designing the main controller to add an output called enable_cooler
to enable the cooler state machine. The Incubator
entity could include two entities called MainController
and Cooler
.
I've extracted the cooler state machine logic into a separate entity called Cooler
. It's in three processes which keep the outputs synchronised to both the clock and the state:
I've also added some else
clauses to prevent inferred latches, and added some constants to make it more readable and maintainable.
Figure 1 – Cooler state machine
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Cooler is
port
(
clock: in std_logic;
reset: in std_logic;
enable: in std_logic; -- ADDED: From cooler enable signal of modified left-hand state machine.
temperature: in std_logic_vector(7 downto 0); -- I've assumed this is a signed temperature.
crs: out std_logic_vector(3 downto 0)
);
end entity;
architecture V1 of Cooler is
type TState is (S_OUT, S_1, S_2, S_3);
signal state, next_state: TState;
signal next_crs: std_logic_vector(3 downto 0); -- ADDED to ensure the outputs are synchronised to the clock and state.
constant TEMPERATURE_P25: integer := 25; -- ADDED for readability and maintainability.
constant TEMPERATURE_P35: integer := 35;
constant TEMPERATURE_P40: integer := 40;
constant TEMPERATURE_P45: integer := 45;
constant RPS_0: std_logic_vector(3 downto 0) := "0000"; -- ADDED for readability and maintainability.
constant RPS_4: std_logic_vector(3 downto 0) := "0100";
constant RPS_6: std_logic_vector(3 downto 0) := "0110";
constant RPS_8: std_logic_vector(3 downto 0) := "1000";
begin
--
-- State Register and Outputs Register
--
process(clock, reset)
begin
if reset then
state <= S_OUT;
crs <= RPS_0; -- ADDED to specify outputs for reset condition.
elsif rising_edge(clock) then
state <= next_state; -- State is synchronised to clock.
crs <= next_crs; -- Outputs are synchronised to clock and state.
end if;
end process;
--
-- Next State Logic
--
process(enable, state, temperature)
variable i_temperature: integer; -- ADDED for numeric comparisons.
begin
if enable then
i_temperature := to_integer(signed(temperature)); -- I've assumed this is a signed temperature.
case state is
when S_OUT =>
if i_temperature > TEMPERATURE_P35 then
next_state <= S_1;
else
next_state <= S_OUT; -- ADDED to prevent inferred latch.
end if;
when S_1 =>
if i_temperature > TEMPERATURE_P40 then
next_state <= S_2;
elsif i_temperature < TEMPERATURE_P25 then
next_state <= S_OUT;
else
next_state <= S_1; -- ADDED to prevent inferred latch.
end if;
when S_2 =>
if i_temperature > TEMPERATURE_P45 then
next_state <= S_3;
elsif i_temperature < TEMPERATURE_P35 then
next_state <= S_1;
else
next_state <= S_2; -- ADDED to prevent inferred latch.
end if;
when S_3 =>
if i_temperature < TEMPERATURE_P40 then
next_state <= S_2;
else
next_state <= S_3; -- ADDED to prevent inferred latch.
end if;
when others =>
next_state <= S_OUT;
end case;
else
next_state <= S_OUT; -- Prevent inferred latch.
end if;
end process;
--
-- Next Outputs Logic
--
process(next_state)
begin
case next_state is
when S_OUT =>
next_crs <= RPS_0;
when S_1 =>
next_crs <= RPS_4;
when S_2 =>
next_crs <= RPS_6;
when S_3 =>
next_crs <= RPS_8;
when others =>
next_crs <= RPS_0;
end case;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MainController is
port
(
clock: in std_logic;
reset: in std_logic;
temperature: in std_logic_vector(7 downto 0);
on_cooler: out std_logic;
on_heater: out std_logic;
enable_cooler: out std_logic -- ADDED to enable cooler when MainController is in state S2.
);
end entity;
architecture V1 of MainController is
type TState is (S1, S2, S3);
signal state, next_state: TState;
constant TEMPERATURE_P15: integer := 15; -- ADDED for readability and maintainability.
constant TEMPERATURE_P25: integer := 25;
constant TEMPERATURE_P30: integer := 30;
constant TEMPERATURE_P35: integer := 35;
signal next_on_cooler: std_logic; -- ADDED to ensure outputs are synchronised to the clock and state.
signal next_on_heater: std_logic;
begin
--
-- State Register and Outputs Register
--
process(clock, reset)
begin
if reset then
state <= S1;
on_cooler <= '0'; -- ADDED to specify outputs for reset condition.
on_heater <= '0';
elsif rising_edge(clock) then
state <= next_state; -- State is synchronised to the clock.
on_cooler <= next_on_cooler; -- Outputs are synchronised to the clock and state.
on_heater <= next_on_heater;
end if;
end process;
--
-- Next State Logic
--
process(state, temperature)
variable i_temperature: integer; -- ADDED for numeric comparisons.
begin
i_temperature := to_integer(signed(temperature)); -- I've assumed this is a signed temperature.
case STATE is
when S1 =>
if i_temperature > TEMPERATURE_P35 then
next_state <= S2;
elsif i_temperature < TEMPERATURE_P15 then
next_state <= S3;
else
next_state <= S1; -- ADDED to prevent inferred latch.
end if;
when S2 =>
if i_temperature < TEMPERATURE_P25 then
next_state <= S1;
else
next_state <= S2; -- ADDED to prevent inferred latch.
end if;
when S3 =>
if i_temperature > TEMPERATURE_P30 then
next_state <= S1;
else
next_state <= S3; -- ADDED to prevent inferred latch.
end if;
when others =>
next_state <= S1;
end case;
end process;
--
-- Next Outputs Logic
--
process(next_state)
begin
case next_state is
when S1 =>
next_on_cooler <= '0';
next_on_heater <= '0';
enable_cooler <= '0';
when S2 =>
next_on_cooler <= '1';
next_on_heater <= '0';
enable_cooler <= '1'; -- ADDED to enable cooler when MainController is in state S2.
when S3 =>
next_on_cooler <= '0';
next_on_heater <= '1';
enable_cooler <= '0';
when others =>
next_on_cooler <= '0';
next_on_heater <= '0';
enable_cooler <= '0';
end case;
end process;
end architecture;
This connects the two state machines together, i.e. Cooler
and MainController
.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Incubator is
port
(
clock: in std_logic;
reset: in std_logic;
temperature: in std_logic_vector(7 downto 0);
on_cooler: out std_logic;
on_heater: out std_logic;
crs: out std_logic_vector(3 downto 0)
);
end entity;
architecture V1 of Incubator is
signal enable_cooler: std_logic; -- ADDED to enable cooler when MainController is in state S2.
component MainController is
port
(
clock: in std_logic;
reset: in std_logic;
temperature: in std_logic_vector(7 downto 0);
on_cooler: out std_logic;
on_heater: out std_logic;
enable_cooler: out std_logic
);
end component;
component Cooler is
port
(
clock: in std_logic;
reset: in std_logic;
enable: in std_logic; -- ADDED: From cooler enable signal of modified left-hand state machine.
temperature: in std_logic_vector(7 downto 0); -- I've assumed this is a signed temperature.
crs: out std_logic_vector(3 downto 0)
);
end component;
begin
MC: MainController
port map
(
clock => clock,
reset => reset,
temperature => temperature,
on_cooler => on_cooler,
on_heater => on_heater,
enable_cooler => enable_cooler
);
CLR: Cooler
port map
(
clock => clock,
reset => reset,
enable => enable_cooler,
temperature => temperature,
crs => crs
);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Incubator_TB is
end entity;
architecture V1 of Incubator_TB is
constant CLOCK_PERIOD: time := 50 ns;
signal halt_sys_clock: boolean := false;
signal clock: std_logic := '0';
signal reset: std_logic := '0';
signal temperature: std_logic_vector(7 downto 0);
signal on_cooler: std_logic;
signal on_heater: std_logic;
signal crs: std_logic_vector(3 downto 0);
component Incubator is
port
(
clock: in std_logic;
reset: in std_logic;
temperature: in std_logic_vector(7 downto 0);
on_cooler: out std_logic;
on_heater: out std_logic;
crs: out std_logic_vector(3 downto 0)
);
end component;
begin
ClockGenerator:
process
begin
while not halt_sys_clock loop
wait for CLOCK_PERIOD / 2.0;
clock <= not clock;
end loop;
wait;
end process ClockGenerator;
Stimulus:
process
begin
reset <= '0';
temperature <= std_logic_vector(to_unsigned(38, temperature'length));
wait for CLOCK_PERIOD / 4.0;
reset <= '1';
wait for CLOCK_PERIOD;
reset <= '0';
wait for CLOCK_PERIOD * 4;
temperature <= std_logic_vector(to_unsigned(12, temperature'length));
wait for CLOCK_PERIOD * 4;
temperature <= std_logic_vector(to_unsigned(38, temperature'length));
wait for CLOCK_PERIOD * 4;
temperature <= std_logic_vector(to_unsigned(43, temperature'length));
wait for CLOCK_PERIOD * 4;
temperature <= std_logic_vector(to_unsigned(48, temperature'length));
wait for CLOCK_PERIOD * 4;
temperature <= std_logic_vector(to_unsigned(10, temperature'length));
wait for CLOCK_PERIOD * 4;
halt_sys_clock <= true;
wait;
end process;
INC: Incubator
port map
(
clock => clock,
reset => reset,
temperature => temperature,
on_cooler => on_cooler,
on_heater => on_heater,
crs => crs
);
end architecture;
Figure 2 – Simulation of incubator
Figure 4 – Main Controller RTL
Upvotes: 2