]> rtime.felk.cvut.cz Git - fpga/pwm.git/commitdiff
MCC_EXEC entity support for multiple axes control.
authorVladimir Burian <buriavl2@fel.cvut.cz>
Fri, 27 May 2011 05:43:28 +0000 (07:43 +0200)
committerVladimir Burian <buriavl2@fel.cvut.cz>
Fri, 27 May 2011 05:43:28 +0000 (07:43 +0200)
mcc_exec.vhd
tb/Makefile
tb/tb_mcc_exec.sav [new file with mode: 0644]
tb/tb_mcc_exec.vhd [new file with mode: 0644]

index 8c39167e067c78a73390223ce9a0f5447f1f2ae4..e26702384b877c15125899e9759080e55623f112 100644 (file)
@@ -6,44 +6,90 @@ use ieee.std_logic_unsigned.all;
 --------------------------------------------------------------------------------
 
 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;
-
index c32d165bf57c9ead11486f1947bdad8be9a08106..a2e1354519f50b05f03ddfa8ffd5c44abfc1df58 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_dump
+VHDL_MAIN     = tb_mcc_exec
 VHDL_ENTITIES = counter.o \
                 pwm.o \
                 wave_table.o \
@@ -17,6 +17,7 @@ VHDL_ENTITIES = counter.o \
                 irc_base.o \
                 pwm_min.o \
                 pwm_min_dump.o \
+                mcc_exec.o \
                 mcc.o
 
 
diff --git a/tb/tb_mcc_exec.sav b/tb/tb_mcc_exec.sav
new file mode 100644 (file)
index 0000000..b7d715b
--- /dev/null
@@ -0,0 +1,20 @@
+[timestart] 0
+[size] 1280 769
+[pos] -1 -169
+*-32.377708 -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
+mcc_exec_i
+mcc_done_o
+mcc_err_o
+@200
+-
+@28
+mcc_stb_o
+mcc_ack_i
+@200
+-
+@29
+mcc_axis_o[1:0]
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/tb/tb_mcc_exec.vhd b/tb/tb_mcc_exec.vhd
new file mode 100644 (file)
index 0000000..89bdb81
--- /dev/null
@@ -0,0 +1,106 @@
+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;
+