VHDL 给定位数,是否有更简洁的方法来设置特定位?

VHDL Is there a cleaner way to set specific bit, given the bit number?

给定一个位数,我试图在 std_logic_vector 中设置该位。这是为了一次切换各种时钟输出。

首先,我已经完全放弃了 sll,或者 SHIFT_LEFT 这似乎是最明显的方法,但根本行不通。

variable v_cmd_clk_1: std_logic_vector(11 downto 0);

...

--- set bit number "s_proc_chan", plus 4, in v_cmd_clk_1
v_cmd_clk_1 := "0000" & "0000" & "0000";
v_cmd_clk_1( to_integer ( unsigned(s_proc_chan(2 downto 0))) + 4  ) := '1';

...
-- And then later on in the process assign it to an actual signal
cmd_clk <= v_cmd_clk_0;

是否有更好或更清晰的语法来执行此操作?

谢谢。

三点建议给你。第一个使用聚合:

v_cmd_clk_1 <= (to_integer(unsigned(s_proc_chan(2 downto 0)))+4) => '1', others => '0');

第二个使用整数到无符号转换:

v_cmd_clk_1 <= std_logic_vector(to_unsigned(2**(to_integer(unsigned(s_proc_chan(2 downto 0)))+4)); -- No guarantee on parentheses matching

第三个,使用shift_left

v_cmd_clk_1 <= std_logic_vector(shift_left(resize(unsigned'("1"), v_cmd_clk_1'length), to_integer(unsigned(s_proc_chan(2 downto 0)))+4));

设置一个index给定的bit的原理,你已经做了,很好,说明了代码的意图,就是设置一个index给定的bit。

可以通过使用其他 std_logic_vector 范围来消除 + 4 偏移量,但是像样的综合工具会消除偏移量,因此不会实现加法运算。

无论如何,作为对评论的回答,如果将 std_logic_vector 直接寻址到 0 到 7,而不是寻址 4 到 11,则可以消除 + 4,最后 4 '0's 可以后置,例如:

variable v_cmd_clk_1    : std_logic_vector(11 downto 0);
variable v_cmd_clk_upper: std_logic_vector( 7 downto 0);
...
v_cmd_clk_upper := (others => '0');
v_cmd_clk_upper(to_integer(unsigned(s_proc_chan(2 downto 0)))) := '1';
v_cmd_clk_1 := v_cmd_clk_upper & "0000";

Jonathan Drolet 建议的聚合看起来不错,但例如 Altera Quartus II 不允许将其用于综合,因为它需要聚合中的恒定选择值。使用 shift2** 将合成。

请注意,初始清算更普遍:

v_cmd_clk_1 := (others => '0');