]> rtime.felk.cvut.cz Git - fpga/pwm.git/commitdiff
Added pwm_min_dump - modified sin wave
authorVladimir Burian <buriavl2@fel.cvut.cz>
Wed, 18 May 2011 22:06:50 +0000 (00:06 +0200)
committerVladimir Burian <buriavl2@fel.cvut.cz>
Wed, 18 May 2011 22:06:50 +0000 (00:06 +0200)
This component dump pwm values relative to minimal pwm value stored
in memory. In conjunction with pwm_min component can serve as modified
sin wave generator.

pwm_min_dump.vhd [new file with mode: 0644]
tb/Makefile
tb/tb_pwm_min_dump.sav [new file with mode: 0644]
tb/tb_pwm_min_dump.vhd [new file with mode: 0644]

diff --git a/pwm_min_dump.vhd b/pwm_min_dump.vhd
new file mode 100644 (file)
index 0000000..a252f10
--- /dev/null
@@ -0,0 +1,98 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+--------------------------------------------------------------------------------
+
+entity pwm_min_dump is
+  generic (
+    IRF_ADR_W  : integer := 5;
+    BASE       : integer := 0;
+    PWMMIN_OFF : integer := 6;
+    P_BASE     : integer := 16;
+    PWM_OFF    : integer := 1;
+    PWM_W      : integer := 10);
+  port (
+    -- Primary slave intefrace
+    ACK_O     : out std_logic;
+    CLK_I     : in  std_logic;
+    RST_I     : in  std_logic;
+    STB_I     : in  std_logic;
+    -- PWM interface
+    PWM_DAT_O : out std_logic_vector (PWM_W-1 downto 0);
+    PWM_STB_O : out std_logic := '0';
+    -- 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_STB_O : out std_logic);
+end entity pwm_min_dump;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of pwm_min_dump is
+
+  type state_t is (ready, dump, done);
+  subtype irf_adr_t is std_logic_vector (IRF_ADR_W-1 downto 0);
+
+  constant PWMMIN_ADR : irf_adr_t := conv_std_logic_vector(BASE+PWMMIN_OFF, IRF_ADR_W);
+  constant PWM_ADR    : irf_adr_t := conv_std_logic_vector(P_BASE + PWM_OFF, IRF_ADR_W);
+  
+  signal state : state_t := ready;
+
+  signal ack     : std_logic := '0';
+  --signal pwm_min : std_logic_vector (PWM_DAT_O'RANGE);
+  signal pwm_min : std_logic_vector (PWM_DAT_O'range);
+  signal pwm_stb : std_logic := '0';
+  signal irf_adr : irf_adr_t := PWMMIN_ADR;
+  signal irf_we  : std_logic := '0';
+  
+--------------------------------------------------------------------------------
+
+begin
+
+  ACK_O <= STB_I and ack;
+
+  PWM_DAT_O <= IRF_DAT_I(pwm_min'RANGE) - pwm_min;
+  PWM_STB_O <= pwm_stb;
+  
+  IRF_ADR_O <= irf_adr;
+  IRF_STB_O <= STB_I;
+
+  
+  FSM : process (CLK_I, RST_I) is
+  begin
+    if RST_I = '1' then
+      state   <= ready;
+      ack     <= '0';
+      irf_adr <= PWMMIN_ADR;
+      pwm_stb <= '0';
+      
+    elsif rising_edge(CLK_I) then
+      case state is
+        when ready =>
+          if STB_I = '1' then
+            state   <= dump;
+            irf_adr <= PWM_ADR;
+          end if;
+          
+        when dump =>
+          state   <= done;
+          ack     <= '1';
+          pwm_stb <= '1';
+          pwm_min <= IRF_DAT_I(pwm_min'RANGE);
+
+        when done =>
+          pwm_stb <= '0';
+          if STB_I = '0' then
+            state   <= ready;
+            ack     <= '0';
+            irf_adr <= PWMMIN_ADR;
+          end if;
+      end case;
+    end if;
+  end process;
+  
+end architecture behavioral;
+
index 99cabe9bae82022c961696e12b73b15c4e356dcf..c32d165bf57c9ead11486f1947bdad8be9a08106 100644 (file)
@@ -2,7 +2,7 @@
 # bottom to up order (e.g. the top entity is the last in this list). Otherwise
 # it won't compile.
 
-VHDL_MAIN     = tb_pwm_min
+VHDL_MAIN     = tb_pwm_min_dump
 VHDL_ENTITIES = counter.o \
                 pwm.o \
                 wave_table.o \
@@ -16,6 +16,7 @@ VHDL_ENTITIES = counter.o \
                 irc_dump.o \
                 irc_base.o \
                 pwm_min.o \
+                pwm_min_dump.o \
                 mcc.o
 
 
diff --git a/tb/tb_pwm_min_dump.sav b/tb/tb_pwm_min_dump.sav
new file mode 100644 (file)
index 0000000..2f457ec
--- /dev/null
@@ -0,0 +1,27 @@
+[timestart] 0
+[size] 1280 769
+[pos] -1 -1
+*-33.327084 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+@28
+clk_i
+stb_i
+ack_o
+@24
+dbg_mem0x06[15:0]
+dbg_mem0x11[15:0]
+uut.pwm_min[9:0]
+@200
+-
+@24
+pwm_dat_o[9:0]
+@28
+pwm_stb_o
+@200
+-
+@22
+uut.irf_dat_i[15:0]
+uut.irf_adr_o[4:0]
+@28
+uut.irf_stb_o
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/tb/tb_pwm_min_dump.vhd b/tb/tb_pwm_min_dump.vhd
new file mode 100644 (file)
index 0000000..5e64983
--- /dev/null
@@ -0,0 +1,146 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+entity tb_pwm_min_dump is
+end tb_pwm_min_dump;
+
+--------------------------------------------------------------------------------
+
+architecture testbench of tb_pwm_min_dump is
+
+  constant period : time := 1 us;
+  constant offset : time := 0 us;
+
+  constant IRF_ADR_W : integer := 5;
+  
+
+  signal ACK_O : std_logic;
+  signal CLK_I : std_logic;
+  signal RST_I : std_logic;
+  signal STB_I : std_logic;
+
+  signal IRF_ACK_I : std_logic;
+  signal IRF_ADR_O : std_logic_vector (IRF_ADR_W-1 downto 0);
+  signal IRF_DAT_I : std_logic_vector (15 downto 0);
+  signal IRF_DAT_O : std_logic_vector (15 downto 0);
+  signal IRF_STB_O : std_logic;
+  signal IRF_WE_O  : std_logic;
+
+  signal PWM_DAT_O : std_logic_vector (9 downto 0);
+  signal PWM_STB_O : std_logic;
+  
+  subtype word_t is std_logic_vector (15 downto 0);
+
+  signal dbg_ack : std_logic := '0';
+  
+  signal dbg_mem0x06 : word_t := (others => '0');
+  signal dbg_mem0x11 : word_t := (others => '0');
+
+--------------------------------------------------------------------------------
+  
+begin
+
+  uut : entity work.pwm_min_dump
+    generic map (
+      IRF_ADR_W  => IRF_ADR_W,
+      BASE       => 0,
+      PWMMIN_OFF => 16#06#,
+      P_BASE     => 16#10#,
+      PWM_OFF    => 1,
+      PWM_W      => 10)
+    port map (
+      ACK_O     => ACK_O,
+      CLK_I     => CLK_I,
+      RST_I     => RST_I,
+      STB_I     => STB_I,
+      PWM_DAT_O => PWM_DAT_O,
+      PWM_STB_O => PWM_STB_O,
+      IRF_ACK_I => IRF_ACK_I,
+      IRF_ADR_O => IRF_ADR_O,
+      IRF_DAT_I => IRF_DAT_I,
+      IRF_STB_O => IRF_STB_O);
+  
+  
+  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;
+
+  
+  DBG_MEM : process (IRF_STB_O, CLK_I) is
+  begin
+    IRF_ACK_I <= IRF_STB_O and (IRF_WE_O or dbg_ack);
+
+    if rising_edge(CLK_I) then
+      dbg_ack <= IRF_STB_O;
+    end if;
+
+    if rising_edge(CLK_I) and IRF_STB_O = '1' then
+      if IRF_WE_O = '0' then
+        case conv_integer(IRF_ADR_O) is
+          when 16#06# => IRF_DAT_I <= dbg_mem0x06;
+          when 16#11# => IRF_DAT_I <= dbg_mem0x11;
+          when others =>
+            IRF_DAT_I <= (others => 'X');
+            report "Reading from non-readable register" severity warning;
+        end case;
+      else
+        case conv_integer(IRF_ADR_O) is
+          when others =>
+            report "Writing to read-only registers" severity error;
+        end case;
+      end if;
+    end if;
+  end process;
+  
+--------------------------------------------------------------------------------
+
+  UUT_FEED : process is
+  begin
+    IRF_DAT_O <= (others => '0');
+    IRF_WE_O  <= '0';
+    STB_I     <= '0';
+    
+    wait for offset;
+    wait for 4*period;
+
+    for i in 0 to 0 loop
+      dbg_mem0x06 <= conv_std_logic_vector(10, 16);
+      dbg_mem0x11 <= conv_std_logic_vector(45, 16);
+      
+      wait for 0.75*period;
+      STB_I <= '1';
+      wait for 0.25*period;
+      wait until rising_edge(CLK_I) and ACK_O = '1';
+      wait for 0.25*period;
+      STB_I <= '0';
+      wait for 0.75*period;
+
+      wait for 4*period;
+    end loop;
+    
+    wait;
+  end process;
+  
+end testbench;
+