]> rtime.felk.cvut.cz Git - fpga/virtex2/msp_motion.git/blobdiff - msp_motion.vhd
Submodule PWM and toplevel updated.
[fpga/virtex2/msp_motion.git] / msp_motion.vhd
index fb48d3d6c9f9c260d5a2e7da1116e5ad2631e974..21ac3e6ec0c26a97abaebd88d164d50090960993 100644 (file)
@@ -41,6 +41,8 @@ end msp_motion;
 
 architecture rtl of msp_motion is
 
+  signal reset_p : std_logic;
+
   ------------------------------------------------------------------------------
   -- OpenMSP430 softcore MCU module
   ------------------------------------------------------------------------------
@@ -59,7 +61,25 @@ architecture rtl of msp_motion is
   signal per_wen16 : std_logic;
   signal per_en    : std_logic;
   signal per_addr  : std_logic_vector (7 downto 0);
+  -- Interrupt
+  --signal irq       : std_logic_vector (13 downto 0) := (others => '0');
+  signal irq       : std_logic_vector (13 downto 0);
+  signal irq_acc   : std_logic_vector (13 downto 0);
 
+  ------------------------------------------------------------------------------
+  -- MCU peripherals
+  ------------------------------------------------------------------------------
+  -- GPIO
+  signal GPIO_IN    : std_logic_vector (15 downto 0);
+  signal GPIO_OUT   : std_logic_vector (15 downto 0);
+  signal GPIO_DAT_O : std_logic_vector (15 downto 0);
+  signal GPIO_SEL   : std_logic;
+  -- Qcounter MCU interface
+  signal QCNT_DAT_O : std_logic_vector (15 downto 0);
+  signal QCNT_SEL   : std_logic;
+  -- Motor feedback IRQ generator
+  signal MOTOR_IRQ  : std_logic;
+  
   ------------------------------------------------------------------------------
   -- Dual-port shared memory
   ------------------------------------------------------------------------------
@@ -70,7 +90,7 @@ architecture rtl of msp_motion is
   signal DPA_SEL     : std_logic;
   signal DPA_STB     : std_logic;
   -- Auxiliary register used to generate IRF_ACK
-  signal IRF_ACK_REG : std_logic;
+  signal IRF_ACK_REG : std_logic := '0';
   -- Auxiliary signal used to form B-port address
   signal DPB_ADR     : std_logic_vector (9 downto 0);
 
@@ -125,7 +145,7 @@ begin
     port map (
       dco_clk                  => CLK_24MHz,
       lfxt_clk                 => '0',
-      reset_n                  => RESET,
+      reset_n                  => '1',
       rxd                      => RXD,
       txd                      => TXD,
       per_addr                 => per_addr,
@@ -134,32 +154,109 @@ begin
       per_wen                  => per_wen,
       per_en                   => per_en,
       nmi                      => '0',
-      irq                      => (others => '0'),
-      irq_acc                  => open,
+      irq                      => irq,
+      irq_acc                  => irq_acc,
       aclk_en                  => open,
       smclk_en                 => open,
       mclk                     => mclk,
-      puc                      => puc,
+      puc                      => open,
       dmem_addr                => dmem_addr,
       dmem_ce                  => dmem_ce,
       dmem_we                  => dmem_we,
       dmem_din                 => dmem_din,
       dmem_dout                => dmem_dout);
 
+  puc     <= '0';
+  reset_p <= not RESET;
+
+  STARTUP_VIRTEX2_inst : STARTUP_VIRTEX2
+    port map (
+      CLK => open,
+      -- Clock input for start-up sequence
+      GSR => reset_p, -- Global Set/Reset input (GSR cannot be used for the port name)
+      GTS => open); -- Global 3-state input (GTS cannot be used for the port name)
+
+
   -- External data bus address decoder and data multiplexer.
   ------------------------------------------------------------------------------
-  -- This statement leads to priority encoder (which should be avoided), but for
-  -- a small mux it doesn't matter and it's better readable.
-  dmem_dout <= DPA_DAT_O when DPA_SEL = '1' else
-               (others => 'X');
+  -- When connection more memories, be aware that 'dmem_dout' can vary only when
+  -- reading cycle is performed. I.e. mux variable must be registered.
+  dmem_dout <= DPA_DAT_O;
   
   DPA_SEL <= '1' when dmem_addr (11 downto 10) = "00" else '0';
   DPA_STB <= dmem_ce and DPA_SEL;
 
   -- Peripheral bus address decoder and data multiplexer.
   ------------------------------------------------------------------------------
-  per_dout <= (others => '0');          -- MUST be 0 when nothing is addressed
+  per_dout <= GPIO_DAT_O when GPIO_SEL = '1' else
+              QCNT_DAT_O when QCNT_SEL = '1' else
+              (others => '0');          -- MUST be 0 when nothing is addressed
+  
+  GPIO_SEL <= '1' when per_addr(7 downto 2) = 16#0140#/2/4 else '0';
+  QCNT_SEL <= '1' when per_addr(7 downto 1) = 16#0148#/2/2 else '0';
 
+  -- Interrupt signals
+  ------------------------------------------------------------------------------
+  irq (13 downto 1) <= (others => '0');
+
+  motor_irq_gen : process (mclk, puc) is
+  begin
+    if rising_edge (mclk) then
+      if puc = '1' or irq_acc (0) = '1' then
+        irq (0) <= '0';
+      elsif MOTOR_IRQ = '1' then
+        irq (0) <= '1';
+      end if;
+    end if;
+  end process;
+
+  
+  ------------------------------------------------------------------------------
+  -- MCU peripherals
+  ------------------------------------------------------------------------------
+  GPIO_IN(0) <= HAL0;
+  GPIO_IN(1) <= HAL1;
+  GPIO_IN(2) <= HAL2;
+  GPIO_IN(3) <= IRC_INDEX;
+
+  gpio_0 : entity work.gpio
+    generic map (
+      W => 16)
+    port map (
+      ACK_O  => open,
+      ADR_I  => per_addr (1 downto 0),
+      CLK_I  => mclk,
+      DAT_I  => per_din,
+      DAT_O  => GPIO_DAT_O,
+      RST_I  => puc,
+      SEL_I  => GPIO_SEL,
+      STB_I  => per_en,
+      WE_I   => per_wen16,
+      GPIO_I => GPIO_IN,
+      GPIO_O => GPIO_OUT);
+
+  qcounter_mcu16_0 : entity work.qcounter_mcu16
+    port map (
+      ACK_O  => open,
+      ADR_I  => per_addr (0),
+      CLK_I  => mclk,
+      DAT_O  => QCNT_DAT_O,
+      SEL_I  => QCNT_SEL,
+      STB_I  => per_en,
+      QCOUNT => QCNT);
+
+  -- Motor feedback IRQ generator
+  -- f_motor_irq approx. 1 kHz
+  irq_counter_1 : entity work.counter
+    generic map (
+      WIDTH => 5,
+      MAX   => 22)
+    port map (
+      clk      => mclk,
+      clk_en   => PWM_OW,
+      reset    => puc,
+      count    => open,
+      event_ow => MOTOR_IRQ);
 
 
   ------------------------------------------------------------------------------
@@ -219,9 +316,14 @@ begin
   -- Motion Control Chain
   ------------------------------------------------------------------------------
   mcc_exec_1 : entity work.mcc_exec
+    generic map (
+      AXIS_CNT   => 1,
+      AXIS_CNT_W => 1)
     port map (
       CLK_I      => mclk,
       RST_I      => puc,
+      MCC_AXIS_O => open,
+      MCC_DONE_O => open,
       MCC_EN_I   => '1',
       MCC_EXEC_I => PWM_OW,
       MCC_ERR_O  => open,
@@ -272,7 +374,7 @@ begin
   ------------------------------------------------------------------------------
   -- PWM counter is shared by all PWM generators. Generator contains only
   -- comparator and desired value.
-  counter_1 : entity work.counter
+  pwm_counter : entity work.counter
     generic map (
       WIDTH => PWM_W,
       MAX   => 2**PWM_W - 2)
@@ -290,6 +392,7 @@ begin
       clk     => mclk,
       reset   => puc,
       din     => PWM_DAT,
+      sel     => '1',
       we      => PWM1_STB,
       pwm_cnt => PWM_CNT,
       pwm_cyc => PWM_OW,
@@ -302,6 +405,7 @@ begin
       clk     => mclk,
       reset   => puc,
       din     => PWM_DAT,
+      sel     => '1',
       we      => PWM2_STB,
       pwm_cnt => PWM_CNT,
       pwm_cyc => PWM_OW,
@@ -314,18 +418,20 @@ begin
       clk     => mclk,
       reset   => puc,
       din     => PWM_DAT,
+      sel     => '1',
       we      => PWM3_STB,
       pwm_cnt => PWM_CNT,
       pwm_cyc => PWM_OW,
       pwm     => PWM3_OUT);
 
   -- PWM signals mapped to FPGA outputs, EN forced to '1'
-  PWM0    <= PWM1_OUT;
+  PWM0    <= not PWM1_OUT;
   PWM0_EN <= '1';
-  PWM1    <= PWM2_OUT;
+  PWM1    <= not PWM2_OUT;
   PWM1_EN <= '1';
-  PWM2    <= PWM3_OUT;
+  PWM2    <= not PWM3_OUT;
   PWM2_EN <= '1';
+
   -- PWM is signalized on LEDs
   LED0    <= PWM1_OUT;
   LED1    <= PWM2_OUT;