Fixed fmv decoder

This commit is contained in:
David Harris 2023-03-28 10:21:33 -07:00
parent 2c8fcc24e0
commit 074fd1d9c3

View File

@ -75,16 +75,19 @@ module fctrl (
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
logic [2:0] FrmD, FrmE; // FP rounding mode logic [2:0] FrmD, FrmE; // FP rounding mode
logic [`FMTBITS-1:0] FmtD; // FP format logic [`FMTBITS-1:0] FmtD; // FP format
logic [1:0] Fmt; // format - before possible reduction logic [1:0] Fmt, Fmt2; // format - before possible reduction
logic SupportedFmt; // is the format supported logic SupportedFmt; // is the format supported
logic SupportedFmt2; // is the source format supported for fp -> fp
logic FCvtIntD, FCvtIntM; // convert to integer opperation logic FCvtIntD, FCvtIntM; // convert to integer opperation
// FPU Instruction Decoder // FPU Instruction Decoder
assign Fmt = Funct7D[1:0]; assign Fmt = Funct7D[1:0];
assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp
// Note: only Fmt is checked; fcvt does not check destination format
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & `D_SUPPORTED) | assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & `D_SUPPORTED) |
(Fmt == 2'b10 & `ZFH_SUPPORTED) | (Fmt == 2'b11 & `Q_SUPPORTED)); (Fmt == 2'b10 & `ZFH_SUPPORTED) | (Fmt == 2'b11 & `Q_SUPPORTED));
assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & `D_SUPPORTED) |
(Fmt2 == 2'b10 & `ZFH_SUPPORTED) | (Fmt2 == 2'b11 & `Q_SUPPORTED));
// decode the instruction // decode the instruction
always_comb always_comb
@ -142,38 +145,42 @@ module fctrl (
default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction
endcase endcase
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass
else if (Funct3D[1:0] == 2'b00) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w to int reg else if (Funct3D == 3'b000 & Rs2D == 5'b00000)
else if (Funct3D[1:0] == 2'b01) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.d to int reg ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register
else ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000)
7'b1101000: case(Rs2D[1:0]) ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg
2'b00: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s 7'b0100000: if (Rs2D[4:2] == 3'b000)
2'b01: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.d
2'b10: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s 7'b0100001: if (Rs2D[4:2] == 3'b000)
2'b11: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.s
// *** other formats here
/* verilator lint_off CASEINCOMPLETE */
7'b1101000: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s
endcase endcase
7'b1100000: case(Rs2D[1:0]) 7'b1100000: case(Rs2D)
2'b00: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w
2'b01: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu
2'b10: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l
2'b11: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu
endcase endcase
7'b1111000: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x to fp reg 7'b1101001: case(Rs2D)
7'b0100000: ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.d 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d
7'b1101001: case(Rs2D[1:0]) 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d
2'b00: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d
2'b01: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d
2'b10: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d
2'b11: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d
endcase endcase
7'b1100001: case(Rs2D[1:0]) 7'b1100001: case(Rs2D)
2'b00: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w
2'b01: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu
2'b10: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l
2'b11: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu
endcase endcase
7'b1111001: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.d.x to fp reg /* verilator lint_off CASEINCOMPLETE */
7'b0100001: ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.s
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
endcase endcase
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction