![]() |
|
|
|||||||
![]() |
VHDL - Newbie Help: How do I deal with variable length vectors? |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
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 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; roninn@gmail.com |
|
|
|
|
#2 |
|
Posts: n/a
|
wrote:
> 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 ... > > Thanks! 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 This message is intended to be my own personal view and it may or may not be shared by my employer Atmel Nordic AB Ulf Samuelsson |
|
|
|
#3 |
|
Posts: n/a
|
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; ---------------------------------- info_ |
|
|
|
#4 |
|
Posts: n/a
|
Thank you Ulf. I was not aware of generics, but they appear to be
exactly what I needed. Thanks agains for your help. roninn@gmail.com |
|
|
|
#5 |
|
Posts: n/a
|
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. roninn@gmail.com |
|
|
|
#6 |
|
Posts: n/a
|
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. wrote: > 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. > info_ |
|