0

I wrote the code below in order the do shift the binary number, I tried to compile it for the device cyclonII - EP2C20F484C7, but got this error:

Error (10779): VHDL error at shiftNbits.vhd(30): expression is not constant

Error (10658): VHDL Operator error at shiftNbits.vhd(30): failed to evaluate call to operator ""&""

vhd(30) is the line:

resultTemp  <= A( N-1-numberOfShifts downto 0) & (numberOfShifts-1 downto 0 => '0');

I saw the some people asked about it, and they got the answer that the compiler don't like the idea of N-1-numberOfShifts or numberOfShifts-1 being negative. The thing is that I ensure that numberOfShifts

if  numberOfShifts>=N then
    resultTemp  <= (N-1 downto 0 => '0');

And I even tried to add range to numberOfShifts definitions:

variable numberOfShifts: integer range 1 to N-1;

In order to ensure that numberOfShifts-1 is not negative.

By the way when I doning A(0 downto 0) I get actually one bit vector, How I define NULL vector if A( -1 downto 0) is not legal?

library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
entity shiftNbits is
  generic(N: integer := 8);
  port (
    typeOfShift :    in std_logic_vector (1 downto 0);
    enable : in std_logic;
    A :      in std_logic_vector(N-1 downto 0);
    B :      in std_logic_vector (N-1 downto 0);
    result : out std_logic_vector(N-1 downto 0)
    );
end shiftNbits;

architecture shiftNbitsGate of shiftNbits is
    signal resultTemp: std_logic_vector(N-1 downto 0);
    begin
        process (typeOfShift, enable, A, B)
        variable numberOfShifts: integer;
        begin
        numberOfShifts:=  to_integer(unsigned(B)); 
        if enable= '1' then
            case typeOfShift is
                when "00" => --RLA
                    if  numberOfShifts>=N then
                        resultTemp  <= (N-1 downto 0 => '0');
                    else
                        resultTemp  <= A( N-1-numberOfShifts downto 0) & (numberOfShifts-1 downto 0 => '0');
                    end if;
                when "01" => --RLC
                    numberOfShifts := numberOfShifts mod N;
                    resultTemp <=  A( N-1-numberOfShifts downto 0) & A( N-1 downto N-numberOfShifts);
                when "10" => --RRA
                    if  numberOfShifts>=N then
                        resultTemp  <= (N-1 downto 0 => A(N-1));
                    else    
                        resultTemp <=  (N-1 downto N-numberOfShifts => A(N-1)) & A( N-1 downto numberOfShifts);
                    end if;                             
                when "11" => --RRC
                    numberOfShifts := numberOfShifts mod N;
                    resultTemp  <=  A( numberOfShifts-1 downto 0) & A( N-1 downto numberOfShifts);
                when others => null;
            end case;
        else
        resultTemp <= A; --what we should insert here?
        end if;
        end process;
        result <= resultTemp;
    end shiftNbitsGate;
Mr.O
  • 342
  • 2
  • 19
  • @user1155120 I fixed the syntax error (the mistake was only here). I don't understand what the code is missing? if the mean the package that I'm using, then I add it. slices using a variable in the range is not allowed? what can I do instead? about the last thing you said: I didn't understand what prefix is missing? the '(ResultTemp <= A( N-1-numberOfShifts downto 0) & (numberOfShifts-1 downto 0 => '0');)' is creating a vector at size N-1. – Mr.O Apr 14 '19 at 22:31
  • Yes. I misread your code due to formatting. A range in an aggregate must be static. See IEEE Std 1076-2008 9.3.3.3 Array aggregates "A named association of an array aggregate is allowed to have a choice that is not locally static, ... , only if the aggregate includes a single element association and this element association has a single choice." That's the case here, it's legal VHDL. It's not acceptable for synthesis here. –  Apr 14 '19 at 22:59
  • For your unrelated question see IEEE Std 1076-2008 5.3.2.2 Index constraints and discrete ranges "If any of the discrete ranges defines a null range, any array thus constrained is a *null array*, having no elements." and 5.2 Scalar types 5.2.1 "A range specifies a subset of values of a scalar type. A range is said to be a *null* range if the specified subset is empty. The range L **to** R is called an *ascending* range; if L > R, then the range is a null range. The range L **downto** R is called a *descending range*; if L < R, then the range is a null range." –  Apr 14 '19 at 23:06

1 Answers1

1

resultTemp <= A( N-1-numberOfShifts downto 0) & (numberOfShifts-1 downto 0 => '0'); can't be implemented in one "line" (one set of gates / one logic equation) in hardware, as it may correspond to many different cases (one per number of shifts).
In VHDL, you're required to expand all these possibilities with if then else or a case select.
If the shift value had been constant, the code could indeed be synthesized, hence the error message!

B. Go
  • 1,436
  • 4
  • 15
  • 22
  • Can you suggest me what to do in this case? what are the alternatives? I new in this, and I tried in simulation and it was working, so I didn't thought it could not be synthesized. thank you. – Mr.O Apr 14 '19 at 22:45
  • Which version of Quartus are you using? (Quartus II or Quartus Prime) and what release? –  Apr 14 '19 at 22:51
  • 1
    You can use a for loop and compare it's loop parameter against numberOfShifts. Within the sequence of statements enclosed in the for loop the parameter is a constant. You'd use the parameter instead of numberOfShifts in expressions for slice name discrete ranges. [You generate hardware for each shift distance](https://i.stack.imgur.com/cVIv5.jpg) and numberOfShifts is used to select the result (with `if numberOfShifts = i then` enclosing the assignment statement). –  Apr 15 '19 at 01:24
  • You can search for "barrel shifter", including the page https://stackoverflow.com/questions/23891811/structure-of-vhdl-code-for-barrel-shifter-with-behavior-architecture – B. Go Apr 15 '19 at 11:26