Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自不同进程的VHDL驱动信号_Vhdl - Fatal编程技术网

来自不同进程的VHDL驱动信号

来自不同进程的VHDL驱动信号,vhdl,Vhdl,我对以下VHDL代码有点问题: process (zbroji) begin if rising_edge(zbroji) then oduzima <= '0'; ucitanPrvi <= '1'; broj1 <= ulaz_broj; end if; end process; process (oduzmi) begin if rising_edge(oduzmi) then od

我对以下VHDL代码有点问题:

process (zbroji)
begin
    if rising_edge(zbroji) then
        oduzima <= '0';
        ucitanPrvi <= '1';
        broj1 <= ulaz_broj;
    end if;
end process;

process (oduzmi)
begin
    if rising_edge(oduzmi) then
        oduzima <= '1';
        ucitanPrvi <= '1';
        broj1 <= ulaz_broj;
    end if;

end process;
过程(zbroji)
开始
如果上升沿(zbroji)那么

oduzima如果您从多个进程驱动
std_逻辑
信号(请记住,进程外的连续赋值也会创建一个隐含进程!),则除一个进程外,所有进程都必须驱动
Z
。对于第一个近似值,分辨率函数(决定最终值应该是什么)将产生
X
s,除非发生这种情况

我不确定如何最好地更改代码-您需要决定某个特定进程何时不应驱动信号,并让它在该点驱动a
Z



ieee.std_logic_1164包中定义了多个驱动程序的解析方式的完整定义,并涵盖了所有可能性,例如
1
L
驱动等。ieee对版权问题表示担忧,因此我不打算在这里发布任何摘录,但是你可以在模拟器的源代码库中找到它。

除非你真的知道自己在做什么,否则从多个进程驱动信号是个坏主意。您可以像这样在单个进程中重新编写此代码

process (zbroji, oduzmi)
begin
    if rising_edge(zbroji) then
        oduzima <= '0';
        ucitanPrvi <= '1';
        broj1 <= ulaz_broj;
    end if;
    if rising_edge(oduzmi) then
        oduzima <= '1';
        ucitanPrvi <= '1';
        broj1 <= ulaz_broj;
    end if;
end process;

除非zbroji和oduzmi是分开的时钟,否则这是我建议的实现

这将注册zbroji和oduzmi,并检查寄存器中的值是否与原始信号相反。只有当zbroji/oduzmi从0变为1且寄存器尚未更新信号变化时,才会发生这种情况

process (clk)
begin
    if rising_edge(clk) then
        if zbroji = '1' and zbroji_old = '0' then
            oduzima <= '0';
            ucitanPrvi <= '1';
            broj1 <= ulaz_broj;
        elif oduzmi = '1' and oduzmi_old = '0' then
            oduzima <= '1';
            ucitanPrvi <= '1';
            broj1 <= ulaz_broj;
        end if;
        zbroji_old <= zbroji;
        oduzmi_old <= oduzmi;
    end if;
end process;
过程(clk)
开始
如果上升沿(clk),则
如果zbroji='1'和zbroji_old='0',则

oduzima如果你想为一个真正的FPGA或ASIC综合你的设计,你必须从真正的硬件(导线、触发器、门等)的角度考虑VHDL。此外,如果您想在硬件中执行真正的上升沿检测,则需要一个驱动触发器的系统时钟。给定您的原始代码示例,zbroji或oduzmi似乎不是系统时钟,而是std_逻辑信号。我编写了这个代码示例,假设您的示例具有基本功能,希望您能够接受我的代码和注释并完成您需要的功能

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity example is
  port (Reset      : in  std_logic;
        SysClk     : in  std_logic;
        zbroji     : in  std_logic;
        oduzmi     : in  std_logic;
        ulaz_broj  : in  std_logic;
        oduzima    : out std_logic;
        ucitanPrvi : out std_logic;
        broj1      : out std_logic
        );

end example;

architecture Behavioral of example is

  -- Delayed version of input signals (1 clock cycle delay)
  signal zbroji_d : std_logic;
  signal oduzmi_d : std_logic;

  signal zbrojiRE : std_logic;
  signal oduzmiRE : std_logic;

begin

  -- Generate 1 clock cycle delayed version of
  -- signals we want to detect the rising edge
  -- Assumes active high reset
  -- Note: You should only use the rising_edge macro
  -- on an actual global or regional clock signal. FPGA's and
  -- ASICs place timing constraints on defined clock signals
  -- that make it possible to use rising_edge, otherwise, we have
  -- to generate our own rising edge signals by comparing delayed
  -- versions of a signal with the current signal.
  -- Also, with any respectable synthesizer / simulator using
  -- rising_edge is almos exactly the same as (clk'event and clk='1')
  -- except rising_edge only returns a '1' when the clock makes a
  -- valid '0' to '1' transition. (see link below)
  EdgeDetectProc : process (Reset, SysClk)
  begin
    if Reset = '1' then
      zbroji_d <= '0';
      oduzmi_d <= '0';
    elsif rising_edge(SysClk) then
      zbroji_d <= zbroji;
      oduzmi_d <= oduzmi;
    end if;
  end process EdgeDetectProc;

  -- Assert risinge edge signals for one clock cycle 
  zbrojiRE <= '1' when zbroji = '1' and zbroji_d = '0' else '0';
  oduzmiRE <= '1' when oduzmi = '1' and oduzmi_d = '0' else '0';

  -- Assumes that you want a single cycle pulse on ucitanPrvi on the
  -- rising edege of zbroji or oduzmi;
  ucitanPrvi <= zbrojiRE or oduzmiRE;

  -- Based on your example, I can't tell what you want to do with the
  -- broj1 signal, but this logic will drive broj1 with ulaz_broj on
  -- either the zbroji or oduzmi rising edge, otherwise '0'.
  broj1 <= ulaz_broj when zbrojiRE = '1' else
           ulaz_broj when oduzmiRE = '1' else
           '0';

  -- Finally, it looks like you want to clear oduzima on the rising
  -- edge of zbroji and assert oduzima on the rising edge of
  -- oduzmi
  LatchProc : process (Reset, SysClk)
  begin
    if Reset = '1' then
      oduzima <= '0';
    elsif rising_edge(SysClk) then
      if zbrojiRE = '1' then
        oduzima <= '0';
      elsif oduzmiRE = '1' then
        oduzima <= '1';
      end if;
    end if;
  end process LatchProc;

end Behavioral;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体示例是
端口(复位:在std_逻辑中;
SysClk:标准逻辑中;
zbroji:标准逻辑;
oduzmi:标准逻辑中;
ulaz_broj:标准逻辑;
oduzima:输出标准逻辑;
ucitanPrvi:输出标准逻辑;
broj1:输出标准逻辑
);
结束示例;
示例的架构是
--输入信号的延迟版本(1个时钟周期延迟)
信号zbroji_d:标准逻辑;
信号oduzmi_d:标准逻辑;
信号zbrojiRE:std_逻辑;
信号oduzmiRE:std_逻辑;
开始
--生成1个时钟周期延迟版本的
--我们想要检测上升沿的信号
--假设主动高电平复位
--注意:应仅使用“上升沿”宏
--在实际的全球或区域时钟信号上。FPGA的和
--ASIC对定义的时钟信号施加定时约束
--这使得使用上升沿成为可能,否则,我们必须
--通过比较延迟信号来产生我们自己的上升沿信号
--具有当前信号的信号版本。
--此外,任何值得尊敬的合成器/模拟器使用
--上升沿与(clk'事件和clk='1'完全相同)
--但上升沿仅在时钟发出“1”时返回“1”
--有效的“0”到“1”转换。(见下面的链接)
EdgeDetectProc:进程(重置,SysClk)
开始
如果重置='1',则

zbroji_d当您从多个进程更改相同的信号值时,模拟器将为此创建多个信号驱动程序。它们的输出将基本上无法解决。将其视为连接在一起的多个门的输出,您期望得到什么

要克服这一点,您需要实现一个分辨率函数,它将输出驱动为信号


如果你有任何疑问,请告诉我

除非zbroji和oduzmi是时钟,否则我不会使用上升沿语句。我认为另一种方法是你提出的两种方法中更好的。上升沿语句来自原始代码。我也不会用它。是odzumi和zbroji时钟还是信号?
    ucitanPrvi <= '0'
    broj1 <= (others=>'0') -- assumed reset?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity example is
  port (Reset      : in  std_logic;
        SysClk     : in  std_logic;
        zbroji     : in  std_logic;
        oduzmi     : in  std_logic;
        ulaz_broj  : in  std_logic;
        oduzima    : out std_logic;
        ucitanPrvi : out std_logic;
        broj1      : out std_logic
        );

end example;

architecture Behavioral of example is

  -- Delayed version of input signals (1 clock cycle delay)
  signal zbroji_d : std_logic;
  signal oduzmi_d : std_logic;

  signal zbrojiRE : std_logic;
  signal oduzmiRE : std_logic;

begin

  -- Generate 1 clock cycle delayed version of
  -- signals we want to detect the rising edge
  -- Assumes active high reset
  -- Note: You should only use the rising_edge macro
  -- on an actual global or regional clock signal. FPGA's and
  -- ASICs place timing constraints on defined clock signals
  -- that make it possible to use rising_edge, otherwise, we have
  -- to generate our own rising edge signals by comparing delayed
  -- versions of a signal with the current signal.
  -- Also, with any respectable synthesizer / simulator using
  -- rising_edge is almos exactly the same as (clk'event and clk='1')
  -- except rising_edge only returns a '1' when the clock makes a
  -- valid '0' to '1' transition. (see link below)
  EdgeDetectProc : process (Reset, SysClk)
  begin
    if Reset = '1' then
      zbroji_d <= '0';
      oduzmi_d <= '0';
    elsif rising_edge(SysClk) then
      zbroji_d <= zbroji;
      oduzmi_d <= oduzmi;
    end if;
  end process EdgeDetectProc;

  -- Assert risinge edge signals for one clock cycle 
  zbrojiRE <= '1' when zbroji = '1' and zbroji_d = '0' else '0';
  oduzmiRE <= '1' when oduzmi = '1' and oduzmi_d = '0' else '0';

  -- Assumes that you want a single cycle pulse on ucitanPrvi on the
  -- rising edege of zbroji or oduzmi;
  ucitanPrvi <= zbrojiRE or oduzmiRE;

  -- Based on your example, I can't tell what you want to do with the
  -- broj1 signal, but this logic will drive broj1 with ulaz_broj on
  -- either the zbroji or oduzmi rising edge, otherwise '0'.
  broj1 <= ulaz_broj when zbrojiRE = '1' else
           ulaz_broj when oduzmiRE = '1' else
           '0';

  -- Finally, it looks like you want to clear oduzima on the rising
  -- edge of zbroji and assert oduzima on the rising edge of
  -- oduzmi
  LatchProc : process (Reset, SysClk)
  begin
    if Reset = '1' then
      oduzima <= '0';
    elsif rising_edge(SysClk) then
      if zbrojiRE = '1' then
        oduzima <= '0';
      elsif oduzmiRE = '1' then
        oduzima <= '1';
      end if;
    end if;
  end process LatchProc;

end Behavioral;
ClockProc : process
begin 
   SysClk <= '0';
   wait for 5 ns;
   SysClk <= '1';
   wait for 5 ns;
end process ClockProc;