--
|
--
|
|
--
|
|
-- This file is a part of JOP, the Java Optimized Processor
|
|
--
|
|
-- Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
|
|
--
|
|
-- This program is free software: you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published by
|
|
-- the Free Software Foundation, either version 3 of the License, or
|
|
-- (at your option) any later version.
|
|
--
|
|
-- This program is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
-- GNU General Public License for more details.
|
|
--
|
|
-- You should have received a copy of the GNU General Public License
|
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
--
|
|
|
|
|
|
--
|
-- sc_mac.vhd
|
-- sc_mac.vhd
|
--
|
--
|
-- A simple MAC unit with a SimpCon interface
|
-- A simple MAC unit with a SimpCon interface
|
--
|
--
|
-- Author: Martin Schoeberl martin@jopdesign.com
|
-- Author: Martin Schoeberl martin@jopdesign.com
|
--
|
--
|
--
|
--
|
-- resources on Cyclone
|
-- resources on Cyclone
|
--
|
--
|
-- xx LCs, max xx MHz
|
-- xx LCs, max xx MHz
|
--
|
--
|
--
|
--
|
-- 2006-02-12 first version
|
-- 2006-02-12 first version
|
--
|
--
|
-- todo:
|
-- todo:
|
--
|
--
|
--
|
--
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
|
|
LIBRARY lpm;
|
LIBRARY lpm;
|
USE lpm.lpm_components.all;
|
USE lpm.lpm_components.all;
|
|
|
entity mac is
|
entity mac is
|
|
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
reset : in std_logic;
|
reset : in std_logic;
|
|
|
-- SimpCon interface
|
-- SimpCon interface
|
|
|
opa, opb : in std_logic_vector(31 downto 0);
|
opa, opb : in std_logic_vector(31 downto 0);
|
start : in std_logic;
|
start : in std_logic;
|
clear : in std_logic;
|
clear : in std_logic;
|
result : out std_logic_vector(63 downto 0)
|
result : out std_logic_vector(63 downto 0)
|
);
|
);
|
end mac;
|
end mac;
|
|
|
architecture rtl of mac is
|
architecture rtl of mac is
|
|
|
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (63 DOWNTO 0);
|
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (63 DOWNTO 0);
|
|
|
COMPONENT lpm_mult
|
COMPONENT lpm_mult
|
GENERIC (
|
GENERIC (
|
lpm_hint : STRING;
|
lpm_hint : STRING;
|
lpm_pipeline : NATURAL;
|
lpm_pipeline : NATURAL;
|
lpm_representation : STRING;
|
lpm_representation : STRING;
|
lpm_type : STRING;
|
lpm_type : STRING;
|
lpm_widtha : NATURAL;
|
lpm_widtha : NATURAL;
|
lpm_widthb : NATURAL;
|
lpm_widthb : NATURAL;
|
lpm_widthp : NATURAL;
|
lpm_widthp : NATURAL;
|
lpm_widths : NATURAL
|
lpm_widths : NATURAL
|
);
|
);
|
PORT (
|
PORT (
|
dataa : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
|
dataa : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
|
datab : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
|
datab : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
|
clock : IN STD_LOGIC ;
|
clock : IN STD_LOGIC ;
|
result : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
|
result : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
|
);
|
);
|
END COMPONENT;
|
END COMPONENT;
|
|
|
type state_type is (idle, mul, add);
|
type state_type is (idle, mul, add);
|
signal state : state_type;
|
signal state : state_type;
|
|
|
signal cnt : unsigned(5 downto 0);
|
signal cnt : unsigned(5 downto 0);
|
|
|
signal mul_res : unsigned(63 downto 0);
|
signal mul_res : unsigned(63 downto 0);
|
signal acc : unsigned(63 downto 0);
|
signal acc : unsigned(63 downto 0);
|
|
|
begin
|
begin
|
|
|
|
|
lpm_mult_component : lpm_mult
|
lpm_mult_component : lpm_mult
|
GENERIC MAP (
|
GENERIC MAP (
|
lpm_hint => "MAXIMIZE_SPEED=5",
|
lpm_hint => "MAXIMIZE_SPEED=5",
|
lpm_pipeline => 16,
|
lpm_pipeline => 16,
|
lpm_representation => "SIGNED",
|
lpm_representation => "SIGNED",
|
lpm_type => "LPM_MULT",
|
lpm_type => "LPM_MULT",
|
lpm_widtha => 32,
|
lpm_widtha => 32,
|
lpm_widthb => 32,
|
lpm_widthb => 32,
|
lpm_widthp => 64,
|
lpm_widthp => 64,
|
lpm_widths => 1
|
lpm_widths => 1
|
)
|
)
|
PORT MAP (
|
PORT MAP (
|
dataa => opa,
|
dataa => opa,
|
datab => opb,
|
datab => opb,
|
clock => clk,
|
clock => clk,
|
result => sub_wire0
|
result => sub_wire0
|
);
|
);
|
|
|
mul_res <= unsigned(sub_wire0);
|
mul_res <= unsigned(sub_wire0);
|
|
|
|
|
|
|
process(clk, reset)
|
process(clk, reset)
|
|
|
begin
|
begin
|
if reset='1' then
|
if reset='1' then
|
acc <= (others => '0');
|
acc <= (others => '0');
|
|
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
|
|
case state is
|
case state is
|
|
|
when idle =>
|
when idle =>
|
if start='1' then
|
if start='1' then
|
state <= mul;
|
state <= mul;
|
cnt <= "010010"; -- for shure
|
cnt <= "010010"; -- for shure
|
end if;
|
end if;
|
|
|
when mul =>
|
when mul =>
|
cnt <= cnt-1;
|
cnt <= cnt-1;
|
if cnt=0 then
|
if cnt=0 then
|
state <= add;
|
state <= add;
|
end if;
|
end if;
|
|
|
when add =>
|
when add =>
|
acc <= acc + mul_res;
|
acc <= acc + mul_res;
|
state <= idle;
|
state <= idle;
|
|
|
end case;
|
end case;
|
|
|
if clear='1' then
|
if clear='1' then
|
acc <= (others => '0');
|
acc <= (others => '0');
|
end if;
|
end if;
|
|
|
end if;
|
end if;
|
|
|
result <= std_logic_vector(acc);
|
result <= std_logic_vector(acc);
|
|
|
end process;
|
end process;
|
|
|
end rtl;
|
end rtl;
|
|
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
|
|
entity sc_mac is
|
entity sc_mac is
|
generic (addr_bits : integer; scale : integer := 16);
|
generic (addr_bits : integer; scale : integer := 16);
|
|
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
reset : in std_logic;
|
reset : in std_logic;
|
|
|
-- SimpCon interface
|
-- SimpCon interface
|
|
|
address : in std_logic_vector(addr_bits-1 downto 0);
|
address : in std_logic_vector(addr_bits-1 downto 0);
|
wr_data : in std_logic_vector(31 downto 0);
|
wr_data : in std_logic_vector(31 downto 0);
|
rd, wr : in std_logic;
|
rd, wr : in std_logic;
|
rd_data : out std_logic_vector(31 downto 0);
|
rd_data : out std_logic_vector(31 downto 0);
|
rdy_cnt : out unsigned(1 downto 0)
|
rdy_cnt : out unsigned(1 downto 0)
|
|
|
);
|
);
|
end sc_mac;
|
end sc_mac;
|
|
|
architecture rtl of sc_mac is
|
architecture rtl of sc_mac is
|
|
|
signal opa, opb : std_logic_vector(31 downto 0);
|
signal opa, opb : std_logic_vector(31 downto 0);
|
signal result : std_logic_vector(63 downto 0);
|
signal result : std_logic_vector(63 downto 0);
|
|
|
signal start : std_logic;
|
signal start : std_logic;
|
signal clear : std_logic;
|
signal clear : std_logic;
|
|
|
begin
|
begin
|
|
|
rdy_cnt <= "00"; -- no wait states, we are hopefully fast enough
|
rdy_cnt <= "00"; -- no wait states, we are hopefully fast enough
|
|
|
cm: entity work.mac
|
cm: entity work.mac
|
port map(
|
port map(
|
clk => clk,
|
clk => clk,
|
reset => reset,
|
reset => reset,
|
|
|
opa => opa,
|
opa => opa,
|
opb => opb,
|
opb => opb,
|
start => start,
|
start => start,
|
clear => clear,
|
clear => clear,
|
result => result
|
result => result
|
);
|
);
|
|
|
--
|
--
|
-- SimpCon read and write
|
-- SimpCon read and write
|
--
|
--
|
process(clk, reset)
|
process(clk, reset)
|
|
|
begin
|
begin
|
|
|
if reset='1' then
|
if reset='1' then
|
rd_data <= (others => '0');
|
rd_data <= (others => '0');
|
|
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
|
|
start <= '0';
|
start <= '0';
|
if wr='1' then
|
if wr='1' then
|
if address(0)='0' then
|
if address(0)='0' then
|
opa <= wr_data;
|
opa <= wr_data;
|
else
|
else
|
opb <= wr_data;
|
opb <= wr_data;
|
start <= '1';
|
start <= '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
-- get MAC result scaled by 'scale' and clear the accumulator
|
-- get MAC result scaled by 'scale' and clear the accumulator
|
clear <= '0';
|
clear <= '0';
|
if rd='1' then
|
if rd='1' then
|
-- if address(0)='0' then
|
-- if address(0)='0' then
|
rd_data <= result(31+scale downto scale);
|
rd_data <= result(31+scale downto scale);
|
clear <= '1';
|
clear <= '1';
|
-- else
|
-- else
|
-- rd_data <= result(63 downto 32);
|
-- rd_data <= result(63 downto 32);
|
-- end if;
|
-- end if;
|
end if;
|
end if;
|
|
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
|
end rtl;
|
end rtl;
|
|
|