Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

counte various value

i have a array with 16 values each with 12 bits i want to count the no of trailingones(1 or -1) maxmim is 3 ,and total no of non zero values and total zeros .

i wrote the program ,it compile successfully but i m unable to get the simulation result. can any one help.

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;

entity rom1 is

port(CLK:in std_logic;

totalcoeffs,totalzeros:out std_logic_vector(4 downto 0);

trailingones:out std_logic_vector(1 downto 0));

end rom1;

architecture rom of rom1 is

signal etotalcoeffs : std_logic_vector(4 downto 0) := b"00000";

signal etotalzeros : std_logic_vector(4 downto 0) := b"00000";

signal etrailingones : std_logic_vector(1 downto 0) := b"00";

signal ecgt1 : std_logic := '0';

signal vin:std_logic_vector(11 downto 0);

type vector_array is array (0 to 15) of

std_logic_vector(11 downto 0);

constant memory:vector_array :=

("111111111111","111111111111","000100000011","000000000100",

"000000000101","000000000110","000000000111","000000001000",

"000000001001","000000001010","000000001011","000100001000",

"000100000001","000100000010","000100001000","000100001000"

);

begin

process(CLK)

begin

if CLK'event and CLK = '1' then

--data <= memory(addr);

--end if;

x2:for i in 1 to 16 loop

vin <= memory(i-1);

if vin /= 0 then

etotalcoeffs <= etotalcoeffs + 1;

elsif vin = 1 or vin = x"FFF" then

etrailingones <= etrailingones +1;

else

etotalzeros <= etotalzeros + 1;

end if;

end if;

end loop x2;

if (etrailingones > 3) then

trailingones <= b"11";

else

trailingones <= etrailingones;

totalzeros <= etotalzeros;

totalcoeffs <= etotalcoeffs;

end if;

end if;

end process;

end rom;

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You can't directly compare a std_logic_vector with an integer.

    You should use the signed type instead. Either just for vin:

    vin <= signed(memory(i-1));

    or also define memory as an array of signed and keep your vin assignment without any cast.

    Once vin is an unsigned, you can directly compare it to 0, 1 and -1 in your if statements.

    Same thing for your counters, you can't add an integer to them. Either redefine them as integers, or as unsigned.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    You can't directly compare a std_logic_vector with an integer.

    You should use the signed type instead. Either just for vin:

    vin <= signed(memory(i-1));
    or also define memory as an array of signed and keep your vin assignment without any cast.

    --- Quote End ---

    To do this, you need to use either numeric_std or std_logic_arith. You cannot use both packages in the same file.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    after modification it compile successfully but simulation result is not correct

    library IEEE;

    use IEEE.STD_LOGIC_1164.ALL;

    --use IEEE.STD_LOGIC_ARITH.ALL;

    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    use ieee.std_logic_signed.all;

    use ieee.numeric_std.ALL;

    entity rom1 is

    port(CLK:in std_logic;

    totalcoeffs,totalzeros:out std_logic_vector(4 downto 0);

    trailingones:out std_logic_vector(1 downto 0));

    end rom1;

    architecture rom of rom1 is

    signal etotalcoeffs : std_logic_vector(4 downto 0) := b"00000";

    signal etotalzeros : std_logic_vector(4 downto 0) := b"00000";

    signal etrailingones : std_logic_vector(1 downto 0) := b"00";

    signal ecgt1 : std_logic := '0';

    signal vin:signed(11 downto 0);

    type ar is array (0 to 15) of signed(11 downto 0);

    constant memory :ar:=

    ("111111111111","111111111111","000100000011","000000000100",

    "000000000101","000000000110","000000000111","000000001000",

    "000000001001","000000001010","000000001011","000100001000",

    "000100000001","000100000010","000100001000","000100001000"

    );

    begin

    process(CLK)

    begin

    if CLK'event and CLK = '1' then

    x2:for i in 1 to 16 loop

    vin <= signed(memory(i-1));

    if vin /= 0 then

    etotalcoeffs <= etotalcoeffs + 1;

    elsif vin = 1 or vin = x"FFF" then

    etrailingones <= etrailingones +1;

    else

    etotalzeros <= etotalzeros + 1;

    end if;

    end loop x2;

    totalzeros <= etotalzeros;

    totalcoeffs <= etotalcoeffs;

    if (etrailingones > 3) then

    trailingones <= b"11";

    else

    trailingones <= etrailingones;

    end if;

    end if;

    end process;

    end rom;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sorry, I didn't see that you also included std_logic_arith in your first code. You should avoid it, especially when using both signed and unsigned signals in the same design.

    Now that vin is signed, you can replace this line:
    elsif vin = 1 or vin = x"FFF" then
    by this one:
    elsif vin = 1 or vin = -1 then
    And that way you won't have to modify your code if you want to work on sizes other than 12 bits in the future.

    Could you define "is not correct" for us?

    There is another problem that I see in your code. You are doing everything within one clock cycle, but as you don't initialize your counters, on each clock cycle they will be increased by the value that you wanted. This is probably not what you wanted.

    You should add something to stop the process once the result has been calculated, or reinitialize the counters to start the calculation again. Anyway in your simulation with this code you should only look at the results after the first clock cycle.

    It may be a better idea to read only one vector on each clock cycle instead of reading all 16. It will take a longer time to run, but will synthesize in a much smaller system.