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