Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

use of function lpm

Hi to everybody,

i write a small machine state to implement the and product separately..

i use std_logic_vector signal, so in the first state i sum the result of the product state.. but i never use lpm function so

i don't know how to istantiate these?

i try to do this but the compiler don't accept it..

I want that my program make product a*y and b*x in the state prodotto and the sum Y=pnum+pden in the second state

i post my code..

LIBRARY lpm;

USE lpm.lpm_components.ALL;

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

USE ieee.std_logic_arith.ALL;

USE ieee.std_logic_unsigned.ALL;

ENTITY add_sum IS

GENERIC (W1: integer:= 11; -- Input bit width

) ;

PORT (CLK : IN STD_logic;

x_in : IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);

y_out : OUT STD_LOGIC_VECTOR(W1-1 DOWNTO 0);

END add_sum;

ARCHITECTURE flex OF add_sum IS

SUBTYPE N1BIT IS STD_LOGIC_VECTOR(W1-1 DOWNTO 0);

TYPE state_type is (somma,prodotto);

SIGNAL stato: state_type :=prodotto;

SIGNAL x : N1BIT;

SIGNAL y : N1BIT;

myprocess: PROCESS

BEGIN

if (rising_edge(clk)) then

case state is

when somma => y<=pnum+pden;

stato<=prodotto;

when prodotto =>

lpm_mult_ist1: lpm_mult

PORT MAP (clock=>clk, dataa=>x, datab=>b, result =>pnum);

lpm_mult_ist2: lpm_mult

PORT MAP ( clock=>clk, dataa=>a, datab=>y, result =>pden);

stato<=somma;

end case;

end if;

end process myprocess;

y_out<=y;

END flex;

Thank for our response and attention!

by enrico

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You cant do a port map inside a process. entities have to be instantiated outside a process. components are not functions, they are like chips on a circuit board - so you cannot just add them when you want them.

    But you dont need lpm mult. If you ditch the non-standard libraries (std_logic_unsigned and std_logic_arith) and use numeric_std instead, you can simply write:

    pmum <= x * b;

    pden <= y *a;

    assuming x,y,a and b are declared signed/unsigned instead of std_logic_vector.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    You cant do a port map inside a process. entities have to be instantiated outside a process. components are not functions, they are like chips on a circuit board - so you cannot just add them when you want them.

    But you dont need lpm mult. If you ditch the non-standard libraries (std_logic_unsigned and std_logic_arith) and use numeric_std instead, you can simply write:

    pmum <= x * b;

    pden <= y *a;

    assuming x,y,a and b are declared signed/unsigned instead of std_logic_vector.

    --- Quote End ---

    thank you,

    but i must use std_logic... so.. is there possibility to change the signal pnum e pden that is the result of moltiplication?

    if i pass the values a,b,x,y when the program go out of the process.. and i use the component like i post here...

    ARCHITECTURE flex OF add_sum IS

    SUBTYPE N1BIT IS STD_LOGIC_VECTOR(W1-1 DOWNTO 0);

    TYPE state_type is (somma,prodotto);

    SIGNAL stato: state_type :=prodotto;

    SIGNAL x : N1BIT;

    SIGNAL y : N1BIT;

    SIGNAL pnum : N1BIT; -- PRODUCT ARRAY numerator

    SIGNAL pden : N1BIT; -- PRODUCT ARRAY denumerat

    constant b : std_logic_VECTOR(W1-1 DOWNTO 0) := "00000000001";

    constant a : std_logic_VECTOR(W1-1 DOWNTO 0) := "00000000010";

    BEGIN

    sop: PROCESS (clk)

    BEGIN

    if (rising_edge(clk)) then

    case stato is

    when somma =>

    y<= pnum+pden;

    stato<=prodotto;

    when prodotto =>

    -- lpm_mult_ist1: lpm_mult(clock=>clk, dataa=>x, datab=>b, result =>pnum);

    -- lpm_mult_ist2: lpm_mult(clock=>clk, dataa=>y, datab=>a, result =>pden);

    stato<=somma;

    end case;

    end if;

    end process SOP;

    MulGen: FOR I IN 0 TO 1 GENERATE

    mymult1: lpm_mult --Moltiplicazione pnum(i)=c(i)*x

    GENERIC MAP (LPM_WIDTHA => W1, LPM_WIDTHB => W1,

    LPM_PIPELINE=>1,

    LPM_REPRESENTATION=>"SIGNED",

    LPM_WIDTHP =>W1,

    LPM_WIDTHS =>W1)

    PORT MAP (clock=>clk, dataa=>x, datab=>b, result =>pnum);

    END GENERATE;

    -- ISTANTIATE L PIPELINED MULTIPLIER DENUM

    MulGen2: FOR K IN 0 TO 1 generate --Moltiplicazione pden(i)=a(i)*y(i))

    mymult2: lpm_mult

    generic MAP (LPM_WIDTHA => W1,

    LPM_WIDTHB => W1,

    LPM_PIPELINE=>1,

    LPM_REPRESENTATION=>"SIGNED",

    LPM_WIDTHP =>W1,

    LPM_WIDTHS =>W1)

    PORT MAP ( clock=>clk, dataa=>a, datab=>y, result =>pden);

    END generate;

    END FLEX;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    why are you now using a generate loop? you're trying to create 4 multipliers.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    why are you now using a generate loop? you're trying to create 4 multipliers.

    --- Quote End ---

    I haven't use a component before.. so i see an example in a book that use lpm.lpmmult to multiplie std_logic_vector.. so my input is std_logic_vector so i use this (component?! i think that generate.. generate components? is it ok?)

    so can you tell me how can multiply two std_logic_vector without this lpm.lpm_mult..

    with signed or unsigned there isn't this problem... so I wouldn't have written..

    my input must be std_logic_vector and my outoput too.

    So i haven't the knoledge of a designer of fpga because i'm only a student.. but if you want help me tell me how can resolve my problem..

    I must realiza a state machine

    in the first state(prodotto) i must do this operation pden=a*y and pnum=b*x, where a e b are costants of std_logic vector and x an input of std_logic_vector

    in the second state (somma) i must sum these y= pden+pnum...

    So.. the multipliers are only two...!

    I think that there is a possibility to pass argoment to a component out of the process and use this at the second moment (second clock) in my process.

    If you have same ideas.. thank!:o

    by enrico
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    you can convert std_logic_vector into signed or unsigned:

    my_us <= unsigned(my_input)

    but you could just declare my_input as unsigned in the first place (it means you have less type conversion)

    but if you really insist on keeping std_logic_vector:

    op <= std_logic_vector(unsigned(a) * unsigned(b) );

    the same for signed.

    std_logic_vector, signed and unsigned are basically all of the same type - an array of bits. But the numeric_std package defines arithmatic functions for signed and unsigned.

    I highly suggest you look for a VHDL tutorial. Altera provides them for free:

    http://www.altera.co.uk/education/training/courses/ohdl1110