architecture rtl of msp_motion is
+ signal reset_p : std_logic;
+
------------------------------------------------------------------------------
-- OpenMSP430 softcore MCU module
------------------------------------------------------------------------------
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
------------------------------------------------------------------------------
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);
port map (
dco_clk => CLK_24MHz,
lfxt_clk => '0',
- reset_n => RESET,
+ reset_n => '1',
rxd => RXD,
txd => TXD,
per_addr => per_addr,
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);
------------------------------------------------------------------------------
-- 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,
------------------------------------------------------------------------------
-- 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)
clk => mclk,
reset => puc,
din => PWM_DAT,
+ sel => '1',
we => PWM1_STB,
pwm_cnt => PWM_CNT,
pwm_cyc => PWM_OW,
clk => mclk,
reset => puc,
din => PWM_DAT,
+ sel => '1',
we => PWM2_STB,
pwm_cnt => PWM_CNT,
pwm_cyc => PWM_OW,
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;