-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmultiply.v
65 lines (56 loc) · 1.47 KB
/
multiply.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/* Multiplier for nanoV
*
* 32x32 -> 32 multiply (mullo)
*
* Multiply runs over bits(b) cycles.
* The user provides the 32-bit value a and the low bit of b.
* Each cycle:
* a is added to the result if b is true.
* a is shifted left (by the user).
* b is shifted right (by the user).
*
* The low bit of the result is presented as d.
* The full result can be read over 32 cycles by holding read_out high,
* which causes the result to be shifted right.
*/
module nanoV_mul #(parameter A_BITS=32) (
input clk,
input [A_BITS-1:0] a,
input b,
output d
);
`ifdef SIM
`define SIMPLE_MULTIPLY
`endif
`ifdef ICE40
`define SIMPLE_MULTIPLY
`endif
`ifdef SIMPLE_MULTIPLY
reg [A_BITS-1:0] accum;
wire [A_BITS:0] next_accum = {1'b0, accum} + {1'b0, a};
always @(posedge clk) begin
accum <= b ? next_accum[A_BITS:1] : {1'b0, accum[A_BITS-1:1]};
end
`else
wire [A_BITS-1:0] accum;
wire [A_BITS:0] next_accum = {1'b0, accum} + {1'b0, a};
genvar i;
for (i = 0; i < A_BITS-1; i = i + 1) begin
sky130_fd_sc_hd__sdfxtp_1 accumff(
.CLK(clk),
.D(accum[i+1]),
.Q(accum[i]),
.SCD(next_accum[i+1]),
.SCE(b)
);
end
sky130_fd_sc_hd__sdfxtp_1 accumff_last(
.CLK(clk),
.D(1'b0),
.Q(accum[A_BITS-1]),
.SCD(next_accum[A_BITS]),
.SCE(b)
);
`endif
assign d = b ? next_accum[0] : accum[0];
endmodule