head	1.4;
access;
symbols;
locks; strict;
comment	@# @;


1.4
date	2006.02.14.15.42.47;	author martin;	state dead;
branches;
next	1.3;
commitid	398143f1fa744567;

1.3
date	2006.02.13.22.51.43;	author martin;	state Exp;
branches;
next	1.2;
commitid	766743f10d704567;

1.2
date	2006.02.13.01.02.06;	author martin;	state Exp;
branches;
next	1.1;
commitid	5ccb43efda844567;

1.1
date	2006.02.12.22.12.42;	author martin;	state Exp;
branches;
next	;
commitid	306443efb2d94567;


desc
@@


1.4
log
@renamed to mac
@
text
@--
--	sc_mac16.vhd
--
--	A simple MAC unit with a SimpCon interface
--	
--	Author: Martin Schoeberl	martin@@jopdesign.com
--
--
--	resources on Cyclone
--
--		xx LCs, max xx MHz
--
--
--	2006-02-12	first version
--
--	todo:
--
--

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

LIBRARY lpm;
USE lpm.lpm_components.all;

entity mac is

port (
	clk		: in std_logic;
	reset	: in std_logic;

-- SimpCon interface

	opa, opb	: in std_logic_vector(31 downto 0);
	start		: in std_logic;
	clear		: in std_logic;
	result		: out std_logic_vector(63 downto 0)
);
end mac;

architecture rtl of mac is

	SIGNAL sub_wire0	: STD_LOGIC_VECTOR (63 DOWNTO 0);

	COMPONENT lpm_mult
	GENERIC (
		lpm_hint		: STRING;
		lpm_pipeline		: NATURAL;
		lpm_representation		: STRING;
		lpm_type		: STRING;
		lpm_widtha		: NATURAL;
		lpm_widthb		: NATURAL;
		lpm_widthp		: NATURAL;
		lpm_widths		: NATURAL
	);
	PORT (
			dataa	: IN STD_LOGIC_VECTOR (31 DOWNTO 0);
			datab	: IN STD_LOGIC_VECTOR (31 DOWNTO 0);
			clock	: IN STD_LOGIC ;
			result	: OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
	);
	END COMPONENT;

	type state_type		is (idle, mul, add);
	signal state 		: state_type;

	signal cnt			: unsigned(5 downto 0);

	signal mul_res		: unsigned(63 downto 0);
	signal acc			: unsigned(63 downto 0);

begin


	lpm_mult_component : lpm_mult
	GENERIC MAP (
		lpm_hint => "MAXIMIZE_SPEED=5",
		lpm_pipeline => 16,
		lpm_representation => "SIGNED",
		lpm_type => "LPM_MULT",
		lpm_widtha => 32,
		lpm_widthb => 32,
		lpm_widthp => 64,
		lpm_widths => 1
	)
	PORT MAP (
		dataa => opa,
		datab => opb,
		clock => clk,
		result => sub_wire0
	);

	mul_res <= unsigned(sub_wire0);



process(clk, reset)

begin
	if reset='1' then
		acc <= (others => '0');

	elsif rising_edge(clk) then

		case state is

			when idle =>
				if start='1' then
					state <= mul;
					cnt <= "010010";	-- for shure
				end if;

			when mul =>
				cnt <= cnt-1;
				if cnt=0 then
					state <= add;
				end if;

			when add =>
				acc <= acc + mul_res;
				state <= idle;
				
		end case;

		if clear='1' then
			acc <= (others => '0');
		end if;

	end if;

	result <= std_logic_vector(acc);

end process;
	
end rtl;


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity sc_mac16 is
generic (addr_bits : integer);

port (
	clk		: in std_logic;
	reset	: in std_logic;

-- SimpCon interface

	address		: in std_logic_vector(addr_bits-1 downto 0);
	wr_data		: in std_logic_vector(31 downto 0);
	rd, wr		: in std_logic;
	rd_data		: out std_logic_vector(31 downto 0);
	rdy_cnt		: out unsigned(1 downto 0)

);
end sc_mac16;

architecture rtl of sc_mac16 is

	signal opa, opb		: std_logic_vector(31 downto 0);
	signal result		: std_logic_vector(63 downto 0);

	signal start		: std_logic;
	signal clear		: std_logic;

begin

	rdy_cnt <= "00";	-- no wait states, we are hopefully fast enough

	cm: entity work.mac
		port map(
			clk => clk,
			reset => reset,

			opa => opa,
			opb => opb,
			start => start,
			clear => clear,
			result => result
	);

--
--	SimpCon read and write
--
process(clk, reset)

begin

	if reset='1' then
		rd_data <= (others => '0');

	elsif rising_edge(clk) then

		start <= '0';
		if wr='1' then
			if address(0)='0' then
				opa <= wr_data;
			else
				opb <= wr_data;
				start <= '1';
			end if;
		end if;

		-- get MAC result and clear the accumulator
		clear <= '0';
		if rd='1' then
			if address(0)='0' then
				rd_data <= result(31 downto 0);
			else
				rd_data <= result(63 downto 32);
				clear <= '1';
			end if;
		end if;

	end if;
end process;


end rtl;
@


1.3
log
@32x32 MAC
@
text
@@


1.2
log
@8 bit MAC
@
text
@d20 118
d163 2
a164 3
	signal opds			: std_logic_vector(31 downto 0);
	signal res			: unsigned(31 downto 0);
	signal mac			: unsigned(31 downto 0);
d166 2
a167 2
	type state_type		is (idle, mul, add);
	signal state 		: state_type;
d173 12
d192 1
a192 3
	if (reset='1') then
		opds <= (others => '0');
		mac <= (others => '0');
d197 1
d199 6
a204 1
			opds <= wr_data;
d208 1
d210 6
a215 2
			rd_data <= std_logic_vector(mac);
			mac <= (others => '0');
a217 18
		case state is

			when idle =>
				if wr='1' then
					state <= mul;
				end if;

			when mul =>
res(31 downto 16) <= (others => '0');
				res(15 downto 0) <= unsigned(opds(23 downto 16)) * unsigned(opds(7 downto 0));
				state <= add;

			when add =>
				mac <= mac + res;
				state <= idle;
				
		end case;

@


1.1
log
@simple MAC unit on SimpCon bus
@
text
@a78 1
	end if;
d80 1
a80 1
	case state is
d82 13
a94 12
		when idle =>
			if wr='1' then
				state <= mul;
			end if;

		when mul =>
			res <= unsigned(opds(31 downto 16)) * unsigned(opds(15 downto 0));
			state <= add;

		when add =>
			mac <= mac + res;
			state <= idle;
d96 1
a96 1
	end case;
d98 1
@

