mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 03:57:18 -04:00
mul unit FIFO trimmed
This commit is contained in:
parent
cb9ea766e1
commit
9e66c2a331
2 changed files with 45 additions and 119 deletions
67
core/mul.sv
67
core/mul.sv
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Initial code developed under the supervision of Dr. Lesley Shannon,
|
||||
* Reconfigurable Computing Lab, Simon Fraser University.
|
||||
*
|
||||
* Author(s):
|
||||
* Eric Matthews <ematthew@sfu.ca>
|
||||
*/
|
||||
|
||||
module mul
|
||||
#(
|
||||
parameter CYCLES = 4
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic new_request,
|
||||
input logic lower,
|
||||
input logic signa,
|
||||
input logic signb,
|
||||
output logic done,
|
||||
output logic completed_lower,
|
||||
input logic [31:0] A,
|
||||
input logic [31:0] B,
|
||||
output logic [63:0] P
|
||||
);
|
||||
|
||||
logic [32:0] A_r;
|
||||
logic [32:0] B_r;
|
||||
logic [65:0] result [0:CYCLES-1];
|
||||
logic valid [0:CYCLES];
|
||||
logic mul_type [0:CYCLES];
|
||||
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
A_r <= signed'({A[31] & signa, A});
|
||||
B_r <= signed'({B[31] & signb, B});
|
||||
valid[0] <= new_request;
|
||||
mul_type[0] <= lower;
|
||||
valid[1] <= valid[0];
|
||||
mul_type[1] <= mul_type[0];
|
||||
result[0] <= signed'(A_r) * signed'(B_r);
|
||||
|
||||
for (int i = 0; i < CYCLES-1; i = i+1) begin
|
||||
result[i+1] <= result[i];
|
||||
valid[i+2] <= valid[i+1];
|
||||
mul_type[i+2] <= mul_type[i+1];
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
assign P = result[CYCLES-1][63:0];
|
||||
assign done = valid[CYCLES];
|
||||
assign completed_lower = mul_type[CYCLES];
|
||||
endmodule
|
|
@ -31,65 +31,58 @@ module mul_unit(
|
|||
unit_writeback_interface.unit mul_wb
|
||||
);
|
||||
|
||||
logic [$clog2(MUL_OUTPUT_BUFFER_DEPTH+1)-1:0] inflight_count;
|
||||
logic [65:0] result;
|
||||
logic [1:0] mulh;
|
||||
logic [1:0] advance;
|
||||
logic [1:0] valid;
|
||||
|
||||
struct packed{
|
||||
logic [31:0] upper;
|
||||
logic [31:0] lower;
|
||||
} mul_result;
|
||||
logic rs1_signed, rs2_signed;
|
||||
logic [33:0] rs1_ext, rs2_ext;
|
||||
logic [33:0] rs1_r, rs2_r;
|
||||
|
||||
logic [31:0] result;
|
||||
logic mul_lower;
|
||||
logic mul_done_lower;
|
||||
logic signa, signb;
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
assign advance[0] = ~valid[0] | advance[1];
|
||||
assign advance[1] = mul_wb.accepted | ~valid[1];
|
||||
|
||||
fifo_interface #(.DATA_WIDTH(XLEN)) wb_fifo();
|
||||
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst)
|
||||
inflight_count <= 0;
|
||||
else if (mul_ex.new_request_dec & ~mul_wb.accepted)
|
||||
inflight_count <= inflight_count + 1;
|
||||
else if (~mul_ex.new_request_dec & mul_wb.accepted)
|
||||
inflight_count <= inflight_count - 1;
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rst) begin
|
||||
valid <= 2'b00;
|
||||
end
|
||||
else begin
|
||||
if (advance[0])
|
||||
valid[0] <= mul_ex.new_request_dec;
|
||||
if (advance[1])
|
||||
valid[1] <= valid[0];
|
||||
end
|
||||
end
|
||||
|
||||
//Multiply pathway fully pipelined
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst)
|
||||
mul_ex.ready <= 1;
|
||||
else if (mul_ex.new_request_dec && ~mul_wb.accepted && inflight_count == (MUL_OUTPUT_BUFFER_DEPTH-1))
|
||||
mul_ex.ready <= 0;
|
||||
else if (mul_wb.accepted)
|
||||
mul_ex.ready <= 1;
|
||||
assign rs1_signed = ~(mul_inputs.op[1:0] == MULHU_fn3[1:0]);
|
||||
assign rs2_signed = ~mul_inputs.op[1];
|
||||
|
||||
assign rs1_ext = {mul_inputs.rs1[31] & rs1_signed, mul_inputs.rs1};
|
||||
assign rs2_ext = {mul_inputs.rs2[31] & rs2_signed, mul_inputs.rs2};
|
||||
|
||||
//Input and output registered Multiply
|
||||
always_ff @ (posedge clk) begin
|
||||
if (mul_ex.new_request_dec) begin
|
||||
rs1_r <= rs1_ext;
|
||||
rs2_r <= rs2_ext;
|
||||
mulh[0] <= ~(mul_inputs.op[1:0] == 0);
|
||||
end
|
||||
if (advance[1]) begin
|
||||
result <= (rs1_r) * (rs2_r);
|
||||
mulh[1] <= mulh[0];
|
||||
end
|
||||
end
|
||||
|
||||
assign mul_lower = (mul_inputs.op[1:0] == 0);
|
||||
//Issue/write-back handshaking
|
||||
////////////////////////////////////////////////////
|
||||
assign mul_ex.ready = mul_wb.accepted | ~(&valid);
|
||||
|
||||
assign signa = ~(mul_inputs.op[1:0] == 2'b11);
|
||||
assign signb = ~mul_inputs.op[1];
|
||||
|
||||
mul #(MUL_CYCLES) multiplier (.*, .A(mul_inputs.rs1), .B(mul_inputs.rs2),
|
||||
.P(mul_result), .new_request(mul_ex.new_request_dec), .signa(signa), .signb(signb), .lower(mul_lower),
|
||||
.done(mul_done), .completed_lower(mul_done_lower));
|
||||
|
||||
assign result = mul_done_lower ? mul_result.lower : mul_result.upper;
|
||||
|
||||
/*********************************
|
||||
* Output FIFO
|
||||
*********************************/
|
||||
taiga_fifo #(
|
||||
.DATA_WIDTH(XLEN), .FIFO_DEPTH(MUL_OUTPUT_BUFFER_DEPTH), .FIFO_TYPE(NON_MUXED_INPUT_FIFO)
|
||||
) output_fifo (.fifo(wb_fifo), .*);
|
||||
|
||||
assign wb_fifo.data_in = result;
|
||||
assign wb_fifo.push = mul_done;
|
||||
assign wb_fifo.pop = mul_wb.accepted;
|
||||
assign mul_wb.rd = wb_fifo.data_out;
|
||||
assign mul_wb.done = wb_fifo.early_valid;
|
||||
|
||||
assign mul_wb.early_done = 0;//mul_done | (mul_wb.done & ~mul_wb.accepted);
|
||||
/*********************************************/
|
||||
assign mul_wb.rd = mulh[1] ? result[63:32] : result[31:0];
|
||||
assign mul_wb.done = valid[0] | (valid[1] & ~mul_wb.accepted);
|
||||
assign mul_wb.early_done = 0;
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue