我的PRN发电机坏了。我想用线性反馈移位寄存器来做。
仿真和编译是没有问题的,但输出错误(lfsr_out = '0'),没有变化。
代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity lfsr_counter is
generic(
WIDTH : integer := 10
);
port(
clk : in std_logic; --clock
rst : in std_logic; --positiv rst
lfsr_out : out std_logic --1 bit output of lfsr
);
end lfsr_counter;
-------------------------------------------------------------------
architecture behavioral of lfsr_counter is
type state_type is (state_rst, state_go); --rst: reset; go: lfsr
shifts
signal present_state : state_type;
signal next_state : state_type;
signal lfsr : std_logic_vector((WIDTH - 1) downto 0) :=
(others => '0');
signal d0 : std_logic := '0';
--stores the current feedbackvalue
begin
--sequencial logic:
-------------------------------------------------------------------
state_register : process(clk, rst)
begin
if (rst = '1') then
present_state <= state_rst; --default state on reset.
elsif (rising_edge(clk)) then
present_state <= next_state; --state change
end if;
end process;
-- combinatorial logic
-------------------------------------------------------------------
comb_logic : process(present_state, rst)
begin
case present_state is
when state_rst =>
if (rst = '1') then
next_state <= state_rst;
else
next_state <= state_go;
end if;
when state_go =>
if (rst = '1') then
next_state <= state_rst;
else
next_state <= state_go;
end if;
end case;
end process;
output_logic : process(present_state)
begin
if (present_state = state_go) then
--assert ((WIDTH >= 3) and (WIDTH <= 10))
--report "Error: the LFSR width must be between 3 and 10" severity
failure;
case WIDTH is --definitions for the feedback
when 3 => d0 <= lfsr(2) xnor lfsr(1);
when 4 => d0 <= lfsr(3) xnor lfsr(2);
when 5 => d0 <= lfsr(4) xnor lfsr(2);
when 6 => d0 <= lfsr(5) xnor lfsr(4);
when 7 => d0 <= lfsr(6) xnor lfsr(5);
when 8 => d0 <= lfsr(7) xnor lfsr(5) xnor lfsr(4) xnor
lfsr(3);
when 9 => d0 <= lfsr(8) xnor lfsr(4);
when 10 => d0 <= lfsr(9) xnor lfsr(6);
when others => null;
end case;
lfsr <= std_logic_vector(unsigned(lfsr) sll 1); --shifting all
bits to left by 1
lfsr_out <= lfsr(WIDTH - 1); --MSB to output
lfsr <= lfsr(WIDTH - 1 downto 1) & d0; --concatenate the
feedback to the lfsr
else
lfsr <= (others => '0'); --reset state -> lfsr contains only
'0'
lfsr_out <= '0';
end if;
end process;
end architecture;如果在lfsr_out中设置“<= '1'”,输出将保持'1‘。我的密码怎么了?
发布于 2017-04-09 21:27:14
我的密码怎么了?
值为“0”和“XNOR”的移位寄存器将产生输出d0 '1‘。这就是“1”的来历。
您可以使用generate语句来生成d0,而不是使用case语句的process语句。
第一次分配给lfsr将没有效果,可以删除。在任何预定时间只有一个预计的输出波形。一个没有后置延迟的分配将产生一个增量循环。其中两个在相同的三角洲周期和最后一个将生效。因此,您不需要包std_logic_unsigned (Synopsys)或numeric_std (IEEE)。
合成结果
lfsr不是一个时钟寄存器,它是一个在合成硬件中总是产生'1‘的组合循环。这是由于缺乏连续换挡造成的。
另外,您的模拟将如何无问题地工作?Process output_logic只对present_state上的事件恢复。
丢弃独立的状态机并实现一个锁定的lfsr移位寄存器,并使用generate语句:
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_unsigned.all;
-- use ieee.numeric_std.all;
entity lfsr_counter is
generic (
-- WIDTH: integer := 10
WIDTH: positive range 3 to 10 := 10
);
port (
clk: in std_logic;
rst: in std_logic; -- positive rst
lfsr_out: out std_logic
);
end entity lfsr_counter;
architecture behavioral of lfsr_counter is
-- type state_type is (state_rst, state_go);
-- signal present_state: state_type;
-- signal next_state: state_type;
signal lfsr: std_logic_vector((WIDTH - 1) downto 0) := (others => '0');
signal d0: std_logic := '0';
begin
-- state_register:
-- process (clk, rst)
-- begin
-- if rst = '1' then
-- present_state <= state_rst;
-- elsif rising_edge(clk) then
-- present_state <= next_state;
-- end if;
-- end process;
-- comb_logic:
-- process (present_state, rst)
-- begin
-- case present_state is
-- when state_rst =>
-- if rst = '1' then
-- next_state <= state_rst;
-- else
-- next_state <= state_go;
-- end if;
-- when state_go =>
-- if rst = '1' then
-- next_state <= state_rst;
-- else
-- next_state <= state_go;
-- end if;
-- end case;
-- end process;
-- Using VHDL -2008 you could use a case generate or elsif
WIDTH3:
if WIDTH = 3 generate
d0 <= lfsr(2) xnor lfsr(1);
end generate;
WIDTH4:
if WIDTH = 4 generate
d0 <= lfsr(3) xnor lfsr(2);
end generate;
WIDTH5:
if WIDTH = 5 generate
d0 <= lfsr(4) xnor lfsr(2);
end generate;
WIDTH6:
if WIDTH = 6 generate
d0 <= lfsr(5) xnor lfsr(4);
end generate;
WIDTH7:
if WIDTH = 7 generate
d0 <= lfsr(6) xnor lfsr(5);
end generate;
WIDTH8:
if WIDTH = 8 generate
d0 <= lfsr(7) xnor lfsr(5) xnor lfsr(4) xnor lfsr(3);
end generate;
WIDTH9:
if WIDTH = 9 generate
d0 <= lfsr(8) xnor lfsr(4);
end generate;
WIDTH10:
if WIDTH = 10 generate
d0 <= lfsr(9) xnor lfsr(6);
end generate;
-- output_logic:
-- process (present_state)
-- begin
-- if present_state = state_go then
-- case WIDTH is
-- when 3 =>
-- d0 <= lfsr(2) xnor lfsr(1);
-- when 4 =>
-- d0 <= lfsr(3) xnor lfsr(2);
-- when 5 =>
-- d0 <= lfsr(4) xnor lfsr(2);
-- when 6 =>
-- d0 <= lfsr(5) xnor lfsr(4);
-- when 7 =>
-- d0 <= lfsr(6) xnor lfsr(5);
-- when 8 =>
-- d0 <= lfsr(7) xnor lfsr(5) xnor lfsr(4) xnor lfsr(3);
-- when 9 =>
-- d0 <= lfsr(8) xnor lfsr(4);
-- when 10 =>
-- d0 <= lfsr(9) xnor lfsr(6);
-- when others =>
-- null;
-- end case;
-- -- lfsr <= lfsr sll 1;
-- lfsr_out <= lfsr(WIDTH - 1);
-- lfsr <= lfsr(WIDTH - 1 downto 1) & d0;
-- else
-- lfsr <= (others => '0');
-- lfsr_out <= '0';
-- end if;
-- end process;
lfsr_reg:
process (rst, clk)
begin
if rst = '1' then
lfsr <= (others =>'0');
elsif rising_edge(clk) then
lfsr <= lfsr(WIDTH - 2 downto 0) & d0; -- WAS WIDTH - 1 downto 1
end if;
end process;
lfsr_out <= lfsr(WIDTH - 1); -- not separately registered
end architecture;具有generate语句的位没有做什么有趣的事情,而是从综合中卸载工作,这将不得不在case语句多路复用器中吃下所有的赋值。
另外,通过添加一个testbench来创建一个Minimal, Complete and Verifiable example,我们可以看到lfsr实际上并没有向左移动。修补程序如上面的代码所示,涉及到一个更改:
lfsr <= lfsr(WIDTH - 2 downto 0) & d0; -- WAS WIDTH - 1 downto 1测试席:
library ieee;
use ieee.std_logic_1164.all;
entity lfsr_counter_tb is -- a testbench
end entity;
architecture foo of lfsr_counter_tb is
constant WIDTH: positive range 1 to 10 := 10; -- test full length
signal clk: std_logic := '1';
signal rst: std_logic := '0';
signal lfsr_out: std_logic;
begin
DUT:
entity work.lfsr_counter
generic map (
WIDTH => WIDTH
)
port map (
clk => clk,
rst => rst,
lfsr_out => lfsr_out
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if now > 550 ns then
wait;
end if;
end process;
STIMULUS:
process
begin
wait for 11 ns;
rst <= '1';
wait for 99 ns;
rst <= '0';
wait;
end process;
end architecture;模拟:

lfsr_counter也应该合成和发挥作用。
嗯哼。在我们的数字设计课程中从未听说过任何关于generate语句的消息!在某些情况下,这可能非常有用。谢谢你举这个例子。我理解你的密码。它真的很简单,很能自我解释。您也可以避免组合循环。然而,这是一种不同的做法。我仍然想把它作为一个有限状态机来实现,并且理解它的机制。现在,我知道output_logic部分没有时钟,这导致了梳子。循环播放。另外,只执行lfsr的最后一个语句。我要编辑什么才能让它工作?
正如人们所说,这是一个不同的问题。只有今天才有双人特色菜。
您的代码显示编程语言思想,而VHDL是一种硬件描述语言。例如,在当前模拟周期中,当任何进程尚未恢复或随后暂停时,都不会发生信号更新。这意味着d0不想成为一个信号,或者它的任务希望处于一个单独的过程中。
信号在进程之间进行通信。对于仅在进程中使用的对象,如果在赋值后计算值,则应使用变量。
还有使用宽度分配d0的复用器。它代表了硬件,因为宽度不变,在合成过程中会被吃掉,作为一个通用常量传递。
泛型常量可以有一个定义的标量范围:
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_unsigned.all;
-- use ieee.numeric_std.all;
entity lfsr_counter is
generic (
-- WIDTH: integer := 10
WIDTH: positive range 3 to 10 := 10
);
port (
clk: in std_logic;
rst: in std_logic; -- positive rst
lfsr_out: out std_logic
);
end entity lfsr_counter;这样就可以编写VHDL设计描述,而不必处理所使用的值之外的值。所有额外的逻辑都会被吃掉,但是您可能会引入错误。
因此,使用d0生成一个变量,宽度受限,并且lsfr_out赋值移动到并发语句:
architecture behave of lfsr_counter is
type state_type is (state_rst, state_go);
signal present_state: state_type;
signal next_state: state_type;
signal lfsr: std_logic_vector((WIDTH - 1) downto 0) := (others => '0');
-- signal d0: std_logic := '0';
begin
state_register:
process (clk, rst)
begin
if rst = '1' then
present_state <= state_rst;
elsif rising_edge(clk) then
present_state <= next_state;
end if;
end process;
comb_logic:
process (present_state, rst)
begin
case present_state is
when state_rst =>
if rst = '1' then
next_state <= state_rst;
else
next_state <= state_go;
end if;
when state_go =>
if rst = '1' then
next_state <= state_rst;
else
next_state <= state_go;
end if;
end case;
end process;
output_logic:
process (clk) -- (present_state)
variable d0: std_logic;
begin
if rising_edge(clk) then
if present_state = state_go then
case WIDTH is
when 3 =>
d0 := lfsr(2) xnor lfsr(1);
when 4 =>
d0 := lfsr(3) xnor lfsr(2);
when 5 =>
d0 := lfsr(4) xnor lfsr(2);
when 6 =>
d0 := lfsr(5) xnor lfsr(4);
when 7 =>
d0 := lfsr(6) xnor lfsr(5);
when 8 =>
d0 := lfsr(7) xnor lfsr(5) xnor lfsr(4) xnor lfsr(3);
when 9 =>
d0 := lfsr(8) xnor lfsr(4);
when 10 =>
d0 := lfsr(9) xnor lfsr(6);
-- when others =>
-- null;
end case;
-- lfsr <= lfsr sll 1;
-- lfsr_out <= lfsr(WIDTH - 1);
-- lfsr <= lfsr(WIDTH - 1 downto 1) & d0;
lfsr <= lfsr(WIDTH - 2 downto 0) & d0;
else
lfsr <= (others => '0'); -- a synchronous reset
-- lfsr_out <= '0';
end if;
end if;
end process;
lfsr_out <= lfsr(WIDTH - 1); -- not separately registered, a mux
end architecture behave;您的第一个体系结构中的所有更改都显示出来了,原始代码注释掉了。在相同的测试平台上进行了分析、阐述和仿真,得到了相同的结果。
移动lfsr_out分配的原因是基于与d0相同的问题,还有另一个观察。只有在找到敏感列表的信号上有一个事件时,output_logic进程才会恢复执行。
这意味着您将错过模拟您的第一个设计的lfsr_out上的转换,或者意味着使用时钟lfsr寄存器的半时钟延迟(对于下一个clk边缘),就像在上面的行为体系结构中一样。
您可以注意到lsfr赋值的更改,以实际提供一个移位,如顶部代码示例中的lfsr_reg过程中所示。您会注意到,lfsr的第一个任务仍然被注释掉。
https://stackoverflow.com/questions/43310685
复制相似问题