-- mul_ser_g.vhdl multiplier implemented as serial adds (one n bit adder) -- needs a generic adder called add_g, else fix to use another adder -- needs reg_g and mux_g or equivalent components in WORK -- this is for positive operands, use Booth multiplier for two's complement entity mul_ser_g is -- test bench constant left : natural := 15; -- word top bit constant prop : time := 100 ps; -- delay constant cleft : natural := 4; -- counter top bit end mul_ser_g; library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_textio.all; use STD.textio.all; architecture schematic of mul_ser_g is subtype word is std_logic_vector(left downto 0); signal md : word := (3=>'1', 0=>'1', others=>'0'); -- multiplier signal mc : word := (3=>'1',2=>'1',1=>'1',0=>'1',others=>'0');-- multiplicand signal hi : word; -- top register signal lo : word; -- bottom register signal cout : std_logic; -- adder carry out signal s : word := (others=>'0'); -- adder sum signal b : word := (others=>'0'); -- multiplexor output signal zero : word := (others=>'0'); signal clk : std_logic := '0'; -- system clock signal mulclk : std_logic := '0'; -- multiplier clock signal mulenb : std_logic := '1'; -- enable multiplication signal cntr : std_logic_vector(cleft downto 0) := (others=>'0'); -- counter signal czero : std_logic_vector(cleft downto 0) := (others=>'0'); signal stop : std_logic_vector(cleft downto 0) := (cleft=>'1', others=>'0'); signal load : std_logic := '1'; -- one shot signal sum_sh : word; -- dummy for wiring signal low_sh : word; -- dummy for wiring begin -- schematic -- multiplier structure, not a component! load <= '0' after 1 ps; clk <= not clk after 5 ns; -- 10 ns period cnt:entity WORK.cntr_g generic map(left=>cleft, prop=>200 ps) port map(clk, load, czero, cntr); mulenb <= '0' when cntr=stop; -- enable/disable multiply mulclk <= clk and mulenb after 50 ps; -- the multipliers "private" clock muxb: entity WORK.mux_g generic map(left, prop) port map(zero, md, lo(0), b); adder:entity WORK.add_g generic map(left, prop) port map(hi, b, '0', s, cout); muxs: sum_sh <= zero when cntr=czero else cout & s(left downto 1); rhi: entity WORK.reg_g generic map(left, prop) port map(mulclk, sum_sh, hi); muxl: low_sh <= mc when cntr=czero else s(0) & lo(left downto 1); rlo: entity WORK.reg_g generic map(left, prop) port map(mulclk, low_sh, lo); printout: postponed process(clk) -- just to see values variable my_line : LINE; -- not part of working circuit begin if clk='0' then -- quiet time, falling clock if cntr=czero then write(my_line, string'("md=")); write(my_line, md); write(my_line, string'(" mc=")); write(my_line, mc); writeline(output, my_line); end if; write(my_line, string'("at count ")); write(my_line, cntr); write(my_line, string'(" hi=")); write(my_line, hi); write(my_line, string'(" lo=")); write(my_line, lo); writeline(output, my_line); end if; end process printout; end schematic; -- of mul_ser_g