VHDL error in for generate - loops

I'm a newbie user of VHDL.
I have an error in this code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity AandB is
Port ( a : in STD_LOGIC_vector(31 downto 0);
b : in STD_LOGIC_vector(31 downto 0);
salida : out STD_LOGIC_vector(31 downto 0)
);
end AandB;
architecture Behavioral of AandB is
begin
for i in 0 to 31 loop
salida(i) <= a(i) and b(i);
end loop;
end Behavioral;
the error is this:
ERROR:HDLCompiler:806 - Line 43: Syntax error near "for".
ERROR:HDLCompiler:69 - Line 45: <i> is not declared.
ERROR:HDLCompiler:806 - Line 47: Syntax error near "generate".
ERROR:HDLCompiler:854 - Line 39: Unit <behavioral> ignored due to previous errors.
I have searched for the enter code here`first 3 errors. Haven't noticed what is the syntax error for the "for" statement; It's supposed that is indirectly declared within the loop; Don't know about the error in "generate".
Some help?

ThirtyTwoAnd: for i in 0 to 31 generate
salida(i) <= a(i) and b(i);
end generate ThirtyTwoAnd;

What Jim said can even be simplified. ieee.std_logic_1164 actually defines:
FUNCTION "and" ( l,r : std_logic_vector ) RETURN std_logic_vector;
So you could in this case of equal length vectors just write:
salida <= "and"(a, b);
But just this will also work:
salida <= a and b;

Related

Im getting a vcom error 1576 in modelsim when working with xor code

I have zero clue what i did wwrong or what im missing. any feedback will be appreciated.
for clarity the error im getting is a vcom 1576 and its near the of it says and it is expecting an identifier.
library ieee;
use ieee.std_logic_1164.all;
entity MCINTOSH_XOR_CASCADE1 is
port(
OP_A: in std_logic_vector(7 downto 0);
OP_Q: out std_logic
);
end MCINTOSH_XOR_CASCADE1;
architecture cascade1_arch of MCINTOSH_XOR_CASCADE1 is
begin
OP_A<= OP_A(0) xor OP_A(1) xor OP_A(2) xor OP_A (3) xor
OP_A(4) xor OP_A(5) xor OP_A(6) xor OP_A(7);
end cascadel_arch;
architecture cascade2_arch of MCINTOSH_XOR_CASCADE1 is
signal p: std_logic_vector (7 downto 0);
begin
p(0) <= OP_A(0);
p(1) <= p(0) xor OP_A(1);
p(2) <= p(1) xor OP_A(2);
p(3) <= p(2) xor OP_A(3);
p(4) <= p(3) xor OP_A(4);
p(5) <= p(4) xor OP_A(5);
p(6) <= p(5) xor OP_A(6);
p(7) <= p(6) xor OP_A(7);
OP_Q <= p(7);
end cascade2_arch;
im doing a project with xors and im trying to put together my entity files to make a test bench

VHDL issue with process loop variables and arrays

I have an array of std_logic_vectors in which I want to implement a delay chain. I wrote it up like this, and it works fine:
--Signal Declaration
type MyArrayType is array(0 to 3) of std_logic_vector(31 downto 0);
signal s_aslv_DelayChain : MyArrayType;
--Concurrent Statement, Load input chain
s_aslv_DelayChain(0) <= ip_slv_Input;
--Delay line Process
DelayProc : process(ip_sl_Clk)
begin
if(rising_edge(ip_sl_Clk)) then
s_aslv_DelayChain(1) <= s_aslv_DelayChain(0);
s_aslv_DelayChain(2) <= s_aslv_DelayChain(1);
s_aslv_DelayChain(3) <= s_aslv_DelayChain(2);
end if; --rising_edge(ip_sl_Clk)
end process DelayProc;
This produces the result I would expect:
However, if I change the process to use a looping variable:
--Delay line Process
DelayProc : process(ip_sl_Clk)
begin
if(rising_edge(ip_sl_Clk)) then
for n in 1 to 3 loop
s_aslv_DelayChain(n) <= s_aslv_DelayChain(n-1);
end loop;
end if; --rising_edge(ip_sl_Clk)
end process DelayProc;
It doesn't work and I get a bunch of U's:
Shouldn't the 2 coding styles describe the same behavior?

vhdl comparing vector output

I have a vector A that's 64bits long and I want the output B to equal 3 while A is 30-35 and zero elsewhere. I can't figure out the testbench to loop through the vector A as a bit. I've tried several different ways but only got 1/5 of the array to give any output at all. This is as far as I could get without syntax/compile errors.
Main code
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.ALL;
entity ent is
port(A:in std_logic_vector(5 downto 0);
B:out std_logic_vector(3 downto 0));
end ent;
architecture arch_ent of ent is
begin
with A select
B <= "0011" when "011110",
"0011" when "011111",
"0011" when "100000",
"0011" when "100001",
"0011" when "100010",
"0011" when "100011",
"0000" when others;
end arch_ent;
Testbench
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb is
end tb;
architecture arch_tb of tb is
component ent
port(A:in std_logic_vector(5 downto 0);
B:out std_logic_vector(3 downto 0));
end component;
signal A_tb: std_logic_vector(5 downto 0);
signal B_tb: std_logic_vector(3 downto 0);
begin
uut: entity ent port map(A=>A_tb, B=>B_tb);
tb: process
constant period: time := 20ns;
begin
for i in A_tb'range loop
A_tb <= std_logic_vector(to_unsigned(i,6));
wait for period;
assert (B_tb = "0011")
report "test failed" severity error;
end loop;
wait;
end process;
end arch_tb;
In the end I'm trying to plot out the waveform like this:
http://i10.photobucket.com/albums/a142/blargonblop/wave.png
where A will go to 63 and each output is its correct value from 30-35 and 0 elsewhere
The loop parameter you use to specify the number of 'tests' is A_tb'range, which happens to be 5 downto 0, or six tests, i is assigned 5,4,3,2,1 and 0 successively.
You want to specify i in 0 to 2**A-tb'length-1 or i in 0 to 63 to get all 64 possible A_tb 'binary' values.
(A_tb'length = 6, 2**6-1 = 63, where ** is the exponentiation operator, 2 to the 6th power minus 1 equals 63)
I found two syntax errors in your test bench, 20ns where the standard requires a space between 20 and ns:
constant period: time := 20 ns;
And entity ent where that should either be just ent (you have a component declaration ent) or entity work.ent and no need for a component declaration:
uut: ent port map(A=>A_tb, B=>B_tb);
or
uut: entity work.ent port map(A=>A_tb, B=>B_tb);
And in keeping with Russell's answer there is no implied logic replication in a loop other than through synthesis which unravels loop iterations by paralleling logic (the replication). Not all loop statements are intended as synthesis targets.
Test benches are generally not synthesized and are used to write tests (as in your case) for a VHDL model that might be used as a synthesis target.
First, loops are just fine, and common, in testbenches. #Russell's comment applies to RTL code. You can adapt his approach for this problem and make it work. You would need to use 64 as a sentinel (ending) value and do your end of test checks then. Keep in mind though that the most important thing you do is code for readability. Test cases generally run from top to bottom of a process one time.
You loop has some issues in addition to the recommendations #DavidKoontz gave. Specifically,
Your assertion is should not be checked when you expect B to be 0.
Using numeric_std_unsigned (requires VHDL-2008 compile switch) will simplify your conversions.
Keep an error count so you can report pass or failed at the end.
Keep your constants in the architecture or a package
So the modified code is:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std_unsigned.all;
entity tb is
end tb;
architecture arch_tb of tb is
constant period: time := 20 ns;
...
begin
...
tb: process
variable ErrorCount :
begin
for i in i in 0 to 2**A-tb'length-1
A_tb <= to_slv(i,6);
wait for period;
if i >= 30 and i <= 35 then
if B_tb /= 3 then
ErrorCount := Error Count + 1 ;
report "B_tb = " & to_string(B_tb) & " Expecting: 0011" severity ERROR ;
end if;
else
if B_tb /= 0 then
ErrorCount := Error Count + 1 ;
report "B_tb = " & to_string(B_tb) & " Expecting: 0000" severity ERROR ;
end if;
end loop;
if ErrorCount = 0 then
report "Test Passed" severity NOTE ;
else
report "Test FAILED. There were " & to_string(ErrorCount) & " Errors " severity NOTE;
end if;
std.env.stop(0) ; -- testbench stops here
end process;
Note that the rules about using (or forbidding usage of) numeric_std_unsigned do not apply to testbenches.
You really should not be using a for loop for this. For loops in VHDL are used to REPLICATE LOGIC, not to do something some number of times. Try something like this in your test bench:
signal r_CLOCK : std_logic := '0';
signal r_INDEX : unsigned(5 downto 0) := (others => '0');
begin
r_CLOCK <= not r_CLOCK after period/2;
process (r_CLOCK)
begin
if rising_edge(r_CLOCK) then
r_INDEX <= r_INDEX + 1;
end if;
end process;
Now simply cast r_INDEX as std_logic_vector and pass it to your ent component.

VHDL file reading program shows an error

I was writing a vhdl code to read the image file. I converted the image file into a note pad file having 65536 lines.ie,256 X 256 pixels. Now when I am running the code I am getting a error that says:
Fatal error in ForLoop loop at C:/MentorGraphics/modeltech_6.5c/win32/test.vhd line 39
# HDL call sequence:
# Stopped at C:/MentorGraphics/modeltech_6.5c/win32/test.vhd 39 ForLoop loop
why it is happening like that.. I am attaching the code below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use std.textio.all;
entity IMAGE_READ is
Port ( CLK : in STD_LOGIC;
IMAGE_LOAD : IN STD_LOGIC:='1';
IMAGE_DONE : OUT STD_LOGIC);
end entity;
architecture Behavioral of IMAGE_READ is
type image is array (1 to 256,1 to 256) of std_logic_vector(7 downto 0);
file IMAGE_FILE:text open read_mode is "D:\Documents\ORIGINAL IMAGE.txt";
begin
PROCESS(CLK,ROW,COLUMN,IMAGE_LOAD)
variable LINE_NUMBER:line;
variable TEMP_PIXEL_VALUE: bit_vector(7 downto 0);
variable image_matrix:IMAGE;
BEGIN
if (clk'event and clk = '1') then
IF(IMAGE_LOAD='1') THEN
for i in 1 to 256 loop
for j in 1 to 256 loop
readline (IMAGE_FILE, LINE_NUMBER);
read (LINE_NUMBER, TEMP_PIXEL_VALUE);
image_matrix(i,j) := to_stdlogicvector(TEMP_PIXEL_VALUE);
if(i=256 and j=256) then
TEMP_image_done:='1';
image_done<='1';
else
TEMP_image_done:='0';
image_done<='0';
end if;
END LOOP;
END LOOP;
END IF;
END IF;
END PROCESS;
end Behavioral;
How to correct it?
You will have to debug the program; preferably in simulation.
Look for clues as to the error : for example, what are the values of the loop counters i and j when the error occurs?
What is the current line of the file?
What is the previous line?
What value do you get for Temp_Pixel from the faulty line?
and so on.
Eventually you will see something unexpected and that will lead you to the answer.

Adressing a specific bits in an array of std_logic vector in VHDL

Im new to VHDL.
my problem is that i cant seem to find the correct syntax for writing or reading from an array of std_logic_vector. i init the array as such :
TYPE eleven_samples_in IS ARRAY ( 0 TO 10 ) OF STD_LOGIC_VECTOR( 87 DOWNTO 0 );
and i try addressing it as such :
odd: for i in 1 to 6 generate
node: compare_level
port map(
input => eleven_samples_in(i*2 - 1)(79 DOWNTO 0),
output => eleven_samples_out(i*2 - 1)(79 DOWNTO 0 )
);
end generate odd;
Or :
port map(
input => eleven_samples_in(i*2 - 1,79 DOWNTO 0),
output => eleven_samples_out(i*2 - 1,79 DOWNTO 0 )
);
end generate odd;
But i get an Errors such as :
Error (10409): VHDL Type Conversion error at Median_Filter.vhd(45): converted type of object near text or symbol "eleven_samples_in" must match std_logic_vector type of target object
I searched the web and found nothing that works.
thank you very much for the help .
you create a type eleven_samples_in, and use that directly. This is incorrect.
Instead:
type eleven_samples_in_type is array (0 to 11) of std_logic_vector(89 downto 0);
signal eleven_samples_in : eleven_samples_in_type;
...
Without knowing anything about your compare_levels component, thats as much help as I can be
To answer about the right syntax to access specific bits from an array of std_logic_vector, as I was wondering myself, it happens to be the first you suggested:
s_array(array_index)(vector_bit_index) -- for a single bit
or
s_array(array_index)(last_bit_index downto first_bit_index) -- for a range

Resources