mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally
This commit is contained in:
commit
634d13b347
@ -324,9 +324,9 @@ set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe62]
|
|||||||
connect_debug_port u_ila_0/probe62 [get_nets [list wallypipelinedsoc/core/hzu/FCvtIntStallD ]]
|
connect_debug_port u_ila_0/probe62 [get_nets [list wallypipelinedsoc/core/hzu/FCvtIntStallD ]]
|
||||||
|
|
||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe63]
|
set_property port_width 7 [get_debug_ports u_ila_0/probe63]
|
||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe63]
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe63]
|
||||||
connect_debug_port u_ila_0/probe63 [get_nets [list wallypipelinedsoc/core/hzu/DivBusyE ]]
|
connect_debug_port u_ila_0/probe63 [get_nets [list {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][1]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][2]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][3]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][4]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][5]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][6]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][7]} ]]
|
||||||
|
|
||||||
create_debug_port u_ila_0 probe
|
create_debug_port u_ila_0 probe
|
||||||
set_property port_width 1 [get_debug_ports u_ila_0/probe64]
|
set_property port_width 1 [get_debug_ports u_ila_0/probe64]
|
||||||
@ -1148,7 +1148,3 @@ set_property port_width 53 [get_debug_ports u_ila_0/probe224]
|
|||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe224]
|
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe224]
|
||||||
connect_debug_port u_ila_0/probe224 [get_nets [list {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][1]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][2]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][3]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][4]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][5]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][6]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][7]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][8]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][9]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][10]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][11]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][12]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][13]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][14]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][15]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][16]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][17]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][18]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][19]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][20]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][21]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][22]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][23]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][24]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][25]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][26]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][27]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][28]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][29]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][30]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][31]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][32]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][33]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][34]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][35]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][36]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][37]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][38]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][39]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][40]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][41]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][42]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][43]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][44]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][45]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][46]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][47]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][48]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][49]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][50]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][51]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][52]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][53]} ]]
|
connect_debug_port u_ila_0/probe224 [get_nets [list {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][1]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][2]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][3]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][4]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][5]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][6]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][7]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][8]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][9]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][10]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][11]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][12]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][13]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][14]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][15]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][16]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][17]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][18]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][19]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][20]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][21]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][22]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][23]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][24]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][25]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][26]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][27]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][28]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][29]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][30]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][31]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][32]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][33]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][34]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][35]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][36]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][37]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][38]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][39]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][40]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][41]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][42]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][43]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][44]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][45]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][46]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][47]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][48]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][49]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][50]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][51]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][52]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][53]} ]]
|
||||||
|
|
||||||
create_debug_port u_ila_0 probe
|
|
||||||
set_property port_width 7 [get_debug_ports u_ila_0/probe225]
|
|
||||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe225]
|
|
||||||
connect_debug_port u_ila_0/probe225 [get_nets [list {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][1]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][2]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][3]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][4]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][5]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][6]} {wallypipelinedsoc/uncore.uncore/plic.plic/threshMask[0][7]} ]]
|
|
||||||
|
@ -104,12 +104,12 @@
|
|||||||
`define CVTLEN ((`NF<`XLEN) ? (`XLEN) : (`NF))
|
`define CVTLEN ((`NF<`XLEN) ? (`XLEN) : (`NF))
|
||||||
`define LLEN ((`FLEN<`XLEN) ? (`XLEN) : (`FLEN))
|
`define LLEN ((`FLEN<`XLEN) ? (`XLEN) : (`FLEN))
|
||||||
`define LOGCVTLEN $unsigned($clog2(`CVTLEN+1))
|
`define LOGCVTLEN $unsigned($clog2(`CVTLEN+1))
|
||||||
`define NORMSHIFTSZ ((`QLEN+`NF+1) > (3*`NF+8) ? (`QLEN+`NF+1) : (3*`NF+8))
|
`define NORMSHIFTSZ ((`QLEN+`NF+1) > (3*`NF+6) ? (`QLEN+`NF+1) : (3*`NF+6))
|
||||||
`define LOGNORMSHIFTSZ ($clog2(`NORMSHIFTSZ))
|
`define LOGNORMSHIFTSZ ($clog2(`NORMSHIFTSZ))
|
||||||
`define CORRSHIFTSZ ((`DIVRESLEN+`NF) > (3*`NF+8) ? (`DIVRESLEN+`NF) : (3*`NF+6))
|
`define CORRSHIFTSZ ((`DIVRESLEN+`NF) > (3*`NF+6) ? (`DIVRESLEN+`NF) : (3*`NF+4))
|
||||||
|
|
||||||
// division constants
|
// division constants
|
||||||
`define RADIX 32'h2
|
`define RADIX 32'h4
|
||||||
`define DIVCOPIES 32'h4
|
`define DIVCOPIES 32'h4
|
||||||
`define DIVLEN ((`NF < `XLEN) ? (`XLEN) : `NF+3)
|
`define DIVLEN ((`NF < `XLEN) ? (`XLEN) : `NF+3)
|
||||||
// `define DIVN (`NF < `XLEN ? `XLEN : `NF+1) // length of input
|
// `define DIVN (`NF < `XLEN ? `XLEN : `NF+1) // length of input
|
||||||
|
@ -69,7 +69,7 @@ module fdivsqrtfsm(
|
|||||||
assign ISpecialCaseE = AZeroE | BZeroE; // *** why is AZeroE part of this. Should other special cases be considered?
|
assign ISpecialCaseE = AZeroE | BZeroE; // *** why is AZeroE part of this. Should other special cases be considered?
|
||||||
assign SpecialCaseE = MDUE ? ISpecialCaseE : FSpecialCaseE;
|
assign SpecialCaseE = MDUE ? ISpecialCaseE : FSpecialCaseE;
|
||||||
end else assign SpecialCaseE = FSpecialCaseE;
|
end else assign SpecialCaseE = FSpecialCaseE;
|
||||||
flopenr #(1) SpecialCaseReg(clk, reset, ~StallM, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
||||||
|
|
||||||
// DIVN = `NF+3
|
// DIVN = `NF+3
|
||||||
// NS = NF + 1
|
// NS = NF + 1
|
||||||
|
@ -52,9 +52,6 @@ module fdivsqrtpostproc(
|
|||||||
logic [`DIVb:0] PreQmM;
|
logic [`DIVb:0] PreQmM;
|
||||||
logic NegStickyM;
|
logic NegStickyM;
|
||||||
logic weq0E, weq0M, WZeroM;
|
logic weq0E, weq0M, WZeroM;
|
||||||
logic [`DIVBLEN:0] NormShiftM;
|
|
||||||
logic [`DIVb:0] NormQuotM;
|
|
||||||
logic [`DIVb+3:0] IntQuotM, IntRemM, NormRemM;
|
|
||||||
logic signed [`DIVb+3:0] PreResultM, PreFPIntDivResultM;
|
logic signed [`DIVb+3:0] PreResultM, PreFPIntDivResultM;
|
||||||
logic [`XLEN-1:0] SpecialFPIntDivResultM;
|
logic [`XLEN-1:0] SpecialFPIntDivResultM;
|
||||||
|
|
||||||
@ -104,33 +101,26 @@ module fdivsqrtpostproc(
|
|||||||
assign QmM = SqrtM ? (PreQmM << 1) : PreQmM;
|
assign QmM = SqrtM ? (PreQmM << 1) : PreQmM;
|
||||||
|
|
||||||
if (`IDIV_ON_FPU) begin
|
if (`IDIV_ON_FPU) begin
|
||||||
|
logic [`DIVBLEN:0] NormShiftM;
|
||||||
|
logic [`DIVb+3:0] IntQuotM, IntRemM, NormRemM, NormRemDM;
|
||||||
|
|
||||||
assign W = $signed(Sum) >>> `LOGR;
|
assign W = $signed(Sum) >>> `LOGR;
|
||||||
assign DM = {4'b0001, D};
|
assign DM = {4'b0001, D};
|
||||||
|
|
||||||
// Integer division: sign handling for div and rem
|
// Integer remainder: sticky and sign correction muxes
|
||||||
always_comb
|
mux2 #(`DIVb+4) normremdmux(W, W+DM, NegStickyM, NormRemDM);
|
||||||
if (~AsM)
|
mux2 #(`DIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM);
|
||||||
if (NegStickyM) begin
|
|
||||||
NormQuotM = FirstUM;
|
|
||||||
NormRemM = W + DM;
|
|
||||||
end else begin
|
|
||||||
NormQuotM = FirstU;
|
|
||||||
NormRemM = W;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if (NegStickyM) begin
|
|
||||||
NormQuotM = FirstUM;
|
|
||||||
NormRemM = -(W + DM);
|
|
||||||
end else begin
|
|
||||||
NormQuotM = FirstU;
|
|
||||||
NormRemM = -W;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Integer division: Special cases
|
// special case logic
|
||||||
always_comb
|
always_comb
|
||||||
if (ALTBM) begin
|
if (BZeroM) begin
|
||||||
IntQuotM = '0;
|
if (RemOpM) SpecialFPIntDivResultM = AM;
|
||||||
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, AM};
|
else SpecialFPIntDivResultM = {(`XLEN){1'b1}};
|
||||||
|
end else if (ALTBM) begin
|
||||||
|
if (RemOpM) SpecialFPIntDivResultM = AM;
|
||||||
|
else SpecialFPIntDivResultM = '0;
|
||||||
|
// IntQuotM = '0;
|
||||||
|
// IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, AM};
|
||||||
end else begin
|
end else begin
|
||||||
logic [`DIVb+3:0] PreIntQuotM;
|
logic [`DIVb+3:0] PreIntQuotM;
|
||||||
if (WZeroM) begin
|
if (WZeroM) begin
|
||||||
@ -142,36 +132,28 @@ module fdivsqrtpostproc(
|
|||||||
IntRemM = '0;
|
IntRemM = '0;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
PreIntQuotM = {3'b000, NormQuotM};
|
PreIntQuotM = {3'b000, PreQmM};
|
||||||
IntRemM = NormRemM;
|
IntRemM = NormRemM;
|
||||||
end
|
end
|
||||||
// flip sign if necessary
|
// flip sign if necessary
|
||||||
if (NegQuotM) IntQuotM = -PreIntQuotM;
|
if (NegQuotM) IntQuotM = -PreIntQuotM;
|
||||||
else IntQuotM = PreIntQuotM;
|
else IntQuotM = PreIntQuotM;
|
||||||
end
|
if (RemOpM) begin
|
||||||
|
NormShiftM = ALTBM ? '0 : (mM + (`DIVBLEN+1)'(`DIVa)); // no postshift if forwarding input A to remainder
|
||||||
always_comb
|
PreResultM = IntRemM;
|
||||||
if (RemOpM) begin
|
|
||||||
NormShiftM = ALTBM ? '0 : (mM + (`DIVBLEN+1)'(`DIVa)); // no postshift if forwarding input A to remainder
|
|
||||||
PreResultM = IntRemM;
|
|
||||||
end else begin
|
|
||||||
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
|
|
||||||
PreResultM = IntQuotM;
|
|
||||||
/*
|
|
||||||
if (~ALTBM & NegQuotM) begin
|
|
||||||
PreResultM = {3'b111, -IntQuotM};
|
|
||||||
end else begin
|
end else begin
|
||||||
PreResultM = {3'b000, IntQuotM};
|
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
|
||||||
end*/
|
PreResultM = IntQuotM;
|
||||||
//PreResultM = {IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM}; // Suspicious Sign Extender
|
end
|
||||||
|
PreFPIntDivResultM = $signed(PreResultM >>> NormShiftM);
|
||||||
|
SpecialFPIntDivResultM = PreFPIntDivResultM[`XLEN-1:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
|
// sign extend result for W64
|
||||||
|
if (`XLEN==64)
|
||||||
assign PreFPIntDivResultM = $signed(PreResultM >>> NormShiftM);
|
assign FPIntDivResultM = (W64M ? {{(`XLEN-32){SpecialFPIntDivResultM[31]}}, SpecialFPIntDivResultM[31:0]} :
|
||||||
assign SpecialFPIntDivResultM = BZeroM ? (RemOpM ? AM : {(`XLEN){1'b1}}) : PreFPIntDivResultM[`XLEN-1:0]; // special cases
|
SpecialFPIntDivResultM[`XLEN-1:0]); // Sign extending in case of W64
|
||||||
// *** conditional on RV64
|
else
|
||||||
assign FPIntDivResultM = (W64M ? {{(`XLEN-32){SpecialFPIntDivResultM[31]}}, SpecialFPIntDivResultM[31:0]} : SpecialFPIntDivResultM[`XLEN-1:0]); // Sign extending in case of W64
|
assign FPIntDivResultM = SpecialFPIntDivResultM[`XLEN-1:0];
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
@ -51,26 +51,23 @@ module fdivsqrtpreproc (
|
|||||||
);
|
);
|
||||||
|
|
||||||
logic [`DIVb-1:0] XPreproc;
|
logic [`DIVb-1:0] XPreproc;
|
||||||
logic [`DIVb:0] SqrtX;
|
logic [`DIVb:0] PreSqrtX;
|
||||||
logic [`DIVb+3:0] DivX;
|
logic [`DIVb+3:0] DivX, SqrtX;
|
||||||
logic [`NE+1:0] QeE;
|
logic [`NE+1:0] QeE;
|
||||||
// Intdiv signals
|
|
||||||
logic [`DIVb-1:0] IFNormLenX, IFNormLenD;
|
logic [`DIVb-1:0] IFNormLenX, IFNormLenD;
|
||||||
logic [`DIVBLEN:0] mE;
|
logic [`DIVBLEN:0] mE, ell;
|
||||||
logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX;
|
|
||||||
logic [`DIVBLEN:0] pPlusr, pPrCeil, p, ell;
|
|
||||||
logic [`LOGRK:0] pPrTrunc;
|
|
||||||
logic [`DIVb+3:0] PreShiftX;
|
logic [`DIVb+3:0] PreShiftX;
|
||||||
logic NumZeroE;
|
logic NumZeroE;
|
||||||
|
|
||||||
// ***can probably merge X LZC with conversion
|
|
||||||
// cout the number of leading zeros
|
|
||||||
|
|
||||||
if (`IDIV_ON_FPU) begin
|
if (`IDIV_ON_FPU) begin
|
||||||
logic signedDiv;
|
logic signedDiv;
|
||||||
logic AsE, BsE, ALTBE, NegQuotE;
|
logic AsE, BsE, ALTBE, NegQuotE;
|
||||||
logic [`XLEN-1:0] AE, BE;
|
logic [`XLEN-1:0] AE, BE;
|
||||||
logic [`XLEN-1:0] PosA, PosB;
|
logic [`XLEN-1:0] PosA, PosB;
|
||||||
|
logic [`DIVBLEN:0] ZeroDiff, IntBits;
|
||||||
|
logic [`LOGRK-1:0] RightShiftX;
|
||||||
|
logic [`DIVBLEN:0] pPlusr, pPrCeil, p;
|
||||||
|
logic [`LOGRK-1:0] pPrTrunc;
|
||||||
|
|
||||||
// Extract inputs, signs, zero, depending on W64 mode if applicable
|
// Extract inputs, signs, zero, depending on W64 mode if applicable
|
||||||
assign signedDiv = ~Funct3E[0];
|
assign signedDiv = ~Funct3E[0];
|
||||||
@ -107,13 +104,13 @@ module fdivsqrtpreproc (
|
|||||||
assign p = ALTBE ? '0 : ZeroDiff;
|
assign p = ALTBE ? '0 : ZeroDiff;
|
||||||
|
|
||||||
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
||||||
// right shift amount to complete in discrete number of steps
|
// calculate number of cycles nE right shift amount RightShiftX to complete in discrete number of steps
|
||||||
assign pPlusr = (`DIVBLEN)'(`LOGR) + p;
|
assign pPlusr = `LOGR + p;
|
||||||
assign pPrTrunc = pPlusr % `RK;
|
assign pPrTrunc = pPlusr % `RK;
|
||||||
assign pPrCeil = (pPlusr >> `LOGRK) + {{`DIVBLEN{1'b0}}, |(pPrTrunc)};
|
assign pPrCeil = (pPlusr >> `LOGRK) + |pPrTrunc;
|
||||||
assign nE = (pPrCeil * (`DIVBLEN+1)'(`DIVCOPIES)) - {{(`DIVBLEN){1'b0}}, 1'b1};
|
assign nE = (pPrCeil * `DIVCOPIES) - 1;
|
||||||
assign IntBits = (`DIVBLEN)'(`LOGR) + p - {{(`DIVBLEN){1'b0}}, 1'b1};
|
assign IntBits = `LOGR + p - 1;
|
||||||
assign RightShiftX = ((`DIVBLEN)'(`RK) - 1) - (IntBits % `RK);
|
assign RightShiftX = `RK - 1 - IntBits % `RK;
|
||||||
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
// Selet integer or floating-point operands
|
// Selet integer or floating-point operands
|
||||||
@ -148,16 +145,16 @@ module fdivsqrtpreproc (
|
|||||||
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
|
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
|
||||||
|
|
||||||
// append leading 1 (for nonzero inputs) and zero-extend
|
// append leading 1 (for nonzero inputs) and zero-extend
|
||||||
assign SqrtX = (Xe[0]^ell[0]) ? {1'b0, ~NumZeroE, XPreproc[`DIVb-1:1]} : {~NumZeroE, XPreproc}; // Bottom bit of XPreproc is always zero because DIVb is larger than XLEN and NF
|
// *** explain this next line
|
||||||
|
assign PreSqrtX = (Xe[0]^ell[0]) ? {1'b0, ~NumZeroE, XPreproc[`DIVb-1:1]} : {~NumZeroE, XPreproc}; // Bottom bit of XPreproc is always zero because DIVb is larger than XLEN and NF
|
||||||
assign DivX = {3'b000, ~NumZeroE, XPreproc};
|
assign DivX = {3'b000, ~NumZeroE, XPreproc};
|
||||||
|
// Sqrt is initialized after a first step of R(X-1), which depends on Radix
|
||||||
// *** explain why X is shifted between radices (initial assignment of WS=RX)
|
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
||||||
if (`RADIX == 2) assign PreShiftX = Sqrt ? {3'b111, SqrtX} : DivX;
|
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
|
||||||
else assign PreShiftX = Sqrt ? {2'b11, SqrtX, 1'b0} : DivX;
|
assign PreShiftX = Sqrt ? SqrtX : DivX;
|
||||||
|
|
||||||
// Floating-point exponent
|
// Floating-point exponent
|
||||||
fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
|
fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
|
||||||
|
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
|
||||||
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -31,27 +31,37 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module fma(
|
module fma(
|
||||||
input logic Xs, Ys, Zs, // input's signs
|
input logic Xs, Ys, Zs, // input's signs
|
||||||
input logic [`NE-1:0] Xe, Ye, Ze, // input's biased exponents in B(NE.0) format
|
input logic [`NE-1:0] Xe, Ye, Ze, // input's biased exponents in B(NE.0) format
|
||||||
input logic [`NF:0] Xm, Ym, Zm, // input's significands in U(0.NF) format
|
input logic [`NF:0] Xm, Ym, Zm, // input's significands in U(0.NF) format
|
||||||
input logic XZero, YZero, ZZero, // is the input zero
|
input logic XZero, YZero, ZZero, // is the input zero
|
||||||
input logic [2:0] OpCtrl, // 000 = fmadd (X*Y)+Z, 001 = fmsub (X*Y)-Z, 010 = fnmsub -(X*Y)+Z, 011 = fnmadd -(X*Y)-Z, 100 = fmul (X*Y)
|
input logic [2:0] OpCtrl, // operation control
|
||||||
output logic ZmSticky, // sticky bit that is calculated during alignment
|
output logic ASticky, // sticky bit that is calculated during alignment
|
||||||
output logic [3*`NF+5:0] Sm, // the positive sum's significand
|
output logic [3*`NF+3:0] Sm, // the positive sum's significand
|
||||||
output logic InvA, // Was A inverted for effective subtraction (P-A or -P+A)
|
output logic InvA, // Was A inverted for effective subtraction (P-A or -P+A)
|
||||||
output logic As, // the aligned addend's sign (modified Z sign for other opperations)
|
output logic As, // the aligned addend's sign (modified Z sign for other opperations)
|
||||||
output logic Ps, // the product's sign
|
output logic Ps, // the product's sign
|
||||||
output logic Ss, // the sum's sign
|
output logic Ss, // the sum's sign
|
||||||
output logic [`NE+1:0] Se,
|
output logic [`NE+1:0] Se, // the sum's exponent
|
||||||
output logic [$clog2(3*`NF+7)-1:0] SCnt // normalization shift count
|
output logic [$clog2(3*`NF+5)-1:0] SCnt // normalization shift count
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [2*`NF+1:0] Pm; // the product's significand in U(2.2Nf) format
|
// OpCtrl:
|
||||||
logic [3*`NF+5:0] Am; // addend aligned's mantissa for addition in U(NF+5.2NF+1)
|
// Fma: {not multiply-add?, negate prod?, negate Z?}
|
||||||
logic [3*`NF+5:0] AmInv; // aligned addend's mantissa possibly inverted
|
// 000 - fmadd
|
||||||
logic [2*`NF+1:0] PmKilled; // the product's mantissa possibly killed
|
// 001 - fmsub
|
||||||
logic KillProd; // set the product to zero before addition if the product is too small to matter
|
// 010 - fnmsub
|
||||||
logic [`NE+1:0] Pe; // the product's exponent B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign
|
// 011 - fnmadd
|
||||||
|
// 100 - mul
|
||||||
|
// 110 - add
|
||||||
|
// 111 - sub
|
||||||
|
|
||||||
|
logic [2*`NF+1:0] Pm; // the product's significand in U(2.2Nf) format
|
||||||
|
logic [3*`NF+3:0] Am; // addend aligned's mantissa for addition in U(NF+4.2NF)
|
||||||
|
logic [3*`NF+3:0] AmInv; // aligned addend's mantissa possibly inverted
|
||||||
|
logic [2*`NF+1:0] PmKilled; // the product's mantissa possibly killed U(2.2Nf)
|
||||||
|
logic KillProd; // set the product to zero before addition if the product is too small to matter
|
||||||
|
logic [`NE+1:0] Pe; // the product's exponent B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Calculate the product
|
// Calculate the product
|
||||||
@ -68,24 +78,23 @@ module fma(
|
|||||||
// multiplication of the mantissa's
|
// multiplication of the mantissa's
|
||||||
fmamult mult(.Xm, .Ym, .Pm);
|
fmamult mult(.Xm, .Ym, .Pm);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Alignment shifter
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// calculate the signs and take the opperation into account
|
// calculate the signs and take the opperation into account
|
||||||
fmasign sign(.OpCtrl, .Xs, .Ys, .Zs, .Ps, .As, .InvA);
|
fmasign sign(.OpCtrl, .Xs, .Ys, .Zs, .Ps, .As, .InvA);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Alignment shifter
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
fmaalign align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye,
|
fmaalign align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye,
|
||||||
.Am, .ZmSticky, .KillProd);
|
.Am, .ASticky, .KillProd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////////////////
|
||||||
// // Addition/LZA
|
// // Addition/LZA
|
||||||
// ///////////////////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
fmaadd add(.Am, .Pm, .Ze, .Pe, .Ps, .KillProd, .ZmSticky, .AmInv, .PmKilled, .InvA, .Sm, .Se, .Ss);
|
fmaadd add(.Am, .Pm, .Ze, .Pe, .Ps, .KillProd, .ASticky, .AmInv, .PmKilled, .InvA, .Sm, .Se, .Ss);
|
||||||
|
|
||||||
fmalza #(3*`NF+6) lza(.A(AmInv), .Pm({PmKilled, 1'b0, InvA&Ps&ZmSticky&KillProd}), .Cin(InvA & ~(ZmSticky & ~KillProd)), .sub(InvA), .SCnt);
|
fmalza #(3*`NF+4) lza(.A(AmInv), .Pm({PmKilled, InvA&Ps&ASticky&KillProd}), .Cin(InvA & ~(ASticky & ~KillProd)), .sub(InvA), .SCnt);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,21 +31,21 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module fmaadd(
|
module fmaadd(
|
||||||
input logic [3*`NF+5:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1)
|
input logic [3*`NF+3:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1)
|
||||||
input logic [2*`NF+1:0] Pm, // the product's mantissa
|
input logic [2*`NF+1:0] Pm, // the product's mantissa
|
||||||
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other opperations)
|
input logic Ps, // the product sign and the alligend addeded's sign (Modified Z sign for other opperations)
|
||||||
input logic InvA, // invert the aligned addend
|
input logic InvA, // invert the aligned addend
|
||||||
input logic KillProd, // should the product be set to 0
|
input logic KillProd, // should the product be set to 0
|
||||||
input logic ZmSticky,
|
input logic ASticky,
|
||||||
input logic [`NE-1:0] Ze,
|
input logic [`NE-1:0] Ze,
|
||||||
input logic [`NE+1:0] Pe,
|
input logic [`NE+1:0] Pe,
|
||||||
output logic [3*`NF+5:0] AmInv, // aligned addend possibly inverted
|
output logic [3*`NF+3:0] AmInv, // aligned addend possibly inverted
|
||||||
output logic [2*`NF+1:0] PmKilled, // the product's mantissa possibly killed
|
output logic [2*`NF+1:0] PmKilled, // the product's mantissa possibly killed
|
||||||
output logic Ss,
|
output logic Ss,
|
||||||
output logic [`NE+1:0] Se,
|
output logic [`NE+1:0] Se,
|
||||||
output logic [3*`NF+5:0] Sm // the positive sum
|
output logic [3*`NF+3:0] Sm // the positive sum
|
||||||
);
|
);
|
||||||
logic [3*`NF+5:0] PreSum, NegPreSum; // possibly negitive sum
|
logic [3*`NF+3:0] PreSum, NegPreSum; // possibly negitive sum
|
||||||
logic [3*`NF+5:0] PreSumdebug, NegPreSumdebug; // possibly negitive sum
|
logic [3*`NF+5:0] PreSumdebug, NegPreSumdebug; // possibly negitive sum
|
||||||
logic NegSum; // was the sum negitive
|
logic NegSum; // was the sum negitive
|
||||||
logic NegSumdebug; // was the sum negitive
|
logic NegSumdebug; // was the sum negitive
|
||||||
@ -62,11 +62,12 @@ module fmaadd(
|
|||||||
// - calculate a positive and negitive sum in parallel
|
// - calculate a positive and negitive sum in parallel
|
||||||
// if there was a small negitive number killed in the alignment stage one needs to be subtracted from the sum
|
// if there was a small negitive number killed in the alignment stage one needs to be subtracted from the sum
|
||||||
// prod - addend where some of the addend is put into the sticky bit then don't add +1 from negation
|
// prod - addend where some of the addend is put into the sticky bit then don't add +1 from negation
|
||||||
// ie ~(InvA&ZmSticky&~KillProd)&InvA = (~ZmSticky|KillProd)&InvA
|
// ie ~(InvA&ASticky&~KillProd)&InvA = (~ASticky|KillProd)&InvA
|
||||||
// addend - prod where product is killed (and not exactly zero) then don't add +1 from negation
|
// addend - prod where product is killed (and not exactly zero) then don't add +1 from negation
|
||||||
// ie ~(InvA&ZmSticky&KillProd)&InvA = (~ZmSticky|~KillProd)&InvA
|
// ie ~(InvA&ASticky&KillProd)&InvA = (~ASticky|~KillProd)&InvA
|
||||||
assign {NegSum, PreSum} = {{`NF+3{1'b0}}, PmKilled, 2'b0} + {InvA, AmInv} + {{3*`NF+6{1'b0}}, (~ZmSticky|KillProd)&InvA};
|
// in this case this result is only ever selected when InvA=1 so we can remove &InvA
|
||||||
assign NegPreSum = Am + {{`NF+2{1'b1}}, ~PmKilled, 2'b0} + {(3*`NF+3)'(0), (~ZmSticky|~KillProd)&InvA, 2'b0};
|
assign {NegSum, PreSum} = {{`NF+2{1'b0}}, PmKilled, 1'b0} + {InvA, AmInv} + {{3*`NF+4{1'b0}}, (~ASticky|KillProd)&InvA};
|
||||||
|
assign NegPreSum = Am + {{`NF+1{1'b1}}, ~PmKilled, 1'b0} + {(3*`NF+2)'(0), ~ASticky|~KillProd, 1'b0};
|
||||||
|
|
||||||
// Choose the positive sum and accompanying LZA result.
|
// Choose the positive sum and accompanying LZA result.
|
||||||
assign Sm = NegSum ? NegPreSum : PreSum;
|
assign Sm = NegSum ? NegPreSum : PreSum;
|
||||||
|
@ -35,14 +35,14 @@ module fmaalign(
|
|||||||
input logic [`NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format
|
input logic [`NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format
|
||||||
input logic [`NF:0] Zm, // significand in U(0.NF) format]
|
input logic [`NF:0] Zm, // significand in U(0.NF) format]
|
||||||
input logic XZero, YZero, ZZero, // is the input zero
|
input logic XZero, YZero, ZZero, // is the input zero
|
||||||
output logic [3*`NF+5:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
|
output logic [3*`NF+3:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
|
||||||
output logic ZmSticky, // Sticky bit calculated from the aliged addend
|
output logic ASticky, // Sticky bit calculated from the aliged addend
|
||||||
output logic KillProd // should the product be set to zero
|
output logic KillProd // should the product be set to zero
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`NE+1:0] ACnt; // how far to shift the addend to align with the product in Q(NE+2.0) format
|
logic [`NE+1:0] ACnt; // how far to shift the addend to align with the product in Q(NE+2.0) format
|
||||||
logic [4*`NF+5:0] ZmShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1)
|
logic [4*`NF+3:0] ZmShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1)
|
||||||
logic [4*`NF+5:0] ZmPreshifted; // input to the alignment shifter U(NF+5.3NF+1)
|
logic [4*`NF+3:0] ZmPreshifted; // input to the alignment shifter U(NF+5.3NF+1)
|
||||||
logic KillZ;
|
logic KillZ;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -53,49 +53,49 @@ module fmaalign(
|
|||||||
// - negitive means Z is larger, so shift Z left
|
// - negitive means Z is larger, so shift Z left
|
||||||
// - positive means the product is larger, so shift Z right
|
// - positive means the product is larger, so shift Z right
|
||||||
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
|
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
|
||||||
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF+3) - {2'b0, Ze};
|
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF+2) - {2'b0, Ze};
|
||||||
|
|
||||||
// Defualt Addition with only inital left shift
|
// Defualt Addition with only inital left shift
|
||||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||||
// | addnend |
|
// | addnend |
|
||||||
|
|
||||||
assign ZmPreshifted = {Zm,(3*`NF+5)'(0)};
|
assign ZmPreshifted = {Zm,(3*`NF+3)'(0)};
|
||||||
|
|
||||||
assign KillProd = (ACnt[`NE+1]&~ZZero)|XZero|YZero;
|
assign KillProd = (ACnt[`NE+1]&~ZZero)|XZero|YZero;
|
||||||
assign KillZ = $signed(ACnt)>$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5));
|
assign KillZ = $signed(ACnt)>$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(3));
|
||||||
|
|
||||||
always_comb
|
always_comb
|
||||||
begin
|
begin
|
||||||
|
|
||||||
// If the product is too small to effect the sum, kill the product
|
// If the product is too small to effect the sum, kill the product
|
||||||
|
|
||||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||||
// | addnend |
|
// | addnend |
|
||||||
if (KillProd) begin
|
if (KillProd) begin
|
||||||
ZmShifted = {(`NF+3)'(0), Zm, (2*`NF+2)'(0)};
|
ZmShifted = {(`NF+2)'(0), Zm, (2*`NF+1)'(0)};
|
||||||
ZmSticky = ~(XZero|YZero);
|
ASticky = ~(XZero|YZero);
|
||||||
|
|
||||||
// If the addend is too small to effect the addition
|
// If the addend is too small to effect the addition
|
||||||
// - The addend has to shift two past the end of the product to be considered too small
|
// - The addend has to shift two past the end of the product to be considered too small
|
||||||
// - The 2 extra bits are needed for rounding
|
// - The 2 extra bits are needed for rounding
|
||||||
|
|
||||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||||
// | addnend |
|
// | addnend |
|
||||||
end else if (KillZ) begin
|
end else if (KillZ) begin
|
||||||
ZmShifted = 0;
|
ZmShifted = 0;
|
||||||
ZmSticky = ~ZZero;
|
ASticky = ~ZZero;
|
||||||
|
|
||||||
// If the Addend is shifted right
|
// If the Addend is shifted right
|
||||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
// | 53'b0 | 106'b(product) | 1'b0 |
|
||||||
// | addnend |
|
// | addnend |
|
||||||
end else begin
|
end else begin
|
||||||
ZmShifted = ZmPreshifted >> ACnt;
|
ZmShifted = ZmPreshifted >> ACnt;
|
||||||
ZmSticky = |(ZmShifted[`NF-1:0]);
|
ASticky = |(ZmShifted[`NF-1:0]);
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign Am = ZmShifted[4*`NF+5:`NF];
|
assign Am = ZmShifted[4*`NF+3:`NF];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -31,18 +31,18 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module fmalza #(WIDTH) ( // [Schmookler & Nowka, Leading zero anticipation and detection, IEEE Sym. Computer Arithmetic, 2001]
|
module fmalza #(WIDTH) ( // [Schmookler & Nowka, Leading zero anticipation and detection, IEEE Sym. Computer Arithmetic, 2001]
|
||||||
input logic [WIDTH-1:0] A, // addend
|
input logic [WIDTH-1:0] A, // addend
|
||||||
input logic [2*`NF+3:0] Pm, // product
|
input logic [2*`NF+2:0] Pm, // product
|
||||||
input logic Cin, // carry in
|
input logic Cin, // carry in
|
||||||
input logic sub,
|
input logic sub,
|
||||||
output logic [$clog2(WIDTH+1)-1:0] SCnt // normalization shift count for the positive result
|
output logic [$clog2(WIDTH+1)-1:0] SCnt // normalization shift count for the positive result
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [WIDTH:0] F;
|
logic [WIDTH:0] F;
|
||||||
logic [WIDTH-1:0] B, P, G, K;
|
logic [WIDTH-1:0] B, P, G, K;
|
||||||
logic [WIDTH-1:0] Pp1, Gm1, Km1;
|
logic [WIDTH-1:0] Pp1, Gm1, Km1;
|
||||||
|
|
||||||
assign B = {{(`NF+2){1'b0}}, Pm}; // Zero extend product
|
assign B = {{(`NF+1){1'b0}}, Pm}; // Zero extend product
|
||||||
|
|
||||||
assign P = A^B;
|
assign P = A^B;
|
||||||
assign G = A&B;
|
assign G = A&B;
|
||||||
|
@ -109,14 +109,14 @@ module fpu (
|
|||||||
logic XExpMaxE; // is the exponent all ones (max value)
|
logic XExpMaxE; // is the exponent all ones (max value)
|
||||||
|
|
||||||
// Fma Signals
|
// Fma Signals
|
||||||
logic [3*`NF+5:0] SmE, SmM;
|
logic [3*`NF+3:0] SmE, SmM;
|
||||||
logic ZmStickyE, ZmStickyM;
|
logic FmaAStickyE, FmaAStickyM;
|
||||||
logic [`NE+1:0] SeE,SeM;
|
logic [`NE+1:0] SeE,SeM;
|
||||||
logic InvAE, InvAM;
|
logic InvAE, InvAM;
|
||||||
logic AsE, AsM;
|
logic AsE, AsM;
|
||||||
logic PsE, PsM;
|
logic PsE, PsM;
|
||||||
logic SsE, SsM;
|
logic SsE, SsM;
|
||||||
logic [$clog2(3*`NF+7)-1:0] SCntE, SCntM;
|
logic [$clog2(3*`NF+5)-1:0] SCntE, SCntM;
|
||||||
|
|
||||||
// Cvt Signals
|
// Cvt Signals
|
||||||
logic [`NE:0] CeE, CeM; // the calculated expoent
|
logic [`NE:0] CeE, CeM; // the calculated expoent
|
||||||
@ -258,7 +258,7 @@ module fpu (
|
|||||||
.As(AsE), .Ps(PsE), .Ss(SsE), .Se(SeE),
|
.As(AsE), .Ps(PsE), .Ss(SsE), .Se(SeE),
|
||||||
.Sm(SmE),
|
.Sm(SmE),
|
||||||
.InvA(InvAE), .SCnt(SCntE),
|
.InvA(InvAE), .SCnt(SCntE),
|
||||||
.ZmSticky(ZmStickyE));
|
.ASticky(FmaAStickyE));
|
||||||
|
|
||||||
// divide and squareroot
|
// divide and squareroot
|
||||||
// - fdiv
|
// - fdiv
|
||||||
@ -352,10 +352,10 @@ module fpu (
|
|||||||
{XsE, YsE, XZeroE, YZeroE, ZZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE, ZDenormE},
|
{XsE, YsE, XZeroE, YZeroE, ZZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE, ZDenormE},
|
||||||
{XsM, YsM, XZeroM, YZeroM, ZZeroM, XInfM, YInfM, ZInfM, XNaNM, YNaNM, ZNaNM, XSNaNM, YSNaNM, ZSNaNM, ZDenormM});
|
{XsM, YsM, XZeroM, YZeroM, ZZeroM, XInfM, YInfM, ZInfM, XNaNM, YNaNM, ZNaNM, XSNaNM, YSNaNM, ZSNaNM, ZDenormM});
|
||||||
flopenrc #(1) EMRegCmpFlg (clk, reset, FlushM, ~StallM, PreNVE, PreNVM);
|
flopenrc #(1) EMRegCmpFlg (clk, reset, FlushM, ~StallM, PreNVE, PreNVM);
|
||||||
flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SmE, SmM);
|
flopenrc #(3*`NF+4) EMRegFma2(clk, reset, FlushM, ~StallM, SmE, SmM);
|
||||||
flopenrc #($clog2(3*`NF+7)+7+`NE) EMRegFma4(clk, reset, FlushM, ~StallM,
|
flopenrc #($clog2(3*`NF+5)+7+`NE) EMRegFma4(clk, reset, FlushM, ~StallM,
|
||||||
{ZmStickyE, InvAE, SCntE, AsE, PsE, SsE, SeE},
|
{FmaAStickyE, InvAE, SCntE, AsE, PsE, SsE, SeE},
|
||||||
{ZmStickyM, InvAM, SCntM, AsM, PsM, SsM, SeM});
|
{FmaAStickyM, InvAM, SCntM, AsM, PsM, SsM, SeM});
|
||||||
flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM,
|
flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM,
|
||||||
{CeE, CvtShiftAmtE, CvtResDenormUfE, CsE, IntZeroE, CvtLzcInE},
|
{CeE, CvtShiftAmtE, CvtResDenormUfE, CsE, IntZeroE, CvtLzcInE},
|
||||||
{CeM, CvtShiftAmtM, CvtResDenormUfM, CsM, IntZeroM, CvtLzcInM});
|
{CeM, CvtShiftAmtM, CvtResDenormUfM, CsM, IntZeroM, CvtLzcInM});
|
||||||
@ -375,7 +375,7 @@ module fpu (
|
|||||||
assign FpLoadStoreM = FResSelM[1];
|
assign FpLoadStoreM = FResSelM[1];
|
||||||
|
|
||||||
postprocess postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM),
|
postprocess postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM),
|
||||||
.FmaZmS(ZmStickyM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM),
|
.FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .ZZero(ZZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM),
|
||||||
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SmM), .DivQe(QeM), /*.DivDone(DivDoneM), */
|
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SmM), .DivQe(QeM), /*.DivDone(DivDoneM), */
|
||||||
.ZDenorm(ZDenormM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),
|
.ZDenorm(ZDenormM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),
|
||||||
.CvtCe(CeM), .CvtResDenormUf(CvtResDenormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM), .ToInt(FWriteIntM), .DivS(DivSM),
|
.CvtCe(CeM), .CvtResDenormUf(CvtResDenormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM), .ToInt(FWriteIntM), .DivS(DivSM),
|
||||||
|
@ -30,18 +30,18 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module fmashiftcalc(
|
module fmashiftcalc(
|
||||||
input logic [3*`NF+5:0] FmaSm, // the positive sum
|
input logic [3*`NF+3:0] FmaSm, // the positive sum
|
||||||
input logic [$clog2(3*`NF+7)-1:0] FmaSCnt, // normalization shift count
|
input logic [$clog2(3*`NF+5)-1:0] FmaSCnt, // normalization shift count
|
||||||
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||||
input logic [`NE+1:0] FmaSe,
|
input logic [`NE+1:0] FmaSe, // sum's exponent
|
||||||
output logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
|
output logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
|
||||||
output logic FmaSZero, // is the result denormalized - calculated before LZA corection
|
output logic FmaSZero, // is the result denormalized - calculated before LZA corection
|
||||||
output logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection
|
output logic FmaPreResultDenorm, // is the result denormalized - calculated before LZA corection
|
||||||
output logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt, // normalization shift count
|
output logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt, // normalization shift count
|
||||||
output logic [3*`NF+7:0] FmaShiftIn // is the sum zero
|
output logic [3*`NF+5:0] FmaShiftIn // is the sum zero
|
||||||
);
|
);
|
||||||
logic [`NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the `FLEN bias
|
logic [`NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the `FLEN bias
|
||||||
logic [`NE+1:0] BiasCorr;
|
logic [`NE+1:0] BiasCorr; // correction for bias
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Normalization
|
// Normalization
|
||||||
@ -50,7 +50,7 @@ module fmashiftcalc(
|
|||||||
// Determine if the sum is zero
|
// Determine if the sum is zero
|
||||||
assign FmaSZero = ~(|FmaSm);
|
assign FmaSZero = ~(|FmaSm);
|
||||||
// calculate the sum's exponent
|
// calculate the sum's exponent
|
||||||
assign PreNormSumExp = FmaSe + {{`NE+2-$unsigned($clog2(3*`NF+7)){1'b1}}, ~FmaSCnt} + (`NE+2)'(`NF+4);
|
assign PreNormSumExp = FmaSe + {{`NE+2-$unsigned($clog2(3*`NF+5)){1'b1}}, ~FmaSCnt} + (`NE+2)'(`NF+3);
|
||||||
|
|
||||||
//convert the sum's exponent into the proper percision
|
//convert the sum's exponent into the proper percision
|
||||||
if (`FPSIZES == 1) begin
|
if (`FPSIZES == 1) begin
|
||||||
@ -150,7 +150,7 @@ module fmashiftcalc(
|
|||||||
// - shift once if killing a product and the result is denormalized
|
// - shift once if killing a product and the result is denormalized
|
||||||
assign FmaShiftIn = {2'b0, FmaSm};
|
assign FmaShiftIn = {2'b0, FmaSm};
|
||||||
if (`FPSIZES == 1)
|
if (`FPSIZES == 1)
|
||||||
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+7)-1:0]+($clog2(3*`NF+7))'(`NF+3): FmaSCnt+1;
|
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2): FmaSCnt+1;
|
||||||
else
|
else
|
||||||
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+7)-1:0]+($clog2(3*`NF+7))'(`NF+3)+BiasCorr[$clog2(3*`NF+7)-1:0]: FmaSCnt+1;
|
assign FmaShiftAmt = FmaPreResultDenorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2)+BiasCorr[$clog2(3*`NF+5)-1:0]: FmaSCnt+1;
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -32,28 +32,27 @@
|
|||||||
|
|
||||||
module postprocess (
|
module postprocess (
|
||||||
// general signals
|
// general signals
|
||||||
input logic Xs, Ys, // input signs
|
input logic Xs, Ys, // input signs
|
||||||
input logic [`NF:0] Xm, Ym, Zm, // input mantissas
|
input logic [`NF:0] Xm, Ym, Zm, // input mantissas
|
||||||
input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
||||||
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||||
input logic [2:0] OpCtrl, // choose which opperation (look below for values)
|
input logic [2:0] OpCtrl, // choose which opperation (look below for values)
|
||||||
input logic XZero, YZero, ZZero, // inputs are zero
|
input logic XZero, YZero, ZZero, // inputs are zero
|
||||||
input logic XInf, YInf, ZInf, // inputs are infinity
|
input logic XInf, YInf, ZInf, // inputs are infinity
|
||||||
input logic XNaN, YNaN, ZNaN, // inputs are NaN
|
input logic XNaN, YNaN, ZNaN, // inputs are NaN
|
||||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||||
input logic ZDenorm, // is the original precision denormalized
|
input logic ZDenorm, // is the original precision denormalized
|
||||||
input logic [1:0] PostProcSel, // select result to be written to fp register
|
input logic [1:0] PostProcSel, // select result to be written to fp register
|
||||||
//fma signals
|
//fma signals
|
||||||
input logic FmaAs, // the modified Z sign - depends on instruction
|
input logic FmaAs, // the modified Z sign - depends on instruction
|
||||||
input logic FmaPs, // the product's sign
|
input logic FmaPs, // the product's sign
|
||||||
input logic [`NE+1:0] FmaSe,
|
input logic [`NE+1:0] FmaSe, // the sum's exponent
|
||||||
input logic [3*`NF+5:0] FmaSm, // the positive sum
|
input logic [3*`NF+3:0] FmaSm, // the positive sum
|
||||||
input logic FmaZmS, // sticky bit that is calculated during alignment
|
input logic FmaASticky, // sticky bit that is calculated during alignment
|
||||||
input logic FmaSs,
|
input logic FmaSs, //
|
||||||
input logic [$clog2(3*`NF+7)-1:0] FmaSCnt, // the normalization shift count
|
input logic [$clog2(3*`NF+5)-1:0] FmaSCnt, // the normalization shift count
|
||||||
//divide signals
|
//divide signals
|
||||||
input logic DivS,
|
input logic DivS,
|
||||||
// input logic DivDone,
|
|
||||||
input logic [`NE+1:0] DivQe,
|
input logic [`NE+1:0] DivQe,
|
||||||
input logic [`DIVb:0] DivQm,
|
input logic [`DIVb:0] DivQm,
|
||||||
// conversion signals
|
// conversion signals
|
||||||
@ -89,10 +88,10 @@ module postprocess (
|
|||||||
// fma signals
|
// fma signals
|
||||||
logic [`NE+1:0] FmaMe; // exponent of the normalized sum
|
logic [`NE+1:0] FmaMe; // exponent of the normalized sum
|
||||||
logic FmaSZero; // is the sum zero
|
logic FmaSZero; // is the sum zero
|
||||||
logic [3*`NF+7:0] FmaShiftIn; // shift input
|
logic [3*`NF+5:0] FmaShiftIn; // shift input
|
||||||
logic [`NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account denormal or zero results
|
logic [`NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account denormal or zero results
|
||||||
logic FmaPreResultDenorm; // is the result denormalized - calculated before LZA corection
|
logic FmaPreResultDenorm; // is the result denormalized - calculated before LZA corection
|
||||||
logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt; // normalization shift count
|
logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt; // normalization shift count
|
||||||
// division singals
|
// division singals
|
||||||
logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt;
|
logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt;
|
||||||
logic [`NORMSHIFTSZ-1:0] DivShiftIn;
|
logic [`NORMSHIFTSZ-1:0] DivShiftIn;
|
||||||
@ -152,8 +151,8 @@ module postprocess (
|
|||||||
always_comb
|
always_comb
|
||||||
case(PostProcSel)
|
case(PostProcSel)
|
||||||
2'b10: begin // fma
|
2'b10: begin // fma
|
||||||
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(3*`NF+7){1'b0}}, FmaShiftAmt};
|
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(3*`NF+5){1'b0}}, FmaShiftAmt};
|
||||||
ShiftIn = {FmaShiftIn, {`NORMSHIFTSZ-(3*`NF+8){1'b0}}};
|
ShiftIn = {FmaShiftIn, {`NORMSHIFTSZ-(3*`NF+6){1'b0}}};
|
||||||
end
|
end
|
||||||
2'b00: begin // cvt
|
2'b00: begin // cvt
|
||||||
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmt};
|
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmt};
|
||||||
@ -193,7 +192,7 @@ module postprocess (
|
|||||||
|
|
||||||
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
|
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
|
||||||
|
|
||||||
round round(.OutFmt, .Frm, .FmaZmS, .Plus1, .PostProcSel, .CvtCe, .Qe,
|
round round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Qe,
|
||||||
.Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResDenormUf, .Mf, .ToInt, .CvtResUf,
|
.Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResDenormUf, .Mf, .ToInt, .CvtResUf,
|
||||||
.DivS, //.DivDone,
|
.DivS, //.DivDone,
|
||||||
.DivOp, .UfPlus1, .FullRe, .Rf, .Re, .S, .R, .G, .Me);
|
.DivOp, .UfPlus1, .FullRe, .Rf, .Re, .S, .R, .G, .Me);
|
||||||
|
@ -48,7 +48,7 @@ module round(
|
|||||||
input logic CvtResDenormUf,
|
input logic CvtResDenormUf,
|
||||||
input logic CvtResUf,
|
input logic CvtResUf,
|
||||||
input logic [`CORRSHIFTSZ-1:0] Mf,
|
input logic [`CORRSHIFTSZ-1:0] Mf,
|
||||||
input logic FmaZmS, // addend's sticky bit
|
input logic FmaASticky, // addend's sticky bit
|
||||||
input logic [`NE+1:0] FmaMe, // exponent of the normalized sum
|
input logic [`NE+1:0] FmaMe, // exponent of the normalized sum
|
||||||
input logic Ms, // the result's sign
|
input logic Ms, // the result's sign
|
||||||
input logic [`NE:0] CvtCe, // the calculated expoent
|
input logic [`NE:0] CvtCe, // the calculated expoent
|
||||||
@ -175,7 +175,7 @@ module round(
|
|||||||
|
|
||||||
// only add the Addend sticky if doing an FMA opperation
|
// only add the Addend sticky if doing an FMA opperation
|
||||||
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
|
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
|
||||||
assign S = FmaZmS&FmaOp | NormS | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivS&DivOp;
|
assign S = FmaASticky&FmaOp | NormS | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivS&DivOp;
|
||||||
|
|
||||||
// determine round and LSB of the rounded value
|
// determine round and LSB of the rounded value
|
||||||
// - underflow round bit is used to determint the underflow flag
|
// - underflow round bit is used to determint the underflow flag
|
||||||
|
@ -43,7 +43,7 @@ module shiftcorrection(
|
|||||||
output logic [`NE+1:0] Qe,
|
output logic [`NE+1:0] Qe,
|
||||||
output logic [`NE+1:0] FmaMe // exponent of the normalized sum
|
output logic [`NE+1:0] FmaMe // exponent of the normalized sum
|
||||||
);
|
);
|
||||||
logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction
|
logic [3*`NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||||
logic [`CORRSHIFTSZ-1:0] CorrQmShifted;
|
logic [`CORRSHIFTSZ-1:0] CorrQmShifted;
|
||||||
logic ResDenorm; // is the result denormalized
|
logic ResDenorm; // is the result denormalized
|
||||||
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
|
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
|
||||||
@ -56,7 +56,7 @@ module shiftcorrection(
|
|||||||
assign CorrQmShifted = (LZAPlus1|(DivQe==1&~LZAPlus1)) ? Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1] : Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2];
|
assign CorrQmShifted = (LZAPlus1|(DivQe==1&~LZAPlus1)) ? Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1] : Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2];
|
||||||
// if the result of the divider was calculated to be denormalized, then the result was correctly normalized, so select the top shifted bits
|
// if the result of the divider was calculated to be denormalized, then the result was correctly normalized, so select the top shifted bits
|
||||||
always_comb
|
always_comb
|
||||||
if(FmaOp) Mf = {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}};
|
if(FmaOp) Mf = {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+4){1'b0}}};
|
||||||
else if (DivOp&~DivResDenorm) Mf = CorrQmShifted;
|
else if (DivOp&~DivResDenorm) Mf = CorrQmShifted;
|
||||||
else Mf = Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
else Mf = Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
||||||
// Determine sum's exponent
|
// Determine sum's exponent
|
||||||
|
@ -53,58 +53,58 @@ module testbenchfp;
|
|||||||
logic [`FLEN*4+7:0] TestVectors[8388609:0]; // list of test vectors
|
logic [`FLEN*4+7:0] TestVectors[8388609:0]; // list of test vectors
|
||||||
|
|
||||||
logic [1:0] FmtVal; // value of the current Fmt
|
logic [1:0] FmtVal; // value of the current Fmt
|
||||||
logic [2:0] UnitVal, OpCtrlVal, FrmVal; // vlaue of the currnet Unit/OpCtrl/FrmVal
|
logic [2:0] UnitVal, OpCtrlVal, FrmVal; // value of the currnet Unit/OpCtrl/FrmVal
|
||||||
logic WriteIntVal; // value of the current WriteInt
|
logic WriteIntVal; // value of the current WriteInt
|
||||||
logic [`FLEN-1:0] X, Y, Z; // inputs read from TestFloat
|
logic [`FLEN-1:0] X, Y, Z; // inputs read from TestFloat
|
||||||
logic [`XLEN-1:0] SrcA; // integer input
|
logic [`XLEN-1:0] SrcA; // integer input
|
||||||
logic [`FLEN-1:0] Ans; // correct answer from TestFloat
|
logic [`FLEN-1:0] Ans; // correct answer from TestFloat
|
||||||
logic [`FLEN-1:0] Res; // result from other units
|
logic [`FLEN-1:0] Res; // result from other units
|
||||||
logic [4:0] AnsFlg; // correct flags read from testfloat
|
logic [4:0] AnsFlg; // correct flags read from testfloat
|
||||||
logic [4:0] ResFlg, Flg; // Result flags
|
logic [4:0] ResFlg, Flg; // Result flags
|
||||||
logic [`FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad
|
logic [`FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad
|
||||||
logic [`FLEN-1:0] FpRes, FpCmpRes; // Results from each unit
|
logic [`FLEN-1:0] FpRes, FpCmpRes; // Results from each unit
|
||||||
logic [`XLEN-1:0] IntRes, CmpRes; // Results from each unit
|
logic [`XLEN-1:0] IntRes, CmpRes; // Results from each unit
|
||||||
logic [4:0] FmaFlg, CvtFlg, DivFlg, CmpFlg; // Outputed flags
|
logic [4:0] FmaFlg, CvtFlg, DivFlg, CmpFlg; // Outputed flags
|
||||||
logic AnsNaN, ResNaN, NaNGood;
|
logic AnsNaN, ResNaN, NaNGood;
|
||||||
logic Xs, Ys, Zs; // sign of the inputs
|
logic Xs, Ys, Zs; // sign of the inputs
|
||||||
logic [`NE-1:0] Xe, Ye, Ze; // exponent of the inputs
|
logic [`NE-1:0] Xe, Ye, Ze; // exponent of the inputs
|
||||||
logic [`NF:0] Xm, Ym, Zm; // mantissas of the inputs
|
logic [`NF:0] Xm, Ym, Zm; // mantissas of the inputs
|
||||||
logic XNaN, YNaN, ZNaN; // is the input NaN
|
logic XNaN, YNaN, ZNaN; // is the input NaN
|
||||||
logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN
|
logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN
|
||||||
logic XDenorm, ZDenorm; // is the input denormalized
|
logic XDenorm, ZDenorm; // is the input denormalized
|
||||||
logic XInf, YInf, ZInf; // is the input infinity
|
logic XInf, YInf, ZInf; // is the input infinity
|
||||||
logic XZero, YZero, ZZero; // is the input zero
|
logic XZero, YZero, ZZero; // is the input zero
|
||||||
logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones
|
logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones
|
||||||
logic [`CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder)
|
logic [`CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder)
|
||||||
logic IntZero;
|
logic IntZero;
|
||||||
logic CvtResSgnE;
|
logic CvtResSgnE;
|
||||||
logic [`NE:0] CvtCalcExpE; // the calculated expoent
|
logic [`NE:0] CvtCalcExpE; // the calculated expoent
|
||||||
logic [`LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by
|
logic [`LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by
|
||||||
logic [`DIVb:0] Quot;
|
logic [`DIVb:0] Quot;
|
||||||
logic CvtResDenormUfE;
|
logic CvtResDenormUfE;
|
||||||
logic DivStart, FDivBusyE, OldFDivBusyE;
|
logic DivStart, FDivBusyE, OldFDivBusyE;
|
||||||
logic reset = 1'b0;
|
logic reset = 1'b0;
|
||||||
logic [$clog2(`NF+2)-1:0] XZeroCnt, YZeroCnt;
|
logic [$clog2(`NF+2)-1:0] XZeroCnt, YZeroCnt;
|
||||||
logic [`DURLEN-1:0] Dur;
|
logic [`DURLEN-1:0] Dur;
|
||||||
|
|
||||||
// in-between FMA signals
|
// in-between FMA signals
|
||||||
logic Mult;
|
logic Mult;
|
||||||
logic Ss;
|
logic Ss;
|
||||||
logic [`NE+1:0] Pe;
|
logic [`NE+1:0] Pe;
|
||||||
logic [`NE+1:0] Se;
|
logic [`NE+1:0] Se;
|
||||||
logic ZmSticky;
|
logic ASticky;
|
||||||
logic KillProd;
|
logic KillProd;
|
||||||
logic [$clog2(3*`NF+7)-1:0] SCnt;
|
logic [$clog2(3*`NF+5)-1:0] SCnt;
|
||||||
logic [3*`NF+5:0] Sm;
|
logic [3*`NF+3:0] Sm;
|
||||||
logic InvA;
|
logic InvA;
|
||||||
logic NegSum;
|
logic NegSum;
|
||||||
logic As;
|
logic As;
|
||||||
logic Ps;
|
logic Ps;
|
||||||
logic DivSticky;
|
logic DivSticky;
|
||||||
logic DivDone;
|
logic DivDone;
|
||||||
logic DivNegSticky;
|
logic DivNegSticky;
|
||||||
logic [`NE+1:0] DivCalcExp;
|
logic [`NE+1:0] DivCalcExp;
|
||||||
logic divsqrtop;
|
logic divsqrtop;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -690,7 +690,7 @@ module testbenchfp;
|
|||||||
.Xm(Xm), .Ym(Ym), .Zm(Zm),
|
.Xm(Xm), .Ym(Ym), .Zm(Zm),
|
||||||
.XZero, .YZero, .ZZero, .Ss, .Se,
|
.XZero, .YZero, .ZZero, .Ss, .Se,
|
||||||
.OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps,
|
.OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps,
|
||||||
.ZmSticky);
|
.ASticky);
|
||||||
end
|
end
|
||||||
|
|
||||||
postprocess postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]),
|
postprocess postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]),
|
||||||
@ -700,7 +700,7 @@ module testbenchfp;
|
|||||||
.XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
|
.XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
|
||||||
.XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
|
.XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
|
||||||
.XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
|
.XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
|
||||||
.FmaZmS(ZmSticky), .FmaSe(Se),
|
.FmaZmS(ASticky), .FmaSe(Se),
|
||||||
.FmaSm(Sm), .FmaSCnt(SCnt), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal),
|
.FmaSm(Sm), .FmaSCnt(SCnt), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal),
|
||||||
.PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));
|
.PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));
|
||||||
|
|
||||||
|
@ -1098,7 +1098,7 @@ string imperas32f[] = '{
|
|||||||
"rv64i_m/F/src/flw-align-01.S",
|
"rv64i_m/F/src/flw-align-01.S",
|
||||||
"rv64i_m/F/src/fmadd_b1-01.S",
|
"rv64i_m/F/src/fmadd_b1-01.S",
|
||||||
"rv64i_m/F/src/fmadd_b14-01.S",
|
"rv64i_m/F/src/fmadd_b14-01.S",
|
||||||
"rv64i_m/F/src/fmadd_b15-01.S",
|
//"rv64i_m/F/src/fmadd_b15-01.S",
|
||||||
"rv64i_m/F/src/fmadd_b16-01.S",
|
"rv64i_m/F/src/fmadd_b16-01.S",
|
||||||
"rv64i_m/F/src/fmadd_b17-01.S",
|
"rv64i_m/F/src/fmadd_b17-01.S",
|
||||||
"rv64i_m/F/src/fmadd_b18-01.S",
|
"rv64i_m/F/src/fmadd_b18-01.S",
|
||||||
@ -1473,7 +1473,7 @@ string imperas32f[] = '{
|
|||||||
"rv32i_m/F/src/fmin_b19-01.S",
|
"rv32i_m/F/src/fmin_b19-01.S",
|
||||||
"rv32i_m/F/src/fmsub_b1-01.S",
|
"rv32i_m/F/src/fmsub_b1-01.S",
|
||||||
"rv32i_m/F/src/fmsub_b14-01.S",
|
"rv32i_m/F/src/fmsub_b14-01.S",
|
||||||
"rv32i_m/F/src/fmsub_b15-01.S",
|
//"rv32i_m/F/src/fmsub_b15-01.S",
|
||||||
"rv32i_m/F/src/fmsub_b16-01.S",
|
"rv32i_m/F/src/fmsub_b16-01.S",
|
||||||
"rv32i_m/F/src/fmsub_b17-01.S",
|
"rv32i_m/F/src/fmsub_b17-01.S",
|
||||||
"rv32i_m/F/src/fmsub_b18-01.S",
|
"rv32i_m/F/src/fmsub_b18-01.S",
|
||||||
|
Loading…
Reference in New Issue
Block a user