这里我发布了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信号变得不确定。
我缺少什么?
答案 0 :(得分:3)
prbs
preset
模块重置不适用于feedback
信号,
可能是因为意图是使用分配的初始值0
feedback
信号的声明。但是,自dff
模块以来
使用同步重置,dintern
信号在开始时将被驱动U
,
从那以后,使用feedback
计算dintern(1)
的下一个值
xor,反馈将在启动后立即变为未定义,并且无法恢复,
即使应用了冗长的重置。请参阅下面的ModelSim中的波形。
立即解决重置问题的方法是同时对feedback
应用重置
main
进程:
...
else -- preset /= '0'
feedback <= '0';
...
现在至少重置有效,并且可以使prbs
生成序列。看到
波形如下。
对代码的一些额外评论,同时在其中:
您可以使用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,或修复预设代码以在预设为高时实际执行某些操作(然后在测试平台开始时断言)。