library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use work.CALC1_PAK.all;
entity CNTRL_FSM is
port ( DATA_FRAME : in MY_RECORD;
CLK : in std_logic;
RESET : in std_logic;
A_IN : out std_logic_vector(3 downto 0);
B_IN : out std_logic_vector(3 downto 0);
C_IN : out std_logic;
OP_CODE : out std_logic_vector(3 downto 0);
EXP : out std_logic_vector(3 downto 0);
ADDR : out std_logic_vector ( 2 downto 0);
COMP_EN : out std_logic;
MEM_EN : out std_logic;
ALU_EN : out std_logic );
end entity CNTRL_FSM;
architecture RTL of CNTRL_FSM is
type CNTRL_STATE is ( S0_INIT, S1_FETCH, S2_ALU, S3_COMP, S4_DONE );
signal CURR_STATE, NEXT_STATE : CNTRL_STATE;
signal ADDR_I, ADDR_Q : std_logic_vector ( 2 downto 0 ) := ( others => ‘0’ );
begin
ADDR <= ADDR_Q; -- used to update output port from synchronous internal signal
SYNC : process ( CLK, RESET )
begin
if ( RESET = '1' ) then
CURR_STATE <= S0_INIT;
ADDR_Q <= ( others => '0' );
elsif rising_edge (CLK) then
CURR_STATE <= NEXT_STATE;
ADDR_Q <= ADDR_I; -- update ADDR_Q with the current value of ADDR_I
end if;
end process SYNC;
COMB : process ( CURR_STATE, DATA_FRAME, ADDR_Q )
begin
--default assignments
A_IN <= DATA_FRAME.A_IN;
B_IN <= DATA_FRAME.B_IN;
C_IN <= DATA_FRAME.C_IN;
OP_CODE <= DATA_FRAME.OP_CODE;
EXP <= DATA_FRAME.EXP;
ADDR_I <= ADDR_Q; -- use the registered ADDR_Q to keep ADDR fully synchronous
case CURR_STATE is
when S0_INIT =>
MEM_EN <= '0';
ALU_EN <= '0';
COMP_EN <= '0';
NEXT_STATE <= S1_FETCH;
when S1_FETCH =>
MEM_EN <= '1';
ALU_EN <= '0';
COMP_EN <= '0';
NEXT_STATE <= S2_ALU;
when S2_ALU =>
MEM_EN <= '0';
ALU_EN <= '1';
COMP_EN <= '0';
NEXT_STATE <= S3_COMP;
when S3_COMP =>
MEM_EN <= '0';
ALU_EN <= '0';
COMP_EN <= '1';
NEXT_STATE <= S4_DONE;
when S4_DONE =>
if ADDR_Q = "111" then
NEXT_STATE <= S4_DONE;
else
NEXT_STATE <= S1_FETCH ;
ADDR_I <= ADDR_Q + 1;
end if;
MEM_EN <= '0' ;
ALU_EN <= '0';
COMP_EN <= '0';
when others =>
NEXT_STATE <= S0_INIT;
MEM_EN <= '0' ;
ALU_EN <= '0';
COMP_EN <= '0';
end case;
end process COMB;
end RTL;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.CALC1_PAK.all;ENTITY CNTRL_FSM_TB_vhd IS
END CNTRL_FSM_TB_vhd;
ARCHITECTURE behavior OF CNTRL_FSM_TB_vhd IS
COMPONENT CNTRL_FSM
PORT(
DATA_FRAME : IN MY_RECORD;
CLK : IN std_logic;
RESET : IN std_logic;
A_OP : OUT std_logic_vector(3 downto 0);
B_OP : OUT std_logic_vector(3 downto 0);
C_IN : OUT std_logic;
OP_CODE : OUT std_logic_vector(3 downto 0);
EXP : OUT std_logic_vector(3 downto 0);
MEM_EN : OUT std_logic;
ALU_EN : OUT std_logic ;
COMP_EN : OUT std_logic ;
ADDR : OUT std_logic_vector(2 downto 0) );
END COMPONENT;
SIGNAL DATA_FRAME : MY_RECORD := ("0000", "0000","0000",'0',"0000");
SIGNAL CLK : std_logic := '0';
SIGNAL RESET : std_logic := '0';
SIGNAL A_IN, B_IN : std_logic_vector(3 downto 0);
SIGNAL C_IN : std_logic;
SIGNAL OP_CODE : std_logic_vector(3 downto 0);
SIGNAL EXP : std_logic_vector(3 downto 0);
SIGNAL ALU_EN, MEM_EN, COMP_EN : std_logic;
SIGNAL ADDR : std_logic_vector(2 downto 0);
BEGIN
uut: CNTRL_FSM PORT MAP(
DATA_FRAME => DATA_FRAME,
CLK => CLK,
RESET => RESET,
A_IN => A_IN,
B_IN => B_IN,
C_IN => C_IN,
OP_CODE => OP_CODE,
EXP => EXP,
ALU_EN => ALU_EN, MEM_EN => MEM_EN, COMP_EN => COMP_EN ,
ADDR => ADDR );
CLK <= not CLK after 20 ns;
RESET <= '1' after 10 ns, '0' after 25 ns;
tb : PROCESS
BEGIN
DATA_FRAME <= ("1000", "0100","0000",'0',"0000");
wait for 100 ns;
DATA_FRAME <= ("1000", "0100","0101",'0',"0000");
wait for 100 ns;
DATA_FRAME <= ("1000", "0100","0100",'0',"0000");
wait; -- will wait forever
END PROCESS;
END TEST;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use work.CALC1_PAK.all;
entity CNTRL_FSM is
port ( DATA_FRAME : in MY_RECORD;
CLK : in std_logic;
RESET : in std_logic;
A_IN : out std_logic_vector(3 downto 0);
B_IN : out std_logic_vector(3 downto 0);
C_IN : out std_logic;
OP_CODE : out std_logic_vector(3 downto 0);
EXP : out std_logic_vector(3 downto 0);
ADDR : out std_logic_vector ( 2 downto 0);
COMP_EN : out std_logic;
MEM_EN : out std_logic;
ALU_EN : out std_logic );
end entity CNTRL_FSM;
architecture RTL of CNTRL_FSM is
type CNTRL_STATE is ( S0_INIT, S1_FETCH, S2_ALU, S3_COMP, S4_DONE );
signal CURR_STATE, NEXT_STATE : CNTRL_STATE;
signal ADDR_I, ADDR_Q : std_logic_vector ( 2 downto 0 ) := ( others => ‘0’ );
begin
ADDR <= ADDR_Q; -- used to update output port from synchronous internal signal
SYNC : process ( CLK, RESET )
begin
if ( RESET = '1' ) then
CURR_STATE <= S0_INIT;
ADDR_Q <= ( others => '0' );
elsif rising_edge (CLK) then
CURR_STATE <= NEXT_STATE;
ADDR_Q <= ADDR_I; -- update ADDR_Q with the current value of ADDR_I
end if;
end process SYNC;
COMB : process ( CURR_STATE, DATA_FRAME, ADDR_Q )
begin
--default assignments
A_IN <= DATA_FRAME.A_IN;
B_IN <= DATA_FRAME.B_IN;
C_IN <= DATA_FRAME.C_IN;
OP_CODE <= DATA_FRAME.OP_CODE;
EXP <= DATA_FRAME.EXP;
ADDR_I <= ADDR_Q; -- use the registered ADDR_Q to keep ADDR fully synchronous
case CURR_STATE is
when S0_INIT =>
MEM_EN <= '0';
ALU_EN <= '0';
COMP_EN <= '0';
NEXT_STATE <= S1_FETCH;
when S1_FETCH =>
MEM_EN <= '1';
ALU_EN <= '0';
COMP_EN <= '0';
NEXT_STATE <= S2_ALU;
when S2_ALU =>
MEM_EN <= '0';
ALU_EN <= '1';
COMP_EN <= '0';
NEXT_STATE <= S3_COMP;
when S3_COMP =>
MEM_EN <= '0';
ALU_EN <= '0';
COMP_EN <= '1';
NEXT_STATE <= S4_DONE;
when S4_DONE =>
if ADDR_Q = "111" then
NEXT_STATE <= S4_DONE;
else
NEXT_STATE <= S1_FETCH ;
ADDR_I <= ADDR_Q + 1;
end if;
MEM_EN <= '0' ;
ALU_EN <= '0';
COMP_EN <= '0';
when others =>
NEXT_STATE <= S0_INIT;
MEM_EN <= '0' ;
ALU_EN <= '0';
COMP_EN <= '0';
end case;
end process COMB;
end RTL;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.CALC1_PAK.all;ENTITY CNTRL_FSM_TB_vhd IS
END CNTRL_FSM_TB_vhd;
ARCHITECTURE behavior OF CNTRL_FSM_TB_vhd IS
COMPONENT CNTRL_FSM
PORT(
DATA_FRAME : IN MY_RECORD;
CLK : IN std_logic;
RESET : IN std_logic;
A_OP : OUT std_logic_vector(3 downto 0);
B_OP : OUT std_logic_vector(3 downto 0);
C_IN : OUT std_logic;
OP_CODE : OUT std_logic_vector(3 downto 0);
EXP : OUT std_logic_vector(3 downto 0);
MEM_EN : OUT std_logic;
ALU_EN : OUT std_logic ;
COMP_EN : OUT std_logic ;
ADDR : OUT std_logic_vector(2 downto 0) );
END COMPONENT;
SIGNAL DATA_FRAME : MY_RECORD := ("0000", "0000","0000",'0',"0000");
SIGNAL CLK : std_logic := '0';
SIGNAL RESET : std_logic := '0';
SIGNAL A_IN, B_IN : std_logic_vector(3 downto 0);
SIGNAL C_IN : std_logic;
SIGNAL OP_CODE : std_logic_vector(3 downto 0);
SIGNAL EXP : std_logic_vector(3 downto 0);
SIGNAL ALU_EN, MEM_EN, COMP_EN : std_logic;
SIGNAL ADDR : std_logic_vector(2 downto 0);
BEGIN
uut: CNTRL_FSM PORT MAP(
DATA_FRAME => DATA_FRAME,
CLK => CLK,
RESET => RESET,
A_IN => A_IN,
B_IN => B_IN,
C_IN => C_IN,
OP_CODE => OP_CODE,
EXP => EXP,
ALU_EN => ALU_EN, MEM_EN => MEM_EN, COMP_EN => COMP_EN ,
ADDR => ADDR );
CLK <= not CLK after 20 ns;
RESET <= '1' after 10 ns, '0' after 25 ns;
tb : PROCESS
BEGIN
DATA_FRAME <= ("1000", "0100","0000",'0',"0000");
wait for 100 ns;
DATA_FRAME <= ("1000", "0100","0101",'0',"0000");
wait for 100 ns;
DATA_FRAME <= ("1000", "0100","0100",'0',"0000");
wait; -- will wait forever
END PROCESS;
END TEST;