我需要多少个进程来监视两个信号? [英] how many processes i need to monitor two signals?

查看:29
本文介绍了我需要多少个进程来监视两个信号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 vhdl 初学者,需要帮助解决我的问题.我有 2 个需要监控的信号.一个是 CHECK,另一个是 OK.每次我要求检查时,我都应该没问题(高或低).我需要连续监测 6 个连续的 CHECK 脉冲,并计算 OK.如果我有 6 OK (LOW) 那么我需要产生输出 (HIGH),任何其他情况下的输出 (LOW).我编写了一些代码,但不会产生上面想要的输出.但我首先有一个基本问题.这可以在一个过程中完成吗?

I am a vhdl begginner, and in need of help for my problem. I have 2 signals that i need to monitor. One is CHECK and the other OK. Every time i ask for a CHECK, I should get OK (HIGH or LOW). I need to monitor contantly 6 consecutive CHECK pulses, and count the OK. If i have 6 OK (LOW) then i need to produce the output (HIGH), any other case output (LOW). I have writen some code that does not produce the wanted output above. But i have a fundamental question first. can this be done in one process?

--one process
if ...
  reset clauses
elsif
  count pulses and set a variable to 6
else  
  if variable = 6, produce output
end if;

或者我需要更多吗?

--first process
start counter on rising_edge of CHECK

-- second process
count pulses and set a signal some value (6)

-- third process 
monitor signal and if =6, produce output

这是我尝试过的代码,但失败了...将调查 FSM...

Here is the code i tried, but failed... will look into FSM...

counter_operation:process (RESETn, CHECK, OK)
variable counter : unsigned (2 downto 0);
variable lost_count : unsigned (2 downto 0);
begin
-- if reset it asserted ensure counter is not running
if ( RESETn = '0') then
    trip_signal <= '0';
    lost_count := to_unsigned (0,3);
    counter := to_unsigned (0,3);

-- run counter and perform actions
elsif (rising_edge(CHECK)) then
        -- increment counter and limit maximum value
        counter := counter+1;   
        if (counter > to_unsigned(6,3) ) then
            counter := to_unsigned (0,3);
            lost_count := to_unsigned (0,3);
        end if;

        -- check for first OK(LOW)
        if (counter = to_unsigned(1,3))  then
            if (OK = '0') then
                lost_count := lost_count + to_unsigned (1,3);
            else
                lost_count := lost_count;   
            end if; 
        end if;
        -- check for second consecutive OK(LOW)
        if (counter = to_unsigned(2,3))  then
            if (OK = '0') then
                lost_count := lost_count + to_unsigned (1,3);
            else
                lost_count := lost_count;   
            end if; 
        end if;
        -- check for third consecutive OK(LOW)
        if (counter = to_unsigned(3,3))  then
            if (OK = '0') then
                lost_count := lost_count + to_unsigned (1,3);
            else
                lost_count := lost_count;   
            end if; 
        end if;
        -- check for fourth consecutive OK(LOW)
        if (counter = to_unsigned(4,3))  then
            if (OK = '0') then
                lost_count := lost_count + to_unsigned (1,3);
            else
                lost_count := lost_count;   
            end if; 
        end if;
        -- check for fifth consecutive OK(LOW)
        if (counter = to_unsigned(5,3))  then
            if (OK = '0') then
                lost_count := lost_count + to_unsigned (1,3);
            else
                lost_count := lost_count;   
            end if; 
        end if;
        -- check for sixth consecutive OK(LOW)
        if (counter = to_unsigned(6,3))  then
            if (OK = '0') then
                lost_count := lost_count + to_unsigned (1,3);
            else
                lost_count := lost_count;   
            end if; 
        end if;
        -- check if we lost 6 consecutive 
        if (lost_count = to_unsigned (6,3)) then
            trip_signal <= '1';
        else
            trip_signal <= '0'; 
        end if; 
    end if;
end process counter_operation;

我在这里肯定有问题,因为模拟前和模拟后不会产生相同的结果.Pre-sim 似乎有效,但 post-sim 无效.

I definetely have something wrong in here, because pre and post simulation do not produce the same results. Pre-sim seems to work, but post-sim does not.

编辑(2):对于 FSM,类似这样的事情?

EDIT (2): for the FSM, something like this?

library IEEE;
use IEEE.std_logic_1164.all;

entity FSM_1 is
port (
    CHECK : in std_logic;
    CRC :in std_logic;
    CLK : in std_logic; 
    RESETn :in std_logic;
    OUT_SIG : out std_logic

);
end FSM_1;

architecture arch of FSM_1 is


-- signal, component etc. declarations
type TargetSeqStates is (IDLE, FIRST_CHECK, SECOND_CHECK, THIRD_CHECK, FOURTH_CHECK, FIFTH_CHECK, SIXTH_CHECK);
signal curr_st, next_st : TargetSeqStates;

begin
--------------------------------------------------------------------------------
-- Using the current state of the counter and the input signals, decide what the next state should be
--------------------------------------------------------------------------------
NxStDecode:process (CHECK, OK, curr_st)
begin
-- default next-state condition
next_st <= IDLE;
-- TODO...

-- TODO...
end process NxStDecode;
--------------------------------------------------------------------------------
-- At the desired clock edge, load the next state of the counter (from 1.) into the counter
-- create the current-state variables 
--------------------------------------------------------------------------------
CurStDecode:process (CLK, RESETn)
begin
-- Clear FSM to start state 
if (RESETn = '0') then
    curr_st <= IDLE;
elsif (rising_edge(CLK)) then
    curr_st <= next_st;
end if;
end process CurStDecode;

--------------------------------------------------------------------------------
-- Using the current state of the counter and the input signals, decide what the values of all output signals should be
--------------------------------------------------------------------------------
DecOutputs;process (curr_st)
begin
-- TODO....

-- TODO...

end process DecOutputs;

end arch;

我猜 TODO 部分依赖于状态图?另外,我需要CLK吗?看来我需要改变状态,在 CHECK 的上升沿,而不是 CLK.

I guess the TODO parts are dependent of the state diagram? Also, do I need the CLK? It seems that I need to change state, on rising_edge of CHECK, not CLK.

最终

counter_operation:process (RESETn, CHECK, OK, CLK)
variable lost_counter : integer := 0;
variable last_CHECK : std_logic;

begin
    if ( RESETn = '0') then
    D_TRIP <= '0';
    lost_counter := 0;

else 
    if (rising_edge(CLK)) then
        if (CHECK /= last_CHECK) then
            if (OK = '0') then
            lost_counter := lost_counter + 1;
            else
            lost_counter := 0;  
            end if; 
            D_TRIP <= '0';
            if (lost_counter = 6) then
            D_TRIP <= '1';
            lost_counter := 0;
            end if;   
        end if;
        last_CHECK := CHECK;
    end if;
end if;
end process counter_operation;

推荐答案

我认为制作单进程状态机是最好的开始方式.它避免了形成闩锁时的一些潜在问题,并阻止您到处跳来跳去试图查看每种状态下发生的情况(为此您必须查看两个甚至三个不同的地方).但我不确定你是否需要一个完整的 FSM!

I'd say making a single-process state machine is the best way to start. It saves some potential problems with latches being formed, and stops you jumping all over the place trying to see what is going on in each state (for which you have to look in two or even three separate places). But I'm not sure you need a full blown FSM!

您的原始代码看起来还不错.对其进行快速评论:

Your original code doesn't look too bad. A quick comment on it:

您可以将整数添加到无符号向量,因此您不必这样做:

You can add integers to unsigned vectors, so you don't have to do this:

lost_count := lost_count + to_unsigned (1,3);

你可以这样做:

lost_count := lost_count + 1;

我也会将 lost_counter 设为 integer,而不是无符号向量,因为您不需要它环绕,也不需要大于 2 的值**31、你也不想直接访问位.因此,整数是一轮胜利.

I'd make lost_counter an integer too, rather than an unsigned vector, as you are not requiring it to wrap around, nor wanting values greater than 2**31, nor do you want direct access to the bits. Therefore an integer is a win all round.

看起来您想要找到 6 个连续的 0 位 - 以下代码是我将如何做到的 - 它将进入(您第一次尝试的)计时进程:

It looks like you want to find 6 consecutive 0 bits - the following code is how I would do it - it will go inside the clocked process (of your first try):

if ok = '0' then
    lost_counter := lost_counter + 1;
else
    lost_counter := 0;
end if;
trip <= '0';
if lost_counter = 6 then
    trip <= '1';
    lost_counter := 0;
end if;  

<小时>

关于时钟的更新...


Update regarding clocks...

是的,有一个时钟几乎是强制性的,所以上升沿是在时钟上完成的,然后你使用这个转换来采样你感兴趣的所有信号.还有其他方法可以做到,但它们是仅适用于非常高级的特殊情况.为每个进程使用一个时钟的方法称为同步设计",它的使用范围非常广泛,以至于所有工具都希望您能够使用它.

Yes, it's pretty much mandatory to have a clock, so the rising_edge is done on the clock, and then you use that transition to sample all the signals you are interested in. There are other ways of doing it, but they are only for very advanced special cases. The method of using a single clock for every process is called "synchronous design" and it is so widely used that all the tools really expect it of you.

为了找到您的 CHECK 信号的上升沿,您必须在时钟的上升沿查看(采样)它,存储该值,然后在得到时将其与下一个值进行比较下一个时钟沿.如果最后一个是 0,而当前是 1,你就知道它在时钟边沿之间上升"了,你可以在那个时候做任何你想做的事情.另请参阅我在此主题上的回答:

In order to find the rising edge of your CHECK signal, you will have to look at it (sample it) on the rising edge of your clock, store the value, and then compare it with the next value when you get the next clock edge. If the last one was a zero and the current one is a one, you know it has "risen" between the clock edges, and you can do whatever you like at that point. See also my answer here on this subject:

https://stackoverflow.com/a/20472791/106092

这篇关于我需要多少个进程来监视两个信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆