vhdl - 如何在不使用 for 循环的情况下获取 one-hot 编码向量的索引?
问题描述
我有一个信号“event_id”,其中任何时候只有一个位为高。我需要将此单热编码信号转换为索引的整数值。
信号:
signal event_id: std_logic_vector(3 downto 0);
signal event_index: natural;
我知道我可以用 for 循环做到这一点。这就是我目前正在做的事情:
for i in 3 downto 0 loop
if(event_id(i) = '1') then
event_index = i;
end if;
end loop;
有没有更好的方法来做到这一点,不需要for循环或单独遍历每一位?我知道我可以使用 for-loop 方法创建一个函数,但我觉得应该有一个我缺少的简单解决方案。
解决方案
没有用于在 VHDL 中生成 one-hot 向量索引的“简单”解决方案。
对于 4 位的 one-hot 向量,因此结果索引为 2 位,您所做的循环是一个好的解决方案,它是可读的并且在实现中不会占用太多资源。虽然它不是最小的解决方案,因为它不允许实现大小从 one-hot 属性中受益,因为它返回设置位的最低索引。对于简短的 one-hot 向量,如果实现是在 FPGA 中,这并不重要,因为它使用量化的 LUT 资源。
对于较长的 one-hot 向量,如果使用 one-hot 属性,则实现将更小。这可以通过一种算法来完成,其中索引位是从 one-hot 向量和掩码生成的。下面显示了一个函数。
-- One hot to index calculate; assuming LEN_HOT = 2 ** LEN_IDX
function hot2idx_cal(hot : std_logic_vector) return std_logic_vector is
variable mask_v : std_logic_vector(LEN_HOT - 1 downto 0);
variable res_v : std_logic_vector(LEN_IDX - 1 downto 0);
begin
for i in 0 to LEN_IDX - 1 loop
-- Generate mask
for j in 0 to LEN_HOT - 1 loop
if ((j / (2 ** i)) mod 2) = 0 then
mask_v(j) := '0';
else
mask_v(j) := '1';
end if;
end loop;
-- Apply mask and generate bit in index
if unsigned(hot and mask_v) = 0 then
res_v(i) := '0';
else
res_v(i) := '1';
end if;
end loop;
return res_v;
end function;
推荐阅读
- xcode - 找不到 -lRNFirebase React Native 的库
- angular - Angular HttpClient 删除
- notepad++ - 我想删除 Notepad++ 中所有出现的类似文本
- vue.js - 带有来自 API 调用的值的 Vue.js 进度条
- dialogflow-es - 如何在 DialogFlow 中保持麦克风打开
- javascript - 使用 jquery 过滤 D3.js 地图?
- sql - SQL:根据属性顺序对行进行排序
- css - 在 :hover 上更改 background-position-x
- git - 是否可以在 git 集成的同时使用远程 PyCharm?
- ruby-on-rails - 为什么在 Rails 系统测试中不会触发“ajax:success”事件?