0

我被要求使用 one-hot 编码创建一个有限状态机,它将检测输入 w 上的四个 1 或 0 的序列。我已经使用 case 语句编写了代码,但我还必须通过提供逻辑表达式作为 9 个触发器的输入来完成它。我在 z 上没有得到正确的输出,我也不太明白为什么。

到目前为止,我已经为 D 触发器编写了以下代码

library ieee;
use ieee.std_logic_1164.all;

entity dflipflop is
    port (D, clk, reset: in std_logic;
        Q: out std_logic);
end dflipflop;

architecture behavior of dflipflop is
begin
process(clk)
begin
    if reset <= '0' then 
        Q <= '0';
    elsif rising_edge(clk) then
        Q <= D;
    end if;
end process;
end behavior;

然后我把它作为我的代码的其余部分,这就是我认为问题所在。

library ieee;
use ieee.std_logic_1164.all;

entity part1 is 
port (clk, w, reset : in std_logic;
        z: out std_logic);
end part1;

architecture behavior of part1 is
    component dflipflop 
    port (D, clk, reset: in std_logic; 
            Q: out std_logic);
    end component;

    signal A, B, C, D, E, F, G, H, I: std_logic;
    signal Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8, Y9: std_logic;

   dff1: dflipflop port map (clk=>clk, reset=>reset, D=>Y1, Q=>A);
   dff2: dflipflop port map (clk=>clk, reset=>reset, D=>Y2, Q=>B);
   dff3: dflipflop port map (clk=>clk, reset=>reset, D=>Y3, Q=>C);
   dff4: dflipflop port map (clk=>clk, reset=>reset, D=>Y4, Q=>D);
   dff5: dflipflop port map (clk=>clk, reset=>reset, D=>Y5, Q=>E);
   dff6: dflipflop port map (clk=>clk, reset=>reset, D=>Y6, Q=>F);
   dff7: dflipflop port map (clk=>clk, reset=>reset, D=>Y7, Q=>G);
   dff8: dflipflop port map (clk=>clk, reset=>reset, D=>Y8, Q=>H);
   dff9: dflipflop port map (clk=>clk, reset=>reset, D=>Y9, Q=>I);

begin
process(clk);
begin
if rising_edge(clk) then
    Y1 <= (((not w) and C) or ((not w) and G) or ((not w) and H) or ((not w) and I) or (w and B) or (w and D) or (w and E) or (w and F));
    Y2 <= ((not w) and A);
    Y3 <= (w and A);
    Y4 <= ((not w) and B);
    Y5 <= ((not w) and D);
    Y6 <= (((not w) and E) or ((not w) and F));
    Y7 <= (w and C);
    Y8 <= (w and G);
    Y9 <= ((w and H) or (w and I));
end if;
end process;
z <= (Y6 OR Y9);

end behavior;

任何人都可以就我可能做错的事情提供任何提示或见解吗?

4

3 回答 3

1

初步评论(查看您的源代码):

  • 您的dflipflop描述似乎很好,尽管我没有看到使用异步复位的任何理由。考虑将其更改为同步复位触发器,除非您的设计确实需要一些 FF 来异步复位。

  • 你已经把你的组合逻辑语句放在了一个时钟过程中。现在,如果您要在结构上实例化触发器,所有这些句子都不应该在一个内部,因为它们已经被触发器计时了。

  • 您应该更明智地使用信号名称,否则您的代码将很难阅读和调试,特别是对于更复杂的设计。此外,如果您想分别使用高电平有效或低电平有效复位,请使用reset= '1'reset='0'代替。reset <='0'

我该怎么做:

我相信您正在寻找具有以下图形表示的位检测器的简单有限状态机 (FSM) 的结构描述,总共有 9 个状态。One-hot 编码意味着您需要为每个状态分配一个触发器。

首先,声明 9 个 std_logic 信号,其中每个信号代表一个热编码 FSM 中的一个状态。这些将是 9 个 FF 的输出信号:

 signal init : std_logic;  -- Initial/reset state            
 signal zeros_1 : std_logic;  -- 1 zero  detected
 signal zeros_2 : std_logic;  -- 2 zeros detected
 signal zeros_3 : std_logic;  -- 3 zeros detected
 signal zeros_4 : std_logic;  -- 4 zeros detected
 signal ones_1  : std_logic;  -- 1 one   detected
 signal ones_2  : std_logic;  -- 1 one   detected
 signal ones_3  : std_logic;  -- 1 one   detected
 signal ones_4  : std_logic;  -- 1 one   detected

声明额外的 9 个 std_logic 信号,以保存相应状态触发器的下一个值。这些将是 9 个 FF 的输入信号:

 signal go_to_init   : std_logic;
 signal go_to_zeros_1 : std_logic;  
 signal go_to_zeros_2 : std_logic;  
 signal go_to_zeros_3 : std_logic;  
 signal go_to_zeros_4 : std_logic;  
 signal go_to_ones_1  : std_logic;  
 signal go_to_ones_2  : std_logic;  
 signal go_to_ones_3  : std_logic;  
 signal go_to_ones_4  : std_logic;  

将 9 个触发器映射到相应的信号。

请注意,如果您想使用 RESET 信号初始化状态机,则需要一个 D 触发器,该触发器在 RESET 时为高电平。您可以使用dflipflop的描述,更改if reset='1' then Q <='0'if reset='1' then Q <='1'并使用它来实现新的dflipflop_RH

init_ff   : dflipflop_RH port map (clk=>clk, reset=>reset,D=> go_to_init, Q=> init);
zeros_1_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_1, Q=> zeros_1 );
zeros_2_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_2, Q=> zeros_2 );
zeros_3_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_3, Q=> zeros_3 );
zeros_4_ff: dflipflop port map (clk=>clk, reset=>reset,D=> go_to_zeros_4, Q=> zeros_4 );
ones_1_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_1, Q=> ones_1 );
ones_2_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_2, Q=> ones_2 );
ones_3_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_3, Q=> ones_3 );
ones_4_ff : dflipflop port map (clk=>clk, reset=>reset,D=> go_to_ones_4, Q=> ones_4 );

最后,添加组合逻辑以根据当前状态和输入信号“w”计算下一个状态。由于它是一个非常简单的 FSM,您只需要将 FSM 图形表示转换为 VHDL 代码:

 go_to_init <= '0';  -- never go to init (only when reset='1') 

 go_to_zeros_1 <= (init or ones_1 or ones_2 or ones_3 or ones_4  ) and (not w);
 go_to_zeros_2 <= zeros_1 and (not w);
 go_to_zeros_3 <= zeros_2 and (not w);
 go_to_zeros_4 <= (zeros_3 or zeros_4) and (not w);

 go_to_ones_1 <= (init or zeros_1 or zeros_2 or zeros_3 or zeros_4) and w;
 go_to_ones_2 <= ones_1 and w;
 go_to_ones_3 <= ones_2 and w;
 go_to_ones_4 <= (ones_3 or ones_4) and w;

 z <= ones_4 or zeros_4;
于 2013-03-03T05:49:10.087 回答
0

我会为这样一个小任务编写更具可读性的代码:

library ieee;
use ieee.std_logic_1164.all;

entity part1 is 
port (
    clk     : in  std_logic;
    w       : in  std_logic;
    reset_n : in  std_logic; -- mark low active signals with suffix _n
    z       : out std_logic
);
end part1;

architecture rtl of part1 is
     signal sreg : std_logic_vector(3 downto 0);
begin
     process
     begin
         wait until rising_edge( clk);

         -- shift register
         sreg <= sreg(2 downto 0) & w;

         if sreg = "0000" or sreg = "1111" then
             z <= '1';
         else
             z <= '0';
         end if;

         -- do we really need a reset?
         if reset_n = '0' then
             sreg <= "0000";
         end if;
     end process;
end architecture rtl;
于 2013-03-04T16:29:35.563 回答
0

复位后,dflipflops 的所有输出都为“0”。

if reset <= '0' then 
    Q <= '0';

所以,A、B、C、D、E、F、G、H 和我都在“0”。

由于分配 Yn 信号的布尔逻辑,Yn 将始终为“0”。

例如

Y2 <= ((not w) and A); -- A is at '0' => Y2 will always be '0'.

输出“z”将始终为“0”:

z <= (Y6 OR Y9); -- Y6 is always '0', Y9 is always '0' => Z will always be '0'.

顺便说一句:注册组件的输出是一个很好的设计规则。我会把z <= (Y6 OR Y9);这个过程放在里面。

难道是dflipflop的输出在复位时必须是'1'?

于 2013-02-27T08:26:47.530 回答