OpenCores
URL https://opencores.org/ocsvn/simpcon/simpcon/trunk

Subversion Repositories simpcon

[/] [simpcon/] [trunk/] [vhdl/] [sc_mac.vhd] - Blame information for rev 29

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 martin
--
2 29 martin
--
3
--  This file is a part of JOP, the Java Optimized Processor
4
--
5
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
6
--
7
--  This program is free software: you can redistribute it and/or modify
8
--  it under the terms of the GNU General Public License as published by
9
--  the Free Software Foundation, either version 3 of the License, or
10
--  (at your option) any later version.
11
--
12
--  This program is distributed in the hope that it will be useful,
13
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
--  GNU General Public License for more details.
16
--
17
--  You should have received a copy of the GNU General Public License
18
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
 
21
 
22
--
23 18 martin
--      sc_mac.vhd
24
--
25
--      A simple MAC unit with a SimpCon interface
26
--      
27
--      Author: Martin Schoeberl        martin@jopdesign.com
28
--
29
--
30
--      resources on Cyclone
31
--
32
--              xx LCs, max xx MHz
33
--
34
--
35
--      2006-02-12      first version
36
--
37
--      todo:
38
--
39
--
40
 
41
library ieee;
42
use ieee.std_logic_1164.all;
43
use ieee.numeric_std.all;
44
 
45
LIBRARY lpm;
46
USE lpm.lpm_components.all;
47
 
48
entity mac is
49
 
50
port (
51
        clk             : in std_logic;
52
        reset   : in std_logic;
53
 
54
-- SimpCon interface
55
 
56
        opa, opb        : in std_logic_vector(31 downto 0);
57
        start           : in std_logic;
58
        clear           : in std_logic;
59
        result          : out std_logic_vector(63 downto 0)
60
);
61
end mac;
62
 
63
architecture rtl of mac is
64
 
65
        SIGNAL sub_wire0        : STD_LOGIC_VECTOR (63 DOWNTO 0);
66
 
67
        COMPONENT lpm_mult
68
        GENERIC (
69
                lpm_hint                : STRING;
70
                lpm_pipeline            : NATURAL;
71
                lpm_representation              : STRING;
72
                lpm_type                : STRING;
73
                lpm_widtha              : NATURAL;
74
                lpm_widthb              : NATURAL;
75
                lpm_widthp              : NATURAL;
76
                lpm_widths              : NATURAL
77
        );
78
        PORT (
79
                        dataa   : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
80
                        datab   : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
81
                        clock   : IN STD_LOGIC ;
82
                        result  : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
83
        );
84
        END COMPONENT;
85
 
86
        type state_type         is (idle, mul, add);
87
        signal state            : state_type;
88
 
89
        signal cnt                      : unsigned(5 downto 0);
90
 
91
        signal mul_res          : unsigned(63 downto 0);
92
        signal acc                      : unsigned(63 downto 0);
93
 
94
begin
95
 
96
 
97
        lpm_mult_component : lpm_mult
98
        GENERIC MAP (
99
                lpm_hint => "MAXIMIZE_SPEED=5",
100
                lpm_pipeline => 16,
101
                lpm_representation => "SIGNED",
102
                lpm_type => "LPM_MULT",
103
                lpm_widtha => 32,
104
                lpm_widthb => 32,
105
                lpm_widthp => 64,
106
                lpm_widths => 1
107
        )
108
        PORT MAP (
109
                dataa => opa,
110
                datab => opb,
111
                clock => clk,
112
                result => sub_wire0
113
        );
114
 
115
        mul_res <= unsigned(sub_wire0);
116
 
117
 
118
 
119
process(clk, reset)
120
 
121
begin
122
        if reset='1' then
123
                acc <= (others => '0');
124
 
125
        elsif rising_edge(clk) then
126
 
127
                case state is
128
 
129
                        when idle =>
130
                                if start='1' then
131
                                        state <= mul;
132
                                        cnt <= "010010";        -- for shure
133
                                end if;
134
 
135
                        when mul =>
136
                                cnt <= cnt-1;
137
                                if cnt=0 then
138
                                        state <= add;
139
                                end if;
140
 
141
                        when add =>
142
                                acc <= acc + mul_res;
143
                                state <= idle;
144
 
145
                end case;
146
 
147
                if clear='1' then
148
                        acc <= (others => '0');
149
                end if;
150
 
151
        end if;
152
 
153
        result <= std_logic_vector(acc);
154
 
155
end process;
156
 
157
end rtl;
158
 
159
 
160
library ieee;
161
use ieee.std_logic_1164.all;
162
use ieee.numeric_std.all;
163
 
164
entity sc_mac is
165
generic (addr_bits : integer; scale : integer := 16);
166
 
167
port (
168
        clk             : in std_logic;
169
        reset   : in std_logic;
170
 
171
-- SimpCon interface
172
 
173
        address         : in std_logic_vector(addr_bits-1 downto 0);
174
        wr_data         : in std_logic_vector(31 downto 0);
175
        rd, wr          : in std_logic;
176
        rd_data         : out std_logic_vector(31 downto 0);
177
        rdy_cnt         : out unsigned(1 downto 0)
178
 
179
);
180
end sc_mac;
181
 
182
architecture rtl of sc_mac is
183
 
184
        signal opa, opb         : std_logic_vector(31 downto 0);
185
        signal result           : std_logic_vector(63 downto 0);
186
 
187
        signal start            : std_logic;
188
        signal clear            : std_logic;
189
 
190
begin
191
 
192
        rdy_cnt <= "00";        -- no wait states, we are hopefully fast enough
193
 
194
        cm: entity work.mac
195
                port map(
196
                        clk => clk,
197
                        reset => reset,
198
 
199
                        opa => opa,
200
                        opb => opb,
201
                        start => start,
202
                        clear => clear,
203
                        result => result
204
        );
205
 
206
--
207
--      SimpCon read and write
208
--
209
process(clk, reset)
210
 
211
begin
212
 
213
        if reset='1' then
214
                rd_data <= (others => '0');
215
 
216
        elsif rising_edge(clk) then
217
 
218
                start <= '0';
219
                if wr='1' then
220
                        if address(0)='0' then
221
                                opa <= wr_data;
222
                        else
223
                                opb <= wr_data;
224
                                start <= '1';
225
                        end if;
226
                end if;
227
 
228
                -- get MAC result scaled by 'scale' and clear the accumulator
229
                clear <= '0';
230
                if rd='1' then
231
--                      if address(0)='0' then
232
                                rd_data <= result(31+scale downto scale);
233
                                clear <= '1';
234
--                      else
235
--                              rd_data <= result(63 downto 32);
236
--                      end if;
237
                end if;
238
 
239
        end if;
240
end process;
241
 
242
 
243
end rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.