UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor flauber
Visitor
8,109 Views
Registered: ‎07-17-2014

cannot convert type universal_integer to type unsigned

Hi,

 

I have a little, strange problem.

I am implementing a small state machine which is supposed to execute a program writen into a buffer via serial.

For this, I would like to use unsigned to make convertion between Integers and std_logic_vectors easy.

I am using

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

 only, yet it doe snot seem to work as expected.

I have a unsigned process counter PC to which I would like to add a 1.

So I write

PC:= PC + 1;

 I had read multiple articles which claim that this should work for unsigned values but I get an error:

cannot convert type  universal_integer to type unsigned

 I have not he slightest clue what an universal_integer is supposed to be or how to cast it to an unsigend.

I tried

to_unsigned(1);
unsigned(1)

 But they both do not work.

Can someone explain to me what I am doing wrong? Isn't ieee.numerical_std.all supposed to enable this behaviour?

 

Here is the module (I am still a beginner so if you see somethign else, please tell me)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library work;
use work.xadc_package.all;

entity command_state_maschine is
    generic(
        COMMAND_SPACE: Positive
    );
    port(
        clk_in: in STD_LOGIC;
        rst_in: in STD_LOGIC;
        start_in: in STD_LOGIC;
        trigger_in: in STD_LOGIC;
        data_in: in command_space_type(0 to COMMAND_SPACE);
        finished_out: out STD_LOGIC;
        PULSES_out: out STD_LOGIC_VECTOR(0 to 7);
        SPI_CHANNELS_out: out SPI_VECTOR
    );
end command_state_maschine;

architecture Behavioral of command_state_maschine is
    signal spi_start: STD_LOGIC_VECTOR(0 to 7);
    signal spi_data: STD_LOGIC_VECTOR(0 to 7);
    signal spi_finished: STD_LOGIC_VECTOR(0 to 7);
begin
    process
        variable PC: unsigned(15 downto 0);
        variable PROGRAM: command_space_type(0 to COMMAND_SPACE);
        variable REGS_16: r16;
        variable REGS_8: r8;
        variable i: natural;
        variable j: natural;
    begin
        if rising_edge(clk_in) then
            spi_start <= ('0','0','0','0','0','0','0','0');
            PULSES_out <= ('0','0','0','0','0','0','0','0');
            if rst_in = '1' then
                PC:= to_unsigned(2**PC'length -1, PC'length);
            elsif PC = to_unsigned(2**PC'length -1, PC'length) then
                if start_in = '1' then
                    PROGRAM:= data_in;
                    PC:= to_unsigned(0, PC'length);
                end if;
            else
                CASE PROGRAM(PC) IS
                    WHEN OP_STOP =>
                        PC:= to_unsigned(2**PC'length -1, PC'length);
                    WHEN OP_NOP =>
                        PC:= PC + 1;
                    WHEN OP_WAIT_SPI =>
                        if (REGS_8(PROGRAM(PC + 1)) xnor spi_finished) or REGS_8(PROGRAM(PC+2)) = (REGS_8'range => '1') then
                            PC:= PC + 2;
                        end if;
                    WHEN OP_WAIT_TRIGGER =>
                        if trigger_in = '1' then
                            PC:= PC + 1;
                        end if;
                    WHEN OP_SEND_SPI =>
                        i:= 0;
                        j:= 0;
                        for k in 0 to 7 loop
                            if REGS_8(PROGRAM(PC+1)) & REGS_8(PROGRAM(PC+2)) = '1' then 
                                spi_data(j) <= REGS_16(PROGRAM(PC+3 + i)); 
                                i := i + 1;
                            end if;
                            j:= j +1;
                        end loop;
                        spi_start <= REGS_8(PROGRAM(PC+1)) & REGS_8(PROGRAM(PC+2));
                        PC:= PC + 3 + i;
                    WHEN OP_SEND_PULSE =>
                        PULSES_out <= REGS_8(PROGRAM(PC+1)) & REGS_8(PROGRAM(PC+2));
                        PC:= PC + 3;
                    WHEN OP_MOVE_CONST_8 =>
                        REGS_8(PROGRAM(PC+1)):= PROGRAM(PC+2) & PROGRAM(PC+3);
                        PC:= PC + 4;
                    WHEN OP_MOVE_CONST_16 =>
                        REGS_16(PROGRAM(PC+1)):= PROGRAM(PC+2) & PROGRAM(PC+3) & PROGRAM(PC+4) & PROGRAM(PC+5);
                        PC:= PC + 6;
                    WHEN OP_MOVE_8 =>
                        REGS_8(PROGRAM(PC+1)):= REGS_8(PROGRAM(PC+2));
                        PC:= PC + 3;
                    WHEN OP_MOVE_16 =>
                        REGS_16(PROGRAM(PC+1)):= REGS_16(PROGRAM(PC+2));
                        PC:= PC + 3;
                    WHEN OP_ADD_8 =>
                        REGS_8(PROGRAM(PC+1)):= REGS_8(PROGRAM(PC+1)) + REGS_8(PROGRAM(PC+2));
                        PC:= PC + 3;
                    WHEN OP_ADD_16 =>
                        REGS_16(PROGRAM(PC+1)):= REGS_16(PROGRAM(PC+1)) + REGS_16(PROGRAM(PC+2));
                        PC:= PC + 3;
                    WHEN OP_IF_8 =>
                        if REGS_8(PROGRAM(PC+1)) = REGS_8(PROGRAM(PC+2)) then
                            PC:= PROGRAM(PC+3) & PROGRAM(PC+4) & PROGRAM(PC+5) & PROGRAM(PC+6); 
                        else
                            PC:= PC + 7;
                        end if;
                    WHEN OP_IF_16 =>
                        if REGS_16(PROGRAM(PC+1)) = REGS_16(PROGRAM(PC+2)) then
                            PC:= PROGRAM(PC+3) & PROGRAM(PC+4) & PROGRAM(PC+5) & PROGRAM(PC+6); 
                        else
                            PC:= PC + 7;
                        end if;
                    WHEN OP_LSHIFT_8 =>
                        REGS_8(PROGRAM(PC+1)):= REGS_8(PROGRAM(PC+1)) rol 1;
                    WHEN OP_LSHIFT_16 =>
                        REGS_16(PROGRAM(PC+1)):= REGS_16(PROGRAM(PC+1)) rol 1;
                END CASE;
            end if;
        end if;
    end process;
    
    GEN_SPIS: for i in 0 to 7 generate
        SPIs: COMPONENT gated_spi
        GENERIC MAP(WIDTH=> 16)
        PORT MAP( 
            clk_in => clk_in,
            rst_in => rst_in,
            start_in => spi_start(i),
            data_in => spi_data(i),
            finished_out => spi_finished(i),
            GATED_SPI_INTERFACE_OUT => SPI_CHANNELS_out(i)
        );
    end generate GEN_CHANNELS;
end architecture;

 Thanks alot!

 

flambda

0 Kudos
6 Replies
Explorer
Explorer
8,088 Views
Registered: ‎08-19-2014

Re: cannot convert type universal_integer to type unsigned

I'm pulling this off the top of my head, so I can't guarantee this is correct but I think the problem is that your statement 

PC := PC + 1;

 doesn't work because PC is an unsigned type, but the '1' isn't a unsigned type.  There's nothing telling the number how many bits to represent it with or if it's a signed or unsigned number.  Try the following wherever you add PC and a constant number:

PC := PC + to_unsigned(1, PC'length);

 

-Jordan

This signature intentionally left blank.
0 Kudos
Visitor flauber
Visitor
8,080 Views
Registered: ‎07-17-2014

Re: cannot convert type universal_integer to type unsigned

Hi,

 

I tried to cast it already but it says that it cannot convert a universal_integer to an unsigned.

My guess is this is about a difference between an universal_integer and an integer but I cannot find any information

how they differ from each other.

 

Also, if you read this: http://www.mikrocontroller.net/articles/Rechnen_in_VHDL  (unfortunately in German),

adding an integer to an unsigend should work due to autocasts but assining a new value needs an manual conversion.

 

Also, if you look here: http://www.csee.umbc.edu/portal/help/VHDL/numeric_std.vhdl you can see function A.5

  -- Id: A.5
  function "+" (L: UNSIGNED; R: NATURAL) return UNSIGNED;
  -- Result subtype: UNSIGNED(L'LENGTH-1 downto 0).
  -- Result: Adds an UNSIGNED vector, L, with a non-negative INTEGER, R.

 Should a contant 1 not be seen as a non-negative integer? Why is it a "universal_integer" instead of an integer?

 

With best regards,

 

flauber

0 Kudos
Historian
Historian
8,054 Views
Registered: ‎02-25-2008

Re: cannot convert type universal_integer to type unsigned

PC := PC + 1;

 

where PC is declared as unsigned and when using numeric_std, absolutely does work.

 

Your code has various other PC incrementers, such as PC := PC + 6; scattered about. Do ALL of them throw that warning, or just one in particular?

----------------------------Yes, I do this for a living.
0 Kudos
Highlighted
Historian
Historian
8,053 Views
Registered: ‎02-25-2008

Re: cannot convert type universal_integer to type unsigned

Also, why is PC declared and used as a variable? It should be a signal.

----------------------------Yes, I do this for a living.
0 Kudos
Visitor flauber
Visitor
8,047 Views
Registered: ‎07-17-2014

Re: cannot convert type universal_integer to type unsigned

Hi,

 

all of them throw the same error  message.

Why, btw, should PC be a signal? it is local to the process and only set by the process ergo should I not use a local variable instead of a global signal?

 

I also think i found my error.

 

i am using PC+1 as an index of an array. Therefore, the compiler is looking for a fucntion which has a signature like this:

unsigned, integer -> integer 

 which does not exist, the functions are always defined to return a signed or unsigned, not an integer.

After I altered it to

to_integer(PC + 1)

 it worked as expected. Still, I find it very strage that I could not cast a 1 to an unsigned..

 

Also, is there a way to make this a bit nicer? Putting in 50 to_intger does not help the readability of my code, i am afraid.

Are unsigned not autocast to integers? I would have assumed this would happen (hm, but maybe this is not possible as the compiler could then cast PC to an integer and add 1, returning an integer instead of an unsigned.)

0 Kudos
Historian
Historian
8,032 Views
Registered: ‎02-25-2008

Re: cannot convert type universal_integer to type unsigned


@flauber wrote:

all of them throw the same error  message.

Why, btw, should PC be a signal? it is local to the process and only set by the process ergo should I not use a local variable instead of a global signal?


Well, one thing is the assignment semantics; you are obviously taking care to increment/update PC after each use, because if you updated it before you used it as your index or whatever you'd get the wrong value. This is VERY important and the use of a signal will ensure that you don't screw it up.

 

Signals aren't global; they only have entity scope.

 

Don't think that you need to have this concept of "global" vs "local."


I also think i found my error.

 

i am using PC+1 as an index of an array. Therefore, the compiler is looking for a fucntion which has a signature like this:

unsigned, integer -> integer 

 which does not exist, the functions are always defined to return a signed or unsigned, not an integer.

After I altered it to

to_integer(PC + 1)

 it worked as expected. Still, I find it very strage that I could not cast a 1 to an unsigned..

 

Also, is there a way to make this a bit nicer? Putting in 50 to_intger does not help the readability of my code, i am afraid.


The way to put it "nicer" would be to declare PC as a ranged integer. Instead of:

    signal PC : unsigned(15 downto 0);

just use:

    signal PC: natural range 0 to 65535;

 

After all, it's a counter, right? Just use an integer to count. Problem solved.

(For some reason, too many designers have this allergy to using integers.)


Are unsigned not autocast to integers? I would have assumed this would happen (hm, but maybe this is not possible as the compiler could then cast PC to an integer and add 1, returning an integer instead of an unsigned.)


No, because unsigned is more akin to std_logic_vector than to integer. unsigned is a vector; integer is not, so you need a conversion function, not a typecast, to and from the vector.

----------------------------Yes, I do this for a living.