使用 Altera Megafunction LPM_SHIFTREG 的 Fibonacci LFSR - 如何初始化? [VHDL]

问题描述 投票:0回答:1

我在设计线性反馈移位寄存器时遇到了令人沮丧的问题,其中需要使用 Altera 的 LPM,在本例中为 LPM_SHIFTREG。这必须被使用,因为我在写这篇文章的几天内就对这些组件进行了作业和考试,当然已经把它放在次要位置一段时间了,所以如果我能得到一些帮助来初始化和正确配置代码,我将不胜感激.

主要代码在顶级组件中实例化,并且运行正常,因此我包含了测试 MWE 所需的最少量的代码。现在我无法判断是否有任何位被移位,因为输出全为零 - 显然 LFSR 只会反馈全零,所以也许没有一些 1 和 0 的初始状态,它可能会移位零。因此,通过我自己的工作,我尝试使用初始化状态,以便

lfsr_out
将有一些位异或作为对
lfsr_in
的反馈。我尝试添加一个重置状态,该状态应该初始化一段时间,然后让 LFSR 的输出接管并离开它。事实并非如此,因此在初始化过程中发生以下错误

是的,我知道我无法同时驱动多个输入,那么我该如何克服这个问题?我曾尝试查看 VHDL LFSR,但使用了 LPM,但几乎没有这样的例子。理想情况下,我需要保留 LPM_SHIFTREG,因为这个组件是在考试问题上,所以我想放心,我不会写完全垃圾!以下是当前代码的 ModelSim 信号的屏幕截图,其中

初始化过程删除


LFSR_comp.vhd

library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.numeric_std.ALL; library altera_mf; library lpm; use lpm.lpm_components.ALL; entity LFSR_comp is PORT ( clk : in std_logic; pa_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(9 downto 0) ); end LFSR_comp; architecture LFSR_comp_bhv of LFSR_comp is signal lfsr_in : std_logic := '0'; signal lfsr_out : std_logic_vector(9 downto 0); signal lfsr_clock : std_logic := '0'; signal lfsr_rst : std_logic := '1'; signal initial_state : std_logic_vector(9 downto 0) := "1010110111"; begin -- Toggle the lfsr_clock using PA as a clk divider lfsr_clock <= pa_in(7); -- Initialization process -- process(lfsr_in, lfsr_rst, lfsr_out, initial_state) -- begin -- if lfsr_rst = '1' then -- lfsr_out <= initial_state; -- lfsr_rst <= '0'; -- end if; -- end process; -- Load the initial state into the shift register lfsr : LPM_SHIFTREG generic map ( LPM_WIDTH => 10, LPM_DIRECTION => "LEFT" ) port map ( data => lfsr_out, clock => lfsr_clock, q => lfsr_out, shiftin => lfsr_in ); lfsr_in <= lfsr_out(7) xor lfsr_out(3) xor lfsr_out(2) xor lfsr_out(0); data_out <= lfsr_out; end LFSR_comp_bhv;


LFSR_top.vhd

library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.numeric_std.all; use IEEE.std_logic_unsigned.ALL; entity LFSR_top is PORT ( clk : in std_logic; fsw_in : in std_logic_vector(7 downto 0); pa_probe_out : out std_logic_vector(7 downto 0); data_out : out std_logic_vector(9 downto 0) ); end LFSR_top; architecture LFSR_top_bhv of LFSR_top is component PA_comp PORT ( CLK : IN STD_LOGIC := '1'; FSW : IN STD_LOGIC_VECTOR (7 DOWNTO 0); DATA_OUT : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); end component; component LFSR_comp PORT ( CLK : in std_logic; PA_IN : in std_logic_vector(7 downto 0); DATA_OUT : out std_logic_vector(9 downto 0) ); end component; signal pa_data_out : std_logic_vector(7 downto 0) := (others => '0'); signal ask_data_out : std_logic_vector(9 downto 0) := (others => '0'); begin -- Phase Accumulator phase_acc : PA_comp PORT MAP ( CLK => clk, FSW => fsw_in, DATA_OUT => pa_data_out ); -- LFSR lfsr : LFSR_comp PORT MAP ( CLK => clk, PA_IN => pa_data_out, DATA_OUT => ask_data_out ); data_out <= ask_data_out; end LFSR_top_bhv;


PA_comp.vhd

library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.numeric_std.ALL; library altera_mf; library lpm; use lpm.lpm_components.ALL; entity PA_comp is PORT ( clk : in std_logic; fsw : in std_logic_vector(7 downto 0); -- Assuming an 8-bit FTW data_out : out std_logic_vector(7 downto 0) ); end PA_comp; architecture PA_comp_bhv of PA_comp is signal add_out : std_logic_vector(7 downto 0) := (others => '0'); signal q_out : std_logic_vector(7 downto 0) := (others => '0'); begin -- LPM_ADD_SUB for phase accumulator addnsub : lpm_add_sub GENERIC MAP ( LPM_WIDTH => 8, LPM_DIRECTION => "ADD" ) PORT MAP ( DATAA => fsw, DATAB => q_out, RESULT => add_out ); -- LPM_FF for phase accumulator dff : lpm_ff GENERIC MAP ( LPM_WIDTH => 8, LPM_FFTYPE => "DFF" ) PORT MAP ( DATA => add_out, CLOCK => clk, Q => q_out ); data_out <= q_out; end PA_comp_bhv;


LFSR_tb.vhd

library IEEE; use IEEE.std_logic_1164.ALL; use IEEE.numeric_std.all; use IEEE.std_logic_unsigned.ALL; entity LFSR_tb is end LFSR_tb; architecture LFSR_tb_bhv of LFSR_tb is signal clk : std_logic := '0'; signal fsw_in : std_logic_vector(7 downto 0) := (others => '0'); signal pa_probe_out : std_logic_vector(7 downto 0) := (others => '0'); signal data_out : std_logic_vector(9 downto 0) := (others => '0'); constant clk_period : time := 10 ns; begin uut: entity work.LFSR_top port map ( clk => clk, fsw_in => fsw_in, pa_probe_out => pa_probe_out, data_out => data_out ); -- Clock process def. clk_process : process begin clk <= '0'; wait for clk_period/2; clk <= '1'; wait for clk_period/2; end process; stimulus_process: process begin fsw_in <= "00000001"; wait for 2560 ns; end process; end LFSR_tb_bhv;
    
vhdl fpga intel-fpga lfsr
1个回答
0
投票
如果不提供 LPM 库中的必要元素,就无法提供最小、完整且可验证的示例(这两个源文件可以被剥离并分析到 lpm 库中)。 LPM 是一项失败的 Actel 计划,旨在实现标准化,而不是 VHDL 的一部分,lpm 库是供应商提供的库。这里 MCVe 意味着摆脱 pa_comp 或不使用库 lpm。

-- Quartus II 9.1 Build 222 10/21/2009

 220model.vhd,实体lpm.LPM_SHIFTREG,有一个预设值,通用lpm_pvalue。不会出现在您链接的文档中,它位于 VHDL 源代码中。英特尔可能不鼓励将其用于某些设备系列,因为这些设备系列不方便或不可能操纵宏 LPM_SHIFTREG 中使用的单元触发器的数据输入和输出的极性。

更改使用预设值:

library IEEE; use IEEE.std_logic_1164.ALL; -- use IEEE.numeric_std.ALL; -- CHANGED no declarations used -- library altera_mf; -- CHANGED no declarations used library lpm; use lpm.lpm_components.ALL; entity LFSR_comp is PORT ( clk : in std_logic; pa_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(9 downto 0) ); end LFSR_comp; architecture LFSR_comp_bhv of LFSR_comp is signal lfsr_in : std_logic := '0'; signal lfsr_out : std_logic_vector(9 downto 0); signal lfsr_clock : std_logic := '0'; -- signal lfsr_rst : std_logic := '1'; -- CHANGED NOT USED -- CHANGED SHOULD BE A CONSTANT: -- signal initial_state : std_logic_vector(9 downto 0) := "1010110111"; begin -- Toggle the lfsr_clock using PA as a clk divider lfsr_clock <= pa_in(7); -- Initialization process -- process(lfsr_in, lfsr_rst, lfsr_out, initial_state) -- begin -- if lfsr_rst = '1' then -- lfsr_out <= initial_state; -- lfsr_rst <= '0'; -- end if; -- end process; -- Load the initial state into the shift register lfsr : LPM_SHIFTREG generic map ( LPM_WIDTH => 10, LPM_DIRECTION => "LEFT", -- CHANGED ADDED comma separeator LPM_PVALUE => "1010110111" -- CHANGED ADDED preset value ) port map ( data => lfsr_out, clock => lfsr_clock, q => lfsr_out, shiftin => lfsr_in ); lfsr_in <= lfsr_out(7) xor lfsr_out(3) xor lfsr_out(2) xor lfsr_out(0); data_out <= lfsr_out; end LFSR_comp_bhv;
还要注意注释掉的 use 子句,其声明在源代码中不被依赖。其他源代码文件中可能还有其他情况。

瞧瞧,改变起作用了!

如果您在使用 lpm_pvalue 时遇到工具限制,有两种选择:使用 sset 和 lpm_svalue 或 aset 和 lpm_avalue。实施工作几乎相同:

architecture LFSR_comp_aset of LFSR_comp is signal lfsr_in : std_logic := '0'; signal lfsr_out : std_logic_vector(9 downto 0); signal lfsr_clock : std_logic := '0'; signal lfsr_rst : std_logic := '1'; -- CHANGED SHOULD BE A CONSTANT: -- signal initial_state : std_logic_vector(9 downto 0) := "1010110111"; begin -- Toggle the lfsr_clock using PA as a clk divider lfsr_clock <= pa_in(7); -- Initialization process -- process(lfsr_in, lfsr_rst, lfsr_out, initial_state) -- begin -- if lfsr_rst = '1' then -- lfsr_out <= initial_state; -- lfsr_rst <= '0'; -- end if; -- end process; LFSR_RESET: process begin wait on clk; if rising_edge(clk) then if lfsr_rst = '1' then lfsr_rst <= '0'; end if; end if; wait; end process; -- Load the initial state into the shift register lfsr : LPM_SHIFTREG generic map ( LPM_WIDTH => 10, LPM_DIRECTION => "LEFT", -- CHANGED ADDED comma separeator LPM_AVALUE => "1010110111" -- CHANGED ADDED preset value ) port map ( aset => lfsr_rst, -- CHANGED non-default value for port in data => lfsr_out, clock => lfsr_clock, q => lfsr_out, shiftin => lfsr_in ); lfsr_in <= lfsr_out(7) xor lfsr_out(3) xor lfsr_out(2) xor lfsr_out(0); data_out <= lfsr_out; end LFSR_comp_aset;
在使用 sset 时,可以考虑 lfsr_rst 的一个时钟延迟会对 pa_comp 产生扭曲影响。

无论如何:

这也有效。 aset信号在这里可能很难看到,它在clk的第一个上升沿后消失。

对于您的学校项目来说,LPM_FF 是否适合使用 Riding_edge(clk) 测试来推断时序逻辑?

© www.soinside.com 2019 - 2024. All rights reserved.