| 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 | |