From 98ced3a20155c627d0c0f911fefa4536b5bbaea2 Mon Sep 17 00:00:00 2001 From: Bast Date: Wed, 3 Aug 2011 18:12:14 +0200 Subject: [PATCH] Added index capture register hardware --- mcu_periph/capture_reg.vhd | 44 +++++++++++++++++++++++++++ mcu_periph/capture_reg16.vhd | 51 +++++++++++++++++++++++++++++++ mcu_periph/event_rwc.vhd | 57 ++++++++++++++++++++++++++++++++++ msp_motion.prj | 3 ++ msp_motion.vhd | 59 +++++++++++++++++++++++++++++++++++- 5 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 mcu_periph/capture_reg.vhd create mode 100644 mcu_periph/capture_reg16.vhd create mode 100644 mcu_periph/event_rwc.vhd diff --git a/mcu_periph/capture_reg.vhd b/mcu_periph/capture_reg.vhd new file mode 100644 index 0000000..b806482 --- /dev/null +++ b/mcu_periph/capture_reg.vhd @@ -0,0 +1,44 @@ +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.std_logic_arith.ALL; + +-------------------------------------------------------------------------------- + +entity capture_reg is + generic ( + W : integer := 32); + port ( + -- Peripheral bus interface + ACK_O : out std_logic; + CLK_I : in std_logic; + DAT_O : out std_logic_vector (W-1 downto 0); + SEL_I : in std_logic; + STB_I : in std_logic; + -- QCounter component interface + EVENT_I : in std_logic; + CAPTURE_I : in std_logic_vector (W-1 downto 0)); +end capture_reg; + +-------------------------------------------------------------------------------- + +architecture behavioral of capture_reg is + + signal capture_mem : std_logic_vector (W-1 downto 0); + +-------------------------------------------------------------------------------- + +begin + + ACK_O <= SEL_I and STB_I; + DAT_O <= capture_mem; + + + process (CLK_I) + begin + if rising_edge(CLK_I) and EVENT_I = '1' then + capture_mem <= CAPTURE_I; + end if; + end process; + +end behavioral; + diff --git a/mcu_periph/capture_reg16.vhd b/mcu_periph/capture_reg16.vhd new file mode 100644 index 0000000..43f0542 --- /dev/null +++ b/mcu_periph/capture_reg16.vhd @@ -0,0 +1,51 @@ +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.std_logic_arith.ALL; + +-------------------------------------------------------------------------------- + +entity capture_reg16 is + port ( + -- Peripheral bus interface + ACK_O : out std_logic; + ADR_I : in std_logic_vector (0 downto 0); + CLK_I : in std_logic; + DAT_O : out std_logic_vector (15 downto 0); + SEL_I : in std_logic; + STB_I : in std_logic; + -- QCounter component interface + EVENT_I : in std_logic; + CAPTURE_I : in std_logic_vector (31 downto 0)); +end capture_reg16; + +-------------------------------------------------------------------------------- + +architecture behavioral of capture_reg16 is + + signal CR_DAT_O : std_logic_vector (31 downto 0); + +-------------------------------------------------------------------------------- + +begin + + with ADR_I select + DAT_O <= + CR_DAT_O (15 downto 0) when "0", + CR_DAT_O (31 downto 16) when "1", + (others => 'X') when others; + + + capture_reg0 : entity work.capture_reg + generic map ( + W => 32) + port map ( + ACK_O => ACK_O, + CLK_I => CLK_I, + DAT_O => CR_DAT_O, + SEL_I => SEL_I, + STB_I => STB_I, + EVENT_I => EVENT_I, + CAPTURE_I => CAPTURE_I); + +end behavioral; + diff --git a/mcu_periph/event_rwc.vhd b/mcu_periph/event_rwc.vhd new file mode 100644 index 0000000..16b6ecf --- /dev/null +++ b/mcu_periph/event_rwc.vhd @@ -0,0 +1,57 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +-------------------------------------------------------------------------------- + +entity event_rwc is + generic ( + W : integer := 16); -- Event port width (pin count) + port ( + -- Peripheral bus interface + ACK_O : out std_logic; + CLK_I : in std_logic; + DAT_I : in std_logic_vector (W-1 downto 0); + DAT_O : out std_logic_vector (W-1 downto 0); + RST_I : in std_logic; + SEL_I : in std_logic; + STB_I : in std_logic; + WE_I : in std_logic; + -- Event port pins + EVENT_I : in std_logic_vector (W-1 downto 0); + EVENT_O : out std_logic_vector (W-1 downto 0)); +end event_rwc; + +-------------------------------------------------------------------------------- + +architecture behavioral of event_rwc is + + signal status : std_logic_vector (W-1 downto 0) := (others => '0'); + signal write_en : std_logic; + +begin + + ACK_O <= SEL_I and STB_I; + DAT_O <= status; + + EVENT_O <= status; + + write_en <= SEL_I and STB_I and WE_I; + + process (CLK_I, RST_I) is + begin + if rising_edge(CLK_I) then + if RST_I = '1' then + status <= (others => '0'); + else + if write_en = '1' then + status <= (status and not DAT_I) or EVENT_I; + else + status <= status or EVENT_I; + end if; + end if; + end if; + end process; + +end behavioral; + diff --git a/msp_motion.prj b/msp_motion.prj index af5a635..0dacb38 100644 --- a/msp_motion.prj +++ b/msp_motion.prj @@ -69,6 +69,9 @@ vhdl work quadcount/qcounter.vhd vhdl work mcu_periph/gpio.vhd vhdl work mcu_periph/qcounter_mcu16.vhd +vhdl work mcu_periph/event_rwc.vhd +vhdl work mcu_periph/capture_reg.vhd +vhdl work mcu_periph/capture_reg16.vhd #==============================================================================# # Top-level design file # diff --git a/msp_motion.vhd b/msp_motion.vhd index 21ac3e6..bdc15de 100644 --- a/msp_motion.vhd +++ b/msp_motion.vhd @@ -79,7 +79,18 @@ architecture rtl of msp_motion is signal QCNT_SEL : std_logic; -- Motor feedback IRQ generator signal MOTOR_IRQ : std_logic; - + -- Event register + signal EVENT_DAT_O : std_logic_vector (15 downto 0); + signal EVENT_SEL : std_logic; + signal event_i : std_logic_vector (15 downto 0); + signal event_o : std_logic_vector (15 downto 0); + -- Qcounter capture + signal CAPTURE_SEL : std_logic; + signal CAPTURE_DAT : std_logic_vector (15 downto 0); + -- IRC index detection + signal INDEX_DETECT_DAT_O : std_logic_vector (15 downto 0); + signal INDEX_DETECT_SEL : std_logic; + ------------------------------------------------------------------------------ -- Dual-port shared memory ------------------------------------------------------------------------------ @@ -133,6 +144,9 @@ architecture rtl of msp_motion is signal PWM3_OUT : std_logic; -- IRC value signal QCNT : std_logic_vector (31 downto 0); + -- IRC capturing + signal IRC_INDEX_DFF : std_logic; -- IRC_INDEX aligned with global clock + signal IRC_INDEX_EVENT : std_logic; -------------------------------------------------------------------------------- @@ -190,10 +204,18 @@ begin ------------------------------------------------------------------------------ per_dout <= GPIO_DAT_O when GPIO_SEL = '1' else QCNT_DAT_O when QCNT_SEL = '1' else + EVENT_DAT_O when EVENT_SEL = '1' else + CAPTURE_DAT when CAPTURE_SEL = '1' else + INDEX_DETECT_DAT_O when INDEX_DETECT_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'; + EVENT_SEL <= '1' when per_addr(7 downto 0) = 16#014C#/2 else '0'; + CAPTURE_SEL <= '1' when per_addr(7 downto 1) = 16#0150#/2/2 else '0'; + INDEX_DETECT_SEL <= '1' when per_addr(7 downto 1) = 16#0152#/2/2 else '0'; + + per_wen16 <= per_wen(0) and per_wen(1); -- Interrupt signals ------------------------------------------------------------------------------ @@ -258,6 +280,41 @@ begin count => open, event_ow => MOTOR_IRQ); + event_io_0 : entity work.event_rwc + port map ( + -- Peripheral bus interface + ACK_O => open, + CLK_I => mclk, + DAT_I => per_din, + DAT_O => EVENT_DAT_O, + RST_I => puc, + SEL_I => EVENT_SEL, + STB_I => per_en, + WE_I => per_wen16, + -- Event port pins + EVENT_I => event_i, + EVENT_O => event_o); + + event_i(0) <= (not IRC_INDEX_DFF) and (not event_o(0)); + IRC_INDEX_EVENT <= event_i(0); + + + irc_index_dff_0 : entity work.dff + port map ( + clock => mclk, + d => IRC_INDEX, + q => IRC_INDEX_DFF); + + capture_reg16_0 : entity work.capture_reg16 + port map ( + ACK_O => open, + ADR_I => per_addr (0 downto 0), + CLK_I => mclk, + DAT_O => CAPTURE_DAT, + SEL_I => CAPTURE_SEL, + STB_I => per_en, + EVENT_I => IRC_INDEX_EVENT, + CAPTURE_I => QCNT); ------------------------------------------------------------------------------ -- Dual-port shared memory -- 2.39.2