来自不同进程的VHDL驱动信号 [英] VHDL driving signal from different processes

查看:28
本文介绍了来自不同进程的VHDL驱动信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 VHDL 代码时遇到了一个小问题:

I have a little problem with following VHDL code:

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;

问题是信号 ucitanPrvi 的值总是 X.如果我不尝试在两个进程中设置它的值,那么我没有任何问题......所以我知道我不能驱动一个信号来自多个进程,但我不知道如何以不同的方式编写...有没有人知道我该如何解决这个问题?

The problem is that signal ucitanPrvi always has value X. If I don't try to set it's value in two processes, then I don't have any problems ... So I know that I mustn't drive one signal from multiple processes, but I don't know how to write this differently ... Does anyone have an idea how I could resolve this problem ?

谢谢!

谢谢大家的回复 :) 现在我明白为什么我不能从多个进程驱动一个信号(至少以我希望的方式工作).

Thank you all guys for replying :) Now I understand why I can't drive one signal from multiple processes (at least in the way I wanted it to work).

推荐答案

如果您想为真正的 FPGA 或 ASIC 综合您的设计,您将不得不从实际硬件(电线、触发器)的角度考虑 VHDL、门等).此外,如果您想在硬件中执行真正的上升沿检测,您将需要一个驱动触发器的系统时钟.鉴于您的原始代码示例,似乎 zbroji 或 oduzmi 不是系统时钟,而只是 std_logic 信号.我编写了这个代码示例,假设您的示例具有基本功能,希望您可以使用我的代码和注释并完成您需要的操作.

If you want to synthesize your design for a real FPGA or ASIC, you are going to have to think of VHDL in terms of real hardware (wires, flip flops, gates, etc.). Also, if you want to perform a real rising edge detect in hardware, you will need a system clock that drives a flip flop. Given your original code sample, it doesn't seem that zbroji or oduzmi are system clocks, but just std_logic signals. I wrote this code example assuming basic functionality from your example, hopefully, you can take my code and comments and accomplish what you need.

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;

前面的代码假设您有一个系统时钟.在像 ModelSim(免费学生版)这样的模拟器中,您可以生成一个 100 MHz 的时钟,其中包含不可综合的测试平台代码,如下所示...

The previous code assumes you have a system clock. In a simulator like ModelSim (free student edition), you can generate a 100 MHz clock with non-synthesizable testbench code like this...

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

在实际的 FPGA/ASIC 实现中,您可能希望使用运行在芯片中的外部振荡器,将信号驱动到 DCM(数字时钟管理器)中,它会向所有设备输出非常干净的时钟信号您的 VHDL 逻辑,因此您可以进行无故障设计.

In an actual FPGA/ASIC implementation, you will probably want to use an external oscillator that you run into your chip, drive the signal into a DCM (Digital clock manager), which will output a very clean clock signal to all of your VHDL logic, so you can have a glitch free design.

最后,这里有一个很好的解释,说明了rising_edge 和(clk'event 和 clk='1')

And finally, here is a great explanation on the differences between rising_edge and (clk'event and clk='1')

http://vhdlguru.blogspot.com/2010/04/difference-between-risingedgeclk-and.html

希望有所帮助.

这篇关于来自不同进程的VHDL驱动信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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