Line 27... |
Line 27... |
|
|
`include "positConfig.sv"
|
`include "positConfig.sv"
|
|
|
module positAddsub(op, a, b, o);
|
module positAddsub(op, a, b, o);
|
`include "positSize.sv"
|
`include "positSize.sv"
|
localparam rs = $clog2(PSTWID-1)-1;
|
localparam rs = $clog2(PSTWID-1);
|
input op;
|
input op;
|
input [PSTWID-1:0] a;
|
input [PSTWID-1:0] a;
|
input [PSTWID-1:0] b;
|
input [PSTWID-1:0] b;
|
output reg [PSTWID-1:0] o;
|
output reg [PSTWID-1:0] o;
|
|
|
Line 114... |
Line 114... |
endgenerate
|
endgenerate
|
|
|
//positCntlz #(.PSTWID(PSTWID)) u3 (.i({|sigov,sig_sd[PSTWID-2:0]}), .o(lzcnt));
|
//positCntlz #(.PSTWID(PSTWID)) u3 (.i({|sigov,sig_sd[PSTWID-2:0]}), .o(lzcnt));
|
wire [PSTWID*2-1:0] sig_ls = sig_sd[PSTWID*2-1:0] << lzcnt;
|
wire [PSTWID*2-1:0] sig_ls = sig_sd[PSTWID*2-1:0] << lzcnt;
|
|
|
wire [rs:0] absrgm1 = rgs1 ? rgm1 : -rgm1; // rgs1 = 1 = positive
|
wire [rs+1:0] absrgm1 = rgs1 ? rgm1 : -rgm1; // rgs1 = 1 = positive
|
wire [es+rs+1:0] rxtmp;
|
wire [es+rs+1:0] rxtmp;
|
wire [es+rs+1:0] rxtmp1;
|
wire [es+rs+1:0] rxtmp1;
|
wire srxtmp1;
|
wire srxtmp1;
|
wire [es+rs:0] abs_rxtmp;
|
wire [es+rs:0] abs_rxtmp;
|
wire [(es==0 ? 0 : es-1):0] expo;
|
wire [(es==0 ? 0 : es-1):0] expo;
|
wire [rs:0] rgmo;
|
wire [rs:0] rgmo;
|
generate begin : gEsz
|
generate begin : gEsz
|
if (es > 0) begin
|
if (es > 0) begin
|
assign rxtmp = {absrgm1,exp1} - {{es+1{1'b0}},lzcnt-es};
|
assign rxtmp = {absrgm1,exp1} + es - {{es+1{1'b0}},lzcnt};
|
assign rxtmp1 = rxtmp + sigov[1]; // add in overflow if any
|
assign rxtmp1 = rxtmp + sigov[1]; // add in overflow if any
|
assign srxtmp1 = rxtmp1[es+rs+1];
|
assign srxtmp1 = rxtmp1[es+rs+1];
|
assign abs_rxtmp = srxtmp1 ? -rxtmp1 : rxtmp1;
|
assign abs_rxtmp = srxtmp1 ? -rxtmp1 : rxtmp1;
|
|
|
assign expo = (srxtmp1 & |abs_rxtmp[es-1:0]) ? rxtmp1[es-1:0] : abs_rxtmp[es-1:0];
|
assign expo = (srxtmp1 & |abs_rxtmp[es-1:0]) ? rxtmp1[es-1:0] : abs_rxtmp[es-1:0];
|
assign rgmo = (~srxtmp1 || (srxtmp1 & |abs_rxtmp[es-1:0])) ? abs_rxtmp[es+rs:es] + 1'b1 : abs_rxtmp[es+rs:es];
|
assign rgmo = (~srxtmp1 || (|abs_rxtmp[es-1:0])) ? abs_rxtmp[es+rs:es] + 1'b1 : abs_rxtmp[es+rs:es];
|
end
|
end
|
else begin
|
else begin
|
assign rxtmp = absrgm1 - {{1{1'b0}},lzcnt};
|
assign rxtmp = absrgm1 - {{1{1'b0}},lzcnt};
|
assign rxtmp1 = rxtmp + sigov[1]; // add in overflow if any
|
assign rxtmp1 = rxtmp + sigov[1]; // add in overflow if any
|
assign srxtmp1 = rxtmp1[rs+1];
|
assign srxtmp1 = rxtmp1[rs+1];
|
Line 155... |
Line 155... |
endcase
|
endcase
|
|
|
wire [3*PSTWID-1+3:0] tmp1 = {tmp,{PSTWID{1'b0}}} >> rgmo;
|
wire [3*PSTWID-1+3:0] tmp1 = {tmp,{PSTWID{1'b0}}} >> rgmo;
|
|
|
// Rounding
|
// Rounding
|
// Gaurd, Round, and Sticky
|
// Guard, Round, and Sticky
|
wire L = tmp1[PSTWID+4], G = tmp1[PSTWID+3], R = tmp1[PSTWID+2], St = |tmp1[PSTWID+1:0],
|
wire L = tmp1[PSTWID+4], G = tmp1[PSTWID+3], R = tmp1[PSTWID+2], St = |tmp1[PSTWID+1:0],
|
ulp = ((G & (R | St)) | (L & G & ~(R | St)));
|
ulp = ((G & (R | St)) | (L & G & ~(R | St)));
|
wire [PSTWID-1:0] rnd_ulp = {{PSTWID-1{1'b0}},ulp};
|
wire [PSTWID-1:0] rnd_ulp = {{PSTWID-1{1'b0}},ulp};
|
|
|
wire [PSTWID:0] tmp1_rnd_ulp = tmp1[2*PSTWID-1+3:PSTWID+3] + rnd_ulp;
|
wire [PSTWID:0] tmp1_rnd_ulp = tmp1[2*PSTWID-1+3:PSTWID+3] + rnd_ulp;
|
Line 180... |
Line 180... |
endcase
|
endcase
|
|
|
wire [PSTWID-1:0] abs_tmp = so ? -tmp1_rnd : tmp1_rnd;
|
wire [PSTWID-1:0] abs_tmp = so ? -tmp1_rnd : tmp1_rnd;
|
|
|
always @*
|
always @*
|
casez({zero,inf,sig_ls[PSTWID]})
|
casez({zero,inf,sig_ls[PSTWID]&1'b0})
|
3'b1??: o = {PSTWID{1'b0}};
|
3'b1??: o = {PSTWID{1'b0}};
|
3'b01?: o = {1'b1,{PSTWID-1{1'b0}}};
|
3'b01?: o = {1'b1,{PSTWID-1{1'b0}}};
|
3'b001: o = {PSTWID{1'b0}};
|
3'b001: o = {PSTWID{1'b0}};
|
default: o = {so, abs_tmp[PSTWID-1:1]};
|
default: o = {so, abs_tmp[PSTWID-1:1]};
|
endcase
|
endcase
|