- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello guys...
I'm trying instatniating some altera MF directly in my top design. From what I have understand I have two use two libraries:
library altera_mf;
use altera_mf.altera_mf.components.all;
library lpm;
use lpm.lpm_components.all;
The first libray is used to avoid the components declarations and the second is used to instantiate directly the lpm objects. So, as I want to use a parallel adder, I wrote: parallel_add_inst : parallale_add
GENERIC MAP(....)
PORT MAP(...);
By the way, looking at the Integer Arithmetic Megafunctions User Guide, the port map of the parallel adder is:
data:in altera_mf_logic_2D(size - 1 downto 0,width- 1 downto 0);
clock : in std_logic := '1';
aclr : in std_logic := '0';
clken : in std_logic := '1';
result : out std_logic_vector(widthr - 1 downto 0));
So, how should I write the port map if I want to add two input signals (eg dataa[15..0] and datab[15..0]) ? Thank you ! Have a nice day !
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is going to be complicated by the fact Altera uses the altera_mf_logic_2D type in this design (instead of just making an array of std_logic_vectors like any normal person would).
For a start, if you're just using two inputs, use the lpm_add_sub block instead, or just do an add in your code: a <= b + c; for parellel add, you have to map each bit individually to the bits on the bus, because of VHDL's strong typing. so: data(0,0) => dataa(0); data(0,1) => dataa(1); --etc data(1,0) => datab(0); data(2,0) => datab(1); For this stupid reason, I would be inclinded to write you own type conversion function:
function slv_to_alteras_stupid_2d_type( a : std_logic_vector; b : std_logic_vector) return altera_mf_logic_2D is
variable ret : altera_mf_logic_2D(
begin
for i in a'range loop
ret(0,i) := a(i);
ret(1,i) := b(i);
end loop;
return ret;
end function;
It could easily be modified to convert an array of std_logic_vectors into a 2d array type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Hello guys... I'm trying instatniating some altera MF directly in my top design. From what I have understand I have two use two libraries:
library altera_mf;
use altera_mf.altera_mf.components.all;
library lpm;
use lpm.lpm_components.all;
The first libray is used to avoid the components declarations and the second is used to instantiate directly the lpm objects. So, as I want to use a parallel adder, I wrote: parallel_add_inst : parallale_add
GENERIC MAP(....)
PORT MAP(...);
By the way, looking at the Integer Arithmetic Megafunctions User Guide, the port map of the parallel adder is:
data:in altera_mf_logic_2D(size - 1 downto 0,width- 1 downto 0);
clock : in std_logic := '1';
aclr : in std_logic := '0';
clken : in std_logic := '1';
result : out std_logic_vector(widthr - 1 downto 0));
So, how should I write the port map if I want to add two input signals (eg dataa[15..0] and datab[15..0]) ? Thank you ! Have a nice day ! --- Quote End --- The altera_mf_logic_2D type is identical to the std_logic_2D type declared in the lpm-library. Unfortunately Altera hasn't declared any user functions/procedures to work with these types. I started using the std_logic_2D type several years back to instantiate AHDL modules where you could use arrays like A[1..0][15..0] (which were represented by std_logic_2D by the generated VHDL components). As such I wrote quite some functions / procedures to work with std_logic_2D. Now a std_logic_2D is a true 2D type where you have a n by m array of (single) bits. This is different to 1Dx1D arrays where you have a vector of vectors. (see e.g. Volnei A. Pedroni: Circuit Design with VHDL page 30 and following). In your case what you need (so far as I can see) is a simple procedure to map the two source std_logic_vectors to a std_logic_2D array: procedure insert_std_logic_2D( signal destination : inout std_logic_2D ;
idx : in integer ;
source : in std_logic_vector )
is
begin
-- select maximum to provoke an error when not equal
for i in 0 to maximum(source'high , destination'high(2)) loop
destination(idx , i) <= source(i) ;
end loop ;
end procedure ;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wouldn't call Altera's std_logic_2D type stupid. Until VHDL 2008 you could not use a 1Dx1D array in a generic way (as one dimension has to be fixed). The 2D is both elegant and pure. Altera's (and other FPGA vendors, EDA vendors included) fault was not to provide a standard library for it. With VHDL 2008 you can declare a 1D array of unconstrained std_logic_vector. And I certainly recommend this. Unfortunately I have too much legacy code to convert. (Altera did not support this either until a few versions of Quartus back, and then it once disappeared and reappeared)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I wouldn't call Altera's std_logic_2D type stupid. Until VHDL 2008 you could not use a 1Dx1D array in a generic way (as one dimension has to be fixed). The 2D is both elegant and pure. Altera's (and other FPGA vendors, EDA vendors included) fault was not to provide a standard library for it. With VHDL 2008 you can declare a 1D array of unconstrained std_logic_vector. And I certainly recommend this. Unfortunately I have too much legacy code to convert. (Altera did not support this either until a few versions of Quartus back, and then it once disappeared and reappeared) --- Quote End --- Ok, not stupid, like you said its more laziness on the part of altera. It could probably have put people off using the blocks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- This is going to be complicated by the fact Altera uses the altera_mf_logic_2D type in this design (instead of just making an array of std_logic_vectors like any normal person would). For a start, if you're just using two inputs, use the lpm_add_sub block instead, or just do an add in your code: a <= b + c; for parellel add, you have to map each bit individually to the bits on the bus, because of VHDL's strong typing. so: data(0,0) => dataa(0); data(0,1) => dataa(1); --etc data(1,0) => datab(0); data(2,0) => datab(1); For this stupid reason, I would be inclinded to write you own type conversion function:
function slv_to_alteras_stupid_2d_type( a : std_logic_vector; b : std_logic_vector) return altera_mf_logic_2D is
variable ret : altera_mf_logic_2D(
begin
for i in a'range loop
ret(0,i) := a(i);
ret(1,i) := b(i);
end loop;
return ret;
end function;
It could easily be modified to convert an array of std_logic_vectors into a 2d array type. --- Quote End --- Thank you tricky ! for now I will go with the lpm_add_sub. The drawback is that I have to add a leading 0 to each input signal each time I use it. By the way, using your function will introduce some delay between inputs and outputs ? Thank you for help !!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you as well josyb.
I will take a look !! If I decide to use your procedure or the function provided by tricky how can use it in my vhdl design ?? It's c-style based ?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Have a read of a VHDL tutorial on functions and how to use them. Type conversions are logic free.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Thank you tricky ! for now I will go with the lpm_add_sub. The drawback is that I have to add a leading 0 to each input signal each time I use it. --- Quote End --- Why do you need to add leading 0s? you can specify the input widths from the generics. you would have the same problem with the parallel add.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The parallel_add returns a nbit+1 output with 2 nbit input as I can see, viceversa the lpm_add_sub gives you a nbit out whith 2 nbit input. So if I don't want to incur in overflow problems I've thought to add a 0 on each of the two inputs..
Am I right ?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The add-Sub component has a cout port, which is the MSB of the output word (it also has an overflow bit)/
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you tricky.
From the lpm_guide I see that cout is defined as: Carry-out (borrow-in) of the most significant bit (MSB). The cout port has a physical interpretation as the carry-out (borrow-in) of the MSB. The cout port detects overflow in UNSIGNED operations. The cout port operates in the same manner for SIGNED and UNSIGNED operations. I can't really understand it very much.. Is that similar to say: dataa+datab == [cout dataout] ?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the carry out bit is the MSB of an add function, so you are correct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you tricky. I ended up with your function suggestion.
One more thing, I have an entity that has a std_logic_vector input. By the way this time I have to assign it only a std_logic signal that is on output of another entity. the question is: Is it possible to do something like:stdLogicVectorIn(0)=>stdLogic
And then left without assignement the other elements of stdLogicVectorIn ? There is a better way ? Thank you guys !! Your help is really appreciated !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a std_logic_vector is an array of std_logic.
Your method is the best way. But the other bits of an Input must be connected to something, even if it is '0' or '1', otherwise it is and error.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you tricky. The vector was a std_logic_vector( 0 downto 0). The problem was only caused by a type mismatch..
Trying to compèile the whole code there are some issues using:function slv_to_alteras_stupid_2d_type( a : std_logic_vector; b : std_logic_vector) return altera_mf_logic_2D is variable ret :
altera_mf_logic_2D(
begin
for i in a'range loop
ret(0,i) := a(i);
ret(1,i) := b(i);
end loop;
return ret;
end function;
in the case of function slv_to_alteras_stupid_2d_type(bus1(18 downto 3), bus(15 downto 0)) I will try with some other attributes in the for loop.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello guys.. ended up with
function slv_to_alteras_stupid_2d_type( a : std_logic_vector; b : std_logic_vector) return altera_mf_logic_2D is
variable ret : altera_mf_logic_2D(0 downto 0, (a'high-a'low) downto 0); -- the two inputs have the same size but can have different subsciript: a(16 downto 1), b(18 downto 3)
variable j: integer :=0;
begin
for i in a'range loop
ret(0,j) := a(i);
j:=j+1;
end loop;
for i in b'range loop
j:=0;
ret(1,j) := b(i);
j:=j+1;
end loop;
return ret;
end function;
By the way when I call my_par_add : parallel_add
generic map (...)
port map(clk=>my_clock,
data=>slv_to_altera2d_type(('0' & bus1), bus2))
result=> dataout);
running modelsim I get the following error: Actual expression (function call "slv_to_altera_2d_type") of formal "data" is not globally static
What I am supposed to do now ?? Thank you for your help guys. have a nice day.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you need to create an intermediate signal to call the function.
my_intermediate_signal <= slv_to_altera2d_type(('0' & bus1), bus2)); .... data => my_intermediate_signal; But your function has errors in it. The return value has 0 downto 0 as the first dimension, but you try and access 1 when you assign to it (out of range error).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you tricky, finally I ended up with this:
function slv_to_altera_2d_type(dataa : std_logic_vector; datab : std_logic_vector) return altera_mf_logic_2d is
variable ret : altera_mf_logic_2D(1 downto 0,(dataa'high - dataa'low) downto 0);
variable temp_dataa,temp_datab : std_logic_vector((dataa'high - dataa'low) downto 0);
begin
temp_dataa:=dataa;
temp_datab:=datab;
for i in temp_dataa'range loop
ret(0,i) :=temp_dataa(i);
ret(1,i) :=temp_datab(i);
end loop;
return ret;
end function;
It seems to work smoothly. One last question.. The lpm_mux uses a STD_LOGIC_2D input type. Can I assign it directly like input(0,16 downto 0)<=signal1(16 downto 0);
input(1,16 downto 0)<=signal2(16 downto 0);
Thank you all guys. have a nice day !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One last question.. The lpm_mux uses a STD_LOGIC_2D input type. Can I assign it directly like
input(0,16 downto 0)<=signal1(16 downto 0);
input(1,16 downto 0)<=signal2(16 downto 0);
--- Quote End --- No. If you could, I wouldnt have suggested the function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yep, I thought it was only due to the alt_mf_2d type...
Thank you !
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page