blob: 9795611f6a5849fb05505347147eec3500d3266a [file] [log] [blame]
// SPDX-FileCopyrightText: 2022 Piotr Wegrzyn
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
`include "config.v"
module alu_mul_div (
`ifdef USE_POWER_PINS
inout vccd1,
inout vssd1,
`endif
input i_clk,
input i_rst,
input [`RW-1:0] i_a, i_b,
output [`RW-1:0] o_d,
input i_mul,
input i_div,
input i_mod,
input i_submit,
input i_flush,
output o_busy
);
`define RWLOG 4
reg [`RWLOG-1:0] cbit;
reg comp;
always @(posedge i_clk) begin
if (i_rst | i_flush) begin
comp <= 1'b0;
end else if (i_submit) begin
cbit <= (i_mul ? `RWLOG'b1 : `RWLOG'b0);
comp <= 1'b1;
end else if (comp) begin
cbit <= cbit+1'b1;
if (cbit == `RWLOG'd15) begin
comp <= 1'b0;
end
end
end
reg [`RW-1:0] mul_res;
always @(posedge i_clk) begin
if (i_submit & i_mul) begin
mul_res <= (i_b[0] ? i_a : `RW'b0);
end else if (comp & i_b[cbit] & i_mul) begin
mul_res <= mul_res + (i_a<<cbit);
end
end
reg [`RW-1:0] div_res, div_cur;
wire [`RW-1:0] div_diff = div_cur-i_b;
always @(posedge i_clk) begin
if (i_submit & (i_div | i_mod)) begin
div_res <= `RW'b0;
div_cur <= {{`RW-1{1'b0}}, i_a[`RW-1]};
end else if (comp & (i_div | i_mod)) begin
if (div_cur >= i_b) begin
div_res[`RW-cbit-1] <= 1'b1;
if (cbit != `RWLOG'd15)
div_cur <= {div_diff[14:0], i_a[`RW-cbit-2]};
else
div_cur <= div_diff;
end else begin
if (cbit != `RWLOG'd15)
div_cur <= {div_cur[14:0], i_a[`RW-cbit-2]};
end
end
end
assign o_d = (i_mod ? div_cur : (i_div ? div_res : mul_res));
assign o_busy = (i_submit | comp);
endmodule