如何在不创建新输入信号的情况下编写具有多个输入的多路复用器?

How to Write A Mux With Several Inputs Without Creating a New Input Signal?

如果无法做到这一点,请给我一个简单的 "no" 以及一个简短的答案来说明原因,但我只是想仔细检查一下这是否无法完成。

我有这个过程:

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 mux 来帮助合成。

你可以这样做:

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...

虽然我要更改几个进程,但我想创建更多的信号名称。所以...

我想知道是否有一些我喜欢的方法(虽然不完全确定最终的 when others 会怎样):

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

您可能可以使用记录 and/or VHDL-2008 语法实现您想要的,但我建议不要这样做。

你不仅会失去可读性,我严重怀疑你是否会获得任何综合增益。

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

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;

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

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

另一种变体(向上和向下是布尔值)可能有助于提高可读性

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;