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 ------------------------------------------------------------------------------
45 -- OpenMSP430 softcore MCU module
46 ------------------------------------------------------------------------------
47 signal mclk : std_logic;
48 signal puc : std_logic;
50 signal dmem_addr : std_logic_vector (11 downto 0);
51 signal dmem_ce : std_logic;
52 signal dmem_we : std_logic;
53 signal dmem_din : std_logic_vector (15 downto 0);
54 signal dmem_dout : std_logic_vector (15 downto 0);
56 signal per_din : std_logic_vector (15 downto 0);
57 signal per_dout : std_logic_Vector (15 downto 0);
58 signal per_wen : std_logic_vector (1 downto 0);
59 signal per_wen16 : std_logic;
60 signal per_en : std_logic;
61 signal per_addr : std_logic_vector (7 downto 0);
63 signal irq : std_logic_vector (13 downto 0);
64 signal irq_acc : std_logic_vector (13 downto 0);
66 ------------------------------------------------------------------------------
68 ------------------------------------------------------------------------------
70 signal GPIO_IN : std_logic_vector (15 downto 0);
71 signal GPIO_OUT : std_logic_vector (15 downto 0);
72 signal GPIO_DAT_O : std_logic_vector (15 downto 0);
73 signal GPIO_SEL : std_logic;
74 -- Qcounter MCU interface
75 signal QCNT_DAT_O : std_logic_vector (15 downto 0);
76 signal QCNT_SEL : std_logic;
77 -- Motor feedback IRQ generator
78 signal MOTOR_IRQ : std_logic;
80 ------------------------------------------------------------------------------
81 -- Dual-port shared memory
82 ------------------------------------------------------------------------------
83 -- These signals of A-port (MCU) enables creation of external data encoder and
84 -- multiplexer in a case of multiple devices connected to the external data
85 -- bus. Otherwise useless.
86 signal DPA_DAT_O : std_logic_vector (15 downto 0);
87 signal DPA_SEL : std_logic;
88 signal DPA_STB : std_logic;
89 -- Auxiliary register used to generate IRF_ACK
90 signal IRF_ACK_REG : std_logic;
91 -- Auxiliary signal used to form B-port address
92 signal DPB_ADR : std_logic_vector (9 downto 0);
94 ------------------------------------------------------------------------------
95 -- Motion Control Chain
96 ------------------------------------------------------------------------------
98 constant PWM_W : integer := 10;
99 constant LUT_ADR_W : integer := 11;
100 constant LUT_INIT : string := "sin1000.lut";
102 -- Bus interface to the shared memory
103 signal IRF_ACK : std_logic;
104 signal IRF_ADR : std_logic_vector (4 downto 0);
105 signal IRF_DAT_I : std_logic_vector (15 downto 0);
106 signal IRF_DAT_O : std_logic_vector (15 downto 0);
107 signal IRF_STB : std_logic;
108 signal IRF_WE : std_logic;
109 -- Wave look-up table
110 signal LUT_ADR : std_logic_vector (LUT_ADR_W-1 downto 0);
111 signal LUT_DAT_O : std_logic_vector (PWM_W-1 downto 0);
112 signal LUT_STB : std_logic;
113 -- MCC execution control
114 signal MCC_ACK : std_logic;
115 signal MCC_STB : std_logic;
117 ------------------------------------------------------------------------------
119 ------------------------------------------------------------------------------
120 signal PWM_CNT : std_logic_vector (PWM_W-1 downto 0);
121 signal PWM_OW : std_logic; -- PWM counter overflow
122 -- PWM interface to the MCC
123 signal PWM_DAT : std_logic_vector (PWM_W-1 downto 0);
124 signal PWM1_STB : std_logic;
125 signal PWM2_STB : std_logic;
126 signal PWM3_STB : std_logic;
128 signal PWM1_OUT : std_logic;
129 signal PWM2_OUT : std_logic;
130 signal PWM3_OUT : std_logic;
132 signal QCNT : std_logic_vector (31 downto 0);
134 --------------------------------------------------------------------------------
138 ------------------------------------------------------------------------------
139 -- OpenMSP430 softcore MCU module
140 ------------------------------------------------------------------------------
141 openMSP430_1 : entity work.openMSP430_8_32_mul_dbus
143 dco_clk => CLK_24MHz,
148 per_addr => per_addr,
150 per_dout => per_dout,
160 dmem_addr => dmem_addr,
163 dmem_din => dmem_din,
164 dmem_dout => dmem_dout);
166 -- External data bus address decoder and data multiplexer.
167 ------------------------------------------------------------------------------
168 -- This statement leads to priority encoder (which should be avoided), but for
169 -- a small mux it doesn't matter and it's better readable.
170 dmem_dout <= DPA_DAT_O when DPA_SEL = '1' else
173 DPA_SEL <= '1' when dmem_addr (11 downto 10) = "00" else '0';
174 DPA_STB <= dmem_ce and DPA_SEL;
176 -- Peripheral bus address decoder and data multiplexer.
177 ------------------------------------------------------------------------------
178 per_dout <= GPIO_DAT_O when GPIO_SEL = '1' else
179 QCNT_DAT_O when QCNT_SEL = '1' else
180 (others => '0'); -- MUST be 0 when nothing is addressed
182 GPIO_SEL <= '1' when per_addr(7 downto 2) = 16#0140#/2/4 else '0';
183 QCNT_SEL <= '1' when per_addr(7 downto 1) = 16#0148#/2/2 else '0';
186 ------------------------------------------------------------------------------
187 irq (13 downto 1) <= (others => '0');
189 motor_irq_ff : process (mclk, puc) is
191 if rising_edge (mclk) then
192 if puc = '1' or irq_acc (0) = '1' then
194 elsif MOTOR_IRQ = '1' then
201 ------------------------------------------------------------------------------
203 ------------------------------------------------------------------------------
207 GPIO_IN(3) <= IRC_INDEX;
209 gpio_0 : entity work.gpio
214 ADR_I => per_addr (1 downto 0),
225 qcounter_mcu16_0 : entity work.qcounter_mcu16
228 ADR_I => per_addr (0),
235 -- Motor feedback IRQ generator
236 -- f_motor_irq approx. 1 kHz
237 mcc_irq_counter_1 : entity work.counter
246 event_ow => MOTOR_IRQ);
249 ------------------------------------------------------------------------------
250 -- Dual-port shared memory
251 ------------------------------------------------------------------------------
252 -- Shared memory between MCU and MCC (size: 16+2 bits x 1k).
253 -- Port A (MCU side) has a priority of writing.
254 shared_mem : RAMB16_S18_S18
256 WRITE_MODE_A => "READ_FIRST",
257 WRITE_MODE_B => "WRITE_FIRST")
260 ADDRA => dmem_addr (9 downto 0),
280 -- B-Port address (10 bits) constructed from IRF_ADR (5 bits). Upper addr bits
281 -- are forced to '0', but in a case of several axes these can be used to
282 -- address memory space of the appropriate one.
283 DPB_ADR (9 downto 5) <= (others => '0');
284 DPB_ADR (4 downto 0) <= IRF_ADR;
286 -- Generation of IRF acknowledge signal for MCC.
287 IRF_ACK <= IRF_STB and (IRF_WE or IRF_ACK_REG);
289 -- IRF_ACK_REG signalizes that data is present on IRF_DAT_O when reading.
290 irf_read : process (mclk, puc) is
292 if rising_edge(mclk) then
296 IRF_ACK_REG <= IRF_STB and not IRF_WE;
302 ------------------------------------------------------------------------------
303 -- Motion Control Chain
304 ------------------------------------------------------------------------------
305 mcc_exec_1 : entity work.mcc_exec
310 MCC_EXEC_I => PWM_OW,
312 MCC_ACK_I => MCC_ACK,
313 MCC_STB_O => MCC_STB);
315 mcc_1 : entity work.mcc
318 LUT_ADR_W => LUT_ADR_W)
324 LUT_STB_O => LUT_STB,
325 LUT_ADR_O => LUT_ADR,
326 LUT_DAT_I => LUT_DAT_O,
327 IRC_DAT_I => QCNT (15 downto 0),
328 PWM_DAT_O => PWM_DAT,
329 PWM1_STB_O => PWM1_STB,
330 PWM2_STB_O => PWM2_STB,
331 PWM3_STB_O => PWM3_STB,
332 IRF_ACK_I => IRF_ACK,
333 IRF_ADR_O => IRF_ADR,
334 IRF_DAT_I => IRF_DAT_O,
335 IRF_DAT_O => IRF_DAT_I,
336 IRF_STB_O => IRF_STB,
339 wave_table_1 : entity work.wave_table
343 INIT_FILE => LUT_INIT)
348 DAT_I => conv_std_logic_vector(0, PWM_W),
354 ------------------------------------------------------------------------------
356 ------------------------------------------------------------------------------
357 -- PWM counter is shared by all PWM generators. Generator contains only
358 -- comparator and desired value.
359 counter_1 : entity work.counter
370 pwm_1 : entity work.pwm
382 pwm_2 : entity work.pwm
394 pwm_3 : entity work.pwm
406 -- PWM signals mapped to FPGA outputs, EN forced to '1'
413 -- PWM is signalized on LEDs
418 qcounter_1 : entity work.qcounter