我现在正在经历第二次或第三次学习VHDL的阶段。 (这次有一个非常好的和免费的e-book),我终于开始“得到”相当多的了。现在我正在学习行为风格和流程陈述,其中大部分都是有道理的。但是,我在许多地方都读过,除了某些情况外,应该避免使用这些流程。我的意思是,从理论上讲,一切都不能在数据流而不是行为中实现?
何时应该明确应该使用流程声明?
答案 0 :(得分:5)
流程声明非常有用,在什么情况下你被告知不要使用它们?
在许多不同的情况下,您会使用流程声明,我将在下面概述其中一些:
过程语句(用于综合)的最常见用法之一是描述与时钟信号同步的逻辑,例如,一个简单的计数器在不复位时每个时钟周期递增可以描述为:
DATA_REGISTER : process(CLOCK)
begin
if rising_edge(CLOCK) then
if RESET = '1' then
COUNTER <= (others => '0');
else
COUNTER <= COUNTER + 1; --COUNTER is assumed to be of type 'unsigned'
end if;
end if;
end process;
随着您的设计变得越来越复杂,您将不可避免地在某个时刻实现状态机,这将根据您选择实施的状态机的样式采用一个或多个进程。
对于行为代码,您可以将进程与wait语句结合使用来生成测试向量或模拟真实系统的行为。这是一个从我的测试平台中取出的100MHz时钟发生器的基本示例:
architecture BEH of ethernet_receive_tb is
signal s_clock : std_logic := '0'; --Initial assignment to clock kicks off the process.
begin
CLOCKGEN : process(s_clock)
begin
s_clock <= not s_clock after 5 NS;
end process CLOCKGEN;
...
您还可以使用进程描述异步逻辑,在这种情况下,您需要包括在灵敏度列表中的过程中读取的所有信号,并且您需要确保始终定义任何输出以避免推断锁存器。
IF_ELSE: process (SEL, A, B)
begin
F <= B; -- Default assignment
if SEL = '1' then
F <= A;
end if;
end process;
希望您可以看到进程语句非常有用,并且您将在许多不同的情况下使用它。我希望这能回答你的问题!
答案 1 :(得分:3)
流程块是你的朋友。
他们提供了一种说法“这段代码是相关的。它的输入是X,Y,Z,它驱动A,B,C”。输入由敏感性列表记录(除非它是一个时钟进程,在这种情况下应该在您的注释中)。如果其他任何东西驱动相同的信号,那么你将在模拟中得到警告,错误,X(取决于你的工具)。无论你得到什么,都很明显。
我个人非常乐意在一个实体中编写多个进程,但每个人都有自己的风格。例如,如果我有多个管线阶段,则每个阶段都是一个过程。如果我有并行的非干扰路径,则每个路径都在一个单独的过程中。通过这种方式,代码构造在易于阅读的小块中。小的简单逻辑合成小的快速块(通常)。
您可以将我的样式视为将它们用作轻量级实体。
答案 2 :(得分:2)
在可合成代码中,只要您需要将信息从一个时钟周期保持到另一个时钟周期,就需要所需的进程。用行话来“存储状态”。
(请注意,某个过程可以隐含在代码中,例如
d <= q when rising_edge(clk);
)
如果是不可合成的代码,则进程对于以特定顺序发生事件非常有用:
p1: process
begin
data <= "--------";
WE <= '0';
wait until reset = '1';
wait until processor_initialised = '1';
assert ACK = '0' report "ACK should be low!" severity error;
data <= X"16";
WE <= '1';
wait until ACK = '1';
end process;
我的大多数代码每个实体都有一个进程。每个实体都会做一些有用的,明确定义的,小到可以测试的任务