如何转换std_logic_vector?

时间:2017-08-22 06:35:31

标签: vhdl fpga

我想换班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”......

1 个答案:

答案 0 :(得分:4)

你的移位者还可以。实际上,它是一个旋转器。

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

此外,您正在使用非标准IEEE包在std_logic_vector上执行算术运算(添加)。请使用包unsigned中的numeric_std类型。

您的计数器所需的位数可以通过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;

```