]> rtime.felk.cvut.cz Git - fpga/virtex2/msp_motion.git/blob - msp_motion.vhd
GPIO connected to MCU
[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
63   ------------------------------------------------------------------------------
64   -- MCU peripherals
65   ------------------------------------------------------------------------------
66   -- GPIO
67   signal GPIO_IN    : std_logic_vector (15 downto 0);
68   signal GPIO_OUT   : std_logic_vector (15 downto 0);
69   signal GPIO_DAT_O : std_logic_vector (15 downto 0);
70   signal GPIO_SEL   : std_logic;
71   
72   ------------------------------------------------------------------------------
73   -- Dual-port shared memory
74   ------------------------------------------------------------------------------
75   -- These signals of A-port (MCU) enables creation of external data encoder and
76   -- multiplexer in a case of multiple devices connected to the external data
77   -- bus. Otherwise useless.
78   signal DPA_DAT_O   : std_logic_vector (15 downto 0);
79   signal DPA_SEL     : std_logic;
80   signal DPA_STB     : std_logic;
81   -- Auxiliary register used to generate IRF_ACK
82   signal IRF_ACK_REG : std_logic;
83   -- Auxiliary signal used to form B-port address
84   signal DPB_ADR     : std_logic_vector (9 downto 0);
85
86   ------------------------------------------------------------------------------
87   -- Motion Control Chain
88   ------------------------------------------------------------------------------
89   -- Constants
90   constant PWM_W     : integer := 10;
91   constant LUT_ADR_W : integer := 11;
92   constant LUT_INIT  : string  := "sin1000.lut";
93   
94   -- Bus interface to the shared memory
95   signal IRF_ACK   : std_logic;
96   signal IRF_ADR   : std_logic_vector (4 downto 0);
97   signal IRF_DAT_I : std_logic_vector (15 downto 0);
98   signal IRF_DAT_O : std_logic_vector (15 downto 0);
99   signal IRF_STB   : std_logic;
100   signal IRF_WE    : std_logic;
101   -- Wave look-up table
102   signal LUT_ADR   : std_logic_vector (LUT_ADR_W-1 downto 0);
103   signal LUT_DAT_O : std_logic_vector (PWM_W-1 downto 0);
104   signal LUT_STB   : std_logic;
105   -- MCC execution control
106   signal MCC_ACK   : std_logic;
107   signal MCC_STB   : std_logic;
108
109   ------------------------------------------------------------------------------
110   -- PWM and IRC
111   ------------------------------------------------------------------------------
112   signal PWM_CNT  : std_logic_vector (PWM_W-1 downto 0);
113   signal PWM_OW   : std_logic;          -- PWM counter overflow
114   -- PWM interface to the MCC
115   signal PWM_DAT  : std_logic_vector (PWM_W-1 downto 0);
116   signal PWM1_STB : std_logic;
117   signal PWM2_STB : std_logic;
118   signal PWM3_STB : std_logic;
119   -- PWM outputs
120   signal PWM1_OUT : std_logic;
121   signal PWM2_OUT : std_logic;
122   signal PWM3_OUT : std_logic;
123   -- IRC value
124   signal QCNT     : std_logic_vector (31 downto 0);
125   
126 --------------------------------------------------------------------------------
127
128 begin
129   
130   ------------------------------------------------------------------------------
131   -- OpenMSP430 softcore MCU module
132   ------------------------------------------------------------------------------
133   openMSP430_1 : entity work.openMSP430_8_32_mul_dbus
134     port map (
135       dco_clk                  => CLK_24MHz,
136       lfxt_clk                 => '0',
137       reset_n                  => RESET,
138       rxd                      => RXD,
139       txd                      => TXD,
140       per_addr                 => per_addr,
141       per_din                  => per_din,
142       per_dout                 => per_dout,
143       per_wen                  => per_wen,
144       per_en                   => per_en,
145       nmi                      => '0',
146       irq                      => (others => '0'),
147       irq_acc                  => open,
148       aclk_en                  => open,
149       smclk_en                 => open,
150       mclk                     => mclk,
151       puc                      => puc,
152       dmem_addr                => dmem_addr,
153       dmem_ce                  => dmem_ce,
154       dmem_we                  => dmem_we,
155       dmem_din                 => dmem_din,
156       dmem_dout                => dmem_dout);
157
158   -- External data bus address decoder and data multiplexer.
159   ------------------------------------------------------------------------------
160   -- This statement leads to priority encoder (which should be avoided), but for
161   -- a small mux it doesn't matter and it's better readable.
162   dmem_dout <= DPA_DAT_O when DPA_SEL = '1' else
163                (others => 'X');
164   
165   DPA_SEL <= '1' when dmem_addr (11 downto 10) = "00" else '0';
166   DPA_STB <= dmem_ce and DPA_SEL;
167
168   -- Peripheral bus address decoder and data multiplexer.
169   ------------------------------------------------------------------------------
170   per_dout <= GPIO_DAT_O when GPIO_SEL = '1' else
171               (others => '0');          -- MUST be 0 when nothing is addressed
172   
173   GPIO_SEL <= '1' when per_addr(7 downto 2) = 16#0140#/2/4 else '0';
174
175
176   ------------------------------------------------------------------------------
177   -- MCU peripherals
178   ------------------------------------------------------------------------------
179   GPIO_IN(0) <= HAL0;
180   GPIO_IN(1) <= HAL1;
181   GPIO_IN(2) <= HAL2;
182   GPIO_IN(3) <= IRC_INDEX;
183
184   gpio_0 : entity work.gpio
185     generic map (
186       W => 16)
187     port map (
188       ACK_O  => open,
189       ADR_I  => per_addr (1 downto 0),
190       CLK_I  => mclk,
191       DAT_I  => per_din,
192       DAT_O  => GPIO_DAT_O,
193       RST_I  => puc,
194       SEL_I  => GPIO_SEL,
195       STB_I  => per_en,
196       WE_I   => per_wen16,
197       GPIO_I => GPIO_IN,
198       GPIO_O => GPIO_OUT);
199
200
201
202   ------------------------------------------------------------------------------
203   -- Dual-port shared memory
204   ------------------------------------------------------------------------------
205   -- Shared memory between MCU and MCC (size: 16+2 bits x 1k).
206   -- Port A (MCU side) has a priority of writing.
207   shared_mem : RAMB16_S18_S18
208     generic map (
209       WRITE_MODE_A => "READ_FIRST",
210       WRITE_MODE_B => "WRITE_FIRST")
211     port map (
212       -- A-Port (MCU)
213       ADDRA => dmem_addr (9 downto 0),
214       CLKA  => mclk,
215       DIA   => dmem_din,
216       DIPA  => "00",
217       DOA   => DPA_DAT_O,
218       DOPA  => open,
219       ENA   => DPA_STB,
220       SSRA  => '0',
221       WEA   => dmem_we,
222       -- B-Port (MCC)
223       ADDRB => DPB_ADR,
224       CLKB  => mclk,
225       DIB   => IRF_DAT_I,
226       DIPB  => "00",
227       DOB   => IRF_DAT_O,
228       DOPB  => open,
229       ENB   => IRF_STB,
230       SSRB  => '0',
231       WEB   => IRF_WE);
232
233   -- B-Port address (10 bits) constructed from IRF_ADR (5 bits). Upper addr bits
234   -- are forced to '0', but in a case of several axes these can be used to
235   -- address memory space of the appropriate one.
236   DPB_ADR (9 downto 5) <= (others => '0');
237   DPB_ADR (4 downto 0) <= IRF_ADR;
238   
239   -- Generation of IRF acknowledge signal for MCC.
240   IRF_ACK <= IRF_STB and (IRF_WE or IRF_ACK_REG);
241
242   -- IRF_ACK_REG signalizes that data is present on IRF_DAT_O when reading.
243   irf_read : process (mclk, puc) is
244   begin
245     if rising_edge(mclk) then
246       if puc = '1' then
247         IRF_ACK_REG <= '0';
248       else
249         IRF_ACK_REG <= IRF_STB  and not IRF_WE;
250       end if;
251     end if;
252   end process;
253
254   
255   ------------------------------------------------------------------------------
256   -- Motion Control Chain
257   ------------------------------------------------------------------------------
258   mcc_exec_1 : entity work.mcc_exec
259     port map (
260       CLK_I      => mclk,
261       RST_I      => puc,
262       MCC_EN_I   => '1',
263       MCC_EXEC_I => PWM_OW,
264       MCC_ERR_O  => open,
265       MCC_ACK_I  => MCC_ACK,
266       MCC_STB_O  => MCC_STB);
267   
268   mcc_1 : entity work.mcc
269     generic map (
270       LUT_DAT_W => PWM_W,
271       LUT_ADR_W => LUT_ADR_W)
272     port map (
273       ACK_O      => MCC_ACK,
274       CLK_I      => mclk,
275       RST_I      => puc,
276       STB_I      => MCC_STB,
277       LUT_STB_O  => LUT_STB,
278       LUT_ADR_O  => LUT_ADR,
279       LUT_DAT_I  => LUT_DAT_O,
280       IRC_DAT_I  => QCNT (15 downto 0),
281       PWM_DAT_O  => PWM_DAT,
282       PWM1_STB_O => PWM1_STB,
283       PWM2_STB_O => PWM2_STB,
284       PWM3_STB_O => PWM3_STB,
285       IRF_ACK_I  => IRF_ACK,
286       IRF_ADR_O  => IRF_ADR,
287       IRF_DAT_I  => IRF_DAT_O,
288       IRF_DAT_O  => IRF_DAT_I,
289       IRF_STB_O  => IRF_STB,
290       IRF_WE_O   => IRF_WE);
291
292   wave_table_1 : entity work.wave_table
293     generic map (
294       DAT_W     => PWM_W,
295       ADR_W     => LUT_ADR_W,
296       INIT_FILE => LUT_INIT)
297     port map (
298       ACK_O => open,
299       ADR_I => LUT_ADR,
300       CLK_I => mclk,
301       DAT_I => conv_std_logic_vector(0, PWM_W),
302       DAT_O => LUT_DAT_O,
303       STB_I => LUT_STB,
304       WE_I  => '0');
305
306
307   ------------------------------------------------------------------------------
308   -- PWM and IRC
309   ------------------------------------------------------------------------------
310   -- PWM counter is shared by all PWM generators. Generator contains only
311   -- comparator and desired value.
312   counter_1 : entity work.counter
313     generic map (
314       WIDTH => PWM_W,
315       MAX   => 2**PWM_W - 2)
316     port map (
317       clk      => mclk,
318       clk_en   => '1',
319       reset    => puc,
320       count    => PWM_CNT,
321       event_ow => PWM_OW);
322
323     pwm_1 : entity work.pwm
324     generic map (
325       PWM_WIDTH => PWM_W)
326     port map (
327       clk     => mclk,
328       reset   => puc,
329       din     => PWM_DAT,
330       we      => PWM1_STB,
331       pwm_cnt => PWM_CNT,
332       pwm_cyc => PWM_OW,
333       pwm     => PWM1_OUT);
334
335   pwm_2 : entity work.pwm
336     generic map (
337       PWM_WIDTH => PWM_W)
338     port map (
339       clk     => mclk,
340       reset   => puc,
341       din     => PWM_DAT,
342       we      => PWM2_STB,
343       pwm_cnt => PWM_CNT,
344       pwm_cyc => PWM_OW,
345       pwm     => PWM2_OUT);
346   
347   pwm_3 : entity work.pwm
348     generic map (
349       PWM_WIDTH => PWM_W)
350     port map (
351       clk     => mclk,
352       reset   => puc,
353       din     => PWM_DAT,
354       we      => PWM3_STB,
355       pwm_cnt => PWM_CNT,
356       pwm_cyc => PWM_OW,
357       pwm     => PWM3_OUT);
358
359   -- PWM signals mapped to FPGA outputs, EN forced to '1'
360   PWM0    <= PWM1_OUT;
361   PWM0_EN <= '1';
362   PWM1    <= PWM2_OUT;
363   PWM1_EN <= '1';
364   PWM2    <= PWM3_OUT;
365   PWM2_EN <= '1';
366   -- PWM is signalized on LEDs
367   LED0    <= PWM1_OUT;
368   LED1    <= PWM2_OUT;
369   LED2    <= PWM3_OUT;
370
371   qcounter_1 : entity work.qcounter
372     port map (
373       clock    => mclk,
374       reset    => puc,
375       a0       => IRC_A,
376       b0       => IRC_B,
377       qcount   => QCNT,
378       a_rise   => open,
379       a_fall   => open,
380       b_rise   => open,
381       b_fall   => open,
382       ab_event => open,
383       ab_error => open);
384
385   
386 end rtl;
387