VHDL - 如何比较两个 bit_vectors 以进行动态 table 查找
VHDL - How to compare two bit_vectors for dynamic table lookup
我在两个信号中存储了两个 table。一个table保存key(地址),一个保存key对应的value。我需要将输入与密钥进行比较,如果它们匹配,return 存储的值。
我需要它的原因是用于分支指令预测的动态查找table。在处理器的获取阶段,我得到输入 Instruction_Address 和 return 一个 branch_To_Address 和一个 branch_Prediction。最初我想存储16个predictions/branch个地址,用一个环形缓冲环根据需要覆盖。
我一直在尝试使用带有嵌套 IF 的 FOR 来搜索 keyTable 中的键。
整个模块似乎工作正常,除非我将两个 bit_vectors 与 IF 语句进行比较。我需要两次(一次读取,一次写入),因此我需要 "sweep" keysTable 以便我可以查看正在查找的地址是否有条目。
我在模拟时注意到错误,无论 keysTable 是否具有正确的条目,ELSE 子句总是被调用。
可验证的例子:
library IEEE;
use ieee.numeric_bit.all;
entity branch_prediction_table is
generic (
addrSize : NATURAL := 4;
tableSize : NATURAL := 4);
port (
clock : in bit;
input_addr: in bit_vector(addrSize-1 downto 0);
return_value : out bit );
end branch_prediction_table;
architecture branch_table of branch_prediction_table is
signal keysTable : bit_vector(addrSize*tableSize-1 downto 0) := ( others => '0');
signal valuesTable : bit_vector(tableSize*2-1 downto 0) := ( others => '0');
begin
tableProc: process(clock) is
variable valueFromTable : bit;
begin
if rising_edge(clock) then
search_table: for iR in (tableSize-1) to 0 loop
if (keysTable(addrSize*(iR+1)-1 downto addrSize*iR) = input_addr) then
valueFromTable := valuesTable((iR+1)*2-1);
EXIT search_table;
else
valueFromTable := '0';
end if;
end loop search_table;
return_value <= valueFromTable;
end if; -- rising_edge(clock)
end process tableProc;
end branch_table;
具有可验证的测试平台模拟 TCL:
add wave -position insertpoint \
sim:/branch_prediction_table/addrSize \
sim:/branch_prediction_table/clock \
sim:/branch_prediction_table/input_addr \
sim:/branch_prediction_table/keysTable \
sim:/branch_prediction_table/return_value \
sim:/branch_prediction_table/tableSize \
sim:/branch_prediction_table/valuesTable
force -freeze sim:/branch_prediction_table/valuesTable 11111111 0
force -freeze sim:/branch_prediction_table/keysTable 1111101001100011 0
force -freeze sim:/branch_prediction_table/clock 0 0, 1 {5000 ps} -r {10 ns}
run 10 ns
force -freeze sim:/branch_prediction_table/input_addr 1010 0
run 20 ns
force -freeze sim:/branch_prediction_table/input_addr 1111 0
run 10 ns
并且testbench仿真结果显示错误确实在IF中:
我试过用 to_integer(unsigned(bit_vector1)) = to_integer(unsigned(bit_vector2)) 转换它们,但没有用
正如 user1155120 指出的那样:
问题出在search_table: for iR **in** (tableSize-1) to 0 loop
它应该是 "下降到" 作为 L > R。因为我使用 "in" 和 L>R,产生一个空范围并且 for 循环迭代被认为是完整的。
(IEEE Std 1076-2008 5.2 Scalar types, "A range specifies a subset of values of a scalar type. A range is said to be a null range if the specified subset is empty. The range L to R is called an ascending range; if L > R, then the range is a null range. The range L downto R is called a descending range; if L < R, then the range is a null range.").
10.10 Loop statement "For the execution of a loop with a for iteration scheme, the discrete range is first evaluated. If the discrete range is a null range, the iteration scheme is said to be complete, ..."
我在两个信号中存储了两个 table。一个table保存key(地址),一个保存key对应的value。我需要将输入与密钥进行比较,如果它们匹配,return 存储的值。
我需要它的原因是用于分支指令预测的动态查找table。在处理器的获取阶段,我得到输入 Instruction_Address 和 return 一个 branch_To_Address 和一个 branch_Prediction。最初我想存储16个predictions/branch个地址,用一个环形缓冲环根据需要覆盖。
我一直在尝试使用带有嵌套 IF 的 FOR 来搜索 keyTable 中的键。
整个模块似乎工作正常,除非我将两个 bit_vectors 与 IF 语句进行比较。我需要两次(一次读取,一次写入),因此我需要 "sweep" keysTable 以便我可以查看正在查找的地址是否有条目。
我在模拟时注意到错误,无论 keysTable 是否具有正确的条目,ELSE 子句总是被调用。
可验证的例子:
library IEEE;
use ieee.numeric_bit.all;
entity branch_prediction_table is
generic (
addrSize : NATURAL := 4;
tableSize : NATURAL := 4);
port (
clock : in bit;
input_addr: in bit_vector(addrSize-1 downto 0);
return_value : out bit );
end branch_prediction_table;
architecture branch_table of branch_prediction_table is
signal keysTable : bit_vector(addrSize*tableSize-1 downto 0) := ( others => '0');
signal valuesTable : bit_vector(tableSize*2-1 downto 0) := ( others => '0');
begin
tableProc: process(clock) is
variable valueFromTable : bit;
begin
if rising_edge(clock) then
search_table: for iR in (tableSize-1) to 0 loop
if (keysTable(addrSize*(iR+1)-1 downto addrSize*iR) = input_addr) then
valueFromTable := valuesTable((iR+1)*2-1);
EXIT search_table;
else
valueFromTable := '0';
end if;
end loop search_table;
return_value <= valueFromTable;
end if; -- rising_edge(clock)
end process tableProc;
end branch_table;
具有可验证的测试平台模拟 TCL:
add wave -position insertpoint \
sim:/branch_prediction_table/addrSize \
sim:/branch_prediction_table/clock \
sim:/branch_prediction_table/input_addr \
sim:/branch_prediction_table/keysTable \
sim:/branch_prediction_table/return_value \
sim:/branch_prediction_table/tableSize \
sim:/branch_prediction_table/valuesTable
force -freeze sim:/branch_prediction_table/valuesTable 11111111 0
force -freeze sim:/branch_prediction_table/keysTable 1111101001100011 0
force -freeze sim:/branch_prediction_table/clock 0 0, 1 {5000 ps} -r {10 ns}
run 10 ns
force -freeze sim:/branch_prediction_table/input_addr 1010 0
run 20 ns
force -freeze sim:/branch_prediction_table/input_addr 1111 0
run 10 ns
并且testbench仿真结果显示错误确实在IF中:
我试过用 to_integer(unsigned(bit_vector1)) = to_integer(unsigned(bit_vector2)) 转换它们,但没有用
正如 user1155120 指出的那样:
问题出在search_table: for iR **in** (tableSize-1) to 0 loop
它应该是 "下降到" 作为 L > R。因为我使用 "in" 和 L>R,产生一个空范围并且 for 循环迭代被认为是完整的。
(IEEE Std 1076-2008 5.2 Scalar types, "A range specifies a subset of values of a scalar type. A range is said to be a null range if the specified subset is empty. The range L to R is called an ascending range; if L > R, then the range is a null range. The range L downto R is called a descending range; if L < R, then the range is a null range.").
10.10 Loop statement "For the execution of a loop with a for iteration scheme, the discrete range is first evaluated. If the discrete range is a null range, the iteration scheme is said to be complete, ..."