我正在编写用于同时将信号与多个信号进行比较的代码。
以下是示例:
process (CLK, reset)
if reset = '0' then
data <= (others => '0');
elsif rising_edge (CLK) then
if A = B then
data <= data OR "0001";
else data <= data AND "1110";
end if;
if A = C then
data <= data OR "0010";
else data <= data AND "1101";
end if;
if A = D then
data <= data OR "0100";
else data <= data AND "1011";
end if;
if A = E then
data <= data OR "1000";
else data <= data AND "0111";
end if;
end if;
end process;
我只想比较A到B,C,D和E信号,然后打开和关闭数据中的相关位。我上面写的代码不起作用,因为综合工具将优化B,C和D if语句并且只留下E if语句。我也考虑过使用case - when语句,但它没有关闭相关单个位的机制。其他人只能关闭所有4位。这样做的有效方法是什么?谢谢!
顺便说一下,所有这4个if语句同时运行吗?或者他们在不同的周期运行?我猜他们会一个接一个地运行,否则会导致扇入。答案 0 :(得分:2)
您正在尝试使用您不需要的语言编写C语言! 在C中你不能访问单个位,只能访问字节和更大的单位,因此C程序员必须求助于AND / OR,即&amp;,|设置或清除位。
在VHDL中,您可以寻址单词的各个位,并写入
if A = B then
data(0) <= '1';
else
data(0) <= '0';
end if;
更简单。是的,它们都是在每个时钟周期的同一时间运行。
我更愿意将数据声明为布尔数组,
signal data : array(3 downto 0) of boolean;
然后我可以写
process (CLK, reset)
begin
if reset = '0' then
data <= (others => false);
elsif rising_edge (CLK) then
data <= (A = E) & (A = D) & (A = C) & (A = B);
end if;
end process;
如果我必须为data
使用std_logic_vector,那么这种形式的便利性(几乎)足以让我为A的类型重载“=”运算符,其中一个返回std_logic。
然后,为了编写一个小函数的代价,我可以保留这段代码。
编辑: 为了解决原始方法不起作用的原因,有必要理解信号分配的语义,如for example here所述。
因此,第一次分配给数据(对于A = B)存储起来,直到进程暂停。然后第二个分配在它发生之前替换它,所以第一个这样的分配永远不会发生。
原始工作方法需要的是变量,因为变量分配会立即发生。
process (CLK, reset)
variable data_int : whatever; -- same type as data
begin
if reset = '0' then
data <= (others => '0');
elsif rising_edge (CLK) then
data_int := data;
if A = B then
data_int := data_int OR "0001";
else data_int := data_int AND "1110";
end if;
...
if A = E then
data_int := data_int OR "1000";
else data_int := data_int AND "0111";
end if;
data <= data_int;
end if;
end process;
现在,data
的单一作业将包含所有单独的修改。然而,它可能会合成比最佳解决方案更大的东西。