Newbie Help: How do I deal with variable length vectors?

R

roninn

I have an entity that has two std_logic_vectors as inputs (see below).
I want to make it so when I instantiate a component of this entity, it
will arrange itself in response to the width of the vectors it receives
as an inputs.

The architecture below shows that I try to take the width of the input
vector (shared variable Width: integer:= A'length;) and then create
signals with that width. These signals then link together some
subcomponents (which attempt to do the same thing to discover the
vector width).

The obvious problem is that the input vectors are not initialized when
this code runs, so A'length returns 0, and the linking vectors created
are useless. I cannot use a "wait on" statement to wait until the input
vectors are initialized, becuase this is a concurrent statement block.

It seems like I'm trying to do a combination of sequential and
concurrent statements, which is not proper VHDL. How can I get around
this problem? I'm still quite new to VHDL, so any information you can
give me would be greatly appreciated.

Thanks!

The entity:

entity SquareRoot is
port(
A, B: in std_logic_vector;
Cin: in std_logic;
Cout: out std_logic;
Sum: out std_logic_vector
);
end;

The architecture:

architecture behav of SquareRoot is
--removed component declarations

shared variable Width: integer:= A'length;
signal Plink, Glink, Slink0, Slink1: std_logic_vector(width-1 downto
0);
signal Clink0, Clink1: std_logic;

begin
pg: pAndG port map (A, B, Plink, Glink);
a0: sradderc0 port map (Plink, Glink, Clink0, Slink0);
a1: sradderc1 port map (Plink, Glink, Clink1, Slink1);
mx: mux port map (Cin, Slink0, Slink1 , Clink0, Clink1, Sum, Cout);
end;
 
U

Ulf Samuelsson

I have an entity that has two std_logic_vectors as inputs (see below).
I want to make it so when I instantiate a component of this entity, it
will arrange itself in response to the width of the vectors it
receives as an inputs.
... snip ...

Do a generic declaration

entity SquareRoot is
generic (W : Integer := 16)
port(
A, B: in std_logic_vector(W-1 downto 0);
Cin: in std_logic;
Cout: out std_logic;
Sum: out std_logic_vector(W+W-1 down to 0)
);
end;

architecture behav of SquareRoot is

--removed component declarations
signal Plink, Glink, Slink0, Slink1: std_logic_vector(W-1 downto 0);
signal Clink0, Clink1: std_logic;

begin
pg: pAndG port map (A, B, Plink, Glink);
a0: sradderc0 port map (Plink, Glink, Clink0, Slink0);
a1: sradderc1 port map (Plink, Glink, Clink1, Slink1);
mx: mux port map (Cin, Slink0, Slink1 , Clink0, Clink1, Sum, Cout);
end;


--
Best Regards,
Ulf Samuelsson
(e-mail address removed)
This message is intended to be my own personal view and it
may or may not be shared by my employer Atmel Nordic AB
 
I

info_

Hi,

It makes me nervous to see "shared variables" in RTL code... As a newbie, you
probably shouldn't be aware of these beasts anyway ;-)
Shared vars can be very handy in test benches and behavioral models, but they must be
used with extreme care.
A constant would have done the trick.

Unconstrained arrays in port is IMO a very elegant style, but it doesn't
have only advantages... I'm not sure all the synthesis tool accept this yet either,
you need to check first before using this style ! Don't rely on manuals, they are
sometimes unaware of what the tool can do !!! Use the code below (wrap it in a
sized-ports top level first indeed) to see of it works.

So below is something which I wrote "similar" to your idea (though the function coded
has nothing to do with a square root. I think there is a synthesizable square root in
the Synplify examples, but if it's an assignment, write your own solution first).
You can throw this code in your VHDL simulator and see it work (PWM on Cout).

Hope this helps,
Bert
--
-- Using unconstrained array : simple example.
-- Bert Cuzeau.
--
-- Note though that unitary synthesis will require a wrapper...
-- so unconstrained arrays in ports, despite their "beauty"
-- is probably not the panacea. But it's elegant and highly reusable.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity pAndG is
port( A, B : in std_logic_vector;
Plink,
Glink : out std_logic_vector );
end pAndG;

architecture dummy of pAndG is
begin
-- just to put something here for the sake of the example
Plink <= A and B;
Glink <= A xor B;
end;
-- we ae going to instanciate this entity.

-- ----------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;

entity SquareRoot is
port( A, B : in std_logic_vector;
Cin : in std_logic;
Cout : out std_logic;
Sum : out std_logic_vector );
end SquareRoot;

library IEEE;
use IEEE.numeric_std.all;

architecture Dummy of SquareRoot is -- just for the example !
-- this does nothing interesting, the purpose is only to show how
-- to use unconstrained array and attributes.

constant Width : positive := A'length; -- if you want to use it.

signal Plink, Glink, Slink0, Slink1: std_logic_vector(A'range);
signal Clink0, Clink1: std_logic;
signal Sum1 : std_logic_vector (A'high+1 downto 0);

begin
-- shows the instanciation of another entity with unconstrained vectors in port
pg: entity work.pAndG(Dummy) port map (A, B, Plink, Glink); --

Sum1 <= std_logic_vector (unsigned('0'& A) + unsigned('0'& B));
Sum <= Sum1(Sum'range);
Cout <= Sum1(Sum1'high);
end;

-------simple test bench-----------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity TB is end;
architecture test of TB is
signal A,B,Sum : std_logic_vector(5 downto 0);
signal Cout : std_logic;
begin
UUT: entity work.SquareRoot port map (A,B,'0',Cout,Sum);
process begin
A <= (others=>'0'); B <= (others=>'0');
for i in 0 to 2**A'length-1 loop
for j in 0 to 2**A'length-1 loop
A <= std_logic_vector (to_unsigned(i,A'length));
B <= std_logic_vector (to_unsigned(j,B'length));
wait for 10 ns;
end loop;
end loop;
wait;
end process;
end test;
----------------------------------
 
R

roninn

Thank you Ulf. I was not aware of generics, but they appear to be
exactly what I needed.

Thanks agains for your help.
 
R

roninn

Hi Bert,

Thank you for the advice. To be honest, I only had shared variables
becuase a compilation error suggested it :)

I do not need to simulate this particular code, but in the future I
will take your advice and try it out on the Xilinx synthesizer I am to
use.

Thank again for your help.
 
I

info_

I'm not sure your understood that generic parameter wasn't the only solution.
You can create generic RTL code with unconstrained vectors, (and no generic
parameter) as shown in my example. You just need to use attributes as shown.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,440
Latest member
YoungBorel

Latest Threads

Top