2

我在硬件领域工作。我需要生成从 0 到 n-1 的所有 nCk 数字组合。使用软件很容易做到这一点,但这需要使用 HDL- VHDL来完成。我不能在计算复杂性上花费太多,并且需要以 1 个样本/秒的速率生成(每个组合 1 个 clk 周期)。中间存储器可用。

例如:-假设对于 6C4,我需要生成

(1,2,3,4) (1,2,3,5) (1,2,3,6) (1,2,4,5) (1,2,4,6) (1,2, 5,6) (1,3,4,5) (1,3,4,6) (1,3,5,6) (1,4,5,6) (2,3,4,5) ( 2,3,4,6) (2,3,5,6) (2,4,5,6) (3,4,5,6)

秩序很重要。

编辑:'k' 和 'n' 总是偶数。考虑到这一点,有什么方法可以简化逻辑。

在这种情况下,实体的“n”和“k”输入可能会有所不同(“n”,上限为 16)

4

1 回答 1

2

这基本上是要求以 M 为底的 N 位数字(在您的示例中,4 位以 6 为底)。

鉴于您有可用的存储空间,您基本上可以定义一个 0..M 计数器,如下所示:

entity counter is
    port(reset : in std_logic; 
         clock : in std_logic;
         count : inout std_logic_vector(2 downto 0);
         carry : out std_logic);

architecture behavioral of counter is
begin
    process(reset, clock) is
    begin
        if reset = '1' then
            count <= "000";
            carry <= '0';
        else if clock = '1' and clock'event then
            count <= (count + 1) mod 6;
            if count = "000" then
                carry <= '1';
            else
                carry <= '0';
            end if;
        end if;
    end process;
end behavioral;

然后你实例化这些计数器中的 N 个。您将系统时钟连接到 N 个计数器右侧一位(最低有效位)的时钟输入。对于每个连续的计数器,您将从较低有效位的计数器的进位连接到下一个较高有效位的计数器的时钟输入。

然后,您将拥有更多的电路来驱动各个计数器的复位线,包括系统复位或系统复位以及计数器中最高有效位的进位(因此您在系统复位时从 0 开始, 并且当你达到所有数字的限制时也回绕到 0000)。

如果您的最大值不是常数,则需要为最大值指定一组输入,并且仅在当前计数 = 最大计数时回绕:

entity counter is
    port (reset : in std_logic;
          clock : in std_logic;
          count : inout std_logic_vector(3 downto 0);
          carry : out std_logic;
          max   : in std_logic_vector(3 downto 0));

-- ...

count <= count + 1;
if count = max then
     count <= "0000";
     carry <= '1';
else
     carry <= '0';
end if;

当然,还有一些其他的小细节——我已经counter“手动”将大小设置为 3 位,基于单个数字的最大值 6。如果您可能需要很多这些,您可以/可以创建一个通用组件,让您在实例化中指定限制并(如果内存服务)计算该计数器范围所需的位数。不过,这往往会使代码变得有些模糊,我猜目前这已经足够了。我还设置了输出小端。如果你想要它是大端的,你可以把它改成 a std_logic_vector(0 to 2)(至少如果我没记错的话——这似乎是对的,但是我已经很久没有写任何大端逻辑了)。

于 2014-01-21T05:43:24.043 回答