cvw/pipelined/src/fpu/fsm_fpdiv.sv
2022-01-07 12:58:40 +00:00

538 lines
13 KiB
Systemverilog
Executable File

///////////////////////////////////////////
//
// Written: James Stine
// Modified: 9/28/2021
//
// Purpose: FSM for floating point divider/square root unit (Goldschmidt)
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////
module fsm_fpdiv (
input logic clk,
input logic reset,
input logic start,
input logic op_type,
output logic done,
output logic load_rega,
output logic load_regb,
output logic load_regc,
output logic load_regd,
output logic load_regr,
output logic load_regs,
output logic [2:0] sel_muxa,
output logic [2:0] sel_muxb,
output logic sel_muxr,
output logic divBusy
);
typedef enum logic [4:0] {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9,
S10, S11, S12, S13, S14, S15, S16, S17, S18, S19,
S20, S21, S22, S23, S24, S25, S26, S27, S28, S29,
S30} statetype;
statetype current_state, next_state;
always @(posedge clk)
begin
if (reset == 1'b1)
current_state = S0;
else
current_state = next_state;
end
always_comb
begin
case(current_state)
S0: // iteration 0
begin
if (start==1'b0)
begin
done = 1'b0;
divBusy = 1'b0;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S0;
end
else if (start==1'b1 & op_type==1'b0)
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b001;
sel_muxb = 3'b001;
sel_muxr = 1'b0;
next_state = S1;
end // if (start==1'b1 & op_type==1'b0)
else if (start==1'b1 & op_type==1'b1)
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b010;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S13;
end
else
begin
done = 1'b0;
divBusy = 1'b0;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S0;
end
end // case: S0
S1:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b010;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S2;
end
S2: // iteration 1
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b011;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S3;
end
S3:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b010;
sel_muxr = 1'b0;
next_state = S4;
end
S4: // iteration 2
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b011;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S5;
end
S5:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b010;
sel_muxr = 1'b0; // add
next_state = S6;
end
S6: // iteration 3
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b011;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S8;
end
S7:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b010;
sel_muxr = 1'b0;
next_state = S8;
end // case: S7
S8: // q,qm,qp
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b1;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S9;
end
S9: // rem
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b1;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b1;
next_state = S10;
end
S10: // done
begin
done = 1'b1;
divBusy = 1'b0;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S11;
end // case: S10
S11: // done
begin
done = 1'b0;
divBusy = 1'b0;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S0;
end
S13: // start of sqrt path
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b1;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b010;
sel_muxb = 3'b001;
sel_muxr = 1'b0;
next_state = S14;
end
S14:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b001;
sel_muxb = 3'b100;
sel_muxr = 1'b0;
next_state = S15;
end
S15: // iteration 1
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b011;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S16;
end
S16:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b1;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S17;
end
S17:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b100;
sel_muxb = 3'b010;
sel_muxr = 1'b0;
next_state = S18;
end
S18: // iteration 2
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b011;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S19;
end
S19:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b1;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S20;
end
S20:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b100;
sel_muxb = 3'b010;
sel_muxr = 1'b0;
next_state = S21;
end
S21: // iteration 3
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b1;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b011;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S22;
end
S22:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b1;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b011;
sel_muxr = 1'b0;
next_state = S23;
end
S23:
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b1;
load_regb = 1'b0;
load_regc = 1'b1;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b100;
sel_muxb = 3'b010;
sel_muxr = 1'b0;
next_state = S24;
end
S24: // q,qm,qp
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b1;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S25;
end
S25: // rem
begin
done = 1'b0;
divBusy = 1'b1;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b1;
load_regs = 1'b0;
sel_muxa = 3'b011;
sel_muxb = 3'b110;
sel_muxr = 1'b1;
next_state = S26;
end
S26: // done
begin
done = 1'b1;
divBusy = 1'b0;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S27;
end // case: S26
S27: // done
begin
done = 1'b0;
divBusy = 1'b0;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S0;
end
default:
begin
done = 1'b0;
divBusy = 1'b0;
load_rega = 1'b0;
load_regb = 1'b0;
load_regc = 1'b0;
load_regd = 1'b0;
load_regr = 1'b0;
load_regs = 1'b0;
sel_muxa = 3'b000;
sel_muxb = 3'b000;
sel_muxr = 1'b0;
next_state = S0;
end
endcase // case(current_state)
end // always @ (current_state or X)
endmodule // fsm