]> rtime.felk.cvut.cz Git - fpga/pwm.git/commitdiff
Added sequencer.
authorVladimir Burian <buriavl2@fel.cvut.cz>
Thu, 24 Mar 2011 10:56:02 +0000 (11:56 +0100)
committerVladimir Burian <buriavl2@fel.cvut.cz>
Thu, 24 Mar 2011 10:56:02 +0000 (11:56 +0100)
This entity controls execution of a slave component for each phase.

sequencer.vhd [new file with mode: 0644]

diff --git a/sequencer.vhd b/sequencer.vhd
new file mode 100644 (file)
index 0000000..74733f8
--- /dev/null
@@ -0,0 +1,107 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+--------------------------------------------------------------------------------
+
+entity sequencer is
+  generic (
+    IRF_ADR_W : integer := 5;
+    P_BASE    : integer := 16;
+    P_SIZE    : integer := 4);
+  port (
+    -- Primary slave interface
+    ACK_O        : out std_logic;
+    CLK_I        : in  std_logic;
+    RST_I        : in  std_logic;
+    STB_I        : in  std_logic;
+    -- Dual-port memory interface
+    IRF_ADR_O    : out std_logic_vector (IRF_ADR_W-1 downto 0);
+    -- Slave interface
+    SL_ACK_I     : in  std_logic;
+    SL_IRF_ADR_I : in  std_logic_vector (IRF_ADR_W-1 downto 0);
+    SL_STB_O     : out std_logic;
+    SL_MUX_CODE  : out std_logic_vector (1 downto 0));
+end entity sequencer;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of sequencer is
+
+  type state_t is (ready, phase1, phase2, phase3, done);
+  subtype irf_adr_t is std_logic_vector (IRF_ADR_W-1 downto 0);
+
+  constant P1_MASK: irf_adr_t := conv_std_logic_vector(P_BASE+0*P_SIZE, IRF_ADR_W);
+  constant P2_MASK: irf_adr_t := conv_std_logic_vector(P_BASE+1*P_SIZE, IRF_ADR_W);
+  constant P3_MASK: irf_adr_t := conv_std_logic_vector(P_BASE+2*P_SIZE, IRF_ADR_W);
+
+  signal state     : state_t;
+
+  signal INNER_ACK : std_logic;
+
+--------------------------------------------------------------------------------
+
+begin
+
+  ACK_O <= STB_I and INNER_ACK;
+
+  IRF_ADR_O <= SL_IRF_ADR_I when conv_integer(SL_IRF_ADR_I) < P_BASE else
+               SL_IRF_ADR_I or P1_MASK when state = phase1 else
+               SL_IRF_ADR_I or P2_MASK when state = phase2 else
+               SL_IRF_ADR_I or P3_MASK when state = phase3 else
+               (others => '-');
+
+  SL_MUX_CODE <= "00" when state = phase1 else
+                 "01" when state = phase2 else
+                 "10" when state = phase3 else
+                 "--";
+
+
+  FSM : process (CLK_I, RST_I) is
+  begin
+    if RST_I = '1' then
+      state     <= ready;
+      INNER_ACK <= '0';
+      SL_STB_O  <= '0';
+
+    elsif rising_edge(CLK_I) then
+      case state is
+        when ready =>
+          if STB_I = '1' then
+            state    <= phase1;
+            SL_STB_O <= '1';
+          end if;
+
+        when phase1 =>
+          if SL_ACK_I = '1' then
+            state    <= phase2;
+            SL_STB_O <= '0';
+          end if;
+          
+        when phase2 =>
+          SL_STB_O <= '1';
+          if SL_ACK_I = '1' then
+            state    <= phase3;
+            SL_STB_O <= '0';
+          end if;
+
+        when phase3 =>
+          SL_STB_O <= '1';
+          if SL_ACK_I = '1' then
+            state     <= done;
+            INNER_ACK <= '1';
+            SL_STB_O  <= '0';
+          end if;
+
+        when done =>
+          if STB_I = '0' then
+            state     <= ready;
+            INNER_ACK <= '0';
+          end if;
+      end case;
+    end if;
+  end process;
+
+end architecture behavioral;
+