0

我正在编写一个灵活的 MUX,它有一个通用的,它决定了选择线的数量,也决定了系统的输入和输出的数量。例如,如果大小 = 3;该系统将有 8 个输入、64 个输出和 3 个选择线。这会创建 2^size 多路复用器,每次选择位更改时我都需要设置它们(它们是全局的)。

到目前为止,我有这个:

library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_unsigned.all ;

entity mux is
    generic ( size : positive := 3 ) ;
    port    ( din  : in  std_logic_vector (((2**size)-1) downto 0) ;
              sel  : in  std_logic_vector (size-1 downto 0) ;
              y    : out std_logic_vector (((2**(size*2))-1) downto 0) ) ;
end mux ;

architecture arc_mux of mux is
begin

    process(sel)
    begin

    end process ;

end arc_mux ;

我想做的是遍历循环中的输入( 0 到 ((2**size)-1) )并将正确的输出调整为存储在该位置的值。问题是我需要为此使用 sel 的值作为 i * 2**size 的偏移量,但我可以在本练习中使用的库不允许我使用 + 运算符将该值添加到 i * 2**尺寸。有什么建议么?

4

1 回答 1

0

您在 for 循环中可能遇到的错误应该告诉您通用整数绑定必须是数字文字或属性。2008 版 VHDL 中放宽的规则。

使用您的端口定义生成符合合成条件的描述并不难。您可以使用 din'reverse_range 或创建具有循环所需范围的数组子类型,或将隐式循环变量的类型指定为整数:

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

entity demux is
    generic ( size: positive := 3);
    port ( 
        din:    in  std_logic_vector (2**size-1 downto 0);
        sel:    in  std_logic_vector (size-1 downto 0);
        y:      out std_logic_vector (2**(size*2)-1 downto 0) 
    );
end entity;

architecture foo of demux is

begin

PROC:
    process(sel, din)
        -- subtype sel_range is std_logic_vector (0 to 2**size-1);
    begin

    SLCT:
        -- for i in sel_range'range loop
        for i in integer range 0 to 2**size-1 loop
            if i = to_integer(unsigned(sel)) then
                y(i*din'length+din'length-1 downto i*din'length) <= din;
            else
                y(i*din'length+din'length-1 downto i*din'length) <= (others => '0');
            end if;
        end loop;
    end process ;

end architecture;

此代码使用 VHDL-93 库 numeric_std 和无符号类型转换以isel. 您可以使用 Synopsys 库,可以很容易地使用。使用循环并将值分配给y索引范围允许综合。

通过 for 循环的迭代将在硬件中(并行)复制。分配的切片y取决于哪些是静态的。idin'length

这个例子分析、阐述和模拟。

demux_tb 模拟

如果您打算锁定 'y' 值并y基于 顺序更新切片sel,那么仅保留din进程敏感度列表是不够的。它不是一个符合合成条件的构造,它对sel. 注意我添加din到过程敏感度列表中。如果您打算使用可寻址锁存器或寄存器,则需要时钟或单独的锁存器启用,因为sel元素的上升和下降时间不一定相等,如果您通过门生成启用。您可能会在实际硬件实现中出现故障。(您的语言“......将正确的输出调整为存储在该位置的值”不清楚)。

您的端口声明是一个很好的例子,它比基于运算符优先级实际需要的括号多。

您可能还注意到,长度din不必要地与sel位数相关联,这就是为什么din'reverse_length会起作用的原因。din是的,长度和长度之间需要存在关系y,并且y长度与size. y'LEFT否则会2**size*din'LENGTH-1。这意味着第二个通用的大小为din. 它还会更改 for 循环语句的y赋值切片边界数学。

于 2014-04-27T03:42:48.053 回答