0

如果这无法做到,请给我一个简单的“否”,或许还有一个简短的答案,说明原因,但我想仔细检查一下,这不能做到。

我有这个过程:

process(clk_p)
begin
    if rising_edge(clk_p) then
        if rst_i = '1' then
            stored_events <= (others => '0');
        else
            if mode_triggered = '1' and ptr = 0 and read_state = ST_ENABLE then
                stored_events <= stored_events;
            elsif mode_triggered = '1' then
                stored_events <= stored_events + 1;
            elsif ptr = 0 and read_state = ST_ENABLE then
                stored_events <= stored_events - 1;
            end if;
        end if;
    end if;
end process;

是的,这不是很好,我们为什么要通过将其变成适当的 case 多路复用器来帮助合成。

你可以这样做:

sel(0) <= '1' when mode_triggered= = '1' else '0';
sel(1) <= '1' when ptr = 1 else '0'; 
sel(2) <= '1' when read_state = ST_ENABLE else '0';

case sel is 
    when "111" => 
        stored_events <= stored_events; -- and so on...

虽然由于我要更改几个进程,但我 cba 会制作更多的信号名称。所以...

我想知道是否有某种我可以喜欢的方式(尽管不完全确定决赛的when others结果):

case mode_triggered, ptr, read_state is 
    when '1', 0, ST_ENABLE =>
        stored_events <= stored_events;
4

2 回答 2

1

Another variant (up and down are boolean) may help readability

down <= ptr = 0 and read_state = ST_ENABLE;
up   <= mode_triggered and not down;

process(clk_p)
begin
    if rising_edge(clk_p) then
        if rst_i = '1' then
            stored_events <= (others => '0');
        else
            if up then
                stored_events <= stored_events + 1;
            elsif down then
                stored_events <= stored_events - 1;
            end if;
        end if;
    end if;
end process;
于 2015-03-24T17:50:35.510 回答
1

您可能可以使用记录和/或 VHDL-2008 语法来实现您所寻求的,但我建议不要这样做。

您不仅会失去可读性,而且我严重怀疑您会获得任何综合收益。

当我查看您的代码时,我没有看到任何多路复用器。相反,我看到了一个带有同步复位和时钟启用端口的向上/向下计数器。如果你愿意,你可以这样写:

clk_en <= '0' when mode_triggered = '1' and ptr = 0 and read_state = ST_ENABLE else
          '1' when mode_triggered = '1' or (ptr = 0 and read_state = ST_ENABLE) else
          '0';
up <= '1' when mode_triggered = '1' else '0';

process(clk_p)
begin
    if rising_edge(clk_p) then
        if rst_i = '1' then
            stored_events <= (others => '0');
        elsif clk_en = '1' then
            if up = '1' then
                stored_events <= stored_events + 1;
            else
                stored_events <= stored_events - 1;
            end if;
        end if;
    end if;
end process;

编写代码的所有三种方式都应该导致相同的网表(希望如此),它们仅在可读性上有所不同。就个人而言,我更喜欢您的第一次尝试,因为它来自您正在实现的功能,但这一切都是偏好。我也不喜欢 mux 方法(对于这种情况)。

根据经验,除非你也有,否则不要写来帮助合成器。查看综合报告和生成的网表,仅在您不喜欢所见内容时进行调整。与我们人类理解充满多路复用器和逻辑门的代码的功能相比,合成器更擅长从代码中提取电路,就像您的第一次尝试一样。

于 2015-03-24T13:52:52.140 回答