2016-04-19 32 views
0

我正在苦于VHDL难题。下面是一些代码,应该解释什么,我试图做的:如何确定是否所有for循环都结束,VHDL,Quartus-II

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use work.all; 

entity forLoopTest is 
-- Number of bits known only at compilation 
generic(
    bits : integer range 1 to 1024;    := 256; 
); 
port(
    clk: in std_logic       := '0'; 
    -- Single bit inputs from foo 
    foo: in std_logic_vector(bits-1 downto 0) := (others => '0'); 
    -- Output should be high when all inputs have gone to '1' at some point 
    bar: out std_logic 
); 
end forLoopTest; 

------------------------------------------------------------------------------------------------------------ 

architecture implementation of forLoopTest is 
    -- Create states for finite state machine, where finish implies a '1' has been received 
    type FSM_states_single is (waitForHigh, finish); 
    -- Make an array of the states, one for each input bit 
    type FSM_states_multi is array (bits-1 downto 0) of FSM_states_single; 
    -- Create signal of states initialised to the waiting condition 
    signal state : FSM_states_multi     := (others => waitForHigh); 

begin 

    process(clk, foo) 
     -- For each input bit: 
     for bitNumber in 0 to bits-1 loop 
      case state(bitNumber) is 
       -- Whilst waiting, poll the input bit 
       when waitForHigh => 
        -- If it goes high, then switch states 
        if (foo(bitNumber) = '1') then 
         state(bitNumber) <= finish; 
        end if; 
       -- If input bit has gone high: 
       when finish => 
        -- What is simplest method of setting "bar"? 
         -- "bar" should be high if and only if all bits have equalled '1' at some point 
         -- Otherwise it should be '0' 
         -- Though of dominant setting '0', and submissive setting 'H', but multiple things setting output fails 
          -- Either explicitly, or only one of them is used, others ignored 
      end case; 
     end loop; 

    end process;   

end implementation; 

基本上,我试图找到当所有for循环的“线程”已完成推导的最佳方法。以上是一个假设的例子来说明这一点。使用上述代码的一种方法是简单地“与”所有状态。但是,我不知道如何和一个未知数量的变量(预编译)。另外我很想知道解决这个问题的其他方法是什么。

在此先感谢!

回答

1

为您的过程添加了时钟和重置。重置允许您清除状态。

没有酒吧的触发器,它很容易做,移动一个if语句。

的情况下发言,因为酒吧是如何得出去除,评估这两个州是没有必要的:

library ieee; 
use ieee.std_logic_1164.all; 
-- use ieee.std_logic_arith.all; -- not used 
use work.all; 

entity forlooptest is 
    generic (
     bits : integer range 1 to 1024 := 256 -- removed ';' 2 places 
    ); 
    port (
     clk: in std_logic; 
     reset: in std_logic; -- added 
     foo: in std_logic_vector(bits-1 downto 0) := (others => '0'); 
     bar: out std_logic 
    ); 
end entity forlooptest; 

architecture foo of forlooptest is 

    type FSM_states_single is (waitForHigh, finish); 
    type FSM_states_multi is array (bits-1 downto 0) of FSM_states_single; 
    signal state : FSM_states_multi := (others => waitForHigh); 

begin 

FOO_BAR: 
    process (clk, reset) 
     variable state_v: FSM_states_multi; -- added 
    begin -- original missing begin 

     state_v := state; -- variable can be evaluated after assignment 
     if reset = '1' then 
      state_v := (others => WaitForHigh); 
     elsif rising_edge(clk) then 
      for bitNumber in 0 to bits-1 loop 
       if state_v(bitNumber) = waitForHigh and 
           foo(BitNumber) = '1'  then 
        state_v(bitNumber) := finish; 
       end if; 
      end loop; 
      state <= state_v; 
     end if; 
     if state_v = (state_v'range => finish) then 
      bar <= '1'; -- bar not a FlipFlop move if statement above 
     else    -- preceding end if and add to reset condition for FF 
      bar <= '0'; -- no latch 
     end if; 
    end process;  

end architecture; 

制作吧触发器可以通过移动它来完成,如果,如果前一结束上述说法,删除else并赋值为'0',并将< ='0'添加到复位。

还有一个状态的变量副本,所以任何更新位立即可用于评估。 (信号分配不会在变量分配时立即生效)。

注意事项的核心,如何使用每个位置设置为完成的聚合值来评估状态(state_v)。这里不能使用others。元素的数量及其类型必须从聚合表达式中作为等于运算符的输入来辨别。

添加小测试台具有有限范围的比特:

library ieee; 
use ieee.std_logic_1164.all; 

entity for_loop_test_tb is 
end entity; 

architecture fum of for_loop_test_tb is 
    constant bits: integer range 1 to 1024 := 16; 
    signal clk: std_logic := '0'; 
    signal reset: std_logic; -- added 
    signal foo: std_logic_vector(bits-1 downto 0) := (others => '0'); 
    signal bar: std_logic; 
begin 
DUT: 
    entity work.forlooptest 
     generic map (bits => bits) 
     port map (
      clk => clk, 
      reset => reset, 
      foo => foo, 
      bar => bar 
     ); 
CLOCK: 
    process 
    begin 
     wait for 5 ns; 
     clk <= not clk; 
     if now > 150 ns then 
      wait; 
     end if; 
    end process; 

STIMULI: 
    process 
    begin 
     wait for 10 ns; 
     reset <= '1'; 
     wait for 10 ns; 
     reset <= '0'; 
     wait for 10 ns; 
     foo <= x"0FF0"; 
     wait for 10 ns; 
     foo <= x"0001"; 
     wait for 10 ns; 
     foo <= x"F002"; 
     wait for 10 ns; 
     foo <= x"0F00"; 
     wait for 10 ns; 
     foo <= x"FF00"; 
     wait for 10 ns; 
     foo <= x"0001"; 
     wait for 10 ns; 
     foo <= x"00F0"; 
     wait for 10 ns; 
     foo <= x"F0F0"; 
     wait for 10 ns; 
     foo <= x"0004"; 
     wait for 10 ns; 
     foo <= x"CCCC"; 
     wait; 
    end process; 

end architecture; 

这给出:

for_loop_test_tb.png

(对位和值不同的输入值的foo的数量分别限制提供容易解释的波形。)

+0

传下来我收到的最佳答案!彻底的,简单的,很好的解释。非常感谢你的帮助!对于编码错误抱歉,由于我火车迟到,所以我很急。 – user3303504

0

(有许多事情错与给定的过程:它可能应该主频,使之运行在每个rising_edge(clk)那么就没有必要在敏感列表foo但是....)

一种方法是在输入for循环之前设置为TRUE的布尔变量finished

尚未完成(例如进入waitforHigh状态或比其他finish任何状态)将清除finished可变任何迭代...(任选地,除非它被转换到finish状态)。

然后,在end loop之后,下一条语句if finished then ...会告诉你你想知道什么。