You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于VHDL的双环形振荡器及异或输出实现问题咨询

VHDL双环形振荡器异或输出异常排查与实现指导

问题背景

已基于板载内部时钟实现单环形振荡器且运行正常,现需添加第二个环形振荡器,将两者输出异或后存入trn向量,但多次尝试出现输出异常。实体已引入外部时钟clk,疑惑是否只需在进程中调用即可。

现有代码

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.ALL;

entity RO_TRNG is
    Port ( trn : out std_logic_vector(20 downto 0);
       reset : in  STD_LOGIC; 
       sample: in STD_LOGIC;
        clk : in  std_logic);
end entity RO_TRNG;

architecture Behavioral of RO_TRNG is

component iclk is 
port(
      iclk_clk : out std_logic;
        iclk_en_oscena : in std_logic);
end component;


  signal ring    : std_logic_vector(20 downto 0):= "100101101011011101001";
  signal clk_int : std_logic;
  attribute KEEP : string; 
  attribute KEEP of ring : signal is "true"; 

begin

  u0 : COMPONENT iclk port map (iclk_clk=>clk_int,iclk_en_oscena=>'1');
  assert ring'length mod 2 = 1 report "Length of ring must be an odd number!" severity failure;

  trn <= ring when sample ='0';
  
  process (clk_int,ring,reset) begin
  if reset='0' then
      ring <= "100101101011011101001";
  else
      if rising_edge(clk_int) then
          for i in ring'range loop
             if i = ring'left then
                  ring(i) <= not ring(0) after 1ns;
             else
                ring(i)   <= not ring(i+1) after 1ns;
             end if;
          end loop;
          end if;
    end if;
  end process;

end Behavioral;

问题分析与修正方案

核心问题点

  1. 异步逻辑隐患:原有进程敏感列表包含ring,导致每次ring变化都会触发进程,形成异步更新逻辑,易产生毛刺和不稳定输出。
  2. 仿真与综合行为不一致:after 1ns延时仅在仿真中有效,综合工具会直接忽略,导致硬件实际运行行为和仿真结果不符。
  3. 缺乏同步采样机制:直接将环形振荡器输出赋值给trn,未利用外部时钟同步,易引发亚稳态问题;且未实现双振荡器异或逻辑。
  4. 未添加独立的第二振荡器:缺少第二个物理独立的环形振荡器模块,无法实现异或所需的两路独立随机信号。

修正后代码示例

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity RO_TRNG is
    Port ( trn : out std_logic_vector(20 downto 0);
           reset : in  STD_LOGIC; 
           sample: in STD_LOGIC;
           clk : in  std_logic);
end entity RO_TRNG;

architecture Behavioral of RO_TRNG is

component iclk is 
port(
      iclk_clk : out std_logic;
      iclk_en_oscena : in std_logic);
end component;

-- 第一个环形振荡器信号
signal ring1    : std_logic_vector(20 downto 0):= "100101101011011101001";
signal clk_int1 : std_logic;
attribute KEEP : string; 
attribute KEEP of ring1 : signal is "true"; 

-- 第二个环形振荡器信号
signal ring2    : std_logic_vector(20 downto 0):= "011010010100100010110";
signal clk_int2 : std_logic;
attribute KEEP of ring2 : signal is "true"; 

-- 采样后的异或结果寄存器
signal xor_result : std_logic_vector(20 downto 0);

begin

-- 实例化两个独立的内部振荡器
u0 : iclk port map (iclk_clk=>clk_int1, iclk_en_oscena=>'1');
u1 : iclk port map (iclk_clk=>clk_int2, iclk_en_oscena=>'1');

-- 环形振荡器长度校验
assert ring1'length mod 2 = 1 report "Length of ring1 must be an odd number!" severity failure;
assert ring2'length mod 2 = 1 report "Length of ring2 must be an odd number!" severity failure;

-- 第一个环形振荡器逻辑(同步更新)
process (clk_int1, reset) begin
    if reset='0' then
        ring1 <= "100101101011011101001";
    elsif rising_edge(clk_int1) then
        for i in ring1'range loop
            if i = ring1'left then
                ring1(i) <= not ring1(0);
            else
                ring1(i) <= not ring1(i+1);
            end if;
        end loop;
    end if;
end process;

-- 第二个环形振荡器逻辑(同步更新)
process (clk_int2, reset) begin
    if reset='0' then
        ring2 <= "011010010100100010110";
    elsif rising_edge(clk_int2) then
        for i in ring2'range loop
            if i = ring2'left then
                ring2(i) <= not ring2(0);
            else
                ring2(i) <= not ring2(i+1);
            end if;
        end loop;
    end if;
end process;

-- 外部时钟同步采样异或结果并控制输出
process (clk, reset) begin
    if reset='0' then
        xor_result <= (others => '0');
        trn <= (others => '0');
    elsif rising_edge(clk) then
        -- 计算两个环形振荡器的异或结果
        xor_result <= ring1 xor ring2;
        -- 根据sample信号控制trn输出更新
        if sample = '0' then
            trn <= xor_result;
        end if;
    end if;
end process;

end Behavioral;

关键修正说明

  • 同步逻辑规范:移除进程敏感列表中的ring信号,同步逻辑仅保留时钟和复位作为触发条件,避免异步更新隐患。
  • 移除仿真延时:删除after 1ns语句,确保综合后硬件行为与逻辑设计一致。
  • 独立双振荡器:添加独立的ring2信号和iclk实例,FPGA实现时需添加布局约束,防止工具将两个振荡器合并优化,保证物理独立性。
  • 外部时钟同步采样:用外部clk采样两路振荡器输出并计算异或,规避亚稳态问题;通过sample信号同步控制trn的输出时机,符合同步设计要求。

内容的提问来源于stack exchange,提问作者Anuel Abrah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 15:30:54