如何平移std_logic_vector?

How to shift std_logic_vector?

我要轮班std_logic_vector

但是这段代码有错误:

architecture led_main of testing is
    signal clk_cnt : std_logic_vector(64 DOWNTO 0) := (others => '0');
    signal led_buf : std_logic_vector( 3 downto 0 ) := "0001";
begin
    process(clk)
    begin
        if rising_edge(clk) then
            clk_cnt <= clk_cnt + 1;
            if clk_cnt >= 24999999 then
                led_buf <= led_buf(0) & led_buf(3 downto 1);
            end if;
        end if;
    end process;

    ground <= '0';
end led_main;

我认为“0001”、“0010”、“0100”...

你的变速杆没问题。其实就是旋转器[​​=17=]

但是您的计数器太大(65 位)并且它不会在适当的时间翻转或重置为零。您当前的设计等待 25M 个周期,然后在每个周期中从 25M 转移到 2**64。

此外,您正在使用非标准 IEEE 包对 std_logic_vector 执行算术运算(加法)。请使用包 numeric_std.

中的类型 unsigned

您的计数器所需的位数可以通过 log2 函数获得,如下所示:

function log2ceil(arg : positive) return natural is
    variable tmp : positive;
    variable log : natural;
begin
    if arg = 1 then return 0; end if;
    tmp := 1;
    log := 0;
    while arg > tmp loop
        tmp := tmp * 2;
        log := log + 1;
    end loop;
    return log;
end function;

来源:https://github.com/VLSI-EDA/PoC/blob/master/src/common/utils.vhdl

完整代码重写:

use IEEE.numeric_std.all;

architecture led_main of testing is
    constant CNT_MAX : positive := 25000000;
    signal clk_cnt : unsigned(log2ceil(CNT_MAX) - 1 downto 0) := (others => '0');
    signal led_buf : std_logic_vector( 3 downto 0 )           := "0001";
begin
    process(clk)
    begin
        if rising_edge(clk) then
            clk_cnt <= clk_cnt + 1;
            if clk_cnt = (CNT_MAX - 1) then
                clk_cnt <= (others => '0');
                led_buf <= led_buf(0) & led_buf(3 downto 1);
            end if;
        end if;
    end process;
end led_main;

```