我在硬件领域工作。我需要生成从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)
答案 0 :(得分:2)
这基本上要求base-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。如果你可能需要很多这些,你可以/可以创建一个通用组件,让你在实例化中指定限制,并且(如果内存服务)计算该范围计数器所需的位数。这往往会使代码混淆一点,我猜这一点已经足够了。我也用输出小端设置它。如果你想要它是big-endian,你可以将它改为std_logic_vector(0 to 2)
(至少如果我没记错的话 - 似乎是正确的,但是自从我编写任何大端逻辑以来已经很长时间了)。