Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

counte various value

Altera_Forum
Honored Contributor II
1,606 Views

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;
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
878 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
878 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
878 Views

still it is showing error

0 Kudos
Altera_Forum
Honored Contributor II
878 Views

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;
0 Kudos
Altera_Forum
Honored Contributor II
878 Views

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" thenby this one:elsif vin = 1 or vin = -1 thenAnd 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.
0 Kudos
Reply