首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >输出保持相同的值

输出保持相同的值
EN

Stack Overflow用户
提问于 2017-04-09 19:02:07
回答 1查看 984关注 0票数 1

我的PRN发电机坏了。我想用线性反馈移位寄存器来做。

仿真和编译是没有问题的,但输出错误(lfsr_out = '0'),没有变化。

代码:

代码语言:javascript
复制
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‘。我的密码怎么了?

EN

回答 1

Stack Overflow用户

发布于 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语句:

代码语言:javascript
复制
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实际上并没有向左移动。修补程序如上面的代码所示,涉及到一个更改:

代码语言:javascript
复制
lfsr <= lfsr(WIDTH - 2 downto 0) & d0;  -- WAS WIDTH - 1 downto 1

测试席:

代码语言:javascript
复制
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的复用器。它代表了硬件,因为宽度不变,在合成过程中会被吃掉,作为一个通用常量传递。

泛型常量可以有一个定义的标量范围:

代码语言:javascript
复制
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赋值移动到并发语句:

代码语言:javascript
复制
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的第一个任务仍然被注释掉。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43310685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档