This commit is contained in:
Ross Thompson 2021-05-03 14:53:54 -05:00
commit 0a44d4dd4e
12 changed files with 261 additions and 252 deletions

View File

@ -85,7 +85,7 @@
// Test modes
// Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 0
`define GPIO_LOOPBACK_TEST 1
// Busybear special CSR config to match OVPSim
`define OVPSIM_CSR_CONFIG 0

View File

@ -10,7 +10,6 @@ add wave /testbench/reset
add wave -divider
add wave /testbench/dut/hart/DataStall
add wave /testbench/dut/hart/InstrStall
add wave /testbench/dut/hart/StallF
add wave /testbench/dut/hart/StallD
add wave /testbench/dut/hart/StallE

View File

@ -31,7 +31,7 @@
`include "wally-config.vh"
package ahbliteState;
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE} statetype;
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE} statetype;
endpackage
module ahblite (
@ -127,7 +127,7 @@ module ahblite (
else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (InstrReadF) NextBusState = INSTRREADC;
else if (InstrReadF) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
@ -135,8 +135,6 @@ module ahblite (
INSTRREAD:
if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; // if (InstrReadF still high)
INSTRREADC: if (~HREADY) NextBusState = INSTRREADC; // "C" for "competing", meaning please don't mess up the memread in the W stage.
else NextBusState = IDLE;
default: NextBusState = IDLE;
endcase
@ -147,12 +145,12 @@ module ahblite (
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
MMUStall);
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
MMUStall);
//assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
// MMUStall);
// Determine access type (important for determining whether to fault)
assign Atomic = ((NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
assign Execute = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC));
assign Execute = ((NextBusState == INSTRREAD));
assign Write = ((NextBusState == MEMWRITE) || (NextBusState == ATOMICWRITE));
assign Read = ((NextBusState == MEMREAD) || (NextBusState == ATOMICREAD) ||
(NextBusState == MMUTRANSLATE));
@ -187,7 +185,7 @@ module ahblite (
assign MMUReady = (BusState == MMUTRANSLATE && NextBusState == IDLE);
assign InstrRData = HRDATA;
assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD) || (BusState == INSTRREADC) && (NextBusState != INSTRREADC);
assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD);
assign MemAckW = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE) ||
((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)) || ((BusState == ATOMICWRITE) && (NextBusState != ATOMICWRITE));
assign MMUReadPTE = HRDATA;

View File

@ -1,90 +1,93 @@
module add3comp2(a, b, c, carry, sum);
/////////////////////////////////////////////////////////////////////////////
//look into diffrent implementations of the compressors?
// //***breaks lint with warnings like: %Warning-UNOPTFLAT: Example path: src/fpu/compressors.sv:37: ASSIGNW
// //%Warning-UNOPTFLAT: Example path: src/fpu/compressors.sv:32: wallypipelinedsoc.hart.fpu.fma1.multiply.genblk5[0].add4.cout
// module add3comp2(a, b, c, carry, sum);
// /////////////////////////////////////////////////////////////////////////////
// //look into diffrent implementations of the compressors?
parameter BITS = 4;
input logic [BITS-1:0] a;
input logic [BITS-1:0] b;
input logic [BITS-1:0] c;
output logic [BITS-1:0] carry;
output logic [BITS-1:0] sum;
genvar i;
// parameter BITS = 4;
// input logic [BITS-1:0] a;
// input logic [BITS-1:0] b;
// input logic [BITS-1:0] c;
// output logic [BITS-1:0] carry;
// output logic [BITS-1:0] sum;
// genvar i;
generate
for(i= 0; i<BITS; i=i+1) begin
sng3comp2 add0(a[i], b[i], c[i], carry[i], sum[i]);
end
endgenerate
// generate
// for(i= 0; i<BITS; i=i+1) begin
// sng3comp2 add0(a[i], b[i], c[i], carry[i], sum[i]);
// end
// endgenerate
endmodule
// endmodule
module add4comp2(a, b, c, d, carry, sum);
/////////////////////////////////////////////////////////////////////////////
// module add4comp2(a, b, c, d, carry, sum);
// /////////////////////////////////////////////////////////////////////////////
parameter BITS = 4;
input logic [BITS-1:0] a;
input logic [BITS-1:0] b;
input logic [BITS-1:0] c;
input logic [BITS-1:0] d;
output logic [BITS:0] carry;
output logic [BITS-1:0] sum;
// parameter BITS = 4;
// input logic [BITS-1:0] a;
// input logic [BITS-1:0] b;
// input logic [BITS-1:0] c;
// input logic [BITS-1:0] d;
// output logic [BITS:0] carry;
// output logic [BITS-1:0] sum;
logic [BITS-1:0] cout;
logic carryTmp;
genvar i;
// logic [BITS-1:0] cout;
// logic carryTmp;
// genvar i;
sng4comp2 add0(a[0], b[0], c[0], d[0], 1'b0, cout[0], carry[0], sum[0]);
// sng4comp2 add0(a[0], b[0], c[0], d[0], 1'b0, cout[0], carry[0], sum[0]);
generate
for(i= 1; i<BITS-1; i=i+1) begin
sng4comp2 add1(a[i], b[i], c[i], d[i], cout[i-1], cout[i], carry[i], sum[i]);
end
endgenerate
// generate
// for(i= 1; i<BITS-1; i=i+1) begin
// sng4comp2 add1(a[i], b[i], c[i], d[i], cout[i-1], cout[i], carry[i], sum[i]);
// end
// endgenerate
sng4comp2 add2(a[BITS-1], b[BITS-1], c[BITS-1], d[BITS-1], cout[BITS-2], cout[BITS-1], carryTmp, sum[BITS-1]);
// sng4comp2 add2(a[BITS-1], b[BITS-1], c[BITS-1], d[BITS-1], cout[BITS-2], cout[BITS-1], carryTmp, sum[BITS-1]);
assign carry[BITS-1] = carryTmp & cout[BITS-1];
assign carry[BITS] = carryTmp ^ cout[BITS-1];
// assign carry[BITS-1] = carryTmp & cout[BITS-1];
// assign carry[BITS] = carryTmp ^ cout[BITS-1];
endmodule
// endmodule
module sng3comp2(a, b, c, carry, sum);
/////////////////////////////////////////////////////////////////////////////
//look into diffrent implementations of the compressors?
// module sng3comp2(a, b, c, carry, sum);
// /////////////////////////////////////////////////////////////////////////////
// //look into diffrent implementations of the compressors?
input logic a;
input logic b;
input logic c;
output logic carry;
output logic sum;
// input logic a;
// input logic b;
// input logic c;
// output logic carry;
// output logic sum;
logic axorb;
// logic axorb;
assign axorb = a ^ b;
assign sum = axorb ^ c;
// assign axorb = a ^ b;
// assign sum = axorb ^ c;
assign carry = axorb ? c : a;
// assign carry = axorb ? c : a;
endmodule
// endmodule
module sng4comp2(a, b, c, d, cin, cout, carry, sum);
/////////////////////////////////////////////////////////////////////////////
//look into pass gate 4:2 counters?
// module sng4comp2(a, b, c, d, cin, cout, carry, sum);
// /////////////////////////////////////////////////////////////////////////////
// //look into pass gate 4:2 counters?
input logic a;
input logic b;
input logic c;
input logic d;
input logic cin;
output logic cout;
output logic carry;
output logic sum;
// input logic a;
// input logic b;
// input logic c;
// input logic d;
// input logic cin;
// output logic cout;
// output logic carry;
// output logic sum;
logic TmpSum;
// logic TmpSum;
sng3comp2 add1(.carry(cout), .sum(TmpSum),.*);
sng3comp2 add2(.a(TmpSum), .b(d), .c(cin), .*);
// sng3comp2 add1(.carry(cout), .sum(TmpSum),.*);
// sng3comp2 add2(.a(TmpSum), .b(d), .c(cin), .*);
endmodule
// endmodule

View File

@ -97,6 +97,9 @@ module fma2(ReadData1M, ReadData2M, ReadData3M, FrmM,
logic sticky;
logic [12:0] de0;
logic isAdd;
logic wsign;
logic [51:0] wman;
logic [10:0] wexp;
assign isAdd = 1;
@ -118,17 +121,19 @@ module fma2(ReadData1M, ReadData2M, ReadData3M, FrmM,
add add(.*);
lza lza(.*);
normalize normalize(.zexp(ReadData3M[62:52]),.*);
round round(.xman(ReadData1M[51:0]), .yman(ReadData2M[51:0]),.zman(ReadData3M[51:0]), .wman(FmaResultM[51:0]),.wsign(FmaResultM[63]),.*);
round round(.xman(ReadData1M[51:0]), .yman(ReadData2M[51:0]),.zman(ReadData3M[51:0]),.*);
// Instantiate exponent datapath
expgen2 expgen2(.xexp(ReadData1M[62:52]),.yexp(ReadData2M[62:52]),.zexp(ReadData3M[62:52]),.wexp(FmaResultM[62:52]),.*);
expgen2 expgen2(.xexp(ReadData1M[62:52]),.yexp(ReadData2M[62:52]),.zexp(ReadData3M[62:52]),.*);
// Instantiate control logic
sign sign(.xsign(ReadData1M[63]),.ysign(ReadData2M[63]),.zsign(ReadData3M[63]),.wsign(FmaResultM[63]),.*);
sign sign(.xsign(ReadData1M[63]),.ysign(ReadData2M[63]),.zsign(ReadData3M[63]),.*);
flag2 flag2(.xsign(ReadData1M[63]),.ysign(ReadData2M[63]),.zsign(ReadData3M[63]),.vbits(v[1:0]),.*);
assign FmaResultM = {wsign,wexp,wman};
endmodule

View File

@ -159,7 +159,8 @@ module fpu (
logic AddDenormInE, AddSwapE, AddNormOvflowE, AddSignAE;
logic AddConvertE;
logic [63:0] AddFloat1E, AddFloat2E;
logic [10:0] AddExp1DenormE, AddExp2DenormE, AddExponentE;
logic [11:0] AddExp1DenormE, AddExp2DenormE;
logic [10:0] AddExponentE;
logic [63:0] AddOp1E, AddOp2E;
logic [2:0] AddRmE;
logic [3:0] AddOpTypeE;
@ -317,7 +318,8 @@ module fpu (
logic AddDenormInM, AddSwapM, AddNormOvflowM, AddSignAM;
logic AddConvertM, AddSignM;
logic [63:0] AddFloat1M, AddFloat2M;
logic [10:0] AddExp1DenormM, AddExp2DenormM, AddExponentM;
logic [11:0] AddExp1DenormM, AddExp2DenormM;
logic [10:0] AddExponentM;
logic [63:0] AddOp1M, AddOp2M;
logic [2:0] AddRmM;
logic [3:0] AddOpTypeM;
@ -380,8 +382,8 @@ module fpu (
flopenrc #(1) EMRegAdd15(clk, reset, PipeClearEM, PipeEnableEM, AddSignAE, AddSignM);
flopenrc #(64) EMRegAdd16(clk, reset, PipeClearEM, PipeEnableEM, AddFloat1E, AddFloat1M);
flopenrc #(64) EMRegAdd17(clk, reset, PipeClearEM, PipeEnableEM, AddFloat2E, AddFloat2M);
flopenrc #(11) EMRegAdd18(clk, reset, PipeClearEM, PipeEnableEM, AddExp1DenormE, AddExp1DenormM);
flopenrc #(11) EMRegAdd19(clk, reset, PipeClearEM, PipeEnableEM, AddExp2DenormE, AddExp2DenormM);
flopenrc #(12) EMRegAdd18(clk, reset, PipeClearEM, PipeEnableEM, AddExp1DenormE, AddExp1DenormM);
flopenrc #(12) EMRegAdd19(clk, reset, PipeClearEM, PipeEnableEM, AddExp2DenormE, AddExp2DenormM);
flopenrc #(11) EMRegAdd20(clk, reset, PipeClearEM, PipeEnableEM, AddExponentE, AddExponentM);
flopenrc #(64) EMRegAdd21(clk, reset, PipeClearEM, PipeEnableEM, AddOp1E, AddOp1M);
flopenrc #(64) EMRegAdd22(clk, reset, PipeClearEM, PipeEnableEM, AddOp2E, AddOp2M);

View File

@ -39,7 +39,7 @@ module fpuaddcvt2 (AddResultM, AddFlagsM, AddDenormM, AddSumM, AddSumTcM, AddSel
input [63:0] AddSumM, AddSumTcM;
input [63:0] AddFloat1M;
input [63:0] AddFloat2M;
input [10:0] AddExp1DenormM, AddExp2DenormM;
input [11:0] AddExp1DenormM, AddExp2DenormM;
input [10:0] AddExponentM, AddExpPostSumM; //exp_pre;
//input exp_valid;
input [3:0] AddSelInvM;
@ -85,7 +85,7 @@ module fpuaddcvt2 (AddResultM, AddFlagsM, AddDenormM, AddSumM, AddSumTcM, AddSel
//AddExponentM value pre-rounding with considerations for denormalized
//cases/conversion cases
assign exp_pre = AddDenormInM ?
((norm_shift == 6'b001011) ? 11'b00000000001 : (AddSwapM ? AddExp2DenormM : AddExp1DenormM))
((norm_shift == 6'b001011) ? 11'b00000000001 : (AddSwapM ? AddExp2DenormM[10:0] : AddExp1DenormM[10:0]))
: (AddConvertM ? 11'b10000111100 : AddExponentM);

View File

@ -26,81 +26,83 @@ module multiply(xman, yman, xdenormE, ydenormE, xzeroE, yzeroE, rE, sE);
// wire [105:0] acc
genvar i;
assign xExt = {1'b0,~(xdenormE|xzeroE),xman};
assign yExt = {1'b0,~(ydenormE|yzeroE),yman, 1'b0};
// assign xExt = {1'b0,~(xdenormE|xzeroE),xman};
// assign yExt = {1'b0,~(ydenormE|yzeroE),yman, 1'b0};
generate
for(i=0; i<27; i=i+1) begin
booth booth(.xExt(xExt), .choose(yExt[(i*2)+2:i*2]), .add1(add1[i]), .e(e[i]), .pp(pp[i]));
end
endgenerate
// generate
// for(i=0; i<27; i=i+1) begin
// booth booth(.xExt(xExt), .choose(yExt[(i*2)+2:i*2]), .add1(add1[i]), .e(e[i]), .pp(pp[i]));
// end
// endgenerate
assign acc[0] = {49'b0,~e[0],e[0],e[0],pp[0]};
assign acc[1] = {49'b01,~e[1],pp[1],add1[0]};
assign acc[2] = {47'b01,~e[2],pp[2],add1[1], 2'b0};
assign acc[3] = {45'b01,~e[3],pp[3],add1[2], 4'b0};
assign acc[4] = {43'b01,~e[4],pp[4],add1[3], 6'b0};
assign acc[5] = {41'b01,~e[5],pp[5],add1[4], 8'b0};
assign acc[6] = {39'b01,~e[6],pp[6],add1[5], 10'b0};
assign acc[7] = {37'b01,~e[7],pp[7],add1[6], 12'b0};
assign acc[8] = {35'b01,~e[8],pp[8],add1[7], 14'b0};
assign acc[9] = {33'b01,~e[9],pp[9],add1[8], 16'b0};
assign acc[10] = {31'b01,~e[10],pp[10],add1[9], 18'b0};
assign acc[11] = {29'b01,~e[11],pp[11],add1[10], 20'b0};
assign acc[12] = {27'b01,~e[12],pp[12],add1[11], 22'b0};
assign acc[13] = {25'b01,~e[13],pp[13],add1[12], 24'b0};
assign acc[14] = {23'b01,~e[14],pp[14],add1[13], 26'b0};
assign acc[15] = {21'b01,~e[15],pp[15],add1[14], 28'b0};
assign acc[16] = {19'b01,~e[16],pp[16],add1[15], 30'b0};
assign acc[17] = {17'b01,~e[17],pp[17],add1[16], 32'b0};
assign acc[18] = {15'b01,~e[18],pp[18],add1[17], 34'b0};
assign acc[19] = {13'b01,~e[19],pp[19],add1[18], 36'b0};
assign acc[20] = {11'b01,~e[20],pp[20],add1[19], 38'b0};
assign acc[21] = {9'b01,~e[21],pp[21],add1[20], 40'b0};
assign acc[22] = {7'b01,~e[22],pp[22],add1[21], 42'b0};
assign acc[23] = {5'b01,~e[23],pp[23],add1[22], 44'b0};
assign acc[24] = {3'b01,~e[24],pp[24],add1[23], 46'b0};
assign acc[25] = {1'b0, ~e[25],pp[25],add1[24], 48'b0};
assign acc[26] = {pp[26],add1[25], 50'b0};
// assign acc[0] = {49'b0,~e[0],e[0],e[0],pp[0]};
// assign acc[1] = {49'b01,~e[1],pp[1],add1[0]};
// assign acc[2] = {47'b01,~e[2],pp[2],add1[1], 2'b0};
// assign acc[3] = {45'b01,~e[3],pp[3],add1[2], 4'b0};
// assign acc[4] = {43'b01,~e[4],pp[4],add1[3], 6'b0};
// assign acc[5] = {41'b01,~e[5],pp[5],add1[4], 8'b0};
// assign acc[6] = {39'b01,~e[6],pp[6],add1[5], 10'b0};
// assign acc[7] = {37'b01,~e[7],pp[7],add1[6], 12'b0};
// assign acc[8] = {35'b01,~e[8],pp[8],add1[7], 14'b0};
// assign acc[9] = {33'b01,~e[9],pp[9],add1[8], 16'b0};
// assign acc[10] = {31'b01,~e[10],pp[10],add1[9], 18'b0};
// assign acc[11] = {29'b01,~e[11],pp[11],add1[10], 20'b0};
// assign acc[12] = {27'b01,~e[12],pp[12],add1[11], 22'b0};
// assign acc[13] = {25'b01,~e[13],pp[13],add1[12], 24'b0};
// assign acc[14] = {23'b01,~e[14],pp[14],add1[13], 26'b0};
// assign acc[15] = {21'b01,~e[15],pp[15],add1[14], 28'b0};
// assign acc[16] = {19'b01,~e[16],pp[16],add1[15], 30'b0};
// assign acc[17] = {17'b01,~e[17],pp[17],add1[16], 32'b0};
// assign acc[18] = {15'b01,~e[18],pp[18],add1[17], 34'b0};
// assign acc[19] = {13'b01,~e[19],pp[19],add1[18], 36'b0};
// assign acc[20] = {11'b01,~e[20],pp[20],add1[19], 38'b0};
// assign acc[21] = {9'b01,~e[21],pp[21],add1[20], 40'b0};
// assign acc[22] = {7'b01,~e[22],pp[22],add1[21], 42'b0};
// assign acc[23] = {5'b01,~e[23],pp[23],add1[22], 44'b0};
// assign acc[24] = {3'b01,~e[24],pp[24],add1[23], 46'b0};
// assign acc[25] = {1'b0, ~e[25],pp[25],add1[24], 48'b0};
// assign acc[26] = {pp[26],add1[25], 50'b0};
//***breaks lint with warnings like: %Warning-UNOPTFLAT: Example path: src/fpu/multiply.sv:86: ASSIGNW
// %Warning-UNOPTFLAT: Example path: src/fpu/multiply.sv:22: wallypipelinedsoc.hart.fpu.fma1.multiply.lv3add
//*** resize adders
generate
for(i=0; i<9; i=i+1) begin
add3comp2 #(.BITS(107)) add1(.a(acc[i*3]), .b(acc[i*3+1]), .c(acc[i*3+2]),
.carry(carryTmp[i][106:0]), .sum(lv1add[i*2+1]));
assign lv1add[i*2] = {carryTmp[i][105:0], 1'b0};
end
endgenerate
// generate
// for(i=0; i<9; i=i+1) begin
// add3comp2 #(.BITS(107)) add1(.a(acc[i*3]), .b(acc[i*3+1]), .c(acc[i*3+2]),
// .carry(carryTmp[i][106:0]), .sum(lv1add[i*2+1]));
// assign lv1add[i*2] = {carryTmp[i][105:0], 1'b0};
// end
// endgenerate
generate
for(i=0; i<6; i=i+1) begin
add3comp2 #(.BITS(107)) add2(.a(lv1add[i*3]), .b(lv1add[i*3+1]), .c(lv1add[i*3+2]),
.carry(carryTmp[i+9][106:0]), .sum(lv2add[i*2+1]));
assign lv2add[i*2] = {carryTmp[i+9][105:0], 1'b0};
end
endgenerate
// generate
// for(i=0; i<6; i=i+1) begin
// add3comp2 #(.BITS(107)) add2(.a(lv1add[i*3]), .b(lv1add[i*3+1]), .c(lv1add[i*3+2]),
// .carry(carryTmp[i+9][106:0]), .sum(lv2add[i*2+1]));
// assign lv2add[i*2] = {carryTmp[i+9][105:0], 1'b0};
// end
// endgenerate
generate
for(i=0; i<4; i=i+1) begin
add3comp2 #(.BITS(107)) add3(.a(lv2add[i*3]), .b(lv2add[i*3+1]), .c(lv2add[i*3+2]),
.carry(carryTmp[i+15][106:0]), .sum(lv3add[i*2+1]));
assign lv3add[i*2] = {carryTmp[i+15][105:0], 1'b0};
end
endgenerate
// generate
// for(i=0; i<4; i=i+1) begin
// add3comp2 #(.BITS(107)) add3(.a(lv2add[i*3]), .b(lv2add[i*3+1]), .c(lv2add[i*3+2]),
// .carry(carryTmp[i+15][106:0]), .sum(lv3add[i*2+1]));
// assign lv3add[i*2] = {carryTmp[i+15][105:0], 1'b0};
// end
// endgenerate
generate
for(i=0; i<2; i=i+1) begin
add4comp2 #(.BITS(107)) add4(.a(lv3add[i*4]), .b(lv3add[i*4+1]), .c(lv3add[i*4+2]), .d(lv3add[i*4+3]),
.carry(carryTmp[i+19]), .sum(lv4add[i*2+1]));
assign lv4add[i*2] = {carryTmp[i+19][105:0], 1'b0};
end
endgenerate
// generate
// for(i=0; i<2; i=i+1) begin
// add4comp2 #(.BITS(107)) add4(.a(lv3add[i*4]), .b(lv3add[i*4+1]), .c(lv3add[i*4+2]), .d(lv3add[i*4+3]),
// .carry(carryTmp[i+19]), .sum(lv4add[i*2+1]));
// assign lv4add[i*2] = {carryTmp[i+19][105:0], 1'b0};
// end
// endgenerate
add4comp2 #(.BITS(107)) add5(.a(lv4add[0]), .b(lv4add[1]), .c(lv4add[2]), .d(lv4add[3]) ,
.carry(carryTmp[21]), .sum(tmpsE));
assign sE = tmpsE[105:0];
assign rE = {carryTmp[21][104:0], 1'b0};
// add4comp2 #(.BITS(107)) add5(.a(lv4add[0]), .b(lv4add[1]), .c(lv4add[2]), .d(lv4add[3]) ,
// .carry(carryTmp[21]), .sum(tmpsE));
// assign sE = tmpsE[105:0];
// assign rE = {carryTmp[21][104:0], 1'b0};
// assign rE = 0;
// assign sE = acc[0] +
// acc[1] +
@ -130,7 +132,7 @@ module multiply(xman, yman, xdenormE, ydenormE, xzeroE, yzeroE, rE, sE);
// acc[25] +
// acc[26];
// assign sE = {53'b0,~(xdenormE|xzeroE),xman} * {53'b0,~(ydenormE|yzeroE),yman};
// assign rE = 0;
assign sE = {53'b0,~(xdenormE|xzeroE),xman} * {53'b0,~(ydenormE|yzeroE),yman};
assign rE = 0;
endmodule

View File

@ -56,6 +56,10 @@ module round(v, sticky, FrmM, wsign,
// 0xx - do nothing
// 100 - tie - plus1 if v[2] = 1
// 101/110/111 - plus1
//***causes lint warning: %Warning-UNOPTFLAT: Example path: src/fpu/round.sv:59: ALWAYS
// %Warning-UNOPTFLAT: Example path: src/fpu/round.sv:42: wallypipelinedsoc.hart.fpu.fma2.round.plus1
always_comb begin
case (FrmM)
3'b000: plus1 = (v[1] & (v[0] | sticky | (~v[0]&~sticky&v[2])));//round to nearest even
@ -66,12 +70,6 @@ module round(v, sticky, FrmM, wsign,
default: plus1 = 1'bx;
endcase
end
// assign plus1 = (rn & v[1] & (v[0] | sticky | (~v[0]&~sticky&v[2]))) |
// (rp & ~wsign) |
// (rm & wsign);
//assign plus1 = rn && ((v[1] && v[0]) || (v[2] && (v[1]))) ||
// rp && ~wsign && (v[1] || v[0]) ||
// rm && wsign && (v[1] || v[0]);
// Compute rounded result
assign v1 = v[53:2] + 1;

View File

@ -82,23 +82,6 @@ module gpio (
// register access
always_ff @(posedge HCLK, negedge HRESETn) begin
// reads
case(entry)
8'h00: Dout <= #1 input_val;
8'h04: Dout <= #1 input_en;
8'h08: Dout <= #1 output_en;
8'h0C: Dout <= #1 output_val;
8'h18: Dout <= #1 rise_ie;
8'h1C: Dout <= #1 rise_ip;
8'h20: Dout <= #1 fall_ie;
8'h24: Dout <= #1 fall_ip;
8'h28: Dout <= #1 high_ie;
8'h2C: Dout <= #1 high_ip;
8'h30: Dout <= #1 low_ie;
8'h34: Dout <= #1 low_ip;
8'h40: Dout <= #1 0; // OUT_XOR reads as 0
default: Dout <= #1 0;
endcase
// writes
if (~HRESETn) begin
// asynch reset
@ -114,22 +97,57 @@ module gpio (
high_ip <= #1 0;
low_ie <= #1 0;
low_ip <= #1 0;
end else if (memwrite)
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
case(entryd)
8'h04: input_en <= #1 Din;
8'h08: output_en <= #1 Din;
8'h0C: output_val <= #1 Din;
8'h18: rise_ie <= #1 Din;
8'h1C: rise_ip <= #1 rise_ip & ~Din;
8'h20: fall_ie <= #1 Din;
8'h24: fall_ip <= #1 fall_ip & ~Din;
8'h28: high_ie <= #1 Din;
8'h2C: high_ip <= #1 high_ip & ~Din;
8'h30: low_ie <= #1 Din;
8'h34: low_ip <= #1 low_ip & ~Din;
8'h40: output_val <= #1 output_val ^ Din; // OUT_XOR
end else begin
// writes
if (memwrite)
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
/* verilator lint_off CASEINCOMPLETE */
case(entryd)
8'h04: input_en <= #1 Din;
8'h08: output_en <= #1 Din;
8'h0C: output_val <= #1 Din;
8'h18: rise_ie <= #1 Din;
8'h20: fall_ie <= #1 Din;
8'h28: high_ie <= #1 Din;
8'h30: low_ie <= #1 Din;
8'h40: output_val <= #1 output_val ^ Din; // OUT_XOR
endcase
/* verilator lint_on CASEINCOMPLETE */
// reads
case(entry)
8'h00: Dout <= #1 input_val;
8'h04: Dout <= #1 input_en;
8'h08: Dout <= #1 output_en;
8'h0C: Dout <= #1 output_val;
8'h18: Dout <= #1 rise_ie;
8'h1C: Dout <= #1 rise_ip;
8'h20: Dout <= #1 fall_ie;
8'h24: Dout <= #1 fall_ip;
8'h28: Dout <= #1 high_ie;
8'h2C: Dout <= #1 high_ip;
8'h30: Dout <= #1 low_ie;
8'h34: Dout <= #1 low_ip;
8'h40: Dout <= #1 0; // OUT_XOR reads as 0
default: Dout <= #1 0;
endcase
// interrupts
if (memwrite && (entryd == 8'h1C))
rise_ip <= rise_ip & ~Din | (input2d & ~input3d);
else
rise_ip <= rise_ip | (input2d & ~input3d);
if (memwrite && (entryd == 8'h24))
fall_ip <= fall_ip & ~Din | (~input2d & input3d);
else
fall_ip <= fall_ip | (~input2d & input3d);
if (memwrite && (entryd == 8'h2C))
high_ip <= high_ip & ~Din | input3d;
else
high_ip <= high_ip | input3d;
if (memwrite && (entryd == 8'h34))
low_ip <= low_ip & ~Din | ~input3d;
else
low_ip <= low_ip | ~input3d;
end
end
// chip i/o
@ -147,25 +165,6 @@ module gpio (
assign GPIOPinsOut = output_val;
assign GPIOPinsEn = output_en;
// interrupts
always_ff @(posedge HCLK) begin
if (memwrite && (entryd == 8'h1C))
rise_ip <= rise_ip & ~Din | (input2d & ~input3d);
else
rise_ip <= rise_ip | (input2d & ~input3d);
if (memwrite && (entryd == 8'h24))
fall_ip <= fall_ip & ~Din | (~input2d & input3d);
else
fall_ip <= fall_ip | (~input2d & input3d);
if (memwrite && (entryd == 8'h2C))
high_ip <= high_ip & ~Din | input3d;
else
high_ip <= high_ip | input3d;
if (memwrite && (entryd == 8'h34))
low_ip <= low_ip & ~Din | ~input3d;
else
low_ip <= low_ip | ~input3d;
end
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ip),(high_ip & high_ie),(low_ip & low_ie)};
endmodule

View File

@ -106,42 +106,44 @@ module plic (
intThreshold <= #1 3'b0;
intInProgress <= #1 {N{1'b0}};
// writing
end else if (memwrite)
casez(entryd)
28'hc0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
`ifdef PLIC_NUM_SRC_LT_32
28'hc002000: intEn[N:1] <= #1 Din[N:1];
`endif
`ifndef PLIC_NUM_SRC_LT_32
28'hc002000: intEn[31:1] <= #1 Din[31:1];
28'hc002004: intEn[N:32] <= #1 Din[31:0];
`endif
28'hc200000: intThreshold[2:0] <= #1 Din[2:0];
28'hc200004: intInProgress <= #1 intInProgress & ~(1'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
endcase
// reading
if (memread)
casez(entry)
28'hc0000??: Dout <= #1 {{(`XLEN-3){1'b0}},intPriority[entry[7:2]]};
`ifdef PLIC_NUM_SRC_LT_32
28'hc001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
28'hc002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
`endif
`ifndef PLIC_NUM_SRC_LT_32
28'hc001000: Dout <= #1 {intPending[31:1],1'b0};
28'hc001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
28'hc002000: Dout <= #1 {intEn[31:1],1'b0};
28'hc002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
`endif
28'hc200000: Dout <= #1 {29'b0,intThreshold[2:0]};
28'hc200004: begin
Dout <= #1 {26'b0,intClaim};
intInProgress <= #1 intInProgress | (1'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
end
default: Dout <= #1 32'hdeadbeef; // invalid access
endcase
else
Dout <= #1 32'h0;
end else begin
if (memwrite)
casez(entryd)
28'hc0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
`ifdef PLIC_NUM_SRC_LT_32
28'hc002000: intEn[N:1] <= #1 Din[N:1];
`endif
`ifndef PLIC_NUM_SRC_LT_32
28'hc002000: intEn[31:1] <= #1 Din[31:1];
28'hc002004: intEn[N:32] <= #1 Din[31:0];
`endif
28'hc200000: intThreshold[2:0] <= #1 Din[2:0];
28'hc200004: intInProgress <= #1 intInProgress & ~(1'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
endcase
// reading
if (memread)
casez(entry)
28'hc0000??: Dout <= #1 {{(`XLEN-3){1'b0}},intPriority[entry[7:2]]};
`ifdef PLIC_NUM_SRC_LT_32
28'hc001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
28'hc002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
`endif
`ifndef PLIC_NUM_SRC_LT_32
28'hc001000: Dout <= #1 {intPending[31:1],1'b0};
28'hc001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
28'hc002000: Dout <= #1 {intEn[31:1],1'b0};
28'hc002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
`endif
28'hc200000: Dout <= #1 {29'b0,intThreshold[2:0]};
28'hc200004: begin
Dout <= #1 {26'b0,intClaim};
intInProgress <= #1 intInProgress | (1'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
end
default: Dout <= #1 32'hdeadbeef; // invalid access
endcase
else
Dout <= #1 32'h0;
end
end
// connect sources to requests

View File

@ -29,14 +29,15 @@
module testbench();
parameter DEBUG = 0;
parameter TESTSBP = 0;
parameter TESTSPERIPH = 0; // set to 0 for regression
parameter TESTSPERIPH = 0 ; // set to 0 for regression
localparam MAXSIGLEN = 1000000;
logic clk;
logic reset;
int test, i, errors, totalerrors;
logic [31:0] sig32[0:10000];
logic [`XLEN-1:0] signature[0:10000];
logic [31:0] sig32[0:MAXSIGLEN];
logic [`XLEN-1:0] signature[0:MAXSIGLEN];
logic [`XLEN-1:0] testadr;
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
logic [31:0] InstrW;
@ -525,7 +526,7 @@ string tests32f[] = '{
if (TESTSPERIPH) begin
tests = tests32periph;
end else begin
tests = {tests32i, tests32p};//,tests32periph}; *** broken at the moment
tests = {tests32i, tests32p, tests32periph};
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
else tests = {tests, tests32iNOc};
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m};
@ -602,7 +603,7 @@ string tests32f[] = '{
$display("Code ended with ecall with gp = 1");
#60; // give time for instructions in pipeline to finish
// clear signature to prevent contamination from previous tests
for(i=0; i<10000; i=i+1) begin
for(i=0; i<MAXSIGLEN; i=i+1) begin
sig32[i] = 'bx;
end
@ -610,7 +611,7 @@ string tests32f[] = '{
signame = {"../../imperas-riscv-tests/work/", tests[test], ".signature.output"};
$readmemh(signame, sig32);
i = 0;
while (i < 10000) begin
while (i < MAXSIGLEN) begin
if (`XLEN == 32) begin
signature[i] = sig32[i];
i = i+1;