blob: 989d8c057c11cd75ac86ee36eb4dae0e953574ea [file] [log] [blame]
module FPU_decode #(parameter FPLEN = 32)
(
input clk,
input rst_l,
input [31:0] instr,
input fpu_active,
input fpu_complete,
input [FPLEN-1:0] fpu_result_1,
output [2:0] scalar_control,
output [4:0] rs1_address,
output [4:0] rs2_address,
output [4:0] rd_address,
output illegal_instr,
output [23:0] sfpu_op,
output [2:0] fpu_rnd,
output [2:0] fpu_pre,
output [FPLEN-1:0] fs1_data,
output [FPLEN-1:0] fs2_data,
output [FPLEN-1:0] fs3_data,
output valid_execution,
output illegal_config,
input scan_mode,
output [3:0] float_control,
output halt_req,
output[2:0]fpu_sel
);
// Internal Wire and Reg decleration
wire [114:0] control_signals;
reg [114:0] control_signals_r;
wire [4:0] fs1_addr, fs2_addr, fs3_addr;
wire [FPLEN-1:0] fs1_data_w, fs2_data_w, fs3_data_w;
wire [4:0] fd_reg;
wire [1:0] fdest_pkg; // bit 1 = Floating Load, bit 0 = Floating Execution
// Floating Destination Register FLops
rvdffsc #(5) fd_reg_ff_x (.clk(clk), .rst_l(rst_l), .en(valid_execution & control_signals[51] & fpu_active), .clear(((~valid_execution | ~fpu_active) & fpu_complete)), .din(control_signals[57] ? instr[11:7] : 5'h00), .dout(fd_reg));
//rvdffsc #(5) fd_reg_ff_wb (.clk(clk), .rst_l(rst_l), .en(fpu_complete_w), .clear(~fpu_active & ~fpu_complete_w & fpu_complete), .din(fd_reg_x), .dout(fd_reg));
// Floating Destination write signal
rvdffsc #(2) fdest_pkg_ff_x (.clk(clk), .rst_l(rst_l), .en(valid_execution & control_signals[51] & fpu_active), .clear(((~valid_execution | ~fpu_active) & fpu_complete)), .din({control_signals[113],(control_signals[57] & ~control_signals[112])}), .dout(fdest_pkg));
//rvdffsc #(2) fdest_pkg_ff_wb (.clk(clk), .rst_l(rst_l), .en(fpu_complete_w), .clear(~fpu_active & ~fpu_complete_w & fpu_complete), .din(fdest_pkg_x), .dout(fdest_pkg));
// Initiating Floating Decode Controller
FPU_dec_ctl FPU_decode_controller (
.fpu_active(fpu_active),
.instr(instr),
.out(control_signals)
);
// Initiating Floating Point Register File
FPU_fpr_ctl floating_point_register_file (
.clk(clk),
.rst_l(rst_l),
.rden0(control_signals[54]),
.rden1(control_signals[55]),
.rden2(control_signals[56]),
.raddr0(fs1_addr),
.raddr1(fs2_addr),
.raddr2(fs3_addr),
.wen0(fpu_complete & fdest_pkg[0]), // single cycle port
.waddr0(fd_reg),
.wd0(fpu_result_1),
.rd0(fs1_data_w), // read data
.rd1(fs2_data_w),
.rd2(fs3_data_w),
.scan_mode(scan_mode)
);
assign illegal_instr = (rst_l == 1'b0) ? 1'b0 : ((fpu_active) & (control_signals[51] == 1'b0) & (~control_signals_r[51])) ? 1'b1 : 1'b0;
// For Single precision
assign valid_execution = (rst_l == 1'b0) ? 1'b0 : (illegal_instr) ? 1'b0 : (fpu_active & control_signals[92] & control_signals_r[92] & ~control_signals[89] & ~control_signals_r[89]) ? 1'b0 : (fpu_active & (control_signals[89] | control_signals_r[89])) ? 1'b1 : 1'b0;
assign scalar_control = (rst_l == 1'b0) ? 3'b00 : control_signals[2:0]; // Contain the active signals for rs1, rs2, rd
// for Single precision
assign illegal_config = (rst_l == 1'b0) ? 1'b0 : (fpu_active & (control_signals[91] | control_signals[90])) ? 1'b1 : 1'b0;
// Scalar Register address
assign rs1_address = (rst_l == 1'b0) ? 5'h00 : (valid_execution | control_signals[10]) ? instr[19:15] : 5'h00;
assign rs2_address = (rst_l == 1'b0) ? 5'h00 : (valid_execution | control_signals[10]) ? instr[24:20] : 5'h00;
assign rd_address = (rst_l == 1'b0) ? 5'h00 : (valid_execution | control_signals[10]) ? instr[11:7] : 5'h00;
// Floating Control
assign float_control = (rst_l == 1'b0) ? 4'b0000 : control_signals[57:54]; // Contain the active signals for fs1, fs2, fs3 and fd
// Floating Point Register address
assign fs1_addr = (rst_l == 1'b0) ? 5'h00 : (valid_execution & control_signals[54]) ? instr[19:15] : 5'h00;
assign fs2_addr = (rst_l == 1'b0) ? 5'h00 : (valid_execution & control_signals[55]) ? instr[24:20] : 5'h00;
assign fs3_addr = (rst_l == 1'b0) ? 5'h00 : (valid_execution & control_signals[56]) ? instr[31:27] : 5'h00;
// Scalar or Vector operation signals
assign fpu_sel = (rst_l == 1'b0 | illegal_config) ? 3'h0 : (valid_execution & fpu_active & control_signals[51]) ? {control_signals[93:92],control_signals[74]} : (~valid_execution | ~fpu_active | fpu_complete) ? 3'h0 : 3'h0;
always @(posedge clk) begin
if(rst_l == 1'b0 | illegal_config)
begin
control_signals_r <= 115'h0;
end
else
begin
// Execution Unit Valid signals and operands
if((valid_execution & control_signals[51] & fpu_active))
begin
control_signals_r <= control_signals;
end
else if((~valid_execution) | ((~fpu_active) & (fpu_complete)))
begin
control_signals_r <= 115'h0;
end
else
begin
control_signals_r <= control_signals_r;
end
end
end
// FP Execution Operands
assign fs1_data = (rst_l == 1'b0 | illegal_config) ? {FPLEN{1'b0}} : (valid_execution & control_signals[51] & fpu_active) ? fs1_data_w : (~valid_execution | ~fpu_active | fpu_complete) ? {FPLEN{1'b0}} : {FPLEN{1'b0}};
assign fs2_data = (rst_l == 1'b0 | illegal_config) ? {FPLEN{1'b0}} : (valid_execution & control_signals[51] & fpu_active) ? fs2_data_w : (~valid_execution | ~fpu_active | fpu_complete) ? {FPLEN{1'b0}} : {FPLEN{1'b0}};
assign fs3_data = (rst_l == 1'b0 | illegal_config) ? {FPLEN{1'b0}} : (valid_execution & control_signals[51] & fpu_active) ? fs3_data_w : (~valid_execution | ~fpu_active | fpu_complete) ? {FPLEN{1'b0}} : {FPLEN{1'b0}};
// Scalar Floating point Control Signals
assign sfpu_op = (rst_l == 1'b0 | illegal_config) ? 24'h0 : (valid_execution & fpu_active & control_signals[51] & control_signals[92]) ? {control_signals[32:31],control_signals[105:98],control_signals[88:75]} : (~valid_execution | ~fpu_active | fpu_complete) ? 24'h0 : 24'h0;
// Floating Rounding mode
assign fpu_rnd = (rst_l == 1'b0 | illegal_config) ? 3'h0 : (valid_execution & fpu_active & control_signals[51] & control_signals[92]) ? instr[14:12] : (~valid_execution | ~fpu_active | fpu_complete) ? 3'h0 : 3'h0;
// Precision info {half,double,single}
assign fpu_pre = (rst_l == 1'b0 | illegal_config) ? 3'h0 : (valid_execution & fpu_active & control_signals[51]) ? control_signals[91:89] : (~valid_execution | ~fpu_active | fpu_complete) ? 3'h0 : 3'h0;
// Halt the core when fdiv/fsqrt
assign halt_req = (rst_l == 1'b0 | illegal_config) ? 1'b0 : (control_signals[78] | control_signals[79]);
endmodule