]> rtime.felk.cvut.cz Git - fpga/pwm.git/commitdiff
Added vector generator.
authorVladimir Burian <buriavl2@fel.cvut.cz>
Sun, 20 Mar 2011 18:25:31 +0000 (19:25 +0100)
committerVladimir Burian <buriavl2@fel.cvut.cz>
Sun, 20 Mar 2011 18:25:31 +0000 (19:25 +0100)
Reads angle value from shared RAM, then looks up 3-phase wave values from
wave_table.vhd and stores them back in shared RAM.

tb/Makefile
tb/tb_vector_gen.sav [new file with mode: 0644]
tb/tb_vector_gen.vhd [new file with mode: 0644]
vector_gen.vhd [new file with mode: 0644]

index 96978b463c588de17ad7a6b35c2ac7fe422fc427..b77d80407bd13aadb6f6616eec14d4dc0adeced7 100644 (file)
@@ -1,6 +1,8 @@
-VHDL_MAIN     = tb_wave_table
+VHDL_MAIN     = tb_vector_gen
 VHDL_ENTITIES = counter.o \
-                pwm.o
+                pwm.o \
+                wave_table.o \
+                vector_gen.o
 
 STOP_TIME     = 50us
 
diff --git a/tb/tb_vector_gen.sav b/tb/tb_vector_gen.sav
new file mode 100644 (file)
index 0000000..cf397d5
--- /dev/null
@@ -0,0 +1,46 @@
+[timestart] 0
+[size] 1280 746
+[pos] -1 -1
+*-33.443600 -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
+rst_i
+stb_i
+ack_o
+@22
+lut_adr_o[8:0]
+@28
+lut_stb_o
+uut.irf_cyc_o
+uut.irf_stb_o
+uut.irf_we_o
+@22
+uut.irf_adr_o[4:0]
+irf_dat_i[15:0]
+irf_dat_o[15:0]
+uut.angle_in[8:0]
+dbg_mem0[15:0]
+@8022
+dbg_mem0[15:0]
+@20000
+-
+@22
+dbg_mem1[15:0]
+@8022
+dbg_mem1[15:0]
+@20000
+-
+@22
+dbg_mem2[15:0]
+@8022
+dbg_mem2[15:0]
+@20000
+-
+@22
+dbg_mem3[15:0]
+@8022
+dbg_mem3[15:0]
+@20000
+-
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/tb/tb_vector_gen.vhd b/tb/tb_vector_gen.vhd
new file mode 100644 (file)
index 0000000..2de9ee0
--- /dev/null
@@ -0,0 +1,211 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+entity tb_vector_gen is
+end tb_vector_gen;
+
+--------------------------------------------------------------------------------
+
+architecture testbench of tb_vector_gen is
+
+  constant period : time := 5 ns;
+  constant offset : time := 0 us;
+
+  constant LUT_DAT_W     : integer := 10;
+  constant LUT_ADR_W     : integer := 9;
+  constant LUT_INIT_FILE : string  := "../sin.lut";
+  constant IRF_ADR_W     : integer := 5;
+
+  constant WAVE_SIZE : integer := 2**LUT_ADR_W;
+  
+
+  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_CYC_O : std_logic;
+  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 LUT_ADR_O : std_logic_vector (LUT_ADR_W-1 downto 0);
+  signal LUT_DAT_I : std_logic_vector (LUT_DAT_W-1 downto 0);
+  signal LUT_STB_O : std_logic;
+
+
+  subtype word_t is std_logic_vector (15 downto 0);
+  
+  signal dbg_mem0 : word_t    := conv_std_logic_vector(1,16);  -- read only by UUT
+  signal dbg_mem1 : word_t    := (others => '0');
+  signal dbg_mem2 : word_t    := (others => '0');
+  signal dbg_mem3 : word_t    := (others => '0');
+  signal dbg_ack  : std_logic := '0';
+
+--------------------------------------------------------------------------------
+
+  component vector_gen is
+    port (
+      ACK_O     : out std_logic;
+      CLK_I     : in  std_logic;
+      RST_I     : in  std_logic;
+      STB_I     : in  std_logic;
+      IRF_ACK_I : in  std_logic;
+      IRF_ADR_O : out std_logic_vector (IRF_ADR_W-1 downto 0);
+      IRF_CYC_O : out std_logic;
+      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;
+      LUT_ADR_O : out std_logic_vector (LUT_ADR_W-1 downto 0);
+      LUT_DAT_I : in  std_logic_vector (LUT_DAT_W-1 downto 0);
+      LUT_STB_O : out std_logic);
+  end component vector_gen;
+  
+  component wave_table is
+    generic (
+      DAT_W     : integer;
+      ADR_W     : integer;
+      INIT_FILE : string);
+    port (
+      ACK_O : out std_logic;
+      ADR_I : in  std_logic_vector (ADR_W-1 downto 0);
+      CLK_I : in  std_logic;
+      DAT_I : in  std_logic_vector (DAT_W-1 downto 0);
+      DAT_O : out std_logic_vector (DAT_W-1 downto 0);
+      STB_I : in  std_logic;
+      WE_I  : in  std_logic);
+  end component wave_table;
+  
+  component test_mem is
+    generic (
+      DAT_W : integer;
+      ADR_W : integer);
+    port (
+      ACK_O : out std_logic;
+      ADR_I : in  std_logic_vector (ADR_W-1 downto 0);
+      CLK_I : in  std_logic;
+      DAT_I : in  std_logic_vector (DAT_W-1 downto 0);
+      DAT_O : out std_logic_vector (DAT_W-1 downto 0);
+      STB_I : in  std_logic;
+      WE_I  : in  std_logic);
+  end component test_mem;
+
+
+  
+--------------------------------------------------------------------------------
+  
+begin
+  
+  uut : vector_gen
+    port map (
+      ACK_O     => ACK_O,
+      CLK_I     => CLK_I,
+      RST_I     => RST_I,
+      STB_I     => STB_I,
+      IRF_ACK_I => IRF_ACK_I,
+      IRF_ADR_O => IRF_ADR_O,
+      IRF_CYC_O => open,
+      IRF_DAT_I => IRF_DAT_I,
+      IRF_DAT_O => IRF_DAT_O,
+      IRF_STB_O => IRF_STB_O,
+      IRF_WE_O  => IRF_WE_O,
+      LUT_ADR_O => LUT_ADR_O,
+      LUT_DAT_I => LUT_DAT_I,
+      LUT_STB_O => LUT_STB_O);
+
+  wave_table_1 : wave_table
+    generic map (
+      DAT_W     => LUT_DAT_W,
+      ADR_W     => LUT_ADR_W,
+      INIT_FILE => LUT_INIT_FILE)
+    port map (
+      ACK_O => open,
+      ADR_I => LUT_ADR_O,
+      CLK_I => CLK_I,
+      DAT_I => (others => '0'),
+      DAT_O => LUT_DAT_I,
+      STB_I => LUT_STB_O,
+      WE_I  => '0');
+
+  
+  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 0 => IRF_DAT_I <= dbg_mem0;
+          when 1 => IRF_DAT_I <= dbg_mem1;
+          when 2 => IRF_DAT_I <= dbg_mem2;
+          when 3 => IRF_DAT_I <= dbg_mem3;
+          when others => IRF_DAT_I <= (others => '0');
+        end case;
+      else
+        case conv_integer(IRF_ADR_O) is
+          when 1 => dbg_mem1 <= IRF_DAT_O;
+          when 2 => dbg_mem2 <= IRF_DAT_O;
+          when 3 => dbg_mem3 <= IRF_DAT_O;
+          when others => null;
+        end case;
+      end if;
+    end if;
+  end process;
+  
+--------------------------------------------------------------------------------
+
+  UUT_FEED : process is
+  begin
+    STB_I <= '0';
+        
+    wait for offset;
+    wait for 4*period;
+
+    for i in 0 to WAVE_SIZE loop
+      dbg_mem0 <= (others => '0');
+      dbg_mem0(LUT_ADR_O'RANGE) <= conv_std_logic_vector(i, LUT_ADR_W);
+      
+      STB_I <= '1';
+      wait until rising_edge(CLK_I) and ACK_O = '1';
+      STB_I <= '0';
+      wait for 4*period;
+    end loop;
+    
+    wait;
+  end process;
+  
+end testbench;
+
diff --git a/vector_gen.vhd b/vector_gen.vhd
new file mode 100644 (file)
index 0000000..f32890b
--- /dev/null
@@ -0,0 +1,126 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+
+--------------------------------------------------------------------------------
+
+entity vector_gen is
+  generic (
+    LUT_DAT_W  : integer := 10;
+    LUT_ADR_W  : integer := 9;
+    LUT_P1_OFF : integer := 0;
+    LUT_P2_OFF : integer := 171;
+    LUT_P3_OFF : integer := 341;
+    IRF_ADR_W  : integer := 5;
+    A_BASE     : integer := 0;
+    P_BASE     : integer := 1;
+    P1_OFF     : integer := 0;
+    P2_OFF     : integer := 1;
+    P3_OFF     : integer := 2);
+  port (
+    -- Primary slave interface
+    ACK_O     : out std_logic;
+    CLK_I     : in  std_logic;
+    RST_I     : in  std_logic;
+    STB_I     : in  std_logic;
+    -- Master interface to the interface memory
+    IRF_ACK_I : in  std_logic;
+    IRF_ADR_O : out std_logic_vector (IRF_ADR_W-1 downto 0);
+    IRF_CYC_O : out std_logic;
+    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;
+    -- Master interface to the wave look-up-table
+    LUT_ADR_O : out std_logic_vector (LUT_ADR_W-1 downto 0);
+    LUT_DAT_I : in  std_logic_vector (LUT_DAT_W-1 downto 0);
+    LUT_STB_O : out std_logic);
+end entity vector_gen;
+
+--------------------------------------------------------------------------------
+
+architecture behavioral of vector_gen is
+
+  type state_t is (ready, angle, phase1, phase2, phase3, done);
+  subtype irf_adr_t is std_logic_vector (IRF_ADR_W-1 downto 0);
+  subtype lut_adr_t is std_logic_vector (LUT_ADR_W-1 downto 0);
+
+  constant A_ADR  : irf_adr_t := conv_std_logic_vector(A_BASE, IRF_ADR_W);
+  constant P1_ADR : irf_adr_t := conv_std_logic_vector(P_BASE+P1_OFF, IRF_ADR_W);
+  constant P2_ADR : irf_adr_t := conv_std_logic_vector(P_BASE+P2_OFF, IRF_ADR_W);
+  constant P3_ADR : irf_adr_t := conv_std_logic_vector(P_BASE+P3_OFF, IRF_ADR_W);
+
+  signal state     : state_t;
+  signal angle_in  : lut_adr_t;
+  signal ack_latch : std_logic;
+
+--------------------------------------------------------------------------------
+  
+begin
+
+  IRF_DAT_O (IRF_DAT_O'HIGH downto LUT_DAT_I'HIGH+1) <= (others => '0');
+  IRF_DAT_O (LUT_DAT_I'RANGE) <= LUT_DAT_I;
+  
+  ACK_O <= ack_latch and STB_I;
+
+  
+  FSM : process (CLK_I) is
+  begin
+    if rising_edge(CLK_I) then
+      if RST_I = '1' or STB_I = '0' then
+        state     <= ready;
+        ack_latch <= '0';
+        IRF_CYC_O <= '0';
+        IRF_STB_O <= '0';
+        IRF_WE_O  <= '0';
+        LUT_STB_O <= '0';
+
+      else
+        case state is
+          when ready =>
+            if STB_I = '1' then
+              state     <= angle;
+              IRF_ADR_O <= A_ADR;
+              IRF_CYC_O <= '1';
+              IRF_STB_O <= '1';
+            end if;
+
+          when angle =>
+            if IRF_ACK_I = '1' then
+              state     <= phase1;
+              angle_in  <= IRF_DAT_I(angle_in'RANGE);
+              LUT_ADR_O <= IRF_DAT_I(angle_in'RANGE) + LUT_P1_OFF;
+              LUT_STB_O <= '1';
+            end if;
+            
+          when phase1 =>
+            state     <= phase2;
+            IRF_ADR_O <= P1_ADR;
+            IRF_WE_O  <= '1';
+            LUT_ADR_O <= angle_in + LUT_P2_OFF;
+            
+          when phase2 =>
+            state     <= phase3;
+            IRF_ADR_O <= P2_ADR;
+            LUT_ADR_O <= angle_in + LUT_P3_OFF;
+
+          when phase3 =>
+            state     <= done;
+            IRF_ADR_O <= P3_ADR;
+
+            
+          when done =>
+            ack_latch <= '1';
+            IRF_CYC_O <= '0';
+            IRF_STB_O <= '0';
+            IRF_WE_O  <= '0';
+            LUT_STB_O <= '0';
+        end case;
+
+      end if;
+    end if;
+  end process;
+
+end architecture behavioral;
+