Assign a value to a position in a std_logic_vector

Discussion in 'VHDL' started by ionutcazacu2007@gmail.com, Feb 25, 2013.

  1. Guest

    Hi , I'm new to VHDL and I can't figure out how to do this :

    I have a vector OP3 : std_logic_vector(31 downto 0) and another one S : std_logic_vector(4 downto 0) ...
    My question is , is it possible , and if yes , how can I do OP3(S) <= '1' ?

    (For example , if S = 00111 then OP3(7) <= '1').
     
    , Feb 25, 2013
    #1
    1. Advertising

  2. On 25 Feb., 09:03, wrote:
    > Hi , I'm new to VHDL and I can't figure out how to do this :
    >
    > I have a vector OP3 : std_logic_vector(31 downto 0) and another one S : std_logic_vector(4 downto 0) ...
    > My question is , is it possible , and if yes , how can I do OP3(S) <= '1' ?
    >
    > (For example , if S = 00111 then OP3(7) <= '1').


    Convert S to natural (integer) type.

    signal S_Nat : natural;
    S_nat <= to_integer(unsigned(S));

    than you can use following code.
    OP3(S_nat) <= '1';

    ofc it is possible to have conversion "Inline" if you don't like to
    have an additional signal.

    best regards
    Thomas
     
    Thomas Stanka, Feb 25, 2013
    #2
    1. Advertising

  3. Tricky Guest

    On Monday, 25 February 2013 10:26:28 UTC, Thomas Stanka wrote:
    > On 25 Feb., 09:03, wrote:
    >
    > > Hi , I'm new to VHDL and I can't figure out how to do this :

    >
    > >

    >
    > > I have a vector OP3 : std_logic_vector(31 downto 0) and another one S : std_logic_vector(4 downto 0) ...

    >
    > > My question is , is it possible , and if yes , how can I do OP3(S) <= '1' ?

    >
    > >

    >
    > > (For example , if S = 00111 then OP3(7) <= '1').

    >
    >
    >
    > Convert S to natural (integer) type.
    >
    >
    >
    > signal S_Nat : natural;
    >
    > S_nat <= to_integer(unsigned(S));
    >
    >
    >
    > than you can use following code.
    >
    > OP3(S_nat) <= '1';
    >
    >
    >
    > ofc it is possible to have conversion "Inline" if you don't like to
    >
    > have an additional signal.
    >
    >
    >
    > best regards
    >
    > Thomas


    Or if OP3(n) is a register, you probably want to do the type conversion via a variable to avoid the extra register that would be implied using a signal inside the process.
     
    Tricky, Feb 25, 2013
    #3
  4. Guest

    Thank you for your fast replies , it is helpful , though I have another question.
    I have : OP3 <= x"0000_0000" and Sa < = "10101" . Then , if I do
    OP3(4 downto 0) <= Sa , the result is 00...X0X0X rather than 00..10101 (.. means many zeros :) ) ... What am I doing wrong here ?
     
    , Feb 26, 2013
    #4
  5. Guest

    Thank you for the replies , it was really helpful , but now I have another problem.
    I have OP3 <= RdData2 (if RdData2 = ABABABAB OP3 <= ABABABAB) , and then
    OP3(to_integer(unsigned(Sa))) <= '1' , and here the problem occurs , that one bit is set correctly to 1 , but all the others become U or X-es . How can i solve this?
     
    , Feb 26, 2013
    #5
  6. Andy Guest

    On Tuesday, February 26, 2013 5:56:27 AM UTC-6, wrote:
    > Thank you for the replies , it was really helpful , but now I have another problem. I have OP3 <= RdData2 (if RdData2 = ABABABAB OP3 <= ABABABAB) , and then OP3(to_integer(unsigned(Sa))) <= '1' , and here the problem occurs , that one bit is set correctly to 1 , but all the others become Uor X-es . How can i solve this?


    You should set the entire vector to zeroes before setting the single bit to'1'.

    opp3 <= (others => '0'); -- prior to assigning single bit

    Andy
     
    Andy, Feb 26, 2013
    #6
  7. GaborSzakacs Guest

    wrote:
    > Thank you for your fast replies , it is helpful , though I have another question.
    > I have : OP3 <= x"0000_0000" and Sa < = "10101" . Then , if I do
    > OP3(4 downto 0) <= Sa , the result is 00...X0X0X rather than 00..10101 (.. means many zeros :) ) ... What am I doing wrong here ?
    >

    If the assignmet of all zeroes is not within a process, then
    what you're seeing is the result of conflicting drivers.
    i.e. All bits that are driven to the same value by
    both assignments will show that value. All bits that
    are driven to different values by the two assignments
    will show as 'X'. In your case one value is all zero,
    so any ones in the other value will be in conflict and
    show up as 'X'.

    -- Gabor
     
    GaborSzakacs, Feb 26, 2013
    #7
  8. Guest

    I've tried to use processes , but still nothing (I'm pretty sure something is still wrong , as I said I'm new to VHDL). Here is my code :

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    ---- Uncomment the following library declaration if instantiating
    ---- any Xilinx primitives in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;

    entity ALU is
    Port (
    RdData1 : in STD_LOGIC_VECTOR (31 downto 0);
    RdData2 : in STD_LOGIC_VECTOR (31 downto 0);
    FAddr : in STD_LOGIC_VECTOR (15 downto 0);
    ALUSrc : in STD_LOGIC;
    ALUOP : in STD_LOGIC_VECTOR (2 downto 0);
    Sa : in STD_LOGIC_VECTOR (4 downto 0);
    Y : out STD_LOGIC_VECTOR (31 downto 0)
    );
    end ALU;

    architecture Behavioral of ALU is
    signal SEAddr : STD_LOGIC_VECTOR(31 downto 0);
    signal OP1 : STD_LOGIC_VECTOR(31 downto 0);
    signal OP2 : STD_LOGIC_VECTOR(31 downto 0);
    signal OP3 : STD_LOGIC_VECTOR(31 downto 0);
    signal S_nat : natural;
    begin
    OP2 <= RdData2 when AluSrc='0' else SEAddr;
    SEAddr(15 downto 0) <= FAddr;
    SEAddr(31 downto 16) <= x"0000" when FAddr(15)='0' else x"FFFF";

    OP1 <= RdData1;

    process (RdData2)
    begin
    OP3 <= RdData2;
    end process;

    with Sa select
    S_nat <= 0 when "00000",1 when "00001",2 when "00010",3 when "00011",4 when "00100",5 when "00101",
    6 when "00110",7 when "00111",8 when "01000",9 when "01001",10 when "01010",11 when "01011",
    12 when "01100",13 when "01101",14 when "01110",15 when "01111",16 when "10000",17 when "10001",
    18 when "10010",19 when "10011",20 when "10100",21 when "10101",22 when "10110",23 when "10111",
    24 when "11000",25 when "11001",26 when "11010",27 when "11011",28 when "11100",29 when "11101",
    30 when "11110",31 when others;

    process (S_nat)
    begin
    OP3(S_nat) <= '1';
    end process;

    with ALUOP select
    y <= OP1 + OP2 when "000", OP1 - OP2 when "001", OP1 AND OP2 when "010", OP1 OR OP2 when "011", OP3 when others;

    end Behavioral;

    What I want is that OP3 to be exactly as RdData2 (and if I just do OP3 <=RdData2 ,it is) but also that 1 bit which is determined by Sa to become 1.

    For example , RdData 2 is 5555 5555 , and if I do only Op3 <= RdData2 then OP3 becomes 5555 5555 , but if i also do OP3(S_nat) <= '1' , then the result is XXXX XXX (to be more precise is xxxx xxxx xxxx xxxx xxxx xx1x xxxxxxx1 , so that 1 specific bit (10 in this case) becomes 1 , but the othersare X-es).

    Any help would be highly appreciated , I'm working on this problem for several days and it still bugs me :(.
     
    , Feb 26, 2013
    #8
  9. GaborSzakacs Guest

    wrote:
    > I've tried to use processes , but still nothing (I'm pretty sure something is still wrong , as I said I'm new to VHDL). Here is my code :
    >
    > library IEEE;
    > use IEEE.STD_LOGIC_1164.ALL;
    > use IEEE.STD_LOGIC_ARITH.ALL;
    > use IEEE.STD_LOGIC_UNSIGNED.ALL;
    >
    > ---- Uncomment the following library declaration if instantiating
    > ---- any Xilinx primitives in this code.
    > --library UNISIM;
    > --use UNISIM.VComponents.all;
    >
    > entity ALU is
    > Port (
    > RdData1 : in STD_LOGIC_VECTOR (31 downto 0);
    > RdData2 : in STD_LOGIC_VECTOR (31 downto 0);
    > FAddr : in STD_LOGIC_VECTOR (15 downto 0);
    > ALUSrc : in STD_LOGIC;
    > ALUOP : in STD_LOGIC_VECTOR (2 downto 0);
    > Sa : in STD_LOGIC_VECTOR (4 downto 0);
    > Y : out STD_LOGIC_VECTOR (31 downto 0)
    > );
    > end ALU;
    >
    > architecture Behavioral of ALU is
    > signal SEAddr : STD_LOGIC_VECTOR(31 downto 0);
    > signal OP1 : STD_LOGIC_VECTOR(31 downto 0);
    > signal OP2 : STD_LOGIC_VECTOR(31 downto 0);
    > signal OP3 : STD_LOGIC_VECTOR(31 downto 0);
    > signal S_nat : natural;
    > begin
    > OP2 <= RdData2 when AluSrc='0' else SEAddr;
    > SEAddr(15 downto 0) <= FAddr;
    > SEAddr(31 downto 16) <= x"0000" when FAddr(15)='0' else x"FFFF";
    >
    > OP1 <= RdData1;
    >
    > process (RdData2)
    > begin
    > OP3 <= RdData2;
    > end process;
    >
    > with Sa select
    > S_nat <= 0 when "00000",1 when "00001",2 when "00010",3 when "00011",4 when "00100",5 when "00101",
    > 6 when "00110",7 when "00111",8 when "01000",9 when "01001",10 when "01010",11 when "01011",
    > 12 when "01100",13 when "01101",14 when "01110",15 when "01111",16 when "10000",17 when "10001",
    > 18 when "10010",19 when "10011",20 when "10100",21 when "10101",22 when "10110",23 when "10111",
    > 24 when "11000",25 when "11001",26 when "11010",27 when "11011",28 when "11100",29 when "11101",
    > 30 when "11110",31 when others;
    >
    > process (S_nat)
    > begin
    > OP3(S_nat) <= '1';
    > end process;
    >
    > with ALUOP select
    > y <= OP1 + OP2 when "000", OP1 - OP2 when "001", OP1 AND OP2 when "010", OP1 OR OP2 when "011", OP3 when others;
    >
    > end Behavioral;
    >
    > What I want is that OP3 to be exactly as RdData2 (and if I just do OP3 <= RdData2 ,it is) but also that 1 bit which is determined by Sa to become 1.
    >
    > For example , RdData 2 is 5555 5555 , and if I do only Op3 <= RdData2 then OP3 becomes 5555 5555 , but if i also do OP3(S_nat) <= '1' , then the result is XXXX XXX (to be more precise is xxxx xxxx xxxx xxxx xxxx xx1x xxxx xxx1 , so that 1 specific bit (10 in this case) becomes 1 , but the others are X-es).
    >
    > Any help would be highly appreciated , I'm working on this problem for several days and it still bugs me :(.

    The problem is that you are making the two assignments in two different
    processes, so they are "fighting" eachother rather than one having
    higher priority. For what you're doing, it may be easier to have
    a separate vector with a single 1 in a position determined by S_nat
    and then OR that vector with OP3 in the same process where you
    currently assign it to RdData2.

    -- Gabor
     
    GaborSzakacs, Feb 26, 2013
    #9
  10. Guest

    Thank You , Thank You ALL , finally it is working . Again , Thank You very much :)
     
    , Feb 26, 2013
    #10
  11. On 26 Feb., 15:54, wrote:
    > use IEEE.STD_LOGIC_ARITH.ALL;
    > use IEEE.STD_LOGIC_UNSIGNED.ALL;


    Not your question but usage of these libraries is bad style. You will
    see them a lot in old books and unfortunately too often in even not so
    old books).

    Use ieee.numeric_std.all instead. The _arith and _unsigned itself are
    vendor dependent, while numeric_std is real ieee standard and
    therefore vendor independent.

    >         process (RdData2)
    >           begin
    >                 OP3 <= RdData2;
    >         end process;
    >         with Sa select
    >                 S_nat <= 0 when "00000",1 when "00001",2 when "00010",3 when "00011",4 when "00100",5 when "00101",
    >                                         6 when "00110",7 when "00111",8 when "01000",9 when "01001",10 when"01010",11 when "01011",
    >                                         12 when "01100",13 when "01101",14 when "01110",15 when "01111",16 when "10000",17 when "10001",
    >                                         18 when "10010",19 when "10011",20 when "10100",21 when "10101",22 when "10110",23 when "10111",
    >                                         24 when "11000",25 when "11001",26 when "11010",27 when "11011",28 when "11100",29 when "11101",
    >                                         30 when "11110",31 when others;
    >
    >         process (S_nat)
    >                 begin
    >         OP3(S_nat) <= '1';
    >         end process;


    Better:

    process (Rddata2, Sa)
    begin
    OP3 <= RdData2; -- initailise all bits of
    OP3 with RdData2
    OP3(to_integer(unsigned(Sa))) <= '1'; -- modify bit selected
    with Sa
    end process;

    This code eliminates the fact that two process drive the same signal,
    is by far more readable and less errorprone than the code above.
    It is important that if you use some branches, each branch defines all
    bits of signal even if you would use OP3 <= OP3; OP3(Sa) <= '1'.

    bye Thomas
     
    Thomas Stanka, Feb 27, 2013
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luqman
    Replies:
    1
    Views:
    662
    Luqman
    Feb 7, 2006
  2. Thomas Rouam
    Replies:
    6
    Views:
    1,150
  3. sundar
    Replies:
    2
    Views:
    1,805
    sundar
    Nov 27, 2007
  4. gabor
    Replies:
    6
    Views:
    30,457
    mahfoudh
    Dec 30, 2013
  5. James Wong
    Replies:
    4
    Views:
    514
    James Wong
    Jul 14, 2004
Loading...

Share This Page