📄 xilinx_simprims.vhd
字号:
if (rst_ipd'event) then clkout_delay <= 0 ps; elsif (period'event or fb_delay'event) then clkout_delay <= period - fb_delay; end if; wait on period, fb_delay, rst_ipd; end process calculate_clkout_delay;----generate master reset signal-- gen_master_rst : process begin if (rising_edge(clkin_ipd)) then rst_reg(2) <= rst_reg(1) and rst_reg(0) and rst_ipd; rst_reg(1) <= rst_reg(0) and rst_ipd; rst_reg(0) <= rst_ipd; end if; wait on clkin_ipd; end process gen_master_rst; check_rst_width : process variable Message : line; begin if (falling_edge(rst_ipd)) then if ((rst_reg(2) and rst_reg(1) and rst_reg(0)) = '0') then Write ( Message, string'(" Timing Violation Error : RST on instance ")); Write ( Message, Instancepath ); Write ( Message, string'(" must be asserted for 3 CLKIN clock cycles. ")); assert false report Message.all severity error; DEALLOCATE (Message); end if; end if; wait on rst_ipd; end process check_rst_width;----phase shift parameters-- determine_phase_shift : process variable Message : line; variable FINE_SHIFT_RANGE : time; variable first_time : boolean := true; variable ps_in : integer; begin if (first_time = true) then if ((CLKOUT_PHASE_SHIFT = "none") or (CLKOUT_PHASE_SHIFT = "NONE")) then ps_in := 256; elsif ((CLKOUT_PHASE_SHIFT = "fixed") or (CLKOUT_PHASE_SHIFT = "FIXED")) then ps_in := 256 + PHASE_SHIFT; elsif ((CLKOUT_PHASE_SHIFT = "variable") or (CLKOUT_PHASE_SHIFT = "VARIABLE")) then ps_in := 256 + PHASE_SHIFT; end if; first_time := false; end if; if (rst_ipd'event) then if ((CLKOUT_PHASE_SHIFT = "none") or (CLKOUT_PHASE_SHIFT = "NONE")) then ps_in := 256; elsif ((CLKOUT_PHASE_SHIFT = "fixed") or (CLKOUT_PHASE_SHIFT = "FIXED")) then ps_in := 256 + PHASE_SHIFT; elsif ((CLKOUT_PHASE_SHIFT = "variable") or (CLKOUT_PHASE_SHIFT = "VARIABLE")) then ps_in := 256 + PHASE_SHIFT; else end if; ps_lock <= '0'; ps_overflow_out <= '0'; ps_delay <= 0 ps; else if (rising_edge (lock_period)) then if (ps_type = 1) then FINE_SHIFT_RANGE := 10000 ps; elsif (ps_type = 2) then FINE_SHIFT_RANGE := 5000 ps; end if; ps_delay <= (ps_in * period_div / 256); if (PHASE_SHIFT > 0) then if (((ps_in * period_orig) / 256) > (period_orig + FINE_SHIFT_RANGE)) then Write ( Message, string'(" Timing Violation Error : FINE_SHIFT_RANGE on instance ")); Write ( Message, Instancepath ); Write ( Message, string'(" exceeds ")); Write ( Message, FINE_SHIFT_RANGE / 1000.0); Write ( Message, string'(" PHASE_SHIFT * PERIOD/256 = ")); Write ( Message, PHASE_SHIFT); Write ( Message, string'(" * ")); Write ( Message, period_orig / 1000.0/256); Write ( Message, string'(" = ")); Write ( Message, (PHASE_SHIFT) * period_orig / 256 / 1000.0); assert false report Message.all severity error; DEALLOCATE (Message); end if; elsif (PHASE_SHIFT < 0) then if ((period_orig > FINE_SHIFT_RANGE) and ((ps_in * period_orig / 256) < period_orig - FINE_SHIFT_RANGE)) then Write ( Message, string'(" Timing Violation Error : FINE_SHIFT_RANGE on instance ")); Write ( Message, Instancepath ); Write ( Message, string'(" exceeds ")); Write ( Message, FINE_SHIFT_RANGE / 1000.0); Write ( Message, string'(" PHASE_SHIFT * PERIOD/256 = ")); Write ( Message, PHASE_SHIFT); Write ( Message, string'(" * ")); Write ( Message, period_orig / 1000.0/256); Write ( Message, string'(" = ")); Write ( Message, -(PHASE_SHIFT) * period_orig / 256 / 1000.0); assert false report Message.all severity error; DEALLOCATE (Message); end if; end if; end if; if (rising_edge(PSCLK_ipd)) then if (ps_type = 2) then if (psen_ipd = '1') then if (ps_lock = '1') then Write ( Message, string'(" Timing Violation Warning : Please wait for PSDONE signal before adjusting the Phase Shift. ")); assert false report Message.all severity warning; DEALLOCATE (Message); else if (psincdec_ipd = '1') then if (ps_in = 511) then ps_overflow_out <= '1'; elsif (((ps_in + 1) * period_orig / 256) > period_orig + FINE_SHIFT_RANGE) then ps_overflow_out <= '1'; else ps_in := ps_in + 1; ps_delay <= (ps_in * period_div / 256); ps_overflow_out <= '0'; end if; ps_lock <= '1'; elsif (psincdec_ipd = '0') then if (ps_in = 1) then ps_overflow_out <= '1'; elsif ((period_orig > FINE_SHIFT_RANGE) and (((ps_in - 1) * period_orig / 256) < period_orig - FINE_SHIFT_RANGE)) then ps_overflow_out <= '1'; else ps_in := ps_in - 1; ps_delay <= (ps_in * period_div / 256); ps_overflow_out <= '0'; end if; ps_lock <= '1'; end if; end if; end if; end if; end if; end if; if (ps_lock_temp'event) then ps_lock <= ps_lock_temp; end if; wait on lock_period, psclk_ipd, ps_lock_temp, rst_ipd; end process determine_phase_shift; determine_psdone_out : process begin if (rising_edge(ps_lock)) then ps_lock_temp <= '1'; wait until (rising_edge(clkin_ps)); wait until (rising_edge(psclk_ipd)); wait until (rising_edge(psclk_ipd)); wait until (rising_edge(psclk_ipd)); psdone_out <= '1'; wait until (rising_edge(psclk_ipd)); psdone_out <= '0'; ps_lock_temp <= '0'; end if; wait on ps_lock; end process determine_psdone_out;----determine clock period-- determine_clock_period : process variable clkin_edge_previous : time := 0 ps; variable clkin_edge_current : time := 0 ps; begin if (rst_ipd'event) then clkin_period_real(0) <= 0 ps; clkin_period_real(1) <= 0 ps; clkin_period_real(2) <= 0 ps; clkin_edge_previous := 0 ps; clkin_edge_current := 0 ps; elsif (rising_edge(clkin_div)) then clkin_edge_previous := clkin_edge_current; clkin_edge_current := NOW; clkin_period_real(2) <= clkin_period_real(1); clkin_period_real(1) <= clkin_period_real(0); if (clkin_edge_previous /= 0 ps) then clkin_period_real(0) <= clkin_edge_current - clkin_edge_previous; end if; end if; if (no_stop'event) then clkin_period_real(0) <= clkin_period_real0_temp; end if; wait on clkin_div, no_stop, rst_ipd; end process determine_clock_period; evaluate_clock_period : process variable clock_stopped : std_ulogic := '1'; variable Message : line; begin if (rst_ipd'event) then lock_period <= '0'; clock_stopped := '1'; clkin_period_real0_temp <= 0 ps; else if (falling_edge(clkin_div)) then if (lock_period = '0') then if ((clkin_period_real(0) /= 0 ps ) and (clkin_period_real(0) - cycle_jitter <= clkin_period_real(1)) and (clkin_period_real(1) <= clkin_period_real(0) + cycle_jitter) and (clkin_period_real(1) - cycle_jitter <= clkin_period_real(2)) and (clkin_period_real(2) <= clkin_period_real(1) + cycle_jitter)) then lock_period <= '1'; period_orig <= (clkin_period_real(0) + clkin_period_real(1) + clkin_period_real(2)) / 3; period <= clkin_period_real(0); end if; elsif (lock_period = '1') then if (100000000 ps < clkin_period_real(0)/1000) then Write ( Message, string'(" Timing Violation Error : CLKIN stopped toggling on instance ")); Write ( Message, Instancepath ); Write ( Message, string'(" exceeds ")); Write ( Message, string'(" 10000 ")); Write ( Message, string'(" Current CLKIN Period = ")); Write ( Message, string'(" clkin_period(0) / 10000.0 ")); Write ( Message, string'(" ns ")); assert false report Message.all severity warning; DEALLOCATE (Message); lock_period <= '0'; wait until (falling_edge(rst_reg(2))); elsif ((period_orig * 2 < clkin_period_real(0)) and (clock_stopped = '0')) then clkin_period_real0_temp <= clkin_period_real(1); no_stop <= not no_stop; clock_stopped := '1'; elsif ((clkin_period_real(0) < period_orig - period_jitter) or (period_orig + period_jitter < clkin_period_real(0))) then Write ( Message, string'(" Timing Violation Error : Input Clock Period Jitter on instance ")); Write ( Message, Instancepath ); Write ( Message, string'(" exceeds ")); Write ( Message, period_jitter / 1000.0 ); Write ( Message, string'(" Locked CLKIN Period = ")); Write ( Message, period_orig / 1000.0 ); Write ( Message, string'(" Current CLKIN Period = ")); Write ( Message, clkin_period_real(0) / 1000.0 ); assert false report Message.all severity warning; DEALLOCATE (Message); lock_period <= '0'; wait until (falling_edge(rst_reg(2))); elsif ((clkin_period_real(0) < clkin_period_real(1) - cycle_jitter) or (clkin_period_real(1) + cycle_jitter < clkin_period_real(0))) then Write ( Message, string'(" Timing Violation Error : Input Clock Cycle Jitter on on instance ")); Write ( Message, Instancepath ); Write ( Message, string'(" exceeds ")); Write ( Message, cycle_jitter / 1000.0 ); Write ( Message, string'(" Previous CLKIN Period = ")); Write ( Message, clkin_period_real(1) / 1000.0 ); Write ( Message, string'(" Current CLKIN Period = ")); Write ( Message, clkin_period_real(0) / 1000.0 ); assert false report Message.all severity warning; DEALLOCATE (Message); lock_period <= '0'; wait until (falling_edge(rst_reg(2))); else period <= clkin_period_real(0); clock_stopped := '0'; end if; end if; end if; end if; wait on clkin_div, rst_ipd; end process evaluate_clock_period;----determine clock delay-- determine_clock_delay : process variable delay_edge : time := 0 ps; variable temp1 : integer := 0; variable temp2 : integer := 0; variable temp : integer := 0; variable delay_edge_current : time := 0 ps; begin if (rst_ipd'event) then fb_delay <= 0 ps; fb_delay_found <= '0'; else if (rising_edge(lock_period)) then if ((lock_period = '1') and (clkfb_type /= 0)) then if (clkfb_type = 1) then wait until ((rising_edge(clk0_temp)) or (rst_ipd'event)); delay_edge := NOW; elsif (clkfb_type = 2) then wait until ((rising_edge(clk2x_temp)) or (rst_ipd'event)); delay_edge := NOW; end if; wait until ((rising_edge(clkfb_ipd)) or (rst_ipd'event)); temp1 := ((NOW*1) - (delay_edge*1))/ (1 ps); temp2 := (period_orig * 1)/ (1 ps); temp := temp1 mod temp2; fb_delay <= temp * 1 ps; end if; end if; fb_delay_found <= '1'; end if; wait on lock_period, rst_ipd; end process determine_clock_delay;---- determine feedback lock-- GEN_CLKFB_WINDOW : process begin if (rst_ipd'event) then clkfb_window <= '0'; else if (rising_edge(CLKFB_ipd)) then wait for 0 ps; clkfb_window <= '1'; wait for cycle_jitter; clkfb_window <= '0'; end if; end if; wait on clkfb_ipd, rst_ipd; end process GEN_CLKFB_WINDOW; GEN_CLKIN_WINDOW : process begin if (rst_ipd'event) then clkin_window <= '0'; else if (rising_edge(clkin_fb)) then wait for 0 ps; clkin_window <= '1'; wait for cycle_jitter; clkin_window <= '0'; end if; end if; wait on clkin_fb, rst_ipd; end process GEN_CLKIN_WINDOW; set_reset_lock_clkin : process begin if (rst_ipd'event) then lock_clkin <= '0'; else if (rising_edge(clkin_fb)) then wait for 1 ps; if ((clkfb_window = '1') and (fb_delay_found = '1')) then lock_clkin <= '1'; else lock_clkin <= '0'; end if; end if; end if; wait on clkin_fb, rst_ipd; end process set_reset_lock_clkin; set_reset_lock_clkfb : process begin if (rst_ipd'event) then lock_clkfb <= '0'; else if (rising_edge(clkfb_ipd)) then wait for 1 ps; if ((clkin_window = '1') and (fb_delay_found = '1')) then lock_clkfb <= '1'; else lock_clkfb <= '0'; end if; end if; end if; wait on clkfb_ipd, rst_ipd; end process set_reset_lock_clkfb; assign_lock_delay : process begin if (rst_ipd'event) then lock_delay <= '0'; else if (falling_edge(clkin_fb)) then lock_delay <= lock_clkin or lock_clkfb; end if; end if; wait on clkin_fb, rst_ipd; end process;----generate lock signal-- generate_lock : process begin if (rst_ipd'event) then lock_out <= "00"; locked_out <= '0'; else if (rising_edge(clkin_ps)) then if (clkfb_type = 0) then lock_out(0) <= lock_period; else lock_out(0) <= lock_period and lock_delay and lock_fb; end if; lock_out(1) <= lock_out(0); locked_out <= lock_out(1); end if; end if; wait on clkin_ps, rst_ipd; end process generate_lock;----generate the clk1x_out-- gen_clk1x : process begin if (rst_ipd'event) then clkin_5050 <= '0'; else if (rising_edge(clkin_ps)) then clkin_5050 <= '1';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -