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

Subversion Repositories openarty

[/] [openarty/] [trunk/] [rtl/] [bigsmpy.v] - Blame information for rev 25

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

Line No. Rev Author Line
1 3 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    bigsmpy.v
4
//
5
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
6
//
7
// Purpose:     
8
//
9
// Creator:     Dan Gisselquist, Ph.D.
10
//              Gisselquist Technology, LLC
11
//
12
////////////////////////////////////////////////////////////////////////////////
13
//
14
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
15
//
16
// This program is free software (firmware): you can redistribute it and/or
17
// modify it under the terms of  the GNU General Public License as published
18
// by the Free Software Foundation, either version 3 of the License, or (at
19
// your option) any later version.
20
//
21
// This program is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License along
27
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
28
// target there if the PDF file isn't present.)  If not, see
29
// <http://www.gnu.org/licenses/> for a copy.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38
module  bigsmpy(i_clk, i_sync, i_sgn, i_a, i_b, o_r, o_sync);
39 25 dgisselq
        parameter       CLOCKS = 1;
40 3 dgisselq
        input                   i_clk, i_sync, i_sgn;
41
        input           [31:0]   i_a, i_b;
42
        output  reg     [63:0]   o_r;
43
        output  reg             o_sync;
44
 
45 25 dgisselq
        generate
46
        if (CLOCKS == 1)
47
        begin
48
                wire    signed  [31:0]   w_sa, w_sb;
49
                wire            [31:0]   w_ua, w_ub;
50 3 dgisselq
 
51 25 dgisselq
                assign  w_sa = i_a;
52
                assign  w_sb = i_b;
53
                assign  w_ua = i_a;
54
                assign  w_ub = i_b;
55
 
56
                always @(posedge i_clk)
57
                begin
58
                        o_sync <= i_sync;
59
                        if (i_sgn)
60
                                o_r <= w_sa * w_sb;
61
                        else
62
                                o_r <= w_ua * w_ub;
63
                end
64
 
65
        end else if (CLOCKS == 2)
66 3 dgisselq
        begin
67 25 dgisselq
                reg     signed  [31:0]   r_sa, r_sb;
68
                wire            [31:0]   w_ua, w_ub;
69
 
70
                always @(posedge i_clk)
71 3 dgisselq
                begin
72 25 dgisselq
                        r_sa = i_a;
73
                        r_sb = i_b;
74 3 dgisselq
                end
75
 
76 25 dgisselq
                assign  w_ua = r_sa;
77
                assign  w_ub = r_sb;
78 3 dgisselq
 
79 25 dgisselq
                always @(posedge i_clk)
80
                begin
81
                        o_sync <= i_sync;
82
                        if (i_sgn)
83
                                o_r <= r_sa * r_sb;
84
                        else
85
                                o_r <= w_ua * w_ub;
86
                end
87
 
88
 
89
        end else if (CLOCKS == 5)
90 3 dgisselq
        begin
91 25 dgisselq
                //
92
                // A pipeline, shift register, to track our
93
                // synchronization pulse as it transits our pipeline
94
                //
95
                reg     [3:0]    r_s;
96 3 dgisselq
 
97 25 dgisselq
                //
98
                // Clock #1: Register our inputs, copy the value of the sign
99
                //              bit.
100
                reg             r_mpy_signed;
101
                reg     [31:0]   r_mpy_a_input, r_mpy_b_input;
102
                always @(posedge i_clk)
103
                begin
104
                        if (i_sgn)
105
                        begin
106
                                // This is about more than making the inputs
107
                                // unsigned, as you'll notice it makes positive
108
                                // inputs otherwise negative.  Instead,
109
                                // this is about making the inputs have offset
110
                                // mode.  Hence
111
                                //      i_a = r_mpy_a_input - 2^31
112
                                // and so forth
113
                                r_mpy_a_input <= {(~i_a[31]), i_a[30:0] };
114
                                r_mpy_b_input <= {(~i_b[31]), i_b[30:0] };
115
                        end else begin
116
                                r_mpy_a_input <= i_a[31:0];
117
                                r_mpy_b_input <= i_b[31:0];
118
                        end
119 3 dgisselq
 
120 25 dgisselq
                        r_mpy_signed <= i_sgn;
121
                        r_s[0] <= i_sync;
122
                end
123 3 dgisselq
 
124 25 dgisselq
                reg     [31:0]   pp_f, pp_o, pp_i, pp_l;
125
                reg     [32:0]   pp_s;
126
                always @(posedge i_clk)
127
                begin
128
                        pp_f <= r_mpy_a_input[31:16] * r_mpy_b_input[31:16];
129
                        pp_o <= r_mpy_a_input[31:16] * r_mpy_b_input[15: 0];
130
                        pp_i <= r_mpy_a_input[15: 0] * r_mpy_b_input[31:16];
131
                        pp_l <= r_mpy_a_input[15: 0] * r_mpy_b_input[15: 0];
132 3 dgisselq
 
133 25 dgisselq
                        if (r_mpy_signed)
134
                                pp_s <= 32'h8000_0000 - (r_mpy_a_input[31:0]
135
                                        + r_mpy_b_input[31:0]);
136
                        else
137
                                pp_s <= 33'h0;
138
                        r_s[1] <= r_s[0];
139
                end
140 3 dgisselq
 
141 25 dgisselq
                reg     [32:0]   partial_mpy_oi, partial_mpy_lo;
142
                reg     [31:0]   partial_mpy_hi;
143
                always @(posedge i_clk)
144
                begin
145
                        partial_mpy_lo[30: 0] <= pp_l[30:0];
146
                        partial_mpy_lo[32:31] <= pp_s[0] + pp_l[31];
147
                        partial_mpy_oi[32: 0] <= pp_o + pp_i;
148
                        partial_mpy_hi[31: 0] <= pp_s[32:1] + pp_f;
149
                        r_s[2] <= r_s[1];
150
                end
151 3 dgisselq
 
152 25 dgisselq
                reg             partial_mpy_2cl, partial_mpy_2ch;
153
                reg     [31:0]   partial_mpy_2lo, partial_mpy_2hi;
154
                always @(posedge i_clk)
155
                begin
156
                        partial_mpy_2lo[15:0] <= partial_mpy_lo[15:0];
157
                        { partial_mpy_2cl, partial_mpy_2lo[31:16] }
158
                                <= { 1'b0, partial_mpy_oi[15:0]}
159
                                                + partial_mpy_lo[32:16];
160
                        { partial_mpy_2ch, partial_mpy_2hi[16:0] }
161
                                <= partial_mpy_oi[32:16] + partial_mpy_hi[16:0];
162
                        partial_mpy_2hi[31:16] <= { partial_mpy_2hi[31:17],
163
                                                        1'b0 };
164
                        r_s[3] <= r_s[2];
165
                end
166
 
167
                always @(posedge i_clk)
168
                begin
169
                        o_r[31: 0] <= partial_mpy_2lo[31:0];
170
                        o_r[63:32] <= partial_mpy_2hi
171
                                + { 14'h0, partial_mpy_2ch, 1'b0,
172
                                                15'h0, partial_mpy_2cl };
173
                        o_sync <= r_s[3];
174
                end
175
        end endgenerate
176
 
177
 
178 3 dgisselq
endmodule

powered by: WebSVN 2.1.0

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