]> rtime.felk.cvut.cz Git - fpga/pwm.git/blobdiff - pwm_min.vhd
Added pwm_min component.
[fpga/pwm.git] / pwm_min.vhd
diff --git a/pwm_min.vhd b/pwm_min.vhd
new file mode 100644 (file)
index 0000000..df0b248
--- /dev/null
@@ -0,0 +1,134 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+--------------------------------------------------------------------------------
+
+entity pwm_min is
+  generic (
+    IRF_ADR_W  : integer := 5;
+    PWM_W      : integer := 10;
+    BASE       : integer := 0;
+    PWMMIN_OFF : integer := 6;
+    P_BASE     : integer := 16;
+    P_SIZE     : integer := 4;
+    PWM_OFF    : integer := 1);
+  port (
+    -- Primary Slave interface
+    ACK_O     : out std_logic;
+    CLK_I     : in  std_logic;
+    RST_I     : in  std_logic;
+    STB_I     : in  std_logic;
+    -- Shared dual-port memory
+    IRF_ACK_I : in  std_logic;
+    IRF_ADR_O : out std_logic_vector (IRF_ADR_W-1 downto 0);
+    IRF_DAT_I : in  std_logic_vector (15 downto 0);
+    IRF_DAT_O : out std_logic_vector (15 downto 0);
+    IRF_STB_O : out std_logic;
+    IRF_WE_O  : out std_logic);
+end pwm_min;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of pwm_min 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 PWMMIN : irf_adr_t := conv_std_logic_vector(BASE+PWMMIN_OFF, IRF_ADR_W);
+  constant PWM1   : irf_adr_t := conv_std_logic_vector(P_BASE+PWM_OFF+0*P_SIZE, IRF_ADR_W);
+  constant PWM2   : irf_adr_t := conv_std_logic_vector(P_BASE+PWM_OFF+1*P_SIZE, IRF_ADR_W);
+  constant PWM3   : irf_adr_t := conv_std_logic_vector(P_BASE+PWM_OFF+2*P_SIZE, IRF_ADR_W);
+
+  signal state : state_t := ready;
+
+  signal pwm_adr     : std_logic_vector (IRF_ADR_W-1 downto 0);
+  --signal pwm_compare : std_logic_vector (PWM_W-1 downto 0);
+  signal pwm_compare : std_logic_vector (PWM_W-1 downto 0);
+  signal pwm_less    : std_logic;
+  signal write_min   : std_logic;
+  
+  signal ack     : std_logic := '0';
+  signal irf_stb : std_logic := '0';
+  signal irf_we  : std_logic;
+
+--------------------------------------------------------------------------------
+  
+begin
+
+  ACK_O     <= ack and STB_I;
+
+  IRF_ADR_O <= PWMMIN when write_min = '1' else pwm_adr;
+  IRF_DAT_O <= IRF_DAT_I;
+  IRF_STB_O <= irf_stb and (not write_min or irf_we);
+  IRF_WE_O  <= irf_we;
+
+  pwm_less <= '1' when IRF_DAT_I(pwm_compare'RANGE) < pwm_compare else '0';
+  irf_we <= '1' when (pwm_less = '1' or state = phase1) and write_min = '1' else '0';
+  
+  process (CLK_I) is
+  begin
+    if rising_edge(CLK_I) then
+      if irf_we = '1' then
+        pwm_compare <= IRF_DAT_I(pwm_compare'RANGE);
+      end if;
+    end if;
+  end process;
+  
+  
+  FSM : process (CLK_I) is
+  begin
+    if rising_edge(CLK_I) then
+      if RST_I = '1' then
+        state   <= ready;
+        ack     <= '0';
+        irf_stb <= '0';
+        
+      else
+        case state is
+          when ready =>
+            if STB_I = '1' then
+              state     <= phase1;
+              pwm_adr   <= PWM1;
+              irf_stb   <= '1';
+              write_min <= '0';
+            end if;
+
+          when phase1 =>
+            write_min <= '1';
+            if write_min = '1' then
+              state     <= phase2;
+              pwm_adr   <= PWM2;
+              write_min <= '0';
+            end if;
+
+          when phase2 =>
+            write_min <= '1';
+            if write_min = '1' then
+              state     <= phase3;
+              pwm_adr   <= PWM3;
+              write_min <= '0';
+            end if;
+
+          when phase3 =>
+            write_min <= '1';
+            if write_min = '1' then
+              state     <= done;
+              ack       <= '1';
+              irf_stb   <= '0';
+              write_min <= '0';
+            end if;
+
+          when done =>
+            if STB_I = '0' then
+              state <= ready;
+              ack   <= '0';
+            end if;
+        end case;
+        
+      end if;
+    end if;
+  end process;
+
+end behavioral;