vhdl 时钟输入到输出作为有限状态机

发布于 01-12 06:46 字数 2803 浏览 3 评论 0原文

输入图片此处描述我必须为上面的信号发生器生成 vhdl 代码作为有限状态机。我无法实现的是这个。如何生成 要输出的时钟值。更具体地说,我想要半个周期 当状态机处于状态时钟时,输出0,另一半输出1。我的实现,正如您在 下面的代码是输出<=时钟,但这显然不起作用。我制作了一个具有 4 个状态(s1、s2、s3、s4)的有限机器

我的测试平台和我的 vhdl 代码是:

测试平台

library ieee;
use ieee.std_logic_1164.all;

entity signal_generator_tb is
end entity;

architecture signal_generator_tb_arch of signal_generator_tb is
  signal clock_tb, reset_tb: std_logic;
  signal output_tb: std_logic;

  component signal_generator
    port(clock, reset: in std_logic;
       output: out std_logic);
  end component;

  begin
    dut : signal_generator port map(clock_tb, reset_tb, output_tb);

    stim_reset : process
      begin
        reset_tb <= '0'; wait for 10 ns;
        reset_tb <= '1'; wait;
    end process;

    stim_clock : process
      begin
        clock_tb <= '1'; wait for 10 ns;
        clock_tb <= '0'; wait for 10 ns;
      end process;

end architecture;

和我的 vhdl 代码是:

library ieee;
use ieee.std_logic_1164.all;

entity signal_generator is
  port (clock, reset: in std_logic;
       output: out std_logic);
end entity;

architecture signal_generator_arch of signal_generator is
  type state_type is (s0, s1, s2, s3); --This is the states of the 
finite state machine and we can create signlas with this type
  signal current_state, next_state: state_type; --We can only assign 
w_open and w_closed because there are type of state_type

  begin
    STATE_MEMORY : process(clock, reset)
      begin
        if(reset = '0') then
          current_state <= s0;
        elsif(falling_edge(clock)) then
          current_state <= next_state;
        end if;
      end process;

    NEXT_STATE_LOGIC : process(current_state)
      begin
        case(current_state) is
          when s0 => next_state <= s1;
          when s1 => next_state <= s2;
          when s2 => next_state <= s3;
          when s3 => next_state <= s0;
          when others => next_state <= s0;
        end case;
      end process;

    OUTPUT_LOGIC : process(current_state)
      begin
        case(current_state) is
          when s0 => output <= '1';
          when s1 => if(rising_edge(clock)) then
                  output <= '1';
                else
                  output <= '0';
                end if;
          when s2 => output <= '1';
          when s3 => output <= '0';
          when others => output <= '0';
        end case;
      end process;
end architecture;

波形 输入图片此处描述

enter image description here
I have to generate the vhdl code for the signal generator above as a finite state machine. What I cant manage to implement is this. How to generate
the clock values to output. To be more specific, I want for half period
output 0 and the other half 1, when the state machine is in state clock. My implementation, as you can see on the
code below, is output <= clock but this obviously does not work. I made a finite machine with 4 states (s1, s2, s3, s4)

My testbench and my vhdl code are these:

testbench

library ieee;
use ieee.std_logic_1164.all;

entity signal_generator_tb is
end entity;

architecture signal_generator_tb_arch of signal_generator_tb is
  signal clock_tb, reset_tb: std_logic;
  signal output_tb: std_logic;

  component signal_generator
    port(clock, reset: in std_logic;
       output: out std_logic);
  end component;

  begin
    dut : signal_generator port map(clock_tb, reset_tb, output_tb);

    stim_reset : process
      begin
        reset_tb <= '0'; wait for 10 ns;
        reset_tb <= '1'; wait;
    end process;

    stim_clock : process
      begin
        clock_tb <= '1'; wait for 10 ns;
        clock_tb <= '0'; wait for 10 ns;
      end process;

end architecture;

and my vhdl code is that:

library ieee;
use ieee.std_logic_1164.all;

entity signal_generator is
  port (clock, reset: in std_logic;
       output: out std_logic);
end entity;

architecture signal_generator_arch of signal_generator is
  type state_type is (s0, s1, s2, s3); --This is the states of the 
finite state machine and we can create signlas with this type
  signal current_state, next_state: state_type; --We can only assign 
w_open and w_closed because there are type of state_type

  begin
    STATE_MEMORY : process(clock, reset)
      begin
        if(reset = '0') then
          current_state <= s0;
        elsif(falling_edge(clock)) then
          current_state <= next_state;
        end if;
      end process;

    NEXT_STATE_LOGIC : process(current_state)
      begin
        case(current_state) is
          when s0 => next_state <= s1;
          when s1 => next_state <= s2;
          when s2 => next_state <= s3;
          when s3 => next_state <= s0;
          when others => next_state <= s0;
        end case;
      end process;

    OUTPUT_LOGIC : process(current_state)
      begin
        case(current_state) is
          when s0 => output <= '1';
          when s1 => if(rising_edge(clock)) then
                  output <= '1';
                else
                  output <= '0';
                end if;
          when s2 => output <= '1';
          when s3 => output <= '0';
          when others => output <= '0';
        end case;
      end process;
end architecture;

wave form
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨曦÷微暖2025-01-19 06:46:49

由于 OUTPUT_LOGIC 进程,您的状态机无法工作。它还应该对 clock 敏感,并且当处于状态 s1 时,它应该输出 clock 本身:

OUTPUT_LOGIC : process(current_state, clock)
      begin
        case(current_state) is
          when s0 => output <= '1';
          when s1 => output <= clock;
          when s2 => output <= '1';
          when s3 => output <= '0';
          when others => output <= '0';
        end case;
      end process;

请注意,您可以通过简单地传递您的时钟通过与门(强制为0)和或门(强制为1)并输出结果。您将初始化为“11”并递减的两位计数器将提供当前状态,以非常方便的方式编码以强制输出为 0 和 1:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;

entity signal_generator is
  port(clock, reset: in std_ulogic;
       output: out std_ulogic);
end entity signal_generator;

architecture arc of signal_generator is
  signal cnt: std_ulogic_vector(1 downto 0); -- the state 
begin

  process(clock, reset)
  begin
    if reset = '0' then
      cnt <= "11";
    elsif falling_edge(clock) then
      cnt <= cnt - 1;
    end if;
  end process;

  output <= (clock and cnt(1)) or cnt(0);

end architecture arc;

注意:始终更喜欢 std_ulogic当您不打算在信号上出现多个驱动情况时,将 (未解决)更改为 std_logic(已解决)。这样,如果您不小心创建了多个驱动器情况,您将收到一条有意义的错误消息,而不必花费数小时尝试了解波形中所有这些 X 值的来源。

Your state machine does not work because of your OUTPUT_LOGIC process. It should also be sensitive to clock and when in state s1 it should output clock itself:

OUTPUT_LOGIC : process(current_state, clock)
      begin
        case(current_state) is
          when s0 => output <= '1';
          when s1 => output <= clock;
          when s2 => output <= '1';
          when s3 => output <= '0';
          when others => output <= '0';
        end case;
      end process;

Note that you could simplify all this by simply passing your clock through a AND gate (to force it to 0) and a OR gate (to force it to 1) and output the result. A two bits counter that you would initialize to "11" and decrement would provide the current state, encoded in a very convenient way to force the output to 0 and 1:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;

entity signal_generator is
  port(clock, reset: in std_ulogic;
       output: out std_ulogic);
end entity signal_generator;

architecture arc of signal_generator is
  signal cnt: std_ulogic_vector(1 downto 0); -- the state 
begin

  process(clock, reset)
  begin
    if reset = '0' then
      cnt <= "11";
    elsif falling_edge(clock) then
      cnt <= cnt - 1;
    end if;
  end process;

  output <= (clock and cnt(1)) or cnt(0);

end architecture arc;

Note: always prefer std_ulogic (unresolved) to std_logic (resolved) when you do not plan to have multiple drive situations on a signal. This way, if you accidentally create a multiple drive situation you will get a meaningful error message instead of spending hours trying to understand where all these X values in your waveforms come from.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文