]> rtime.felk.cvut.cz Git - fpga/virtex2/msp_motion.git/blobdiff - msp_motion.vhd
Improper top module signals initialization.
[fpga/virtex2/msp_motion.git] / msp_motion.vhd
index c5aef7d052d6b5e846a3babc36c3344ddc62de10..b131d18948e3929c5df9ea173c0b8f34cfc69af4 100644 (file)
@@ -3,6 +3,9 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 
+library unisim;
+use unisim.vcomponents.all;
+
 --------------------------------------------------------------------------------
 
 entity msp_motion is
@@ -38,9 +41,98 @@ end msp_motion;
 
 architecture rtl of msp_motion is
 
+  signal reset_p : std_logic;
+
+  ------------------------------------------------------------------------------
   -- OpenMSP430 softcore MCU module
-  signal mclk     : std_logic;
-  signal puc      : std_logic;
+  ------------------------------------------------------------------------------
+  signal mclk      : std_logic;
+  signal puc       : std_logic;
+  -- External data bus
+  signal dmem_addr : std_logic_vector (11 downto 0);
+  signal dmem_ce   : std_logic;
+  signal dmem_we   : std_logic;
+  signal dmem_din  : std_logic_vector (15 downto 0);
+  signal dmem_dout : std_logic_vector (15 downto 0);
+  -- Peripheral bus
+  signal per_din   : std_logic_vector (15 downto 0);
+  signal per_dout  : std_logic_Vector (15 downto 0);
+  signal per_wen   : std_logic_vector (1 downto 0);
+  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
+  ------------------------------------------------------------------------------
+  -- These signals of A-port (MCU) enables creation of external data encoder and
+  -- multiplexer in a case of multiple devices connected to the external data
+  -- bus. Otherwise useless.
+  signal DPA_DAT_O   : std_logic_vector (15 downto 0);
+  signal DPA_SEL     : std_logic;
+  signal DPA_STB     : std_logic;
+  -- Auxiliary register used to generate IRF_ACK
+  signal IRF_ACK_REG : std_logic := '0';
+  -- Auxiliary signal used to form B-port address
+  signal DPB_ADR     : std_logic_vector (9 downto 0);
+
+  ------------------------------------------------------------------------------
+  -- Motion Control Chain
+  ------------------------------------------------------------------------------
+  -- Constants
+  constant PWM_W     : integer := 10;
+  constant LUT_ADR_W : integer := 11;
+  constant LUT_INIT  : string  := "sin1000.lut";
+  
+  -- Bus interface to the shared memory
+  signal IRF_ACK   : std_logic;
+  signal IRF_ADR   : std_logic_vector (4 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   : std_logic;
+  signal IRF_WE    : std_logic;
+  -- Wave look-up table
+  signal LUT_ADR   : std_logic_vector (LUT_ADR_W-1 downto 0);
+  signal LUT_DAT_O : std_logic_vector (PWM_W-1 downto 0);
+  signal LUT_STB   : std_logic;
+  -- MCC execution control
+  signal MCC_ACK   : std_logic;
+  signal MCC_STB   : std_logic;
+
+  ------------------------------------------------------------------------------
+  -- PWM and IRC
+  ------------------------------------------------------------------------------
+  signal PWM_CNT  : std_logic_vector (PWM_W-1 downto 0);
+  signal PWM_OW   : std_logic;          -- PWM counter overflow
+  -- PWM interface to the MCC
+  signal PWM_DAT  : std_logic_vector (PWM_W-1 downto 0);
+  signal PWM1_STB : std_logic;
+  signal PWM2_STB : std_logic;
+  signal PWM3_STB : std_logic;
+  -- PWM outputs
+  signal PWM1_OUT : std_logic;
+  signal PWM2_OUT : std_logic;
+  signal PWM3_OUT : std_logic;
+  -- IRC value
+  signal QCNT     : std_logic_vector (31 downto 0);
   
 --------------------------------------------------------------------------------
 
@@ -53,26 +145,303 @@ begin
     port map (
       dco_clk                  => CLK_24MHz,
       lfxt_clk                 => '0',
-      reset_n                  => RESET,
+      reset_n                  => '1',
       rxd                      => RXD,
       txd                      => TXD,
-      per_addr                 => open,
-      per_din                  => open,
-      per_dout                 => (others => '0'),
-      per_wen                  => open,
-      per_en                   => open,
+      per_addr                 => per_addr,
+      per_din                  => per_din,
+      per_dout                 => per_dout,
+      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,
-      dmem_addr                => open,
-      dmem_ce                  => open,
-      dmem_we                  => open,
-      dmem_din                 => open,
-      dmem_dout                => (others => '0'));
+      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.
+  ------------------------------------------------------------------------------
+  -- 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 <= 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_ff : 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
+  mcc_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);
+
+
+  ------------------------------------------------------------------------------
+  -- Dual-port shared memory
+  ------------------------------------------------------------------------------
+  -- Shared memory between MCU and MCC (size: 16+2 bits x 1k).
+  -- Port A (MCU side) has a priority of writing.
+  shared_mem : RAMB16_S18_S18
+    generic map (
+      WRITE_MODE_A => "READ_FIRST",
+      WRITE_MODE_B => "WRITE_FIRST")
+    port map (
+      -- A-Port (MCU)
+      ADDRA => dmem_addr (9 downto 0),
+      CLKA  => mclk,
+      DIA   => dmem_din,
+      DIPA  => "00",
+      DOA   => DPA_DAT_O,
+      DOPA  => open,
+      ENA   => DPA_STB,
+      SSRA  => '0',
+      WEA   => dmem_we,
+      -- B-Port (MCC)
+      ADDRB => DPB_ADR,
+      CLKB  => mclk,
+      DIB   => IRF_DAT_I,
+      DIPB  => "00",
+      DOB   => IRF_DAT_O,
+      DOPB  => open,
+      ENB   => IRF_STB,
+      SSRB  => '0',
+      WEB   => IRF_WE);
+
+  -- B-Port address (10 bits) constructed from IRF_ADR (5 bits). Upper addr bits
+  -- are forced to '0', but in a case of several axes these can be used to
+  -- address memory space of the appropriate one.
+  DPB_ADR (9 downto 5) <= (others => '0');
+  DPB_ADR (4 downto 0) <= IRF_ADR;
+  
+  -- Generation of IRF acknowledge signal for MCC.
+  IRF_ACK <= IRF_STB and (IRF_WE or IRF_ACK_REG);
+
+  -- IRF_ACK_REG signalizes that data is present on IRF_DAT_O when reading.
+  irf_read : process (mclk, puc) is
+  begin
+    if rising_edge(mclk) then
+      if puc = '1' then
+        IRF_ACK_REG <= '0';
+      else
+        IRF_ACK_REG <= IRF_STB  and not IRF_WE;
+      end if;
+    end if;
+  end process;
+
+  
+  ------------------------------------------------------------------------------
+  -- Motion Control Chain
+  ------------------------------------------------------------------------------
+  mcc_exec_1 : entity work.mcc_exec
+    port map (
+      CLK_I      => mclk,
+      RST_I      => puc,
+      MCC_EN_I   => '1',
+      MCC_EXEC_I => PWM_OW,
+      MCC_ERR_O  => open,
+      MCC_ACK_I  => MCC_ACK,
+      MCC_STB_O  => MCC_STB);
+  
+  mcc_1 : entity work.mcc
+    generic map (
+      LUT_DAT_W => PWM_W,
+      LUT_ADR_W => LUT_ADR_W)
+    port map (
+      ACK_O      => MCC_ACK,
+      CLK_I      => mclk,
+      RST_I      => puc,
+      STB_I      => MCC_STB,
+      LUT_STB_O  => LUT_STB,
+      LUT_ADR_O  => LUT_ADR,
+      LUT_DAT_I  => LUT_DAT_O,
+      IRC_DAT_I  => QCNT (15 downto 0),
+      PWM_DAT_O  => PWM_DAT,
+      PWM1_STB_O => PWM1_STB,
+      PWM2_STB_O => PWM2_STB,
+      PWM3_STB_O => PWM3_STB,
+      IRF_ACK_I  => IRF_ACK,
+      IRF_ADR_O  => IRF_ADR,
+      IRF_DAT_I  => IRF_DAT_O,
+      IRF_DAT_O  => IRF_DAT_I,
+      IRF_STB_O  => IRF_STB,
+      IRF_WE_O   => IRF_WE);
+
+  wave_table_1 : entity work.wave_table
+    generic map (
+      DAT_W     => PWM_W,
+      ADR_W     => LUT_ADR_W,
+      INIT_FILE => LUT_INIT)
+    port map (
+      ACK_O => open,
+      ADR_I => LUT_ADR,
+      CLK_I => mclk,
+      DAT_I => conv_std_logic_vector(0, PWM_W),
+      DAT_O => LUT_DAT_O,
+      STB_I => LUT_STB,
+      WE_I  => '0');
+
+
+  ------------------------------------------------------------------------------
+  -- PWM and IRC
+  ------------------------------------------------------------------------------
+  -- PWM counter is shared by all PWM generators. Generator contains only
+  -- comparator and desired value.
+  counter_1 : entity work.counter
+    generic map (
+      WIDTH => PWM_W,
+      MAX   => 2**PWM_W - 2)
+    port map (
+      clk      => mclk,
+      clk_en   => '1',
+      reset    => puc,
+      count    => PWM_CNT,
+      event_ow => PWM_OW);
+
+    pwm_1 : entity work.pwm
+    generic map (
+      PWM_WIDTH => PWM_W)
+    port map (
+      clk     => mclk,
+      reset   => puc,
+      din     => PWM_DAT,
+      we      => PWM1_STB,
+      pwm_cnt => PWM_CNT,
+      pwm_cyc => PWM_OW,
+      pwm     => PWM1_OUT);
+
+  pwm_2 : entity work.pwm
+    generic map (
+      PWM_WIDTH => PWM_W)
+    port map (
+      clk     => mclk,
+      reset   => puc,
+      din     => PWM_DAT,
+      we      => PWM2_STB,
+      pwm_cnt => PWM_CNT,
+      pwm_cyc => PWM_OW,
+      pwm     => PWM2_OUT);
+  
+  pwm_3 : entity work.pwm
+    generic map (
+      PWM_WIDTH => PWM_W)
+    port map (
+      clk     => mclk,
+      reset   => puc,
+      din     => PWM_DAT,
+      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_EN <= '1';
+  PWM1    <= PWM2_OUT;
+  PWM1_EN <= '1';
+  PWM2    <= PWM3_OUT;
+  PWM2_EN <= '1';
+  -- PWM is signalized on LEDs
+  LED0    <= PWM1_OUT;
+  LED1    <= PWM2_OUT;
+  LED2    <= PWM3_OUT;
+
+  qcounter_1 : entity work.qcounter
+    port map (
+      clock    => mclk,
+      reset    => puc,
+      a0       => IRC_A,
+      b0       => IRC_B,
+      qcount   => QCNT,
+      a_rise   => open,
+      a_fall   => open,
+      b_rise   => open,
+      b_fall   => open,
+      ab_event => open,
+      ab_error => open);
+
   
 end rtl;