16-07-2016, 07:47 PM
(This post was last modified: 16-07-2016, 07:48 PM by ppppenguin.)
Looked at the multiplier problem again. In VHDL you can just say PRODUCT <= A * B; and it will synthesise a mutliplier. No guarantees that it will be the best possible multiplier structure for the device or for your application. In a FPGA type device with dedicated multiplier hardware this usually works well, in a CPLD it completely blew the macrocell etc budget for reasons that are unknown and probably unknowable. The Coregen system that allows you to make mutlipliers and much else with good control over implementation isn't available for CPLDs. So it's DIY time. A bit like the old days in the 1990s when I desgined efficient multipliers from scratch to use in ancient FPGA families.
Mutliply is just a row of gated adders and simple shifts. This is 8 bit signed by 6 bit unsigned with only the top 8 output bits used. It took 57 macrocells which is affordable. Probably full of errors but it proves the concept will work. On this basis the whole design for a colour bar generator llooks feasible.
Mutliply is just a row of gated adders and simple shifts. This is 8 bit signed by 6 bit unsigned with only the top 8 output bits used. It took 57 macrocells which is affordable. Probably full of errors but it proves the concept will work. On this basis the whole design for a colour bar generator llooks feasible.
Code:
----------------------------------------------------------------------------------
-- Invotron router controller
-- Running on PLDkit XM2C2 module. Coolrunner-II XC2C384-7FT256
-- Multiplier for colour bars.
-- A is up to 8 bit signed multiplicand, B is up to 8 bit unsigned multiplier
-- Product is only 8 bit. Lower bits are truncated
-- 8x6 piped multiplier without B delay compensation uses 57 macrocells. Another 15 needed for B delays
-- 16/7/16: Ideas
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Allows use of Xilinx primitives
library UNISIM; use UNISIM.VComponents.all;
use USEFUL_FUNCTIONS.all; -- Useful functions such as "to_std_logic" (boolean to std_logic)
----------------------------------------------------------------------------------------------------------------------
-- START OF ENTITY
----------------------------------------------------------------------------------------------------------------------
entity multiplier is Port (
CK : in std_logic;
iMULTIPLICAND, iMULTIPLIER : in std_logic_vector(7 downto 0);
oPRODUCT : out std_logic_vector(7 downto 0));
end multiplier;
--===================================================================================================================
----------------------------------------------------------------------------------------------------------------------
-- START OF ARCHITECTURE
----------------------------------------------------------------------------------------------------------------------
architecture rtl of multiplier is
--------------------------------- Internal signals -------------------------------------------------------------------
signal PARTIAL0, PARTIAL1, PARTIAL2, PARTIAL3, PARTIAL4, PARTIAL5 : signed(7 downto 0);
signal A: signed(7 downto 0);
signal B: unsigned(5 downto 0);
--===================================================================================================================
--A is mutliplicand. 8 bit, 2's comp. Use SIGNED
--B is multiplier 6 bit, +ve Use UNSIGNED or SLV
-- Set of 6 conditional adders
-- B needs pipeline delays if stages are registered
-- Since low order products are not used there's no need for pipelines there
-- Can use mixture of registered and unregistered stages. Possibly 2 or 3 stages before register
-- Need to sort out shifts
begin
-- Assign inputs
A <= signed(iMULTIPLICAND);
B <= unsigned(iMULTIPLIER(5 downto 0));
process (CK) begin
if rising_edge(CK) then
-- First stage is just a set of AND gates
if B(0) = '1' then PARTIAL0 <= A;
else PARTIAL0 <= X"00";
end if;
-- Shift with sign extension
if B(1) = '1' then PARTIAL1 <= (PARTIAL0(7) & PARTIAL0(7 downto 1)) + A;
else PARTIAL1 <= (PARTIAL0(7) & PARTIAL0(7 downto 1));
end if;
if B(2) = '1' then PARTIAL2 <= (PARTIAL1(7) & PARTIAL1(7 downto 1)) + A;
else PARTIAL2 <= (PARTIAL1(7) & PARTIAL1(7 downto 1));
end if;
if B(3) = '1' then PARTIAL3 <= (PARTIAL2(7) & PARTIAL2(7 downto 1)) + A;
else PARTIAL3 <= (PARTIAL2(7) & PARTIAL2(7 downto 1));
end if;
if B(4) = '1' then PARTIAL4 <= (PARTIAL3(7) & PARTIAL3(7 downto 1)) + A;
else PARTIAL4 <= (PARTIAL3(7) & PARTIAL3(7 downto 1));
end if;
if B(5) = '1' then PARTIAL5 <= (PARTIAL4(7) & PARTIAL4(7 downto 1)) + A;
else PARTIAL5 <= (PARTIAL4(7) & PARTIAL4(7 downto 1));
end if;
end if; -- CK
end process;
-- Assign output
oPRODUCT <= std_logic_vector(PARTIAL5);
--===================================================================================================================
end rtl;
www.borinsky.co.uk Jeffrey Borinsky www.becg.tv







