VHDL中的PRBS Generator模块

时间:2013-08-30 12:32:54

标签: vhdl

这里我发布了prbs的快照

我的prbs模块代码是

-- Module Name:    prbs - Behavioral 
-- Project Name:   modulator

-- Description: 
--To make it of N bit replace existing value of N with desired value of N
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity prbs is
    Port ( pclock : in  STD_LOGIC;
            preset : IN std_logic := '0';
           prbsout : out  STD_LOGIC);
end prbs;

architecture Behavioral of prbs is

COMPONENT dff is
    PORT(
        dclock : IN std_logic;
        dreset : IN std_logic;
        din : IN std_logic ;          
        dout : OUT std_logic 
        );
    END COMPONENT;


signal dintern : std_logic_vector (4 downto 1); --Change value of N to change size of shift register
signal feedback : std_logic := '0';

begin

instdff : dff port map (pclock , preset , feedback , dintern(1));
genreg : for i in 2 to 4 generate --Change Value of N Here to generate that many instance of d flip flop
begin
instdff : dff port map ( pclock , preset , dintern(i-1) , dintern(i));
end generate genreg;

main : process(pclock)

begin
    if pclock'event and pclock = '1' then   
            if preset = '0'  then
                if dintern /= "0" then

                    feedback <= dintern(1) xor dintern(3); -- For N equals four;
                    --feedback <= dintern(4) xor dintern(5) xor dintern(6) xor dintern(8); -- For N equals eight;
                    --feedback <= dintern(11) xor dintern(13) xor dintern(14) xor dintern(16); -- For N equals sixteen;
                    --feedback <= dintern(1) xor dintern(2) xor dintern(22) xor dintern(32); -- For N equals thirty two                     

                else
                feedback <= '1';
                end if;
            end if;                                     
    end if; 
end process main;

prbsout <= dintern(4) ; --Change Value of N Here to take output to top entity 

end Behavioral;

在其中我实例化一个d触发器模块

d ff模块代码

----------------------------------------------------------------------------------
-- Module Name:    dff - Behavioral 
-- Project Name: 
-- Description: 
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity dff is
    Port ( dclock : in  STD_LOGIC ;
           dreset : in  STD_LOGIC ;
           din : in  STD_LOGIC;
           dout : out  STD_LOGIC);
end dff;

architecture Behavioral of dff is

begin
process(dclock)

begin
    if dclock'event and dclock = '1' then
        if dreset = '0' then
            dout <= din;
      else
            dout <= '1';
        end if;
    end if;
end process;


end Behavioral;

但我没有得到理想的输出。 在顶级实体中,我总是在prbsout信号处获得1。

当我尝试模拟时,prbsout信号变得不确定。

我缺少什么?

2 个答案:

答案 0 :(得分:3)

prbs preset模块重置不适用于feedback信号, 可能是因为意图是使用分配的初始值0 feedback信号的声明。但是,自dff模块以来 使用同步重置,dintern信号在开始时将被驱动U, 从那以后,使用feedback计算dintern(1)的下一个值 xor,反馈将在启动后立即变为未定义,并且无法恢复, 即使应用了冗长的重置。请参阅下面的ModelSim中的波形。

Before preset applied to feedback

立即解决重置问题的方法是同时对feedback应用重置 main进程:

...
else  -- preset /= '0'
  feedback <= '0';
...

现在至少重置有效,并且可以使prbs生成序列。看到 波形如下。

After preset applied to feedback

对代码的一些额外评论,同时在其中:

  • 您可以使用dclock'event and dclock = '1'代替rising_edge(dclock), 我认为读者必须更容易理解,而且更少 容易出错

  • 对于大多数工具,没有必要仅为a创建一个separte模块 触发器,就像dff模块一样,因为工具可以推断触发器 即使高级表达式用于信号,也直接来自该过程 使用作业。

但是,我不认为输出是你真正想要的。基于你的 设计,以及LFSR的选定点击,它看起来像你想要生成 最大长度LFSR序列,即长度为2 ** N - 1的序列 对于LFSR寄存器,N位长。

描述了LFSR的原理和反馈生成的分类 在维基百科上:Linear feedback shift register

然而,由于feedback信号是作为触发器产生的,因此它变为 LSFR移位寄存器的一部分,因此增加了一个长度,但是抽头 值仅基于LFSR的dintern部分,抽头将是 错误。选择错误的位将导致LFSR序列减少 比最大序列,你还可以在模拟输出中看到, 序列只有6个周期,即使通过dintern(4 downto 1) + feedback一起产生5位寄存器。

因此,如果您需要,则需要更彻底地重写prbs模块 是生成最大长度的PRBS序列,下面是一个如何的例子 可以写prbs模块:

library ieee;
use ieee.std_logic_1164.all;

entity prbs_new is
  generic(
    BITS : natural);
  port(
    clk_i  : in  std_logic;
    rst_i  : in  std_logic;
    prbs_o : out std_logic);
end entity;


library ieee;
use ieee.numeric_std.all;

architecture syn of prbs_new is

  signal lfsr : std_logic_vector(BITS downto 1);  -- Flip-flops with LFSR state

  function feedback(slv : std_logic_vector) return std_logic is  -- For maximum length LFSR generation
  begin
    case slv'length is
      when  3     => return slv( 3) xor slv( 2);
      when  4     => return slv( 4) xor slv( 3);
      when  8     => return slv( 8) xor slv( 6) xor slv( 5) xor slv(4);
      when 16     => return slv(16) xor slv(15) xor slv(13) xor slv(4);
      when 32     => return slv(32) xor slv(22) xor slv( 2) xor slv(1);
      when others => report "feedback function not defined for slv'lenght as " & integer'image(slv'length)
                     severity FAILURE;
                     return 'X';
    end case;
  end function;

begin

  process (clk_i, rst_i) is
  begin
    if rising_edge(clk_i) then
      if unsigned(lfsr) /= 0 then
        lfsr <= lfsr(lfsr'left - 1 downto lfsr'right) & feedback(lfsr);  -- Left shift with feedback in
      end if;
    end if;
    if rst_i = '1' then  -- Asynchronous reset
      lfsr <= std_logic_vector(to_unsigned(1, BITS));  -- Reset assigns 1 to lfsr signal
    end if;
  end process;

  prbs_o <= lfsr(BITS);  -- Drive output

end architecture;

对'prbs_new'模块的评论

  • 添加了通用BITS,因此可以使用相同的代码生成不同的LFSR长度。

  • 由于此命名,端口以输入“_i”和输出“_o”命名 当在多个顶层跟踪信号时,对流非常有用 模块。

  • 使用VHDL标准包ieee.numeric_std代替 非标准包ieee.std_logic_unsigned

  • 使用异步复位代替同步复位和初始值 信号声明。

    • 优于同步复位的是异步复位典型 适用于FPGA和ASIC中触发器的专用输入 技术,而不是潜在的时间关键数据路径 设计可以更快。

    • 信号衰减相对于初始值的优势在于FPGA和FPGA ASIC技术更有可能实现这一点;有 不支持初始值的情况。功能重置 无需重新加载即可在测试台上重新启动 模拟器。

  • 过程中没有检查lfsr信号的全0值, 因为如果适当的最大长度点击,lfsr永远不会获得全0值 使用,lfsr信号重置为非0值。

答案 1 :(得分:0)

看起来你永远不会将你的内部状态(dintern)设置为已知值。由于所有后续状态都是根据您的初始dintern值计算的,因此它们也是未知的。尝试将初始状态分配给dintern,或修复预设代码以在预设为高时实际执行某些操作(然后在测试平台开始时断言)。