2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
7 use unisim.vcomponents.all;
9 --------------------------------------------------------------------------------
14 CLK_24MHz : in std_logic;
25 PWM0_EN : out std_logic;
27 PWM1_EN : out std_logic;
29 PWM2_EN : out std_logic;
31 IRC_INDEX : in std_logic;
40 --------------------------------------------------------------------------------
42 architecture rtl of msp_motion is
44 signal reset_p : std_logic;
46 ------------------------------------------------------------------------------
47 -- OpenMSP430 softcore MCU module
48 ------------------------------------------------------------------------------
49 signal mclk : std_logic;
50 signal puc : std_logic;
52 signal dmem_addr : std_logic_vector (11 downto 0);
53 signal dmem_ce : std_logic;
54 signal dmem_we : std_logic;
55 signal dmem_din : std_logic_vector (15 downto 0);
56 signal dmem_dout : std_logic_vector (15 downto 0);
58 signal per_din : std_logic_vector (15 downto 0);
59 signal per_dout : std_logic_Vector (15 downto 0);
60 signal per_wen : std_logic_vector (1 downto 0);
61 signal per_wen16 : std_logic;
62 signal per_en : std_logic;
63 signal per_addr : std_logic_vector (7 downto 0);
65 --signal irq : std_logic_vector (13 downto 0) := (others => '0');
66 signal irq : std_logic_vector (13 downto 0);
67 signal irq_acc : std_logic_vector (13 downto 0);
69 ------------------------------------------------------------------------------
71 ------------------------------------------------------------------------------
73 signal GPIO_IN : std_logic_vector (15 downto 0);
74 signal GPIO_OUT : std_logic_vector (15 downto 0);
75 signal GPIO_DAT_O : std_logic_vector (15 downto 0);
76 signal GPIO_SEL : std_logic;
77 -- Qcounter MCU interface
78 signal QCNT_DAT_O : std_logic_vector (15 downto 0);
79 signal QCNT_SEL : std_logic;
80 -- Motor feedback IRQ generator
81 signal MOTOR_IRQ : std_logic;
83 signal EVENT_DAT_O : std_logic_vector (15 downto 0);
84 signal EVENT_SEL : std_logic;
85 signal event_i : std_logic_vector (15 downto 0);
86 signal event_o : std_logic_vector (15 downto 0);
89 signal EDGE_DAT_O : std_logic_vector (15 downto 0);
90 signal EDGE_DETECT_SEL : std_logic;
91 signal event_in : std_logic_vector (15 downto 0);
92 signal edge_detect_o : std_logic_vector (15 downto 0);
93 signal rst_edge : std_logic;
96 signal CAPTURE_SEL : std_logic;
97 signal CAPTURE_DAT : std_logic_vector (15 downto 0);
98 -- IRC index detection
99 signal INDEX_DETECT_DAT_O : std_logic_vector (15 downto 0);
100 signal INDEX_DETECT_SEL : std_logic;
102 ------------------------------------------------------------------------------
103 -- Dual-port shared memory
104 ------------------------------------------------------------------------------
105 -- These signals of A-port (MCU) enables creation of external data encoder and
106 -- multiplexer in a case of multiple devices connected to the external data
107 -- bus. Otherwise useless.
108 signal DPA_DAT_O : std_logic_vector (15 downto 0);
109 signal DPA_SEL : std_logic;
110 signal DPA_STB : std_logic;
111 -- Auxiliary register used to generate IRF_ACK
112 signal IRF_ACK_REG : std_logic := '0';
113 -- Auxiliary signal used to form B-port address
114 signal DPB_ADR : std_logic_vector (9 downto 0);
116 ------------------------------------------------------------------------------
117 -- Motion Control Chain
118 ------------------------------------------------------------------------------
120 constant PWM_W : integer := 10;
121 constant LUT_ADR_W : integer := 11;
122 constant LUT_INIT : string := "sin1000.lut";
124 -- Bus interface to the shared memory
125 signal IRF_ACK : std_logic;
126 signal IRF_ADR : std_logic_vector (4 downto 0);
127 signal IRF_DAT_I : std_logic_vector (15 downto 0);
128 signal IRF_DAT_O : std_logic_vector (15 downto 0);
129 signal IRF_STB : std_logic;
130 signal IRF_WE : std_logic;
131 -- Wave look-up table
132 signal LUT_ADR : std_logic_vector (LUT_ADR_W-1 downto 0);
133 signal LUT_DAT_O : std_logic_vector (PWM_W-1 downto 0);
134 signal LUT_STB : std_logic;
135 -- MCC execution control
136 signal MCC_ACK : std_logic;
137 signal MCC_STB : std_logic;
139 ------------------------------------------------------------------------------
141 ------------------------------------------------------------------------------
142 signal PWM_CNT : std_logic_vector (PWM_W-1 downto 0);
143 signal PWM_OW : std_logic; -- PWM counter overflow
144 -- PWM interface to the MCC
145 signal PWM_DAT : std_logic_vector (PWM_W-1 downto 0);
146 signal PWM1_STB : std_logic;
147 signal PWM2_STB : std_logic;
148 signal PWM3_STB : std_logic;
150 signal PWM1_OUT : std_logic;
151 signal PWM2_OUT : std_logic;
152 signal PWM3_OUT : std_logic;
154 signal QCNT : std_logic_vector (31 downto 0);
156 signal IRC_INDEX_DFF : std_logic; -- IRC_INDEX aligned with global clock
157 signal IRC_INDEX_EVENT : std_logic;
159 --------------------------------------------------------------------------------
163 ------------------------------------------------------------------------------
164 -- OpenMSP430 softcore MCU module
165 ------------------------------------------------------------------------------
166 openMSP430_1 : entity work.openMSP430_8_32_mul_dbus
168 dco_clk => CLK_24MHz,
173 per_addr => per_addr,
175 per_dout => per_dout,
185 dmem_addr => dmem_addr,
188 dmem_din => dmem_din,
189 dmem_dout => dmem_dout);
192 reset_p <= not RESET;
194 STARTUP_VIRTEX2_inst : STARTUP_VIRTEX2
197 -- Clock input for start-up sequence
198 GSR => reset_p, -- Global Set/Reset input (GSR cannot be used for the port name)
199 GTS => open); -- Global 3-state input (GTS cannot be used for the port name)
202 -- External data bus address decoder and data multiplexer.
203 ------------------------------------------------------------------------------
204 -- When connection more memories, be aware that 'dmem_dout' can vary only when
205 -- reading cycle is performed. I.e. mux variable must be registered.
206 dmem_dout <= DPA_DAT_O;
208 DPA_SEL <= '1' when dmem_addr (11 downto 10) = "00" else '0';
209 DPA_STB <= dmem_ce and DPA_SEL;
211 -- Peripheral bus address decoder and data multiplexer.
212 ------------------------------------------------------------------------------
213 per_dout <= GPIO_DAT_O when GPIO_SEL = '1' else
214 QCNT_DAT_O when QCNT_SEL = '1' else
215 EVENT_DAT_O when EVENT_SEL = '1' else
216 CAPTURE_DAT when CAPTURE_SEL = '1' else
217 EDGE_DAT_O when EDGE_DETECT_SEL = '1' else
218 (others => '0'); -- MUST be 0 when nothing is addressed
220 GPIO_SEL <= '1' when per_addr(7 downto 2) = 16#0140#/2/4 else '0';
221 QCNT_SEL <= '1' when per_addr(7 downto 1) = 16#0148#/2/2 else '0';
222 EVENT_SEL <= '1' when per_addr(7 downto 0) = 16#014C#/2 else '0';
223 CAPTURE_SEL <= '1' when per_addr(7 downto 1) = 16#0150#/2/2 else '0';
224 EDGE_DETECT_SEL <= '1' when per_addr(7 downto 0) = 16#0154#/2 else '0';
226 per_wen16 <= per_wen(0) and per_wen(1);
229 ------------------------------------------------------------------------------
230 irq (13 downto 1) <= (others => '0');
232 motor_irq_gen : process (mclk, puc) is
234 if rising_edge (mclk) then
235 if puc = '1' or irq_acc (0) = '1' then
237 elsif MOTOR_IRQ = '1' then
244 ------------------------------------------------------------------------------
246 ------------------------------------------------------------------------------
250 GPIO_IN(3) <= IRC_INDEX;
252 gpio_0 : entity work.gpio
257 ADR_I => per_addr (1 downto 0),
268 qcounter_mcu16_0 : entity work.qcounter_mcu16
271 ADR_I => per_addr (0),
278 -- Motor feedback IRQ generator
279 -- f_motor_irq approx. 1 kHz
280 irq_counter_1 : entity work.counter
289 event_ow => MOTOR_IRQ);
292 event_io_0 : entity work.event_rwc
294 -- Peripheral bus interface
298 DAT_O => EVENT_DAT_O,
307 event_i(0) <= (not IRC_INDEX_DFF) and (not event_o(0));
308 IRC_INDEX_EVENT <= event_i(0);
311 edge_detector_0 : entity work.edge_detector
313 -- Peripheral bus interface
319 SEL_I => EDGE_DETECT_SEL,
323 EVENT_I => event_in);
326 --rst_edge <= '0' when per_addr()
327 event_in(0) <= IRC_INDEX_DFF;
329 irc_index_dff_0 : entity work.dff
335 capture_reg16_0 : entity work.capture_reg16
338 ADR_I => per_addr (0 downto 0),
340 DAT_O => CAPTURE_DAT,
341 SEL_I => CAPTURE_SEL,
343 EVENT_I => IRC_INDEX_EVENT,
346 ------------------------------------------------------------------------------
347 -- Dual-port shared memory
348 ------------------------------------------------------------------------------
349 -- Shared memory between MCU and MCC (size: 16+2 bits x 1k).
350 -- Port A (MCU side) has a priority of writing.
351 shared_mem : RAMB16_S18_S18
353 WRITE_MODE_A => "READ_FIRST",
354 WRITE_MODE_B => "WRITE_FIRST")
357 ADDRA => dmem_addr (9 downto 0),
377 -- B-Port address (10 bits) constructed from IRF_ADR (5 bits). Upper addr bits
378 -- are forced to '0', but in a case of several axes these can be used to
379 -- address memory space of the appropriate one.
380 DPB_ADR (9 downto 5) <= (others => '0');
381 DPB_ADR (4 downto 0) <= IRF_ADR;
383 -- Generation of IRF acknowledge signal for MCC.
384 IRF_ACK <= IRF_STB and (IRF_WE or IRF_ACK_REG);
386 -- IRF_ACK_REG signalizes that data is present on IRF_DAT_O when reading.
387 irf_read : process (mclk, puc) is
389 if rising_edge(mclk) then
393 IRF_ACK_REG <= IRF_STB and not IRF_WE;
399 ------------------------------------------------------------------------------
400 -- Motion Control Chain
401 ------------------------------------------------------------------------------
402 mcc_exec_1 : entity work.mcc_exec
412 MCC_EXEC_I => PWM_OW,
414 MCC_ACK_I => MCC_ACK,
415 MCC_STB_O => MCC_STB);
417 mcc_1 : entity work.mcc
420 LUT_ADR_W => LUT_ADR_W)
426 LUT_STB_O => LUT_STB,
427 LUT_ADR_O => LUT_ADR,
428 LUT_DAT_I => LUT_DAT_O,
429 IRC_DAT_I => QCNT (15 downto 0),
430 PWM_DAT_O => PWM_DAT,
431 PWM1_STB_O => PWM1_STB,
432 PWM2_STB_O => PWM2_STB,
433 PWM3_STB_O => PWM3_STB,
434 IRF_ACK_I => IRF_ACK,
435 IRF_ADR_O => IRF_ADR,
436 IRF_DAT_I => IRF_DAT_O,
437 IRF_DAT_O => IRF_DAT_I,
438 IRF_STB_O => IRF_STB,
441 wave_table_1 : entity work.wave_table
445 INIT_FILE => LUT_INIT)
450 DAT_I => conv_std_logic_vector(0, PWM_W),
456 ------------------------------------------------------------------------------
458 ------------------------------------------------------------------------------
459 -- PWM counter is shared by all PWM generators. Generator contains only
460 -- comparator and desired value.
461 pwm_counter : entity work.counter
472 pwm_1 : entity work.pwm
485 pwm_2 : entity work.pwm
498 pwm_3 : entity work.pwm
511 -- PWM signals mapped to FPGA outputs, EN forced to '1'
512 PWM0 <= not PWM1_OUT;
514 PWM1 <= not PWM2_OUT;
516 PWM2 <= not PWM3_OUT;
519 -- PWM is signalized on LEDs
524 qcounter_1 : entity work.qcounter