+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 10 of 20
Discuss VHDL Component: Wallace Tree Multiplier (Generic) at the VHDL within the OpenHDL - Verilog and VHDL Discussion Forums; Hi everyone! Today, I'm going to illustrate the construction and VHDL code of a generic ...
  1. #1
    Administrator
    Join Date
    Oct 2011
    Posts
    69
    Blog Entries
    19

    Default VHDL Component: Wallace Tree Multiplier (Generic)

    Hi everyone!

    Today, I'm going to illustrate the construction and VHDL code of a generic coded Wallace tree multiplier. The Wallace tree multiplier is not necessarily faster than other multiplier designs, particularly in an FPGA but does result in a small number of layers needed to compute the sum of the partial products.

    The Wallace tree has a 3-step algorithm:

    1. Multiply (i.e. AND) each bit of one of the arguments, by each bit of the other, yielding n^2 results.
    2. Reduce the number of partial products to two by layers of full and half adders.
    3. Group the wires in two numbers, and add them with a conventional adder.


    To reduce the number of partial products, we maximize the number of 3:2 and 2:2 (i.e. full and half adders respectively) that we can bit along a set of weights. Weights are define the relative alignment of a bit with respect to the other partial products. For every 3:2 and 2:2 compressor, the sum bit is fed into the next layer of the same weight and the carry bit is fed into the next highest weight of the next layer. If only 1 bit remains in the weight for that layer, pass it up to the same weight in the next layer. Here's a look at the structure of an 8x8 multiplier and the resulting Wallace tree reduction on the initial 8 partial products.



    Notice the reduction in using compressors from layer to layer. The construction of a generic version of the Wallace tree multiplier can be tricky, so here's a look at the VHDL code. Take some time to look at how a set of recursive VHDL functions can cue the tree process on how many compressors to insert at each layer.

    VHDL Code:
    1. LIBRARY ieee;
    2. USE ieee.std_logic_1164.all;
    3.  
    4. PACKAGE my_funs IS
    5. FUNCTION clogb2 (a: NATURAL) RETURN NATURAL;
    6. FUNCTION prev_lvl_carry (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL;
    7. FUNCTION this_lvl_bits (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL;
    8. FUNCTION num_full_adders (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL;
    9. FUNCTION num_half_adders (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL;
    10. END my_funs;
    11.  
    12. PACKAGE BODY my_funs IS
    13. FUNCTION clogb2 (a: NATURAL) RETURN NATURAL IS
    14. VARIABLE aggregate : NATURAL := a;
    15. VARIABLE return_val : NATURAL := 0;
    16. BEGIN
    17. compute_clogb2:
    18. FOR i IN a DOWNTO 0 LOOP
    19.  
    20. IF aggregate > 0 THEN
    21. return_val := return_val + 1;
    22. END IF;
    23.  
    24. aggregate := aggregate / 2;
    25. END LOOP;
    26.  
    27. RETURN return_val;
    28.  
    29. END clogb2;
    30.  
    31. FUNCTION prev_lvl_carry (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL IS
    32. VARIABLE this_weight_base_bits: NATURAL := 0;
    33. VARIABLE this_num_bits: NATURAL := 0;
    34. VARIABLE num_carry: NATURAL := 0;
    35. BEGIN
    36. IF this_weight > (width-1) THEN
    37. IF this_weight = 2*width-1 THEN
    38. this_weight_base_bits := 1;
    39. ELSIF this_weight = width THEN
    40. this_weight_base_bits := 2*width-this_weight;
    41. ELSE
    42. this_weight_base_bits := 2*width-this_weight-1;
    43. END IF;
    44. ELSE
    45. this_weight_base_bits := this_weight+1;
    46. END IF;
    47.  
    48. IF this_lvl > 0 THEN -- Recursive case
    49. IF this_weight > 0 THEN
    50. this_num_bits := this_lvl_bits(width,this_weight-1,this_lvl-1);
    51. num_carry := this_num_bits/3;
    52. num_carry := num_carry + (this_num_bits-num_carry*3)/2;
    53. ELSE
    54. num_carry := 0;
    55. END IF;
    56. ELSE
    57. num_carry := this_weight_base_bits/3;
    58. num_carry := num_carry + (this_weight_base_bits-num_carry*3)/2;
    59. END IF;
    60.  
    61. RETURN num_carry;
    62. END prev_lvl_carry;
    63.  
    64. FUNCTION this_lvl_bits (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL IS
    65. VARIABLE this_weight_base_bits: NATURAL := 0;
    66. VARIABLE prev_lvl_bits: NATURAL := 0;
    67. VARIABLE full_adder_sums: NATURAL := 0;
    68. VARIABLE half_adder_sums: NATURAL := 0;
    69. VARIABLE this_num_bits: NATURAL := 0;
    70. BEGIN
    71. IF this_weight > (width-1) THEN
    72. IF this_weight = 2*width-1 THEN
    73. this_weight_base_bits := 1;
    74. ELSIF this_weight = width THEN
    75. this_weight_base_bits := 2*width-this_weight;
    76. ELSE
    77. this_weight_base_bits := 2*width-this_weight-1;
    78. END IF;
    79. ELSE
    80. this_weight_base_bits := this_weight+1;
    81. END IF;
    82.  
    83. IF this_lvl > 0 THEN -- Recursive case
    84. IF this_weight > 0 THEN
    85. prev_lvl_bits := this_lvl_bits(width,this_weight,this_lvl-1);
    86. full_adder_sums := prev_lvl_bits/3;
    87. half_adder_sums := (prev_lvl_bits-full_adder_sums*3)/2;
    88. this_num_bits := prev_lvl_bits - 2*full_adder_sums- half_adder_sums + prev_lvl_carry(width,this_weight,this_lvl);
    89. ELSE
    90. this_num_bits := this_lvl_bits(width,this_weight,this_lvl-1);
    91. END IF;
    92. ELSE
    93. this_num_bits := this_weight_base_bits;
    94. END IF;
    95.  
    96. RETURN this_num_bits;
    97. END this_lvl_bits;
    98.  
    99. FUNCTION num_full_adders (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL IS
    100. VARIABLE this_num_bits: INTEGER := this_lvl_bits(width,this_weight,this_lvl);
    101. BEGIN
    102. RETURN (this_num_bits/3);
    103. END num_full_adders;
    104.  
    105. FUNCTION num_half_adders (width: NATURAL; this_weight: NATURAL; this_lvl: NATURAL) RETURN NATURAL IS
    106. VARIABLE this_num_bits: INTEGER := this_lvl_bits(width,this_weight,this_lvl);
    107. VARIABLE num_full_adds: INTEGER := 0;
    108. BEGIN
    109. num_full_adds := this_num_bits/3;
    110. RETURN ((this_num_bits-num_full_adds*3)/2);
    111. END num_half_adders;
    112. END my_funs;
    113.  
    114. LIBRARY ieee;
    115. USE ieee.std_logic_1164.all;
    116. USE work.my_funs.all;
    117.  
    118. ENTITY wallace_mult IS
    119. GENERIC (
    120. width : INTEGER := 4
    121. );
    122. PORT (
    123. a : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    124. b : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    125. prod : OUT STD_LOGIC_VECTOR(2*width-1 DOWNTO 0)
    126. );
    127. END wallace_mult;
    128.  
    129. ARCHITECTURE behavioral OF wallace_mult IS
    130. TYPE layer_depth_type IS ARRAY(32 DOWNTO 3) OF INTEGER;
    131. CONSTANT layer_depth: layer_depth_type := (9,9,9,8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,6 ,5,5,4,3,3);
    132. CONSTANT stages: INTEGER := layer_depth(width);
    133. TYPE W_type IS ARRAY(2*width-1 DOWNTO 0, width-1 DOWNTO 0, stages-1 DOWNTO 0) OF STD_LOGIC;
    134. TYPE P_type IS ARRAY(width-1 DOWNTO 0, width-1 DOWNTO 0) OF STD_LOGIC;
    135. SIGNAL P: P_type; -- Initial product tree
    136. SIGNAL W: W_type; -- Wallace tree
    137. SIGNAL add_a, add_b, add_sum: STD_LOGIC_VECTOR(2*width-1 DOWNTO 0);
    138. SIGNAL c_in: STD_LOGIC := '0';
    139.  
    140. COMPONENT bk_adder
    141. GENERIC (
    142. width : INTEGER := 4
    143. );
    144. PORT (
    145. a : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    146. b : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    147. c_in : IN STD_LOGIC;
    148. sum : OUT STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    149. c_out : OUT STD_LOGIC
    150. );
    151. END COMPONENT;
    152.  
    153. BEGIN
    154.  
    155. partial_proc: PROCESS(a,b)
    156. BEGIN
    157. FOR i IN width-1 DOWNTO 0 LOOP
    158. FOR j IN width-1 DOWNTO 0 LOOP
    159. P(i,j) <= a(i) AND b(j);
    160. END LOOP;
    161. END LOOP;
    162. END PROCESS;
    163.  
    164. wallace_proc: PROCESS(W,P)
    165. VARIABLE this_carry_bits: NATURAL := 0;
    166. VARIABLE num_full_adds: NATURAL := 0;
    167. VARIABLE num_half_adds: NATURAL := 0;
    168. VARIABLE num_wires: NATURAL := 0;
    169. BEGIN
    170. W(2*width-1,0,0) <= '1'; -- Extended sign bit
    171. W(width,width-1,0) <= '1'; -- Sign bit
    172. FOR i IN 2*width-2 DOWNTO 0 LOOP
    173. IF i <= (width-1) THEN
    174. FOR j IN i DOWNTO 0 LOOP
    175. IF (j = width-1) XOR (i-j = width-1) THEN
    176. W(i,j,0) <= NOT(P(j,i-j));
    177. ELSE
    178. W(i,j,0) <= P(j,i-j);
    179. END IF;
    180. END LOOP;
    181. ELSE
    182. FOR j IN width-1 DOWNTO i-width+1 LOOP
    183. IF (j = width-1) XOR (i-j = width-1) THEN
    184. W(i,j-i+width-1,0) <= NOT(P(j,i-j));
    185. ELSE
    186. W(i,j-i+width-1,0) <= P(j,i-j);
    187. END IF;
    188. END LOOP;
    189. END IF;
    190. END LOOP;
    191.  
    192. FOR k IN 0 TO stages-2 LOOP
    193. FOR i IN 2*width-1 DOWNTO 0 LOOP
    194. this_carry_bits := prev_lvl_carry(width, i, k+1);
    195.  
    196. -- Full adders (3:2 Compressors)
    197. num_full_adds := num_full_adders(width,i,k);
    198. FOR j IN 0 TO num_full_adds-1 LOOP
    199. W(i,this_carry_bits+j,k+1) <= W(i,j*3,k) XOR W(i,j*3+1,k) XOR W(i,j*3+2,k);
    200. IF i < 2*width-1 THEN
    201. W(i+1,j,k+1) <= (W(i,j*3,k) AND W(i,j*3+1,k)) XOR (W(i,j*3+2,k) AND (W(i,j*3,k) XOR W(i,j*3+1,k)));
    202. END IF;
    203. END LOOP;
    204.  
    205. -- Half adders (2:2 Compressors)
    206. num_half_adds := num_half_adders(width,i,k);
    207. FOR j IN 0 TO num_half_adds-1 LOOP
    208. W(i,this_carry_bits+num_full_adds+j,k+1) <= W(i,num_full_adds*3+j*2,k) XOR W(i,num_full_adds*3+j*2+1,k);
    209. IF i < 2*width-1 THEN
    210. W(i+1,num_full_adds+j,k+1) <= W(i,num_full_adds*3+j*2,k) AND W(i,num_full_adds*3+j*2+1,k);
    211. END IF;
    212. END LOOP;
    213.  
    214. -- Wires
    215. num_wires := this_lvl_bits(width,i,k)-num_full_adds*3-num_half_adds*2;
    216. FOR j IN 0 TO num_wires-1 LOOP
    217. W(i,this_carry_bits+num_full_adds+num_half_adds+j, k+1) <= W(i,num_full_adds*3+num_half_adds*2+j,k);
    218. END LOOP;
    219. END LOOP;
    220. END LOOP;
    221. END PROCESS;
    222.  
    223. -- Final Adder (Using a Brent Kung Adder)
    224. signal_vect_proc: PROCESS(W)
    225. BEGIN
    226. FOR i IN 2*width-1 DOWNTO 0 LOOP
    227. add_a(i) <= W(i,0,stages-1);
    228. add_b(i) <= W(i,1,stages-1);
    229. END LOOP;
    230. END PROCESS;
    231.  
    232. U_bk_add: bk_adder
    233. GENERIC MAP (
    234. width => 2*width
    235. )
    236. PORT MAP (
    237. a => add_a,
    238. b => add_b,
    239. c_in => c_in,
    240. sum => add_sum
    241. );
    242.  
    243. prod <= add_sum;
    244.  
    245. END behavioral;
    246.  
    247. LIBRARY ieee;
    248. USE ieee.std_logic_1164.all;
    249. USE work.my_funs.all;
    250.  
    251. ENTITY bk_adder IS
    252. GENERIC (
    253. width : INTEGER := 7
    254. );
    255. PORT (
    256. a : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    257. b : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    258. c_in : IN STD_LOGIC;
    259. sum : OUT STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    260. c_out : OUT STD_LOGIC
    261. );
    262. END bk_adder;
    263.  
    264. ARCHITECTURE behavioral OF bk_adder IS
    265. CONSTANT nn: INTEGER := clogb2(width);
    266. CONSTANT inv_nn: INTEGER := clogb2(width+2**(nn-2))-2;
    267. TYPE T_type IS ARRAY(nn+inv_nn-1 DOWNTO 0, width-1 DOWNTO 0) OF STD_LOGIC_VECTOR(1 DOWNTO 0);
    268. SIGNAL T: T_type;
    269. BEGIN
    270.  
    271. -- Carry tree with maximum number of stages
    272. tree_proc: PROCESS(T,a,b,c_in)
    273. BEGIN
    274. -- First bit is a full adder
    275. T(0,0)(0) <= (a(0) AND b(0)) OR (c_in AND (a(0) XOR b(0)));
    276. T(0,0)(1) <= a(0) XOR b(0) XOR c_in;
    277.  
    278. -- Leaves of tree
    279. FOR j IN width-1 DOWNTO 1 LOOP
    280. T(0,j)(0) <= a(j) AND b(j); -- Generate bit base
    281. T(0,j)(1) <= a(j) XOR b(j); -- Propagate bit base
    282. END LOOP;
    283.  
    284. -- Carry tree
    285. FOR i IN 1 TO nn-1 LOOP
    286. FOR j IN width-1 DOWNTO 0 LOOP
    287. IF(j mod 2**i = (2**i)-1) THEN
    288. IF((j-2**(i-1)) >= 0) THEN
    289. T(i,j)(0) <= (T(i-1,j)(1) AND T(i-1,j-2**(i-1))(0)) OR T(i-1,j)(0); -- G = (P_i and G_i_prev) or G_i
    290. T(i,j)(1) <= T(i-1,j)(1) AND T(i-1,j-2**(i-1))(1); -- P = P_i and P_i_prev
    291. ELSE
    292. T(i,j)(0) <= T(i-1,j)(0); -- G = G_i (since we are at tree's edge, there is no G_i_prev)
    293. T(i,j)(1) <= T(i-1,j)(1); -- P = P_i (since we are at tree's edge, there is no P_i_prev)
    294. END IF;
    295. ELSE
    296. T(i,j)(0) <= T(i-1,j)(0);
    297. T(i,j)(1) <= T(i-1,j)(1);
    298. END IF;
    299. END LOOP;
    300. END LOOP;
    301.  
    302. -- Inverse carry tree
    303. FOR i IN nn+inv_nn DOWNTO nn+1 LOOP
    304. FOR j IN width-1 DOWNTO 0 LOOP
    305. IF((j-2**(nn+inv_nn-(i))) mod 2**((nn+inv_nn-(i))+1) = 2**((nn+inv_nn-(i))+1)-1) THEN
    306. IF(j >= 2**(nn+inv_nn-i)) THEN
    307. T(i-1,j)(0) <= (T(i-2,j)(1) AND T(i-2,j-2**((nn+inv_nn-(i))))(0)) OR T(i-2,j)(0); -- G = (P_i and G_i_prev) or G_i
    308. T(i-1,j)(1) <= T(i-2,j)(1) AND T(i-2,j-2**((nn+inv_nn-(i))))(1); -- P = P_i and P_i_prev
    309. ELSE
    310. T(i-1,j)(0) <= T(i-2,j)(0);
    311. T(i-1,j)(1) <= T(i-2,j)(1);
    312. END IF;
    313. ELSE
    314. T(i-1,j)(0) <= T(i-2,j)(0);
    315. T(i-1,j)(1) <= T(i-2,j)(1);
    316. END IF;
    317. END LOOP;
    318. END LOOP;
    319. END PROCESS;
    320.  
    321. -- Basic summation for carry tree
    322. sum_proc: PROCESS(T)
    323. BEGIN
    324. sum(0) <= T(0,0)(1);
    325. FOR i IN width-1 DOWNTO 1 LOOP
    326. sum(i) <= T(0,i)(1) XOR T(nn+inv_nn-1,i-1)(0);
    327. END LOOP;
    328. END PROCESS;
    329.  
    330. c_out <= T(nn+inv_nn-1,width-1)(0) OR (T(nn+inv_nn-1,width-1)(1) AND T(nn+inv_nn-1,width-2)(0));
    331.  
    332. END behavioral;


    Note that this Wallace tree multiplier is set up as a combinational and signed operand multiplier. An unsigned synchronous and signed synchronous version of each is attached. Also, note that I have used a Brent-Kung Adder for the final partial sums that I previously discussed. Now, here's a test bench to verify proper function of the Wallace tree multiplier.

    VHDL Code:
    1. LIBRARY ieee;
    2. USE ieee.std_logic_1164.all;
    3. USE ieee.numeric_std.all;
    4. USE std.textio.all;
    5.  
    6. ENTITY wallace_mult_tb IS
    7. GENERIC (
    8. width: INTEGER := 11
    9. );
    10. END wallace_mult_tb;
    11.  
    12. ARCHITECTURE tb OF wallace_mult_tb IS
    13. SIGNAL t_a: STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    14. SIGNAL t_b: STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    15. SIGNAL t_p: STD_LOGIC_VECTOR(2*width-1 DOWNTO 0);
    16. SIGNAL t_clk: STD_LOGIC;
    17. SIGNAL t_reset: STD_LOGIC;
    18.  
    19. COMPONENT wallace_mult
    20. GENERIC (
    21. width : INTEGER := 4
    22. );
    23. PORT (
    24. a : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    25. b : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
    26. clk : IN STD_LOGIC;
    27. reset : IN STD_LOGIC;
    28. prod : OUT STD_LOGIC_VECTOR(2*width-1 DOWNTO 0)
    29. );
    30. END COMPONENT;
    31.  
    32. FUNCTION to_string(sv: Std_Logic_Vector) return string is
    33. USE Std.TextIO.all;
    34. USE ieee.std_logic_textio.all;
    35. VARIABLE lp: line;
    36. BEGIN
    37. write(lp, to_integer(unsigned(sv)));
    38. RETURN lp.all;
    39. END;
    40. BEGIN
    41. U_wallace_mult: wallace_mult
    42. GENERIC MAP (
    43. width => width
    44. )
    45. PORT MAP (
    46. a => t_a,
    47. b => t_b,
    48. clk => t_clk,
    49. reset => t_reset,
    50. prod => t_p
    51. );
    52.  
    53. -- Clock Process
    54. clk_prc: PROCESS
    55. BEGIN
    56. t_clk <= '0';
    57. WAIT FOR 5 ns;
    58. t_clk <= '1';
    59. WAIT FOR 5 ns;
    60. END PROCESS;
    61.  
    62. -- Input Processes
    63. inp_prc: PROCESS
    64. VARIABLE v_a: INTEGER := 0;
    65. VARIABLE v_b: INTEGER := 2**(width-1);
    66. BEGIN
    67. FOR i IN 0 TO 2**width LOOP
    68. WAIT FOR 10 ns;
    69. v_a := v_a + 1;
    70. v_b := v_b - i;
    71. t_a <= std_logic_vector(to_signed(v_a,width));
    72. t_b <= std_logic_vector(to_signed(v_b,width));
    73.  
    74. END LOOP;
    75. END PROCESS;
    76.  
    77. -- Reset Process
    78. rst_prc: PROCESS
    79. BEGIN
    80. t_reset <= '1';
    81. WAIT FOR 10 ns;
    82. t_reset <= '0';
    83. WAIT;
    84. END PROCESS;
    85.  
    86. END tb;


    And here's the output waveform:



    Next, let's take a look at the performance of a 16x16 bit (combinatorial!) version of this Wallace tree multiplier. Using Synplify Pro and choosing Xilinx Virtex2 XC2V40 with CS144 Package and -6 Speed yields the following performance data:


    Code:
    Performance Summary
    *******************
    
    
    Worst slack in design: -1.450
    
                       Requested     Estimated     Requested     Estimated                Clock        Clock                
    Starting Clock     Frequency     Frequency     Period        Period        Slack      Type         Group                
    ------------------------------------------------------------------------------------------------------------------------
    top|clk            108.6 MHz     93.8 MHz      9.207         10.657        -1.450     inferred     Autoconstr_clkgroup_0
    ========================================================================================================================
    
    ---------------------------------------
    Resource Usage Report for top
    
    Mapping to part: xc2v40cs144-6
    Cell usage:
    FD              128 uses
    MULT_AND        4 uses
    MUXCY           1 use
    MUXCY_L         4 uses
    MUXF5           2 uses
    XORCY           5 uses
    LUT1            1 use
    LUT2            228 uses
    LUT3            216 uses
    LUT4            476 uses
    
    I/O ports: 66
    I/O primitives: 64
    IBUF           32 uses
    OBUF           32 uses
    
    BUFGP          1 use
    
    Mapping Summary:
    Total  LUTs: 921 (179%)
    This 16x16 bit multiplier may be unsuitable for use in a high-speed FPGA application requiring many multipliers (that's when device specific multipliers should be used). However, a synchronous version of the multiplier (attached) may be useful for lower power and simpler devices that do not have multipliers built in. Here's a look at some layer and delay specifics for this particular multiplier implementation:



    The layer depth is charted out to 32 bit operands (you'll have to experiment yourself if you are interested in larger operands). The layer depth is a good indicator of how much delay the multiplier would have if it were placed in a pipelined situation. This implementation is "delay fat" so there are actual 2 additional delays on top of the layer depth. You are welcome to play with it to remove the input and output registers.

    Until next time!

    VHDL Coder
    Attached Images Attached Images    
    Attached Files Attached Files
    Last edited by VHDLCoder; 10-14-2011 at 07:14 PM.

  2. #2
    jeevitha
    Guest

    Default

    sir/mam, I need to do my project. im new to this dept vhdl n verilog n to wallace. i cudnt get the output for the above prog. In output the prod,add_a, sum is not produced...Can u pls explain me.. Thank u in advance..

  3. #3
    Administrator
    Join Date
    Oct 2011
    Posts
    69
    Blog Entries
    19

    Default

    Hi jeevitha,

    Thanks for trying out my wallace tree multiplier! Perhaps you have identified a bug. Can you explain what version of the code you used (i.e. signed, unsigned, or combinatorial signed)? Were you using the test bench from the original post? What software are you using to synthesize and simulate the multiplier? Are any other signals not working properly?

    Thanks!

    VHDLCoder

  4. #4
    jeevitha
    Guest

    Default

    hi
    Im using modelsim and xilinx in both i got the same result. In xilinx its mentioning as "Matrix not supported yet" for the W type array. in modelsim it dint show any error after simulation i dint get the output for add_b, add_sum, and the pro. The last three four bits are undefines inthem. i ve tried to trace the program but i couldnt succeed.
    Thank you .

  5. #5
    Administrator
    Join Date
    Oct 2011
    Posts
    69
    Blog Entries
    19

    Default

    Hi jeevitha,

    I may understand what is happening with the modelsim simulation. The multiplier has a separate entity called 'bk_adder' which is a type of carry tree adder to add the final two vectors of the Wallace carry save adder tree. Try compiling the wallace_mult and wallace_mult_tb first, then you may see a new entity 'bk_adder' appear in your workspace in ModelSim. Then, recompile all 3 entities and try the simulation again. I noticed that in the way the code is written, ModelSim may give the error:

    "** Warning: (vsim-3473) Component 'u_bk_add' is not bound."

    Recompiling again after compiling bk_adder will remedy this.

    As for the Xilinx ISE, you may need to adjust some of your compiler settings to get it to accept multi-dimensional arrays in VHDL.

    Good luck!

    VHDLCoder

  6. #6
    gorand2
    Guest

    Default Hi

    Hi VHDLCoder
    I have looked at wallace_mult_signed.vhd‎
    It seems that it always assumes one of the numbers is negative and the other positive, and doesn't work if this is not the case. Is that correct?
    Also i would like to ask if you know a book describing how to implement signed wallace tree multiplier.

  7. #7
    Administrator
    Join Date
    Oct 2011
    Posts
    69
    Blog Entries
    19

    Default

    Hi gorand2,

    The input process uses the "engineering approach" to signed binary multiplication that you can read more about at Wikipedia. Both multiplicands can be signed and here's a section of the simulation of the signed synchronous wallace tree multiplier implementation where the multiplicands are alternating negative and positive.

    Name:  wallace_neg.png
Views: 6697
Size:  95.3 KB

    I'd have to look through my material to see if there are any specific examples of implementing a Wallace tree multiplier. I am not sure if I have seen an example of one in a book.

    Hope that helps!

    VHDLCoder

  8. #8
    New Member
    Join Date
    Nov 2012
    Posts
    4

    Default

    sir i am trying to write vhdl code for logarithmic multiplier.. i am in need help in this

  9. #9
    Administrator
    Join Date
    Oct 2011
    Posts
    69
    Blog Entries
    19

    Default

    Hi devesh,

    Did you see my article for logarithms? You can find it here:

    http://www.openhdl.com/blogs/vhdlcod...hesizable.html

    Does that help? It will compute logarithms in VHDL given any base and any input of your desired size.

  10. #10
    New Member
    Join Date
    Dec 2012
    Posts
    4

    Default

    hello sir, i tried your generic modified wallace tree combinational multplier in xlinx ISE and i got the synthesised result but lots of warnings are coming, and in test bench it is not getting the exact output
    and we want to extend the length of the multplier for that we placed 8 in width of the above code, is it enough or any other changes to made?

 

 

Quick Reply Quick Reply

If you are already a member, please login above.

Please enter the six letters or digits that appear in the image opposite.


Posting Permissions

  • You may post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts
  •