【问题标题】:Pseudo Random Number Generator using LFSR in VHDL在 VHDL 中使用 LFSR 的伪随机数生成器
【发布时间】:2017-08-22 04:57:30
【问题描述】:

我在使用 lfsr 方法创建 prng 时遇到了一些麻烦。这是我的代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity pseudorng is
Port ( clock : in STD_LOGIC;
       reset : in STD_LOGIC;
       Q : out STD_LOGIC_VECTOR (7 downto 0);
       check: out STD_LOGIC);

       constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;

architecture Behavioral of pseudorng is

signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0);

begin

PROCESS(clock)
BEGIN

IF rising_edge(clock) THEN
IF (reset='1') THEN Qt <= "00000000";
ELSE Qt <= seed; 
END IF;
temp <= Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
--Qt <= temp & Qt(7 downto 1);

END IF;
END PROCESS;

check <= temp;
Q <= Qt;

end Behavioral;

这是我运行的模拟: prng sim

首先,检查输出就在那里,所以我可以监控温度信号的输出。其次,被注释掉的行是导致问题的原因。

从仿真中可以看出,在时钟的第一个上升沿,Qt 信号读取种子。但是,这是我的问题,由于某种原因,临时信号仅在时钟的第二个上升沿对 Qt 信号的位进行异或。它在第一个时钟脉冲上保持未定义。这是为什么?如果它在 Qt 信号读取种子后的第一个上升沿上运行,那么我可以取消注释移动位的行,它会解决我的问题。任何帮助将不胜感激!

如果有人关心,这里是测试台:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity tb_pseudorng is
end tb_pseudorng;

architecture bench of tb_pseudorng is

COMPONENT pseudorng
      Port ( clock : in STD_LOGIC;
      reset : in STD_LOGIC;
      Q : out STD_LOGIC_VECTOR (7 downto 0);
      check: out STD_LOGIC);
END COMPONENT;

signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;

begin

mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
Q => Q1,
check => check1);

clock: PROCESS
BEGIN
clock1<='0'; wait for 50ns;
clock1<='1'; wait for 50ns;
END PROCESS;

reset: PROCESS
BEGIN
reset1<='0'; wait for 900ns;
END PROCESS; 

end bench;

【问题讨论】:

    标签: random numbers vhdl generator lfsr


    【解决方案1】:

    我对你所拥有的做了一些细微的修改(不过你几乎在那里);我不认为 LFSR 会正确地采取其他措施。我向 LFSR 添加了一个启用信号,以便您可以有效地控制何时需要它步进。生成的 sim 卡是 here

    顺便说一句,如果您想为 LFSR 设置不同的值(而不是设为 const),还可以包含 loadseed 输入。

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    entity pseudorng is
    Port ( clock : in STD_LOGIC;
           reset : in STD_LOGIC;
           en : in STD_LOGIC;
           Q : out STD_LOGIC_VECTOR (7 downto 0);
           check: out STD_LOGIC);
    
    --       constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
    end pseudorng;
    
    architecture Behavioral of pseudorng is
    
    --signal temp: STD_LOGIC;
    signal Qt: STD_LOGIC_VECTOR(7 downto 0) := x"01";
    
    begin
    
    PROCESS(clock)
    variable tmp : STD_LOGIC := '0';
    BEGIN
    
    IF rising_edge(clock) THEN
       IF (reset='1') THEN
       -- credit to QuantumRipple for pointing out that this should not
       -- be reset to all 0's, as you will enter an invalid state
          Qt <= x"01"; 
       --ELSE Qt <= seed;
       ELSIF en = '1' THEN
          tmp := Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
          Qt <= tmp & Qt(7 downto 1);
       END IF;
    
    END IF;
    END PROCESS;
    -- check <= temp;
    check <= Qt(7);
    Q <= Qt;
    
    end Behavioral;
    

    和结核病:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    entity tb_pseudorng is
    end tb_pseudorng;
    
    architecture bench of tb_pseudorng is
    
    COMPONENT pseudorng
          Port ( clock : in STD_LOGIC;
          reset : in STD_LOGIC;
          en : in STD_LOGIC;
          Q : out STD_LOGIC_VECTOR (7 downto 0);
          check: out STD_LOGIC);
    END COMPONENT;
    
    signal clock1: STD_LOGIC;
    signal reset1: STD_LOGIC;
    signal Q1: STD_LOGIC_VECTOR(7 downto 0);
    signal check1: STD_LOGIC;
    signal en : STD_LOGIC;
    
    begin
    
    mapping: pseudorng PORT MAP(
    clock => clock1,
    reset => reset1,
    en => en,
    Q => Q1,
    check => check1);
    
    clock: PROCESS
    BEGIN
       clock1 <= '0'; wait for 50 ns;
       clock1 <= '1'; wait for 50 ns;
    END PROCESS;
    
    reset: PROCESS
    BEGIN
       reset1 <= '0';
       en <= '1';
       wait for 900 ns;
    END PROCESS;
    
    end bench;
    

    【讨论】:

    • 原始问题“它在第一个时钟脉冲上仍未定义。这是为什么?”是因为在时钟控制过程中分配tmp 添加了一个触发器(即一个延迟周期),然后使用该触发器的输出转移到Qt。这是可以适当使用变量的罕见情况之一。也可以通过同时分配tmp 来避免翻牌,但在这种特殊情况下,它可以更好地使用变量进行扫描。提问者可能想要考虑重置为 0 以外的任何值(例如种子常量),因为 0 是此 LFSR 的死状态。
    • 不错的收获;我完全错过了归零
    猜你喜欢
    • 2013-07-19
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    相关资源
    最近更新 更多