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 ------------------------------------------------------------------------------
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);
70 ------------------------------------------------------------------------------
71 -- Motion Control Chain
72 ------------------------------------------------------------------------------
74 constant PWM_W : integer := 10;
75 constant LUT_ADR_W : integer := 11;
76 constant LUT_INIT : string := "sin1000.lut";
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;
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;
93 ------------------------------------------------------------------------------
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;
104 signal PWM1_OUT : std_logic;
105 signal PWM2_OUT : std_logic;
106 signal PWM3_OUT : std_logic;
108 signal QCNT : std_logic_vector (31 downto 0);
110 --------------------------------------------------------------------------------
114 ------------------------------------------------------------------------------
115 -- OpenMSP430 softcore MCU module
116 ------------------------------------------------------------------------------
117 openMSP430_1 : entity work.openMSP430_8_32_mul_dbus
119 dco_clk => CLK_24MHz,
126 per_dout => (others => '0'),
130 irq => (others => '0'),
136 dmem_addr => dmem_addr,
139 dmem_din => dmem_din,
140 dmem_dout => dmem_dout);
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
149 DPA_SEL <= '1' when dmem_addr (11 downto 10) = "00" else '0';
150 DPA_STB <= dmem_ce and DPA_SEL;
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
160 WRITE_MODE_A => "READ_FIRST",
161 WRITE_MODE_B => "WRITE_FIRST")
164 ADDRA => dmem_addr (9 downto 0),
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;
190 -- Generation of IRF acknowledge signal for MCC.
191 IRF_ACK <= IRF_STB and (IRF_WE or IRF_ACK_REG);
193 -- IRF_ACK_REG signalizes that data is present on IRF_DAT_O when reading.
194 irf_read : process (mclk, puc) is
196 if rising_edge(mclk) then
200 IRF_ACK_REG <= IRF_STB and not IRF_WE;
206 ------------------------------------------------------------------------------
207 -- Motion Control Chain
208 ------------------------------------------------------------------------------
209 mcc_exec_1 : entity work.mcc_exec
214 MCC_EXEC_I => PWM_OW,
216 MCC_ACK_I => MCC_ACK,
217 MCC_STB_O => MCC_STB);
219 mcc_1 : entity work.mcc
222 LUT_ADR_W => LUT_ADR_W)
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,
243 wave_table_1 : entity work.wave_table
247 INIT_FILE => LUT_INIT)
252 DAT_I => conv_std_logic_vector(0, PWM_W),
258 ------------------------------------------------------------------------------
260 ------------------------------------------------------------------------------
261 -- PWM counter is shared by all PWM generators. Generator contains only
262 -- comparator and desired value.
263 counter_1 : entity work.counter
274 pwm_1 : entity work.pwm
286 pwm_2 : entity work.pwm
298 pwm_3 : entity work.pwm
310 -- PWM signals mapped to FPGA outputs, EN forced to '1'
317 -- PWM is signalized on LEDs
322 qcounter_1 : entity work.qcounter