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

Subversion Repositories astron_multiplier

[/] [astron_multiplier/] [trunk/] [ip_stratixiv_complex_mult_rtl.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2009
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
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
LIBRARY IEEE;
23
USE IEEE.std_logic_1164.ALL;
24
USE IEEE.numeric_std.ALL;
25
 
26
--
27
-- Function: Signed complex multiply
28
--   p = a * b       when g_conjugate_b = FALSE
29
--     = (ar + j ai) * (br + j bi)
30
--     =  ar*br - ai*bi + j ( ar*bi + ai*br)
31
--
32
--   p = a * conj(b) when g_conjugate_b = TRUE
33
--     = (ar + j ai) * (br - j bi)
34
--     =  ar*br + ai*bi + j (-ar*bi + ai*br)
35
--
36
-- Architectures:
37
-- . rtl          : uses RTL to have all registers in one clocked process
38
-- . str          : uses two RTL instances of common_mult_add2 for out_pr and out_pi
39
-- . str_stratix4 : uses two Stratix4 instances of common_mult_add2 for out_pr and out_pi
40
-- . stratix4     : uses MegaWizard component from common_complex_mult(stratix4).vhd
41
-- . rtl_dsp      : uses RTL with one process (as in Altera example)
42
-- . altera_rtl   : uses RTL with one process (as in Altera example, by Raj R. Thilak)
43
--
44
-- Preferred architecture: 'str', see synth\quartus\common_top.vhd
45
 
46
ENTITY ip_stratixiv_complex_mult_rtl IS
47
  GENERIC (
48
    g_in_a_w           : POSITIVE;
49
    g_in_b_w           : POSITIVE;
50
    g_out_p_w          : POSITIVE;          -- default use g_out_p_w = g_in_a_w+g_in_b_w = c_prod_w
51
    g_conjugate_b      : BOOLEAN := FALSE;
52
    g_pipeline_input   : NATURAL := 1;      -- 0 or 1
53
    g_pipeline_product : NATURAL := 0;      -- 0 or 1
54
    g_pipeline_adder   : NATURAL := 1;      -- 0 or 1
55
    g_pipeline_output  : NATURAL := 1       -- >= 0
56
  );
57
  PORT (
58
    rst        : IN   STD_LOGIC := '0';
59
    clk        : IN   STD_LOGIC;
60
    clken      : IN   STD_LOGIC := '1';
61
    in_ar      : IN   STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0);
62
    in_ai      : IN   STD_LOGIC_VECTOR(g_in_a_w-1 DOWNTO 0);
63
    in_br      : IN   STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0);
64
    in_bi      : IN   STD_LOGIC_VECTOR(g_in_b_w-1 DOWNTO 0);
65
    result_re  : OUT  STD_LOGIC_VECTOR(g_out_p_w-1 DOWNTO 0);
66
    result_im  : OUT  STD_LOGIC_VECTOR(g_out_p_w-1 DOWNTO 0)
67
  );
68
END ip_stratixiv_complex_mult_rtl;
69
 
70
ARCHITECTURE str OF ip_stratixiv_complex_mult_rtl IS
71
 
72
  FUNCTION RESIZE_NUM(s : SIGNED; w : NATURAL) RETURN SIGNED IS
73
  BEGIN
74
    -- extend sign bit or keep LS part
75
    IF w>s'LENGTH THEN
76
      RETURN RESIZE(s, w);                    -- extend sign bit
77
    ELSE
78
      RETURN SIGNED(RESIZE(UNSIGNED(s), w));  -- keep LSbits (= vec[w-1:0])
79
    END IF;
80
  END;
81
 
82
  CONSTANT c_prod_w     : NATURAL := g_in_a_w+g_in_b_w;
83
  CONSTANT c_sum_w      : NATURAL := c_prod_w+1;
84
 
85
--  CONSTANT c_re_add_sub : STRING := sel_a_b(g_conjugate_b, "ADD", "SUB");
86
--  CONSTANT c_im_add_sub : STRING := sel_a_b(g_conjugate_b, "SUB", "ADD");
87
 
88
  -- registers
89
  SIGNAL reg_ar         : SIGNED(g_in_a_w-1 DOWNTO 0);
90
  SIGNAL reg_ai         : SIGNED(g_in_a_w-1 DOWNTO 0);
91
  SIGNAL reg_br         : SIGNED(g_in_b_w-1 DOWNTO 0);
92
  SIGNAL reg_bi         : SIGNED(g_in_b_w-1 DOWNTO 0);
93
  SIGNAL reg_prod_ar_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- re
94
  SIGNAL reg_prod_ai_bi : SIGNED(c_prod_w-1 DOWNTO 0);
95
  SIGNAL reg_prod_ai_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- im
96
  SIGNAL reg_prod_ar_bi : SIGNED(c_prod_w-1 DOWNTO 0);
97
  SIGNAL reg_sum_re     : SIGNED(c_sum_w-1 DOWNTO 0);
98
  SIGNAL reg_sum_im     : SIGNED(c_sum_w-1 DOWNTO 0);
99
  SIGNAL reg_result_re  : SIGNED(g_out_p_w-1 DOWNTO 0);
100
  SIGNAL reg_result_im  : SIGNED(g_out_p_w-1 DOWNTO 0);
101
 
102
  -- combinatorial
103
  SIGNAL nxt_ar         : SIGNED(g_in_a_w-1 DOWNTO 0);
104
  SIGNAL nxt_ai         : SIGNED(g_in_a_w-1 DOWNTO 0);
105
  SIGNAL nxt_br         : SIGNED(g_in_b_w-1 DOWNTO 0);
106
  SIGNAL nxt_bi         : SIGNED(g_in_b_w-1 DOWNTO 0);
107
  SIGNAL nxt_prod_ar_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- re
108
  SIGNAL nxt_prod_ai_bi : SIGNED(c_prod_w-1 DOWNTO 0);
109
  SIGNAL nxt_prod_ai_br : SIGNED(c_prod_w-1 DOWNTO 0);  -- im
110
  SIGNAL nxt_prod_ar_bi : SIGNED(c_prod_w-1 DOWNTO 0);
111
  SIGNAL nxt_sum_re     : SIGNED(c_sum_w-1 DOWNTO 0);
112
  SIGNAL nxt_sum_im     : SIGNED(c_sum_w-1 DOWNTO 0);
113
  SIGNAL nxt_result_re  : SIGNED(g_out_p_w-1 DOWNTO 0);
114
  SIGNAL nxt_result_im  : SIGNED(g_out_p_w-1 DOWNTO 0);
115
 
116
  -- the active signals
117
  SIGNAL ar             : SIGNED(g_in_a_w-1 DOWNTO 0);
118
  SIGNAL ai             : SIGNED(g_in_a_w-1 DOWNTO 0);
119
  SIGNAL br             : SIGNED(g_in_b_w-1 DOWNTO 0);
120
  SIGNAL bi             : SIGNED(g_in_b_w-1 DOWNTO 0);
121
  SIGNAL prod_ar_br     : SIGNED(c_prod_w-1 DOWNTO 0);  -- re
122
  SIGNAL prod_ai_bi     : SIGNED(c_prod_w-1 DOWNTO 0);
123
  SIGNAL prod_ai_br     : SIGNED(c_prod_w-1 DOWNTO 0);  -- im
124
  SIGNAL prod_ar_bi     : SIGNED(c_prod_w-1 DOWNTO 0);
125
  SIGNAL sum_re         : SIGNED(c_sum_w-1 DOWNTO 0);
126
  SIGNAL sum_im         : SIGNED(c_sum_w-1 DOWNTO 0);
127
 
128
BEGIN
129
 
130
  ------------------------------------------------------------------------------
131
  -- Registers
132
  ------------------------------------------------------------------------------
133
 
134
  -- Put all potential registers in a single process for optimal DSP inferrence
135
  -- Use rst only if it is supported by the DSP primitive, else leave it at '0'
136
  p_reg : PROCESS (rst, clk)
137
  BEGIN
138
    IF rising_edge(clk) THEN
139
      IF rst='1' THEN
140
        reg_ar         <= (OTHERS=>'0');
141
        reg_ai         <= (OTHERS=>'0');
142
        reg_br         <= (OTHERS=>'0');
143
        reg_bi         <= (OTHERS=>'0');
144
        reg_prod_ar_br <= (OTHERS=>'0');
145
        reg_prod_ai_bi <= (OTHERS=>'0');
146
        reg_prod_ai_br <= (OTHERS=>'0');
147
        reg_prod_ar_bi <= (OTHERS=>'0');
148
        reg_sum_re     <= (OTHERS=>'0');
149
        reg_sum_im     <= (OTHERS=>'0');
150
        reg_result_re  <= (OTHERS=>'0');
151
        reg_result_im  <= (OTHERS=>'0');
152
      ELSIF clken='1' THEN
153
        reg_ar         <= nxt_ar;          -- inputs
154
        reg_ai         <= nxt_ai;
155
        reg_br         <= nxt_br;
156
        reg_bi         <= nxt_bi;
157
        reg_prod_ar_br <= nxt_prod_ar_br;  -- products for re
158
        reg_prod_ai_bi <= nxt_prod_ai_bi;
159
        reg_prod_ai_br <= nxt_prod_ai_br;  -- products for im
160
        reg_prod_ar_bi <= nxt_prod_ar_bi;
161
        reg_sum_re     <= nxt_sum_re;      -- sum
162
        reg_sum_im     <= nxt_sum_im;
163
        reg_result_re  <= nxt_result_re;   -- result sum after optional register stage
164
        reg_result_im  <= nxt_result_im;
165
      END IF;
166
    END IF;
167
  END PROCESS;
168
 
169
  ------------------------------------------------------------------------------
170
  -- Inputs
171
  ------------------------------------------------------------------------------
172
 
173
  nxt_ar <= SIGNED(in_ar);
174
  nxt_ai <= SIGNED(in_ai);
175
  nxt_br <= SIGNED(in_br);
176
  nxt_bi <= SIGNED(in_bi);
177
 
178
  no_input_reg : IF g_pipeline_input=0 GENERATE   -- wired
179
    ar <= nxt_ar;
180
    ai <= nxt_ai;
181
    br <= nxt_br;
182
    bi <= nxt_bi;
183
  END GENERATE;
184
 
185
  gen_input_reg : IF g_pipeline_input>0 GENERATE  -- register input
186
    ar <= reg_ar;
187
    ai <= reg_ai;
188
    br <= reg_br;
189
    bi <= reg_bi;
190
  END GENERATE;
191
 
192
 
193
  ------------------------------------------------------------------------------
194
  -- Products
195
  ------------------------------------------------------------------------------
196
 
197
  nxt_prod_ar_br <= ar * br;  -- products for re
198
  nxt_prod_ai_bi <= ai * bi;
199
  nxt_prod_ai_br <= ai * br;  -- products for im
200
  nxt_prod_ar_bi <= ar * bi;
201
 
202
  no_product_reg : IF g_pipeline_product=0 GENERATE   -- wired
203
    prod_ar_br <= nxt_prod_ar_br;
204
    prod_ai_bi <= nxt_prod_ai_bi;
205
    prod_ai_br <= nxt_prod_ai_br;
206
    prod_ar_bi <= nxt_prod_ar_bi;
207
  END GENERATE;
208
  gen_product_reg : IF g_pipeline_product>0 GENERATE  -- register
209
    prod_ar_br <= reg_prod_ar_br;
210
    prod_ai_bi <= reg_prod_ai_bi;
211
    prod_ai_br <= reg_prod_ai_br;
212
    prod_ar_bi <= reg_prod_ar_bi;
213
  END GENERATE;
214
 
215
 
216
  ------------------------------------------------------------------------------
217
  -- Sum
218
  ------------------------------------------------------------------------------
219
 
220
  -- Re
221
  -- . "ADD" for a*conj(b) : ar*br + ai*bi
222
  -- . "SUB" for a*b       : ar*br - ai*bi
223
  gen_re_add : IF g_conjugate_b GENERATE
224
    nxt_sum_re <= RESIZE_NUM(prod_ar_br, c_sum_w) + prod_ai_bi;
225
  END GENERATE;
226
  gen_re_sub : IF NOT g_conjugate_b GENERATE
227
    nxt_sum_re <= RESIZE_NUM(prod_ar_br, c_sum_w) - prod_ai_bi;
228
  END GENERATE;
229
 
230
  -- Im
231
  -- . "ADD" for a*b       : ai*br + ar*bi
232
  -- . "SUB" for a*conj(b) : ai*br - ar*bi
233
  gen_im_add : IF NOT g_conjugate_b GENERATE
234
    nxt_sum_im <= RESIZE_NUM(prod_ai_br, c_sum_w) + prod_ar_bi;
235
  END GENERATE;
236
  gen_im_sub : IF g_conjugate_b GENERATE
237
    nxt_sum_im <= RESIZE_NUM(prod_ai_br, c_sum_w) - prod_ar_bi;
238
  END GENERATE;
239
 
240
 
241
  no_adder_reg : IF g_pipeline_adder=0 GENERATE   -- wired
242
    sum_re <= nxt_sum_re;
243
    sum_im <= nxt_sum_im;
244
  END GENERATE;
245
  gen_adder_reg : IF g_pipeline_adder>0 GENERATE  -- register
246
    sum_re <= reg_sum_re;
247
    sum_im <= reg_sum_im;
248
  END GENERATE;
249
 
250
  ------------------------------------------------------------------------------
251
  -- Result sum after optional rounding
252
  ------------------------------------------------------------------------------
253
 
254
  nxt_result_re <= RESIZE_NUM(sum_re, g_out_p_w);
255
  nxt_result_im <= RESIZE_NUM(sum_im, g_out_p_w);
256
 
257
  no_result_reg : IF g_pipeline_output=0 GENERATE   -- wired
258
    result_re <= STD_LOGIC_VECTOR(nxt_result_re);
259
    result_im <= STD_LOGIC_VECTOR(nxt_result_im);
260
  END GENERATE;
261
  gen_result_reg : IF g_pipeline_output>0 GENERATE  -- register
262
    result_re <= STD_LOGIC_VECTOR(reg_result_re);
263
    result_im <= STD_LOGIC_VECTOR(reg_result_im);
264
  END GENERATE;
265
 
266
END ARCHITECTURE;

powered by: WebSVN 2.1.0

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