2

I want shift std_logic_vector.

But this code is has an error:

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;

I think "0001", "0010", "0100" ...

4
  • this code led_buf <= led_buf(0) & led_buf(3 downto 1); change led_buf <= led_buf srl 1; (error) Commented Aug 22, 2017 at 6:38
  • Do you want to shift or rotate? Your question asks for shift, but your code shows rotate. Do you want an operation to the right or left, because your code is to the right, whereas your texts shows an example to the left! Commented Aug 22, 2017 at 7:00
  • @YannVernier No, a barrel shifter is an implementation form of a shifter that is very fast but also resource consuming. You can extend a barrel shift to also do rotations, but the barrel shifter describes the structure how to build a good shifter, not that it rotates. See this answer n bit barrel shifter for the barrel shifter structure. Commented Aug 22, 2017 at 8:09
  • Ah. Pardon the confusion and thank you! Commented Aug 22, 2017 at 8:10

1 Answer 1

4

Your shifter is OK. Actually, it's a rotator.

But your counter is to big (65 bits) and it doesn't roll over or reset to zero in a proper time. Your current design waits for 25M cycles and then shifts in every cycle from 25M to 2**64.

More over, you are using a non standard IEEE package to perform arithmetic operations (addition) on std_logic_vector. Please use type unsigned from package numeric_std.

The needed number of bits for your counter can be obtained by a log2 function like this:

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;

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

Full code rewrite:

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;

```

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.