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

Subversion Repositories simpcon

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 martin
--
2
--      sc_mac.vhd
3
--
4
--      A simple MAC unit with a SimpCon interface
5
--      
6
--      Author: Martin Schoeberl        martin@jopdesign.com
7
--
8
--
9
--      resources on Cyclone
10
--
11
--              xx LCs, max xx MHz
12
--
13
--
14
--      2006-02-12      first version
15
--
16
--      todo:
17
--
18
--
19
 
20
library ieee;
21
use ieee.std_logic_1164.all;
22
use ieee.numeric_std.all;
23
 
24
LIBRARY lpm;
25
USE lpm.lpm_components.all;
26
 
27
entity mac is
28
 
29
port (
30
        clk             : in std_logic;
31
        reset   : in std_logic;
32
 
33
-- SimpCon interface
34
 
35
        opa, opb        : in std_logic_vector(31 downto 0);
36
        start           : in std_logic;
37
        clear           : in std_logic;
38
        result          : out std_logic_vector(63 downto 0)
39
);
40
end mac;
41
 
42
architecture rtl of mac is
43
 
44
        SIGNAL sub_wire0        : STD_LOGIC_VECTOR (63 DOWNTO 0);
45
 
46
        COMPONENT lpm_mult
47
        GENERIC (
48
                lpm_hint                : STRING;
49
                lpm_pipeline            : NATURAL;
50
                lpm_representation              : STRING;
51
                lpm_type                : STRING;
52
                lpm_widtha              : NATURAL;
53
                lpm_widthb              : NATURAL;
54
                lpm_widthp              : NATURAL;
55
                lpm_widths              : NATURAL
56
        );
57
        PORT (
58
                        dataa   : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
59
                        datab   : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
60
                        clock   : IN STD_LOGIC ;
61
                        result  : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
62
        );
63
        END COMPONENT;
64
 
65
        type state_type         is (idle, mul, add);
66
        signal state            : state_type;
67
 
68
        signal cnt                      : unsigned(5 downto 0);
69
 
70
        signal mul_res          : unsigned(63 downto 0);
71
        signal acc                      : unsigned(63 downto 0);
72
 
73
begin
74
 
75
 
76
        lpm_mult_component : lpm_mult
77
        GENERIC MAP (
78
                lpm_hint => "MAXIMIZE_SPEED=5",
79
                lpm_pipeline => 16,
80
                lpm_representation => "SIGNED",
81
                lpm_type => "LPM_MULT",
82
                lpm_widtha => 32,
83
                lpm_widthb => 32,
84
                lpm_widthp => 64,
85
                lpm_widths => 1
86
        )
87
        PORT MAP (
88
                dataa => opa,
89
                datab => opb,
90
                clock => clk,
91
                result => sub_wire0
92
        );
93
 
94
        mul_res <= unsigned(sub_wire0);
95
 
96
 
97
 
98
process(clk, reset)
99
 
100
begin
101
        if reset='1' then
102
                acc <= (others => '0');
103
 
104
        elsif rising_edge(clk) then
105
 
106
                case state is
107
 
108
                        when idle =>
109
                                if start='1' then
110
                                        state <= mul;
111
                                        cnt <= "010010";        -- for shure
112
                                end if;
113
 
114
                        when mul =>
115
                                cnt <= cnt-1;
116
                                if cnt=0 then
117
                                        state <= add;
118
                                end if;
119
 
120
                        when add =>
121
                                acc <= acc + mul_res;
122
                                state <= idle;
123
 
124
                end case;
125
 
126
                if clear='1' then
127
                        acc <= (others => '0');
128
                end if;
129
 
130
        end if;
131
 
132
        result <= std_logic_vector(acc);
133
 
134
end process;
135
 
136
end rtl;
137
 
138
 
139
library ieee;
140
use ieee.std_logic_1164.all;
141
use ieee.numeric_std.all;
142
 
143
entity sc_mac is
144
generic (addr_bits : integer; scale : integer := 16);
145
 
146
port (
147
        clk             : in std_logic;
148
        reset   : in std_logic;
149
 
150
-- SimpCon interface
151
 
152
        address         : in std_logic_vector(addr_bits-1 downto 0);
153
        wr_data         : in std_logic_vector(31 downto 0);
154
        rd, wr          : in std_logic;
155
        rd_data         : out std_logic_vector(31 downto 0);
156
        rdy_cnt         : out unsigned(1 downto 0)
157
 
158
);
159
end sc_mac;
160
 
161
architecture rtl of sc_mac is
162
 
163
        signal opa, opb         : std_logic_vector(31 downto 0);
164
        signal result           : std_logic_vector(63 downto 0);
165
 
166
        signal start            : std_logic;
167
        signal clear            : std_logic;
168
 
169
begin
170
 
171
        rdy_cnt <= "00";        -- no wait states, we are hopefully fast enough
172
 
173
        cm: entity work.mac
174
                port map(
175
                        clk => clk,
176
                        reset => reset,
177
 
178
                        opa => opa,
179
                        opb => opb,
180
                        start => start,
181
                        clear => clear,
182
                        result => result
183
        );
184
 
185
--
186
--      SimpCon read and write
187
--
188
process(clk, reset)
189
 
190
begin
191
 
192
        if reset='1' then
193
                rd_data <= (others => '0');
194
 
195
        elsif rising_edge(clk) then
196
 
197
                start <= '0';
198
                if wr='1' then
199
                        if address(0)='0' then
200
                                opa <= wr_data;
201
                        else
202
                                opb <= wr_data;
203
                                start <= '1';
204
                        end if;
205
                end if;
206
 
207
                -- get MAC result scaled by 'scale' and clear the accumulator
208
                clear <= '0';
209
                if rd='1' then
210
--                      if address(0)='0' then
211
                                rd_data <= result(31+scale downto scale);
212
                                clear <= '1';
213
--                      else
214
--                              rd_data <= result(63 downto 32);
215
--                      end if;
216
                end if;
217
 
218
        end if;
219
end process;
220
 
221
 
222
end rtl;

powered by: WebSVN 2.1.0

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