]> rtime.felk.cvut.cz Git - fpga/virtex2/msp_motion.git/blob - msp_motion.vhd
Makefile - save xst report in xst.log file.
[fpga/virtex2/msp_motion.git] / msp_motion.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5
6 library unisim;
7 use unisim.vcomponents.all;
8
9 --------------------------------------------------------------------------------
10
11 entity msp_motion is
12   port (
13     -- Clock & reset
14     CLK_24MHz : in  std_logic;
15     RESET     : in  std_logic;
16     -- RS232
17     RXD       : in  std_logic;
18     TXD       : out std_logic;
19     -- LED
20     LED0      : out std_logic;
21     LED1      : out std_logic;
22     LED2      : out std_logic;
23     -- PWM
24     PWM0      : out std_logic;
25     PWM0_EN   : out std_logic;
26     PWM1      : out std_logic;
27     PWM1_EN   : out std_logic;
28     PWM2      : out std_logic;
29     PWM2_EN   : out std_logic;
30     -- IRC
31     IRC_INDEX : in  std_logic;
32     IRC_A     : in  std_logic;
33     IRC_B     : in  std_logic;
34     -- HALL
35     HAL0      : in  std_logic;
36     HAL1      : in  std_logic;
37     HAL2      : in  std_logic);
38 end msp_motion;
39
40 --------------------------------------------------------------------------------
41
42 architecture rtl of msp_motion is
43
44   ------------------------------------------------------------------------------
45   -- OpenMSP430 softcore MCU module
46   ------------------------------------------------------------------------------
47   signal mclk      : std_logic;
48   signal puc       : std_logic;
49   -- External data bus
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);
55   -- Peripheral bus
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);
62   -- Interrupt
63   signal irq       : std_logic_vector (13 downto 0);
64   signal irq_acc   : std_logic_vector (13 downto 0);
65
66   ------------------------------------------------------------------------------
67   -- MCU peripherals
68   ------------------------------------------------------------------------------
69   -- GPIO
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;
79   
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);
93
94   ------------------------------------------------------------------------------
95   -- Motion Control Chain
96   ------------------------------------------------------------------------------
97   -- Constants
98   constant PWM_W     : integer := 10;
99   constant LUT_ADR_W : integer := 11;
100   constant LUT_INIT  : string  := "sin1000.lut";
101   
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;
116
117   ------------------------------------------------------------------------------
118   -- PWM and IRC
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;
127   -- PWM outputs
128   signal PWM1_OUT : std_logic;
129   signal PWM2_OUT : std_logic;
130   signal PWM3_OUT : std_logic;
131   -- IRC value
132   signal QCNT     : std_logic_vector (31 downto 0);
133   
134 --------------------------------------------------------------------------------
135
136 begin
137   
138   ------------------------------------------------------------------------------
139   -- OpenMSP430 softcore MCU module
140   ------------------------------------------------------------------------------
141   openMSP430_1 : entity work.openMSP430_8_32_mul_dbus
142     port map (
143       dco_clk                  => CLK_24MHz,
144       lfxt_clk                 => '0',
145       reset_n                  => RESET,
146       rxd                      => RXD,
147       txd                      => TXD,
148       per_addr                 => per_addr,
149       per_din                  => per_din,
150       per_dout                 => per_dout,
151       per_wen                  => per_wen,
152       per_en                   => per_en,
153       nmi                      => '0',
154       irq                      => irq,
155       irq_acc                  => irq_acc,
156       aclk_en                  => open,
157       smclk_en                 => open,
158       mclk                     => mclk,
159       puc                      => puc,
160       dmem_addr                => dmem_addr,
161       dmem_ce                  => dmem_ce,
162       dmem_we                  => dmem_we,
163       dmem_din                 => dmem_din,
164       dmem_dout                => dmem_dout);
165
166   -- External data bus address decoder and data multiplexer.
167   ------------------------------------------------------------------------------
168   -- When connection more memories, be aware that 'dmem_dout' can vary only when
169   -- reading cycle is performed. I.e. mux variable must be registered.
170   dmem_dout <= DPA_DAT_O;
171   
172   DPA_SEL <= '1' when dmem_addr (11 downto 10) = "00" else '0';
173   DPA_STB <= dmem_ce and DPA_SEL;
174
175   -- Peripheral bus address decoder and data multiplexer.
176   ------------------------------------------------------------------------------
177   per_dout <= GPIO_DAT_O when GPIO_SEL = '1' else
178               QCNT_DAT_O when QCNT_SEL = '1' else
179               (others => '0');          -- MUST be 0 when nothing is addressed
180   
181   GPIO_SEL <= '1' when per_addr(7 downto 2) = 16#0140#/2/4 else '0';
182   QCNT_SEL <= '1' when per_addr(7 downto 1) = 16#0148#/2/2 else '0';
183
184   -- Interrupt signals
185   ------------------------------------------------------------------------------
186   irq (13 downto 1) <= (others => '0');
187
188   motor_irq_ff : process (mclk, puc) is
189   begin
190     if rising_edge (mclk) then
191       if puc = '1' or irq_acc (0) = '1' then
192         irq (0) <= '0';
193       elsif MOTOR_IRQ = '1' then
194         irq (0) <= '1';
195       end if;
196     end if;
197   end process;
198
199   
200   ------------------------------------------------------------------------------
201   -- MCU peripherals
202   ------------------------------------------------------------------------------
203   GPIO_IN(0) <= HAL0;
204   GPIO_IN(1) <= HAL1;
205   GPIO_IN(2) <= HAL2;
206   GPIO_IN(3) <= IRC_INDEX;
207
208   gpio_0 : entity work.gpio
209     generic map (
210       W => 16)
211     port map (
212       ACK_O  => open,
213       ADR_I  => per_addr (1 downto 0),
214       CLK_I  => mclk,
215       DAT_I  => per_din,
216       DAT_O  => GPIO_DAT_O,
217       RST_I  => puc,
218       SEL_I  => GPIO_SEL,
219       STB_I  => per_en,
220       WE_I   => per_wen16,
221       GPIO_I => GPIO_IN,
222       GPIO_O => GPIO_OUT);
223
224   qcounter_mcu16_0 : entity work.qcounter_mcu16
225     port map (
226       ACK_O  => open,
227       ADR_I  => per_addr (0),
228       CLK_I  => mclk,
229       DAT_O  => QCNT_DAT_O,
230       SEL_I  => QCNT_SEL,
231       STB_I  => per_en,
232       QCOUNT => QCNT);
233
234   -- Motor feedback IRQ generator
235   -- f_motor_irq approx. 1 kHz
236   mcc_irq_counter_1 : entity work.counter
237     generic map (
238       WIDTH => 5,
239       MAX   => 22)
240     port map (
241       clk      => mclk,
242       clk_en   => PWM_OW,
243       reset    => puc,
244       count    => open,
245       event_ow => MOTOR_IRQ);
246
247
248   ------------------------------------------------------------------------------
249   -- Dual-port shared memory
250   ------------------------------------------------------------------------------
251   -- Shared memory between MCU and MCC (size: 16+2 bits x 1k).
252   -- Port A (MCU side) has a priority of writing.
253   shared_mem : RAMB16_S18_S18
254     generic map (
255       WRITE_MODE_A => "READ_FIRST",
256       WRITE_MODE_B => "WRITE_FIRST")
257     port map (
258       -- A-Port (MCU)
259       ADDRA => dmem_addr (9 downto 0),
260       CLKA  => mclk,
261       DIA   => dmem_din,
262       DIPA  => "00",
263       DOA   => DPA_DAT_O,
264       DOPA  => open,
265       ENA   => DPA_STB,
266       SSRA  => '0',
267       WEA   => dmem_we,
268       -- B-Port (MCC)
269       ADDRB => DPB_ADR,
270       CLKB  => mclk,
271       DIB   => IRF_DAT_I,
272       DIPB  => "00",
273       DOB   => IRF_DAT_O,
274       DOPB  => open,
275       ENB   => IRF_STB,
276       SSRB  => '0',
277       WEB   => IRF_WE);
278
279   -- B-Port address (10 bits) constructed from IRF_ADR (5 bits). Upper addr bits
280   -- are forced to '0', but in a case of several axes these can be used to
281   -- address memory space of the appropriate one.
282   DPB_ADR (9 downto 5) <= (others => '0');
283   DPB_ADR (4 downto 0) <= IRF_ADR;
284   
285   -- Generation of IRF acknowledge signal for MCC.
286   IRF_ACK <= IRF_STB and (IRF_WE or IRF_ACK_REG);
287
288   -- IRF_ACK_REG signalizes that data is present on IRF_DAT_O when reading.
289   irf_read : process (mclk, puc) is
290   begin
291     if rising_edge(mclk) then
292       if puc = '1' then
293         IRF_ACK_REG <= '0';
294       else
295         IRF_ACK_REG <= IRF_STB  and not IRF_WE;
296       end if;
297     end if;
298   end process;
299
300   
301   ------------------------------------------------------------------------------
302   -- Motion Control Chain
303   ------------------------------------------------------------------------------
304   mcc_exec_1 : entity work.mcc_exec
305     port map (
306       CLK_I      => mclk,
307       RST_I      => puc,
308       MCC_EN_I   => '1',
309       MCC_EXEC_I => PWM_OW,
310       MCC_ERR_O  => open,
311       MCC_ACK_I  => MCC_ACK,
312       MCC_STB_O  => MCC_STB);
313   
314   mcc_1 : entity work.mcc
315     generic map (
316       LUT_DAT_W => PWM_W,
317       LUT_ADR_W => LUT_ADR_W)
318     port map (
319       ACK_O      => MCC_ACK,
320       CLK_I      => mclk,
321       RST_I      => puc,
322       STB_I      => MCC_STB,
323       LUT_STB_O  => LUT_STB,
324       LUT_ADR_O  => LUT_ADR,
325       LUT_DAT_I  => LUT_DAT_O,
326       IRC_DAT_I  => QCNT (15 downto 0),
327       PWM_DAT_O  => PWM_DAT,
328       PWM1_STB_O => PWM1_STB,
329       PWM2_STB_O => PWM2_STB,
330       PWM3_STB_O => PWM3_STB,
331       IRF_ACK_I  => IRF_ACK,
332       IRF_ADR_O  => IRF_ADR,
333       IRF_DAT_I  => IRF_DAT_O,
334       IRF_DAT_O  => IRF_DAT_I,
335       IRF_STB_O  => IRF_STB,
336       IRF_WE_O   => IRF_WE);
337
338   wave_table_1 : entity work.wave_table
339     generic map (
340       DAT_W     => PWM_W,
341       ADR_W     => LUT_ADR_W,
342       INIT_FILE => LUT_INIT)
343     port map (
344       ACK_O => open,
345       ADR_I => LUT_ADR,
346       CLK_I => mclk,
347       DAT_I => conv_std_logic_vector(0, PWM_W),
348       DAT_O => LUT_DAT_O,
349       STB_I => LUT_STB,
350       WE_I  => '0');
351
352
353   ------------------------------------------------------------------------------
354   -- PWM and IRC
355   ------------------------------------------------------------------------------
356   -- PWM counter is shared by all PWM generators. Generator contains only
357   -- comparator and desired value.
358   counter_1 : entity work.counter
359     generic map (
360       WIDTH => PWM_W,
361       MAX   => 2**PWM_W - 2)
362     port map (
363       clk      => mclk,
364       clk_en   => '1',
365       reset    => puc,
366       count    => PWM_CNT,
367       event_ow => PWM_OW);
368
369     pwm_1 : entity work.pwm
370     generic map (
371       PWM_WIDTH => PWM_W)
372     port map (
373       clk     => mclk,
374       reset   => puc,
375       din     => PWM_DAT,
376       we      => PWM1_STB,
377       pwm_cnt => PWM_CNT,
378       pwm_cyc => PWM_OW,
379       pwm     => PWM1_OUT);
380
381   pwm_2 : entity work.pwm
382     generic map (
383       PWM_WIDTH => PWM_W)
384     port map (
385       clk     => mclk,
386       reset   => puc,
387       din     => PWM_DAT,
388       we      => PWM2_STB,
389       pwm_cnt => PWM_CNT,
390       pwm_cyc => PWM_OW,
391       pwm     => PWM2_OUT);
392   
393   pwm_3 : entity work.pwm
394     generic map (
395       PWM_WIDTH => PWM_W)
396     port map (
397       clk     => mclk,
398       reset   => puc,
399       din     => PWM_DAT,
400       we      => PWM3_STB,
401       pwm_cnt => PWM_CNT,
402       pwm_cyc => PWM_OW,
403       pwm     => PWM3_OUT);
404
405   -- PWM signals mapped to FPGA outputs, EN forced to '1'
406   PWM0    <= PWM1_OUT;
407   PWM0_EN <= '1';
408   PWM1    <= PWM2_OUT;
409   PWM1_EN <= '1';
410   PWM2    <= PWM3_OUT;
411   PWM2_EN <= '1';
412   -- PWM is signalized on LEDs
413   LED0    <= PWM1_OUT;
414   LED1    <= PWM2_OUT;
415   LED2    <= PWM3_OUT;
416
417   qcounter_1 : entity work.qcounter
418     port map (
419       clock    => mclk,
420       reset    => puc,
421       a0       => IRC_A,
422       b0       => IRC_B,
423       qcount   => QCNT,
424       a_rise   => open,
425       a_fall   => open,
426       b_rise   => open,
427       b_fall   => open,
428       ab_event => open,
429       ab_error => open);
430
431   
432 end rtl;
433