Sample VHDL Code for use with Synplify Software This file contains VHDL code samples that infer the DSP block in the correct operation mode. Note: The syntax is slightly different for signed and unsigned representation. Important: Please see Altera AN 193: Design Guidelines for Using DSP Blocks in the Synplify Software for information on the latency or number of pipeline stages in the design passed on to the Quartus II software using the LPM_PIPELINE parameter. The sample VHDL code is in the following order: -- Unsigned Multiplication: a*b (Pipeline 0) -- Unsigned Multiplication: a*b (Pipeline 1) -- Unsigned Multiplication: a*b (Pipeline 2) -- Signed Multiplication: a*b (Pipeline 0) -- Signed Multiplication: a*b (Pipeline 1) -- Signed Multiplication: a*b (Pipeline 2) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 0) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 1) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 2) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 3) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 0) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 1) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 2) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 3) -- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 1) -- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 2) -- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 3) -- Signed ALTMULT_ACCUM: a*b + x (Pipeline 1) -- Signed ALTMULT_ACCUM: a*b + x (Pipeline 2) -- Signed ALTMULT_ACCUM: a*b + x (Pipeline 3) ----------------------------------------- Unsigned Multiplication: a*b (Pipeline 0) ----------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity unsigned_mult is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); result: out std_logic_vector (15 downto 0) ) ; end unsigned_mult; architecture rtl of unsigned_mult is signal a_int, b_int: unsigned (7 downto 0); signal pdt_int : unsigned (15 downto 0); --signal result_int: signed (15 downto 0); begin a_int <= unsigned (a); b_int <= unsigned (b); pdt_int <= a_int * b_int ; result <= std_logic_vector(pdt_int); end rtl; ----------------------------------------- Unsigned Multiplication: a*b (Pipeline 1) ----------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity signed_mult1 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ); end signed_mult1; architecture rtl of signed_mult1 is signal a_int, b_int : std_logic_vector (7 downto 0); signal pdt_int : unsigned (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; end if; end process; pdt_int <= unsigned(a_int) * unsigned(b_int); result <= std_logic_vector(pdt_int); end rtl; ----------------------------------------- Unsigned Multiplication: a*b (Pipeline 2) ----------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; module lpm_mult_8_inreg_pipereg_unsigned (out, clk, a, b); //Port Declarations output [15:0] out; input clk; input [7:0] a; input [7:0] b; //Register Declarations reg [7:0] a_reg; reg [7:0] b_reg; reg [15:0] out; //Wire Declarations wire [15:0] mult_out; assign mult_out = a_reg * b_reg; always@(posedge clk) begin a_reg <= a; b_reg <= b; out <= mult_out; end endmodule ----------------------------------------- Signed Multiplication: a*b (Pipeline 0) ----------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity multsigned is generic (size : integer := 4); port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); result: out std_logic_vector (15 downto 0) ); end multsigned; architecture rtl of multsigned is signal a_int, b_int, c_int, d_int : signed (7 downto 0); signal pdt_int : signed (15 downto 0); --signal result_int: signed (15 downto 0); begin a_int <= signed (a); b_int <= signed (b); pdt_int <= a_int * b_int; result <= std_logic_vector(pdt_int); end rtl; ----------------------------------------- Signed Multiplication: a*b (Pipeline 1) ----------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity signed_mult1 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0) ; clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ) ; end signed_mult1; architecture rtl of signed_mult1 is signal a_int, b_int : std_logic_vector (7 downto 0); signal pdt_int : signed (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; end if; end process; pdt_int <= signed(a_int) * signed(b_int); result <= std_logic_vector(pdt_int); end rtl; ----------------------------------------- Signed Multiplication: a*b (Pipeline 2) ----------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity signed_mult1 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ) ; end signed_mult1; architecture rtl of signed_mult1 is signal a_int, b_int : std_logic_vector (7 downto 0); signal pdt_int : signed (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; pdt_int <= signed(a_int) * signed(b_int); end if; end process; result <= std_logic_vector(pdt_int); end rtl; -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 0) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity unsignedmult_add is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); result: out std_logic_vector (15 downto 0) ) ; end unsignedmult_add; architecture rtl of unsignedmult_add is signal a_int, b_int, c_int, d_int : unsigned (7 downto 0); signal pdt_int, pdt2_int : unsigned (15 downto 0); signal result_int: unsigned (15 downto 0); begin a_int <= unsigned (a); b_int <= unsigned (b); c_int <= unsigned (c); d_int <= unsigned (d); pdt_int <= a_int * b_int; pdt2_int <= c_int * d_int; result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end rtl; -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 1) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity unsignedmult_add1 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ) ; end unsignedmult_add1; architecture rtl of unsignedmult_add1 is signal a_int, b_int, c_int, d_int : std_logic_vector (7 downto 0); signal pdt_int, pdt2_int: unsigned (15 downto 0); signal result_int: unsigned (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); c_int <= (others => '0'); d_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; c_int <= c; d_int <= d; end if; end process; pdt_int <= unsigned(a_int) * unsigned(b_int); pdt2_int <= unsigned(c_int) * unsigned(d_int); result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end rtl; -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 2) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity unsignedmult_add2 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ); end unsignedmult_add2; architecture rtl of unsignedmult_add2 is signal a_int, b_int, c_int, d_int : std_logic_vector (7 downto 0); signal pdt_int, pdt2_int: unsigned (15 downto 0); signal result_int: unsigned (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); c_int <= (others => '0'); d_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; c_int <= c; d_int <= d; pdt_int <= unsigned(a_int) * unsigned(b_int); pdt2_int <= unsigned(c_int) * unsigned(d_int); end if; end process; result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end rtl; -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 3) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity unsignedmult_add3 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ); end unsignedmult_add3; architecture rtl of unsignedmult_add3 is signal a_int, b_int, c_int, d_int : std_logic_vector (7 downto 0); signal pdt_int, pdt2_int: unsigned (15 downto 0); signal result_int: unsigned (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); c_int <= (others => '0'); d_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; c_int <= c; d_int <= d; pdt_int <= unsigned(a_int) * unsigned(b_int); pdt2_int <= unsigned(c_int) * unsigned(d_int); result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end if; end process; end rtl; -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 0) -------------------------------------------- library ieee ; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity signedmult_add is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); result: out std_logic_vector (15 downto 0) ) ; end signedmult_add; architecture rtl of signedmult_add is signal a_int, b_int, c_int, d_int : signed (7 downto 0); signal pdt_int, pdt2_int : signed (15 downto 0); signal result_int: signed (15 downto 0); begin a_int <= signed (a); b_int <= signed (b); c_int <= signed (c); d_int <= signed (d); pdt_int <= a_int * b_int; pdt2_int <= c_int * d_int; result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end rtl; -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 1) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity signedmult_add1 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ); end signedmult_add1; architecture rtl of signedmult_add1 is signal a_int, b_int, c_int, d_int : std_logic_vector (7 downto 0); signal pdt_int, pdt2_int: signed (15 downto 0); signal result_int: signed (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); c_int <= (others => '0'); d_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; c_int <= c; d_int <= d; end if; end process; pdt_int <= signed(a_int) * signed(b_int); pdt2_int <= signed(c_int) * signed(d_int); result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end rtl; -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 2) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity signedmult_add2 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ); end signedmult_add2; architecture rtl of signedmult_add2 is signal a_int, b_int, c_int, d_int : std_logic_vector (7 downto 0); signal pdt_int, pdt2_int: signed (15 downto 0); signal result_int: signed (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); c_int <= (others => '0'); d_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; c_int <= c; d_int <= d; pdt_int <= signed(a_int) * signed(b_int); pdt2_int <= signed(c_int) * signed(d_int); end if; end process; result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end rtl; -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 3) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity signedmult_add3 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); c: in std_logic_vector (7 downto 0); d: in std_logic_vector (7 downto 0); clk : in std_logic; aclr : in std_logic; result: out std_logic_vector (15 downto 0) ); end signedmult_add3; architecture rtl of signedmult_add3 is signal a_int, b_int, c_int, d_int : std_logic_vector (7 downto 0); signal pdt_int, pdt2_int: signed (15 downto 0); signal result_int: signed (15 downto 0); begin process (clk, aclr) begin if ( aclr = '1' ) then a_int <= (others => '0'); b_int <= (others => '0'); c_int <= (others => '0'); d_int <= (others => '0'); elsif (clk'event and clk = '1') then a_int <= a; b_int <= b; c_int <= c; d_int <= d; pdt_int <= signed(a_int) * signed(b_int); pdt2_int <= signed(c_int) * signed(d_int); result_int <= pdt_int + pdt2_int; result <= std_logic_vector(result_int); end if; end process; end rtl; -------------------------------------------- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 1) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity usigaltmult_accum1 is generic (size : integer := 4) ; port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; accum_out: inout std_logic_vector (15 downto 0) ); end usigaltmult_accum1; architecture synplify of usigaltmult_accum1 is signal a_int, b_int : unsigned (7 downto 0); signal pdt_int : unsigned (15 downto 0); signal adder_out : unsigned (15 downto 0); begin a_int <= unsigned (a); b_int <= unsigned (b); pdt_int <= a_int * b_int; adder_out <= pdt_int + unsigned(accum_out); process (clk) begin if (clk'event and clk = '1') then accum_out <= std_logic_vector (adder_out); end if; end process; end synplify; -------------------------------------------- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 2) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity usigaltmult_accum2 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; accum_out: inout std_logic_vector (15 downto 0) ) ; end usigaltmult_accum2; architecture rtl of usigaltmult_accum2 is signal a_int, b_int : unsigned (7 downto 0); signal pdt_int : unsigned (15 downto 0); signal adder_out : unsigned (15 downto 0); begin pdt_int <= a_int * b_int; adder_out <= pdt_int + unsigned(accum_out); process (clk) begin if (clk'event and clk = '1') then a_int <= unsigned(a); b_int <= unsigned(b); accum_out <= std_logic_vector (adder_out); end if; end process; end rtl; -------------------------------------------- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 3) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity usigaltmult_accum3 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; accum_out: inout std_logic_vector (15 downto 0) ); end usigaltmult_accum3; architecture rtl of usigaltmult_accum3 is signal a_int, b_int : unsigned (7 downto 0); signal pdt_int : unsigned (15 downto 0); signal adder_out : unsigned (15 downto 0); begin adder_out <= pdt_int + unsigned(accum_out); process (clk) begin if (clk'event and clk = '1') then a_int <= unsigned (a); b_int <= unsigned (b); pdt_int <= a_int * b_int; accum_out <= std_logic_vector (adder_out); end if; end process; end rtl; -------------------------------------------- Signed ALTMULT_ACCUM: a*b + x (Pipeline 1) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity sigaltmult_accum1 is generic (size : integer := 4) ; port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; accum_out: inout std_logic_vector (15 downto 0) ) ; end sigaltmult_accum1; architecture synplify of sigaltmult_accum1 is signal a_int, b_int : signed (7 downto 0); signal pdt_int : signed (15 downto 0); signal adder_out : signed (15 downto 0); begin a_int <= signed (a); b_int <= signed (b); pdt_int <= a_int * b_int; adder_out <= pdt_int + signed(accum_out); process (clk) begin if (clk'event and clk = '1') then accum_out <= std_logic_vector (adder_out); end if; end process; end synplify; -------------------------------------------- Signed ALTMULT_ACCUM: a*b + x (Pipeline 2) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity sigaltmult_accum2 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; accum_out: inout std_logic_vector (15 downto 0) ) ; end sigaltmult_accum2; architecture rtl of sigaltmult_accum2 is signal a_int, b_int : signed (7 downto 0); signal pdt_int : signed (15 downto 0); signal adder_out : signed (15 downto 0); begin pdt_int <= a_int * b_int; adder_out <= pdt_int + signed(accum_out); process (clk) begin if (clk'event and clk = '1') then a_int <= signed(a); b_int <= signed(b); accum_out <= std_logic_vector (adder_out); end if; end process; end rtl; -------------------------------------------- Signed ALTMULT_ACCUM: a*b + x (Pipeline 3) -------------------------------------------- library ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_signed.all; entity sigaltmult_accum3 is port ( a: in std_logic_vector (7 downto 0); b: in std_logic_vector (7 downto 0); clk : in std_logic; accum_out: inout std_logic_vector (15 downto 0) ) ; end sigaltmult_accum3; architecture rtl of sigaltmult_accum3 is signal a_int, b_int : signed (7 downto 0); signal pdt_int : signed (15 downto 0); signal adder_out : signed (15 downto 0); begin adder_out <= pdt_int + signed(accum_out); process (clk) begin if (clk'event and clk = '1') then a_int <= signed (a); b_int <= signed (b); pdt_int <= a_int * b_int; accum_out <= std_logic_vector (adder_out); end if; end process; end rtl;