1

How would anyone peform a rightshift or left shift in VHDL on a STD_LOGIC_VECTor...

It will not work , why??`

AN <= "0001";        
CounterProcess: process(CLK,Switch)
    begin
    if rising_edge(CLK) then
        if prescaler < limit then 
            prescaler <= prescaler + 1;
            else
                prescaler <= (others => '0'); 
                counter <= counter + 1;
                AN sll 1;
        end if;
    end if; 
    end process;
    An <= anode;

    Segment <= counter; 

    end Behavioral;

I get the Error message: sll can not have such operands in this context. But in which context can it then be used in, and how can perform my left shift?

these are my includes:

    library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

isn't the one needed to perform my leftshift operations included??


Complete code

entity Main is
PORT(
        CLK: in std_logic;
        LED: out std_logic_vector (7 downto 0);
        Switch: in std_logic_vector(7 downto 0);
        Segment: out std_logic_vector (7 downto 0); 
        AN: out std_logic_vector (3 downto 0) 
        );

end Main;


architecture Behavioral of Main is
signal counter: std_logic_vector (7 downto 0);
signal prescaler:  std_logic_vector(25 downto 0);
signal limit: std_logic_vector (25 downto 0);
signal anode: std_logic_vector (3 downto 0);
begin
AN <= "0001";

ScalerChoice: Process(switch)
begin
CASE Switch IS
when "00000001" => limit <= "10111110101111000010000000"; -- 1 Hz;
when "00000010" => limit <= "00111111100101000000101011"; -- 3 HZ
When "00000100" => limit <= "00010011000100101101000000"; -- 10 Hz
when "00001000" => limit <= "00000111101000010010000000"; -- 25 Hz
When "00010000" => limit <= "00000011110100001001000000"; -- 50 Hz; 
when "00100000" => limit <= "00000001111010000100100000"; -- 100 hz
when others => limit <=      "00000000000000000000000001"; -- 50 MHz
end case;
end process;


CounterProcess: process(CLK,Switch)
begin
if rising_edge(CLK) then
    if prescaler < limit then 
        prescaler <= prescaler + 1;
        else
            prescaler <= (others => '0'); 
            counter <= counter + 1;
            AN sll AN 1;
    end if;
end if; 
end process;

Segment <= counter; 

end Behavioral;

2 Answers2

1

In addition to what trumpetlicks said, use these packages instead. Make sure to enable the VHDL-2008 switch. Also try this with your FPGA vendor first as these require VHDL-2008 updates:

library IEEE;
   use IEEE.STD_LOGIC_1164.ALL;
   use ieee.numeric_std.all;
   use ieee.numeric_std_unsigned.all;

The above packages are all IEEE standards. The packages STD_LOGIC_ARITH and std_logic_unsigned are not IEEE standards. Note also that numeric_std and STD_LOGIC_ARITH conflict with each other and make it difficult (way beyond basic usage) to use the types signed and unsigned. Note that std_logic_unsigned conflicts with numeric_std_unsigned. So if your synthesis tool supports numeric_std_unsigned, I recommend using it instead. Furthermore, if it does not you should submit a bug report against it.

Martin Thompson
  • 16,395
  • 1
  • 38
  • 56
Jim Lewis
  • 3,601
  • 10
  • 20
0

EDIT 1:

Your Code Edited with reset logic, notice the addition of the RESET signal to the ports list, the deletion of the asynchronous line setting that value, addition of RESET to the sensitivity list of your CounterProcess process, the addition of the if(RESET = '1') line, and change of your if to an elsif, as well as the change of your shifting line:

I actually don't know what your An <= Anode line is doing, and believe this to be in error also.

entity Main is PORT(
    RESET:   in  std_logic;
    CLK:     in  std_logic;
    LED:     out std_logic_vector(7 downto 0);
    Switch:  in  std_logic_vector(7 downto 0);
    Segment: out std_logic_vector(7 downto 0); 
    AN:      out std_logic_vector(3 downto 0)
);
end Main;

architecture Behavioral of Main is
signal counter:   std_logic_vector(7  downto 0);
signal prescaler: std_logic_vector(25 downto 0);
signal limit:     std_logic_vector(25 downto 0);
signal anode:     std_logic_vector(3  downto 0);

begin

ScalerChoice: Process(switch)
begin
CASE Switch IS
when "00000001" => limit <= "10111110101111000010000000"; -- 1 Hz;
when "00000010" => limit <= "00111111100101000000101011"; -- 3 HZ
When "00000100" => limit <= "00010011000100101101000000"; -- 10 Hz
when "00001000" => limit <= "00000111101000010010000000"; -- 25 Hz
When "00010000" => limit <= "00000011110100001001000000"; -- 50 Hz; 
when "00100000" => limit <= "00000001111010000100100000"; -- 100 hz
when others => limit <=     "00000000000000000000000001"; -- 50 MHz
end case;
end process;


CounterProcess: process(RESET, CLK, Switch)
begin
    if(RESET = '1') then
        AN <= "0001";
    elsif rising_edge(CLK) then
        if prescaler < limit then 
            prescaler <= prescaler + 1;
        else
            prescaler <= (others => '0'); 
            counter <= counter + 1;
            AN <= std_logic_vector(unsigned(AN) sll 1);
        end if;
    end if;
end process;

An <= anode;
Segment <= counter; 

end Behavioral;

you need to write the line that you currently have:

AN sll 1;

as

AN <= AN sll 1;

Remember that AN is essentially like a variable that needs to be "set". Like your line above

counter <= counter + 1;
trumpetlicks
  • 7,033
  • 2
  • 19
  • 33
  • please look at my revision - New error message: parse error, unexpected SLL, expecting OPENPAR or TICK or LSQBRACK –  Mar 06 '14 at 12:22
  • @BobBurt - Well, the other problem is that you essentially have 2 circuits driving the same register "AN". At the top of your code, you have `AN <= "0001";` which will indeed set that value, the problem is that is an asynchronous circuit that is CONSTANTLY trying to force that value into AN. While that is going to constantly happen, you have a SYNCHRONOUS circuit trying to drive a left shifted value into the same AN register. You might show more of your code as well, especially your newly edited version. – trumpetlicks Mar 06 '14 at 12:28
  • Yes.. You are absolute right about that. But the problem is that i am not able to set the value before begin, since AN is set to out in my entity.. –  Mar 06 '14 at 12:38
  • @BobBurt Traditionally this is done with reset logic, I will try to post an example above in my answer. – trumpetlicks Mar 06 '14 at 12:38
  • I don't see how the reset button would work?? What would trigger?.. I don't have access to the reset button on my FPGA and getting access to it would be weird.. I get this error message : parse error, unexpected SLL, expecting OPENPAR or TICK or LSQBRACK –  Mar 06 '14 at 13:02
  • @BobBurt - So I might pose this question to you. How do you know when you need to reset the value to your initial condition without knowing you have been reset? Most FPGAs have what's called a Power On Reset (POR) capability, usually based upon the internal clocking circuitry settling (i.e. a PLL (phase locked loop) locking). YOU NEED TO FIGURE OUT HOW TO ACCESS THIS, else functionally you CANNOT accomplish what you are wanting to accomplish. – trumpetlicks Mar 06 '14 at 13:08
  • with your code i get this error message ERROR:HDLParsers:808 - "C:/.Xilinx/Counter/Main.vhd" Line 78. sll can not have such operands in this context. –  Mar 06 '14 at 13:13
  • Look at the new edited line, sll works only on `unsigned` types. Therefore, it has to be converted to an unsigned, but first it has to be converted to an integer type (this is due to crazy VHDL standards through time, but the first function converts your std_logic_vector into an integer of bitwidth size 4, then the outer routine converts that integer type into a unsigned type. That should be able to be shifted. finally after shifting, it has to be converted BACK TO std_logic_vector. – trumpetlicks Mar 06 '14 at 13:37