From: Pavel Pisa Date: Fri, 1 May 2015 14:59:49 +0000 (+0200) Subject: Include in PMSM design to implement safe behavior when external clocks are not present. X-Git-Url: https://rtime.felk.cvut.cz/gitweb/fpga/rpi-motor-control.git/commitdiff_plain/24df44d1c49bcb0f29f43f577ef3d245bced9e28 Include in PMSM design to implement safe behavior when external clocks are not present. The PLL is configured to synthesize 200 MHz clock from 50 MHz input. The clock monitor holds PWM outputs low if the external clocks are not present. The reference lost is recognized 6 in 8 cycles of 200 MHz synthesized clock as well. Signed-off-by: Pavel Pisa --- diff --git a/pmsm-control/pll50to200.vhd b/pmsm-control/pll50to200.vhd new file mode 100644 index 0000000..3f110ad --- /dev/null +++ b/pmsm-control/pll50to200.vhd @@ -0,0 +1,124 @@ +-- Version: 9.1 9.1.0.18 + +library ieee; +use ieee.std_logic_1164.all; +library igloo; +use igloo.all; + +entity pll50to200 is + port(POWERDOWN, CLKA : in std_logic; LOCK, GLA : out + std_logic) ; +end pll50to200; + + +architecture DEF_ARCH of pll50to200 is + + component PLL + generic (VCOFREQUENCY:real := 0.0); + + port(CLKA, EXTFB, POWERDOWN : in std_logic := 'U'; GLA, + LOCK, GLB, YB, GLC, YC : out std_logic; OADIV0, OADIV1, + OADIV2, OADIV3, OADIV4, OAMUX0, OAMUX1, OAMUX2, DLYGLA0, + DLYGLA1, DLYGLA2, DLYGLA3, DLYGLA4, OBDIV0, OBDIV1, + OBDIV2, OBDIV3, OBDIV4, OBMUX0, OBMUX1, OBMUX2, DLYYB0, + DLYYB1, DLYYB2, DLYYB3, DLYYB4, DLYGLB0, DLYGLB1, DLYGLB2, + DLYGLB3, DLYGLB4, OCDIV0, OCDIV1, OCDIV2, OCDIV3, OCDIV4, + OCMUX0, OCMUX1, OCMUX2, DLYYC0, DLYYC1, DLYYC2, DLYYC3, + DLYYC4, DLYGLC0, DLYGLC1, DLYGLC2, DLYGLC3, DLYGLC4, + FINDIV0, FINDIV1, FINDIV2, FINDIV3, FINDIV4, FINDIV5, + FINDIV6, FBDIV0, FBDIV1, FBDIV2, FBDIV3, FBDIV4, FBDIV5, + FBDIV6, FBDLY0, FBDLY1, FBDLY2, FBDLY3, FBDLY4, FBSEL0, + FBSEL1, XDLYSEL, VCOSEL0, VCOSEL1, VCOSEL2 : in std_logic := + 'U') ; + end component; + + component VCC + port( Y : out std_logic); + end component; + + component GND + port( Y : out std_logic); + end component; + + signal VCC_1_net, GND_1_net : std_logic ; + begin + + VCC_2_net : VCC port map(Y => VCC_1_net); + GND_2_net : GND port map(Y => GND_1_net); + Core : PLL + generic map(VCOFREQUENCY => 200.000) + + port map(CLKA => CLKA, EXTFB => GND_1_net, POWERDOWN => + POWERDOWN, GLA => GLA, LOCK => LOCK, GLB => OPEN , YB => + OPEN , GLC => OPEN , YC => OPEN , OADIV0 => GND_1_net, + OADIV1 => GND_1_net, OADIV2 => GND_1_net, OADIV3 => + GND_1_net, OADIV4 => GND_1_net, OAMUX0 => GND_1_net, + OAMUX1 => GND_1_net, OAMUX2 => VCC_1_net, DLYGLA0 => + GND_1_net, DLYGLA1 => GND_1_net, DLYGLA2 => GND_1_net, + DLYGLA3 => GND_1_net, DLYGLA4 => GND_1_net, OBDIV0 => + GND_1_net, OBDIV1 => GND_1_net, OBDIV2 => GND_1_net, + OBDIV3 => GND_1_net, OBDIV4 => GND_1_net, OBMUX0 => + GND_1_net, OBMUX1 => GND_1_net, OBMUX2 => GND_1_net, + DLYYB0 => GND_1_net, DLYYB1 => GND_1_net, DLYYB2 => + GND_1_net, DLYYB3 => GND_1_net, DLYYB4 => GND_1_net, + DLYGLB0 => GND_1_net, DLYGLB1 => GND_1_net, DLYGLB2 => + GND_1_net, DLYGLB3 => GND_1_net, DLYGLB4 => GND_1_net, + OCDIV0 => GND_1_net, OCDIV1 => GND_1_net, OCDIV2 => + GND_1_net, OCDIV3 => GND_1_net, OCDIV4 => GND_1_net, + OCMUX0 => GND_1_net, OCMUX1 => GND_1_net, OCMUX2 => + GND_1_net, DLYYC0 => GND_1_net, DLYYC1 => GND_1_net, + DLYYC2 => GND_1_net, DLYYC3 => GND_1_net, DLYYC4 => + GND_1_net, DLYGLC0 => GND_1_net, DLYGLC1 => GND_1_net, + DLYGLC2 => GND_1_net, DLYGLC3 => GND_1_net, DLYGLC4 => + GND_1_net, FINDIV0 => VCC_1_net, FINDIV1 => GND_1_net, + FINDIV2 => GND_1_net, FINDIV3 => VCC_1_net, FINDIV4 => + GND_1_net, FINDIV5 => GND_1_net, FINDIV6 => GND_1_net, + FBDIV0 => VCC_1_net, FBDIV1 => VCC_1_net, FBDIV2 => + VCC_1_net, FBDIV3 => GND_1_net, FBDIV4 => GND_1_net, + FBDIV5 => VCC_1_net, FBDIV6 => GND_1_net, FBDLY0 => + GND_1_net, FBDLY1 => GND_1_net, FBDLY2 => GND_1_net, + FBDLY3 => GND_1_net, FBDLY4 => GND_1_net, FBSEL0 => + VCC_1_net, FBSEL1 => GND_1_net, XDLYSEL => GND_1_net, + VCOSEL0 => VCC_1_net, VCOSEL1 => VCC_1_net, VCOSEL2 => + VCC_1_net); +end DEF_ARCH; + +-- _Disclaimer: Please leave the following comments in the file, they are for internal purposes only._ + + +-- _GEN_File_Contents_ + +-- Version:9.1.0.18 +-- ACTGENU_CALL:1 +-- BATCH:T +-- FAM:IGLOO +-- OUTFORMAT:VHDL +-- LPMTYPE:LPM_PLL_STATIC +-- LPM_HINT:NONE +-- INSERT_PAD:NO +-- INSERT_IOREG:NO +-- GEN_BHV_VHDL_VAL:F +-- GEN_BHV_VERILOG_VAL:F +-- MGNTIMER:F +-- MGNCMPL:T +-- DESDIR:/tmp/igloo/pll50to200 +-- GEN_BEHV_MODULE:F +-- SMARTGEN_DIE:IS4X4M1LP +-- SMARTGEN_PACKAGE:vq100 +-- AGENIII_IS_SUBPROJECT_LIBERO:F +-- FIN:50.000000 +-- CLKASRC:0 +-- FBDLY:1 +-- FBMUX:1 +-- XDLYSEL:0 +-- PRIMFREQ:200.000000 +-- PPHASESHIFT:0 +-- DLYAVAL:1 +-- OAMUX:4 +-- POWERDOWN_POLARITY:0 +-- LOCK_POLARITY:1 +-- LOCK_CTL:1 +-- VOLTAGE:1.5 + +-- _End_Comments_ + diff --git a/pmsm-control/rpi_pmsm_control.sdc b/pmsm-control/rpi_pmsm_control.sdc new file mode 100644 index 0000000..7670b71 --- /dev/null +++ b/pmsm-control/rpi_pmsm_control.sdc @@ -0,0 +1,16 @@ + +# create_clock -name name -period period_value [-waveform edge_list] source +create_clock -name {gpio_clk} -period 20 -waveform {0 10} {p:gpio4} + +#create_clock -name {pll_clkout} -period 5 -waveform {0 2.5} {n:pll_clkout} + +# create_generated_clock -name {name -source reference_pin [-divide_by divide_factor] \ +# [-multiply_by multiply_factor] [-invert] source -pll_output pll_feedback_clock \ +# -pll_feedback pll_feedback_input + +create_generated_clock -name {pll_clkout} \ + -multiply_by 4 \ + -source {n:gpio_clk} \ + {n:pll_clkout} + +# set_false_path -through {n:clkmon_fail} diff --git a/pmsm-control/rpi_pmsm_control.vhdl b/pmsm-control/rpi_pmsm_control.vhdl index 4829beb..c3f8416 100644 --- a/pmsm-control/rpi_pmsm_control.vhdl +++ b/pmsm-control/rpi_pmsm_control.vhdl @@ -93,13 +93,14 @@ architecture behavioral of rpi_pmsm_control is attribute syn_preserve :boolean; attribute syn_keep :boolean; attribute syn_hier :boolean; + -- Actel lib - -- component pll50to200 - -- port ( - -- powerdown, clka: in std_logic; - -- lock, gla: out std_logic - -- ); - -- end component; + component pll50to200 + port ( + powerdown, clka: in std_logic; + lock, gla: out std_logic + ); + end component; component CLKINT port (A: in std_logic; Y: out std_logic); @@ -159,10 +160,18 @@ architecture behavioral of rpi_pmsm_control is signal adc_reset : std_logic; signal adc_channels: std_logic_vector(71 downto 0); signal adc_m_count: std_logic_vector(8 downto 0); - + + --clock signals for logic and master fail monitoring + signal gpio_clk: std_logic; + signal pll_clkin, pll_clkout, pll_lock: std_logic; + signal clkmon_dly1, clkmon_dly2: std_logic; + signal clkmon_fail, clkmon_fail_next: std_logic; + signal clkmon_wdg: integer range 0 to 6; + signal reset_sync, reset_async: std_logic; + signal failsafe, next_failsafe: std_logic; + signal spiclk_old: std_logic_vector(1 downto 0); --pro detekci hrany SPI hodin --signal pwm_in, pwm_dir_in: std_logic; - signal gpio_clk: std_logic; signal dat_reg : STD_LOGIC_VECTOR (127 downto 0); --shift register for spi signal position: std_logic_vector(31 downto 0); --pozice z qcounteru signal index_position: std_logic_vector(11 downto 0); --pozice irc_i @@ -202,6 +211,19 @@ begin y => gpio_clk ); + pll: pll50to200 + port map ( + powerdown => '1', + clka => pll_clkin, + gla => pll_clkout, + lock => pll_lock); + + -- the failasfe signal from communication block if CRC is used + next_failsafe <= '0'; + + reset_async <= not pll_lock or clkmon_fail; + + pll_clkin <= gpio_clk; qcount: qcounter port map ( @@ -227,7 +249,7 @@ begin clock => gpio_clk, --50 Mhz clk from gpclk on raspberry sync => pwm_sync, --counter restarts data_valid => income_data_valid, - failsafe => '0', + failsafe => failsafe, -- -- pwm config bits & match word -- @@ -266,19 +288,6 @@ begin ); - - - -- pll: pll50to200 - -- port map ( - -- powerdown => '1', - -- clka => pll_clkin, - -- gla => pll_clkout, - -- lock => pll_lock); - -- -- reset <= not pll_lock; - -- reset <= '0'; -- TODO: apply reset for good failsafe - -- upon power-on - -- clock <= clkm; - dummy_unused <= gpio2 and gpio3 and gpio4 and gpio5 and gpio6 and gpio12 and gpio13 and gpio14 and @@ -372,6 +381,41 @@ begin income_data_valid<='1'; end if; end process; - + + clock_monitor: process (pll_clkout, gpio_clk, clkmon_dly1, clkmon_wdg, clkmon_fail_next) + begin + if pll_clkout'event and pll_clkout = '1' then + clkmon_dly1 <= gpio_clk; + clkmon_dly2 <= clkmon_dly1; + if clkmon_dly1 = '0' and clkmon_dly2 = '1' then + clkmon_wdg <= 6; + clkmon_fail_next <= '0'; + elsif clkmon_wdg > 0 then + clkmon_wdg <= clkmon_wdg - 1; + clkmon_fail_next <= '0'; + else + clkmon_wdg <= 0; + clkmon_fail_next <= '1'; + end if; + clkmon_fail <= clkmon_fail_next; + end if; + end process; + + async_rst: process (gpio_clk, reset_async, reset_sync) + begin + if reset_async = '1' then + failsafe <= '1'; + elsif gpio_clk'event and gpio_clk = '1' then + failsafe <= next_failsafe or reset_sync; + end if; + end process; + + sync_rst: process (gpio_clk, reset_async) + begin + if gpio_clk'event and gpio_clk = '1' then + reset_sync <= reset_async; + end if; + end process; + end behavioral;