我正在使用高速时钟(来自内部PLL),并试图对其进行分频以生成2个时钟,它们具有不同的占空比和相位关系。如果我单步输入时钟,代码将正确运行。随着频率的增加,辅助输出的相位和占空比(代码样本中的iDM_out)会损坏。在某些频率下,次级输出的占空比将是正确的。在其他频率下,占空比可能达到90%或199%。同相位关系(DMDelay)。我似乎有一些有关时钟缓冲器需求的文章,所以我在输出上尝试了几种类型的BUFF,CLKBUF和CLKINT,这似乎使情况变得更糟。是否有人对造成这种情况的原因有任何想法?
use work.A208_pckgs.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DutyPhaseMod is
port (
rst : in std_logic;
GLA : in std_logic; -- GLA is 36x faster than target frequency
EXDuty : in std_logic_vector(4 downto 0); -- the number of GLA clock cycles for the EX duty cycle
DMDuty : in std_logic_vector(4 downto 0); -- the number of GLA clock cycles for the DM duty cycle
DMDelay : in std_logic_vector(4 downto 0); -- the number of GLA clock cycles for the DM phase delay
EX_out : out std_logic;
DM_out : out std_logic
);
end entity;
architecture behavioral of DutyPhaseMod is
signal iGLA : std_logic;
signal iFREQlen : integer range 0 to 35;
begin
process (rst, GLA)
variable iEX_out : std_logic;
variable iDM_out : std_logic;
variable iEXctr : natural range 0 to 35;
variable iDMctr : natural range 0 to 35;
begin
iFREQlen <= 35; -- number of clock cycles
if rst = '1' then -- reset the counters on reset signal
iEXctr := 0;
iDMctr := 0;
elsif rising_edge(GLA) then
if iEXctr <= unsigned(EXDuty) then -- first part of EX the duty cycle
iEX_out := '1';
iEXctr := iEXctr + 1;
elsif iEXctr < iFREQlen then -- second part of EX duty cycle
iEX_out := '0';
iEXctr := iEXctr + 1;
else -- set for the start of the next cycle
iEX_out := '1';
iEXctr := 0;
end if;
if iEXctr = unsigned(DMDelay) then -- reset for DM phase offset
iDMctr := 0;
elsif iDMctr <= unsigned(DMDuty) then -- first part of the DM duty cycle
iDM_out := '1';
iDMctr := iDMctr + 1;
elsif iDMctr <= iFREQlen - 1 then -- second part of the DM duty cycle
iDM_out := '0';
iDMctr := iDMctr + 1;
else -- set for the start of the next cycle
iDM_out := '1';
end if;
EX_out <= iEX_out;
DM_out <= iDM_out;
end if;
end process;
end behavioral;
答案 0 :(得分:0)
我要弯腰回答自己的问题。如果您认为我的答案不正确(或可以进一步添加/阐明),请随时发表评论。我决定将我的实体分为两个过程,并且看来工作正常。第一个过程在高速时钟的rising_edge上处理基本时钟划分。第二个过程在高速时钟的下降沿处理辅助(相位延迟)时钟。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity DutyPhaseMod is
port (
rst : in std_logic;
GLA : in std_logic;
EXDuty : in std_logic_vector(3 downto 0);
DMDuty : in std_logic_vector(3 downto 0);
DMDelay : in std_logic_vector(4 downto 0);
EX_out : out std_logic;
DM_out : out std_logic
);
end entity;
architecture behavioral of DutyPhaseMod is
signal iGLA : std_logic;
signal iFREQlen : integer range 0 to 35;
signal iEXctr : natural range 0 to 35;
begin
process (rst, GLA)
variable iEX_out : std_logic;
begin
iFREQlen <= 35;
if rst = '1' then
iEXctr <= 0;
elsif rising_edge(GLA) then
if iEXctr <= unsigned(EXDuty) then
iEX_out := '1'; --
iEXctr <= iEXctr + 1;
elsif iEXctr < iFREQlen then
iEX_out := '0';
iEXctr <= iEXctr + 1;
else
iEX_out := '1';
iEXctr <= 0;
end if;
EX_out <= iEX_out;
end if;
end process;
process (rst, GLA)
variable iDM_out : std_logic;
variable iDMctr : natural range 0 to 30;
begin
case FW_FREQ is
when F_46 =>
iFREQlen <= 35;
when F_82 =>
iFREQlen <= 23;
end case;
if rst = '1' then
iDMctr := 0;
elsif falling_edge(GLA) then
if iEXctr = unsigned(DMDelay) then
iDMctr := 0;
elsif iDMctr <= unsigned(DMDuty) then
iDM_out := '1';
iDMctr := iDMctr + 1;
elsif iDMctr <= iFREQlen - 1 then
iDM_out := '0';
iDMctr := iDMctr + 1;
else
iDM_out := '1';
end if;
DM_out <= iDM_out;
end if;
end process;
end behavioral;