cvw/wally-pipelined/src/fpu/fsm_fpdiv.sv

533 lines
13 KiB
Systemverilog
Raw Normal View History

///////////////////////////////////////////
//
// 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
//
// 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.
///////////////////////////////////////////
2021-04-04 18:09:13 +00:00
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
2021-07-24 18:59:57 +00:00
);
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
always @(posedge clk)
2021-04-04 18:09:13 +00:00
begin
if (reset == 1'b1)
current_state = S0;
2021-04-04 18:09:13 +00:00
else
current_state = next_state;
2021-04-04 18:09:13 +00:00
end
always_comb
2021-04-04 18:09:13 +00:00
begin
case(current_state)
2021-04-04 18:09:13 +00:00
S0: // iteration 0
begin
if (start==1'b0)
begin
done = 1'b0;
2021-05-21 02:17:59 +00:00
divBusy = 1'b0;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
else if (start==1'b1 && op_type==1'b0)
begin
done = 1'b0;
2021-05-21 02:17:59 +00:00
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end // if (start==1'b1 && op_type==1'b0)
else if (start==1'b1 && op_type==1'b1)
begin
done = 1'b0;
2021-05-21 02:17:59 +00:00
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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
2021-04-04 18:09:13 +00:00
end // case: S0
S1:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S2: // iteration 1
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S3:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S4: // iteration 2
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S5:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S6: // iteration 3
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S7:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end // case: S7
S8: // q,qm,qp
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S9: // rem
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S10: // done
begin
done = 1'b1;
divBusy = 1'b0;
2021-04-04 18:09:13 +00:00
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
2021-04-04 18:09:13 +00:00
S13: // start of sqrt path
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S14:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S15: // iteration 1
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S16:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S17:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S18: // iteration 2
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S19:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S20:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S21: // iteration 3
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S22:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S23:
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S24: // q,qm,qp
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
S25: // rem
begin
done = 1'b0;
divBusy = 1'b1;
2021-04-04 18:09:13 +00:00
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
2021-04-04 18:09:13 +00:00
S26: // done
begin
done = 1'b1;
divBusy = 1'b0;
2021-04-04 18:09:13 +00:00
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
2021-04-04 18:09:13 +00:00
default:
begin
done = 1'b0;
divBusy = 1'b0;
2021-04-04 18:09:13 +00:00
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;
2021-04-04 18:09:13 +00:00
end
endcase // case(current_state)
end // always @ (current_state or X)
2021-04-04 18:09:13 +00:00
endmodule // fsm