--------------------------------------------------------------------------------
entity mcc_exec is
+ generic (
+ AXIS_CNT : integer := 1;
+ AXIS_CNT_W : integer := 1);
port (
-- Clock & reset
- CLK_I : in std_logic;
- RST_I : in std_logic;
+ CLK_I : in std_logic;
+ RST_I : in std_logic;
-- MCC execution
- MCC_EN_I : in std_logic;
- MCC_EXEC_I : in std_logic;
- MCC_ERR_O : out std_logic;
+ MCC_AXIS_O : out std_logic_vector (AXIS_CNT_W-1 downto 0);
+ MCC_DONE_O : out std_logic;
+ MCC_EN_I : in std_logic;
+ MCC_EXEC_I : in std_logic;
+ MCC_ERR_O : out std_logic;
-- MCC master interface
- MCC_ACK_I : in std_logic;
- MCC_STB_O : out std_logic);
+ MCC_ACK_I : in std_logic;
+ MCC_STB_O : out std_logic);
end entity mcc_exec;
--------------------------------------------------------------------------------
architecture behavioral of mcc_exec is
- signal mcc_stb : std_logic := '0';
+ type state_t is (ready, do);
+
+ signal state : state_t := ready;
+
+ signal mcc_axis : std_logic_vector (MCC_AXIS_O'range);
+ signal mcc_done : std_logic := '0';
+ signal mcc_stb : std_logic := '0';
--------------------------------------------------------------------------------
begin
- MCC_STB_O <= mcc_stb;
+ assert (AXIS_CNT <= 2**AXIS_CNT_W)
+ report "Insufficient count of bits in MCC_AXIS_O to express axis number."
+ severity error;
+
- MCC_ERR_O <= MCC_EXEC_I and (mcc_stb or MCC_ACK_I);
+ MCC_AXIS_O <= mcc_axis;
+ MCC_DONE_O <= mcc_done;
+ MCC_ERR_O <= '1' when (MCC_EXEC_I = '1' and state = do) else '0';
+
+ MCC_STB_O <= mcc_stb;
- process (CLK_I, RST_I) is
+ FSM : process (CLK_I) is
begin
if rising_edge(CLK_I) then
- if RST_I = '1' or MCC_ACK_I = '1' then
- mcc_stb <= '0';
- elsif MCC_EN_I = '1' and MCC_EXEC_I = '1' then
- mcc_stb <= '1';
+ if RST_I = '1' then
+ state <= ready;
+ mcc_done <= '0';
+ mcc_stb <= '0';
+
+ else
+
+ case state is
+ when ready =>
+ mcc_stb <= '0';
+ mcc_done <= '0';
+
+ if MCC_EXEC_I = '1' and MCC_EN_I = '1' then
+ state <= do;
+ mcc_stb <= '1';
+ mcc_axis <= conv_std_logic_vector(0,AXIS_CNT_W);
+ end if;
+
+ when do =>
+ mcc_stb <= '1';
+
+ if MCC_ACK_I = '1' then
+ mcc_stb <= '0';
+
+ if mcc_axis = (AXIS_CNT-1) then
+ state <= ready;
+ mcc_done <= '1';
+ else
+ mcc_axis <= mcc_axis + 1;
+ end if;
+ end if;
+
+ end case;
end if;
end if;
end process;
end architecture behavioral;
-
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+entity tb_mcc_exec is
+end tb_mcc_exec;
+
+--------------------------------------------------------------------------------
+
+architecture testbench of tb_mcc_exec is
+
+ constant period : time := 500 ns;
+ constant offset : time := 0 us;
+
+ signal CLK_I : std_logic;
+ signal RST_I : std_logic;
+
+
+ signal MCC_AXIS_O : std_logic_vector (1 downto 0);
+ signal MCC_DONE_O : std_logic;
+ signal MCC_EXEC_I : std_logic;
+ signal MCC_ERR_O : std_logic;
+
+ signal MCC_ACK_I : std_logic;
+ signal MCC_STB_O : std_logic;
+
+--------------------------------------------------------------------------------
+
+begin
+
+ uut : entity work.mcc_exec
+ generic map (
+ AXIS_CNT => 3,
+ AXIS_CNT_W => 2)
+ port map (
+ CLK_I => CLK_I,
+ RST_I => RST_I,
+ MCC_AXIS_O => MCC_AXIS_O,
+ MCC_DONE_O => MCC_DONE_O,
+ MCC_EN_I => '1',
+ MCC_EXEC_I => MCC_EXEC_I,
+ MCC_ERR_O => MCC_ERR_O,
+ MCC_ACK_I => MCC_ACK_I,
+ MCC_STB_O => MCC_STB_O);
+
+ MCC_EMULATION : process is
+ begin
+ MCC_ACK_I <= '0';
+ loop
+ wait until MCC_STB_O = '1';
+ wait for 4*period;
+ MCC_ACK_I <= '1';
+ wait until MCC_STB_O <= '0';
+ MCC_ACK_I <= '0';
+ end loop;
+ end process MCC_EMULATION;
+
+
+ SYSCON_CLK : process is
+ begin
+ CLK_I <= '0';
+ wait for offset;
+ loop
+ CLK_I <= '1';
+ wait for period/2;
+ CLK_I <= '0';
+ wait for period/2;
+ end loop;
+ end process;
+
+ SYSCON_RST : process is
+ begin
+ RST_I <= '0';
+ wait for offset;
+ wait for 0.75*period;
+ RST_I <= '1';
+ wait for 2*period;
+ RST_I <= '0';
+ wait;
+ end process;
+
+--------------------------------------------------------------------------------
+
+ UUT_FEED : process is
+ begin
+ MCC_EXEC_I <= '0';
+
+ wait for offset;
+ wait for 4*period;
+
+ for i in 0 to 1 loop
+ wait for 0.25*period;
+ MCC_EXEC_I <= '1';
+ wait for period;
+ MCC_EXEC_I <= '0';
+
+ wait until MCC_DONE_O = '1';
+ wait for 8*period;
+ end loop;
+
+ wait;
+ end process;
+
+end testbench;
+