过程评估次数过多

时间:2015-05-30 11:32:18

标签: vhdl fpga

我有一个简单的设计,我从RS-232端口读取传入的字节,然后解析"它们。

我试图把它分成两个过程:

  1. 第一个从串口接收位并尝试构造它们 - 如果成功,它会将结果分配给next_byte类型unsigned(7 downto 0)的信号:

    -- simplified version
    rxbits := serial_rx & rxbits(...);
    if (rxbits contain a frame) then:
        next_byte <= ....;
        rxbits := (others => '1');
    end if;
    
  2. 第二个在敏感列表中有next_byte;它将ascii '0' / '1'转换为位值。我假设在分配next_byte时会对其进行评估:

    -- simplified version
    num <= num(...) & ascii_to_bit(next_byte);
    
  3. next_byte发生变化时,似乎过程2的评估次数过多:

    • 如果我将'1'发送到FPGA,num立即更改为所有'1' s(我稍后会在七段* 4显示屏上显示它,所以我可以看到)。
    • 如果我发送'0'num会立即更改所有'0'

    为什么会这样?导致它被评估多次的事件是什么?也许事实上它不是一个简单的&#34;信号(即不是std_logic)?

    顺便说一句,在Xilinx ISE的ISim中运行它并没有按照预期发送'1'num更新后重现这些结果。

    另外,如果我删除第二个进程,只需将第一个进程修改为:

    -- simplified version
    -- next_byte is a variable this time
    rxbits := serial_rx & rxbits(...);
    if (rxbits contain a frame) then:
        next_byte := ....;
        num <= num(...) & ascii_to_bit(next_byte);
        rxbits := (others => '1');
    end if;
    

    一切按预期工作 ...

    编辑:我已将代码修改为 sum 接收数字的值(即'1'1添加到num'5'添加5 ...)。如果我使用这2个进程运行它,显示(显示num)只是永远闪烁( - &gt;进程2被称为无限期 ...);如果我使用1个进程运行它,它就可以正常工作。

    编辑2:最小,但重现问题:

    signal a: unsigned(7 downto 0) := (others => '0');
    signal num: unsigned(13 downto 0) := (others => '0');
    
    ...
    
    process1: process(clk)
        variable counter: unsigned(31 downto 0) := (others => '0');
    begin
        if rising_edge(clk) then
            counter := counter + 1;
            if counter(23 downto 0) = 0 then
                a <= counter(31 downto 24);
            end if;
        end if;
    end process;
    
    process2: process(a)
    begin
        num <= num + a;
    end process;
    

    num的显示永远闪烁。

    但是在这里:

    signal num: unsigned(13 downto 0) := (others => '0');
    
    ...
    
    process1: process(clk)
        variable counter: unsigned(31 downto 0) := (others => '0');
    begin
        if rising_edge(clk) then
            counter := counter + 1;
            if counter(23 downto 0) = 0 then
                num <= num + counter(31 downto 24);
            end if;
        end if;
    end process;
    

    它运作正常,num的显示会随着您的预期而增加。

1 个答案:

答案 0 :(得分:1)

您的问题是您希望在合成后观察灵敏度列表。灵敏度列表严格用于模拟。

简化后,模拟器的工作假设是它们只需要在某些输入发生变化时重新评估过程。当指定VHDL时,计算能力来计算哪些信号触发了一个过程中有意义的变化并不容易获得。因此,语言创建者使用模拟工具来告知哪些信号会发生变化,从而手动重新评估过程。

您的问题是您在敏感列表中遗漏了一个信号:pair<CDrug, pair<unsigned,double>> expirednull(pair<CDrug, pair<unsigned,double>> temp){ if (temp.first.isValid() == false) temp.second.first = 0; return temp; } string checkForExpiredDrugs() { stringstream s; vector<CDealer>::iterator it1; map<CDrug, pair<unsigned, double>> d; map<CDrug, pair<unsigned, double>>::iterator it2; //transform algorithm for (it1 = this->m_dealers.begin(); it1 != this->m_dealers.end(); it1++) { s << "Dealer: " << it1->getCompany() << " " << it1->getRepresentative() << " " << it1->getTelephone() << endl; d = it1->getDrugs(); transform(d.begin(),d.end(),d.begin(),expirednull); for (it2 = d.begin(); it2 != d.end(); it2++) { if (it2->first.isValid() == false) { it2->second.first = 0; s << "Expired: " << it2->first << endl; } } it1->setDrugs(d); } return s.str(); }

num

您希望仅在更改时评估此内容。但是,硬件并没有这样做!在硬件中,这只是一个具有正反馈回路的加法器,因此它将继续一直添加。要在测试平台中查看正确的行为,请将process2: process(a) begin num <= num + a; end process; 添加到敏感度列表中,因为如果仔细观察,您会发现在您的流程中也会读取num

num

现在,您将在模拟工具中看到正确的行为,并且可能会收到一条消息,表明您已超过每个步骤的最大评估数。

想一想:

process2: process(a, num)
begin
    num <= num + a;
end process;

正如您所观察到的那样,显示屏会永远闪烁,因为num处于一个恒定的递增状态。

正如您也发现的那样,解决方法是让您的加法器同步。添加t = 0: num is 00, a is 00, num + a is also zero t = 1: a changes to 01 due to your UART receiving '1' num is 000, a is 01, num + a = 001 num is 001, a is 01, num + a = 002 num is 002, a is 01, num + a = 003 num is 003, a is 01, num + a = 004 num is 004, a is 01, num + a = 005 num is 005, a is 01, num + a = 006 num is 006, a is 01, num + a = 007 num is 007, a is 01, num + a = 008 num is 008, a is 01, num + a = 009 ... num is 255, a is 01, num + a = 000 num is 000, a is 01, num + a = 001 ... t = 2: simulator will never reach this point in time 信号,该信号仅在一个时钟周期内被置位,以指示从UART到达的新字符。 <{1}}被声明后,只能valid添加a

但在更改设计中的任何内容之前,您应该查看综合工具的输出。您的综合工具可能已经指出a)错误的灵敏度列表和b)设计中的组合循环。

您必须学会阅读综合工具的输出,并了解哪些警告只是警告,哪些警告表明您的设计存在致命缺陷。

相关问题