From d8947fa616dffb9e976dadec88664401e2a4db96 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 11 Mar 2022 18:09:22 -0600 Subject: [PATCH 1/6] cleanup of ram.sv --- pipelined/src/lsu/lsu.sv | 3 +-- pipelined/src/uncore/ram.sv | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 1d0588b46..2e20b3a2e 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -106,7 +106,7 @@ module lsu ( logic [`XLEN-1:0] LSUWriteDataM; logic [(`XLEN-1)/8:0] ByteMaskM; - // *** TO DO: Burst mode, byte write enables to DTIM, cache, exeternal memory, remove subword write from uncore, + // *** TO DO: Burst mode flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); assign IEUAdrExtM = {2'b00, IEUAdrM}; @@ -187,7 +187,6 @@ module lsu ( logic SelUncachedAdr; assign IgnoreRequest = IgnoreRequestTLB | IgnoreRequestTrapM; - // *** change to allow TIM and BUS. seaparate parameter for having bus (but have to have bus if have cache - check in testbench) if (`DMEM == `MEM_TIM) begin : dtim // *** directly instantiate RAM or ROM here. Instantiate SRAM1P1RW. // Merge SimpleRAM and SRAM1p1rw into one that is good for synthesis and RAM libraries and flops diff --git a/pipelined/src/uncore/ram.sv b/pipelined/src/uncore/ram.sv index 7eef08a71..e9b0af32d 100644 --- a/pipelined/src/uncore/ram.sv +++ b/pipelined/src/uncore/ram.sv @@ -48,7 +48,6 @@ module ram #(parameter BASE=0, RANGE = 65535) ( logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; logic [31:0] HWADDR, A; - logic [`XLEN-1:0] HREADRam0; logic prevHREADYRam, risingHREADYRam; logic initTrans; @@ -157,7 +156,7 @@ module ram #(parameter BASE=0, RANGE = 65535) ( HWADDR <= #1 A; if (`XLEN == 64) begin:ramrw always_ff @(posedge HCLK) - HREADRam0 <= #1 RAM[A[31:3]]; + HREADRam <= #1 RAM[A[31:3]]; for(index = 0; index < `XLEN/8; index++) begin always_ff @(posedge HCLK) begin if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:3]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index]; @@ -165,7 +164,7 @@ module ram #(parameter BASE=0, RANGE = 65535) ( end end else begin always_ff @(posedge HCLK) - HREADRam0 <= #1 RAM[A[31:2]]; + HREADRam <= #1 RAM[A[31:2]]; for(index = 0; index < `XLEN/8; index++) begin always_ff @(posedge HCLK) begin:ramrw if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:2]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index]; @@ -174,8 +173,5 @@ module ram #(parameter BASE=0, RANGE = 65535) ( end /* verilator lint_on WIDTH */ - //assign HREADRam = HREADYRam ? HREADRam0 : `XLEN'bz; - // *** Ross Thompson: removed tristate as fpga synthesis removes. - assign HREADRam = HREADRam0; endmodule From d347de8c4947d140147d667b7a1a33fa3c6948a8 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sat, 12 Mar 2022 00:46:11 -0600 Subject: [PATCH 2/6] dtim writes are supressed on non cacheable operation. --- pipelined/src/ifu/ifu.sv | 2 +- pipelined/src/lsu/dtim.sv | 37 +++++++++++++++++++------------------ pipelined/src/lsu/lsu.sv | 2 +- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index b2eb00399..6adc5ad2d 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -177,7 +177,7 @@ module ifu ( dtim irom(.clk, .reset, .CPUBusy, .LSURWM(2'b10), .IEUAdrM(PCPF[31:0]), .IEUAdrE(PCNextFSpill), .TrapM(1'b0), .FinalWriteDataM(), .ByteMaskM('0), .ReadDataWordM(FinalInstrRawF), .BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), - .BusCommittedM(), .DCacheStallM(ICacheStallF), + .BusCommittedM(), .DCacheStallM(ICacheStallF), .Cacheable(CacheableF), .DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess)); end diff --git a/pipelined/src/lsu/dtim.sv b/pipelined/src/lsu/dtim.sv index 38a12c752..6ca5be4a6 100644 --- a/pipelined/src/lsu/dtim.sv +++ b/pipelined/src/lsu/dtim.sv @@ -30,28 +30,29 @@ `include "wally-config.vh" module dtim( - input logic clk, reset, - input logic CPUBusy, - input logic [1:0] LSURWM, - input logic [`XLEN-1:0] IEUAdrM, - input logic [`XLEN-1:0] IEUAdrE, - input logic TrapM, - input logic [`XLEN-1:0] FinalWriteDataM, - input logic [`XLEN/8-1:0] ByteMaskM, - output logic [`XLEN-1:0] ReadDataWordM, - output logic BusStall, - output logic LSUBusWrite, - output logic LSUBusRead, - output logic BusCommittedM, - output logic DCacheStallM, - output logic DCacheCommittedM, - output logic DCacheMiss, - output logic DCacheAccess); + input logic clk, reset, + input logic CPUBusy, + input logic [1:0] LSURWM, + input logic [`XLEN-1:0] IEUAdrM, + input logic [`XLEN-1:0] IEUAdrE, + input logic TrapM, + input logic [`XLEN-1:0] FinalWriteDataM, + input logic [`XLEN/8-1:0] ByteMaskM, + input logic Cacheable, + output logic [`XLEN-1:0] ReadDataWordM, + output logic BusStall, + output logic LSUBusWrite, + output logic LSUBusRead, + output logic BusCommittedM, + output logic DCacheStallM, + output logic DCacheCommittedM, + output logic DCacheMiss, + output logic DCacheAccess); simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( .clk, .ByteMask(ByteMaskM), .a(CPUBusy | LSURWM[0] | reset ? IEUAdrM[31:0] : IEUAdrE[31:0]), // move mux out; this shouldn't be needed when stails are handled differently *** - .we(LSURWM[0] & ~TrapM), // have to ignore write if Trap. + .we(LSURWM[0] & Cacheable & ~TrapM), // have to ignore write if Trap. .wd(FinalWriteDataM), .rd(ReadDataWordM)); // since we have a local memory the bus connections are all disabled. diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 2e20b3a2e..aa617db68 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -192,7 +192,7 @@ module lsu ( // Merge SimpleRAM and SRAM1p1rw into one that is good for synthesis and RAM libraries and flops dtim dtim(.clk, .reset, .CPUBusy, .LSURWM, .IEUAdrM, .IEUAdrE, .TrapM, .FinalWriteDataM, .ReadDataWordM, .BusStall, .LSUBusWrite,.LSUBusRead, .BusCommittedM, - .DCacheStallM, .DCacheCommittedM, .ByteMaskM, + .DCacheStallM, .DCacheCommittedM, .ByteMaskM, .Cacheable(CacheableM), .DCacheMiss, .DCacheAccess); end if (`DBUS) begin : bus From abdbc31d144d1e38aa8fb3af88675e6201a11192 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Wed, 23 Mar 2022 18:26:59 +0000 Subject: [PATCH 3/6] fixed typo in unpack.sv --- pipelined/src/fpu/fma.sv | 352 ++++++++++++++++++------------------ pipelined/src/fpu/unpack.sv | 8 +- 2 files changed, 180 insertions(+), 180 deletions(-) diff --git a/pipelined/src/fpu/fma.sv b/pipelined/src/fpu/fma.sv index 2b2a6b9ed..8d1ae344a 100644 --- a/pipelined/src/fpu/fma.sv +++ b/pipelined/src/fpu/fma.sv @@ -186,20 +186,20 @@ module expadd( end else if (`FPSIZES == 3) begin always_comb begin case (FmtE) - `FMT: assign Denorm = 1; - `FMT1: assign Denorm = `BIAS-`BIAS1+1; - `FMT2: assign Denorm = `BIAS-`BIAS2+1; - default: assign Denorm = 1'bx; + `FMT: Denorm = 1; + `FMT1: Denorm = `BIAS-`BIAS1+1; + `FMT2: Denorm = `BIAS-`BIAS2+1; + default: Denorm = 1'bx; endcase end end else begin always_comb begin case (FmtE) - 2'h3: assign Denorm = 1; - 2'h1: assign Denorm = `BIAS-`D_BIAS+1; - 2'h0: assign Denorm = `BIAS-`S_BIAS+1; - 2'h2: assign Denorm = `BIAS-`H_BIAS+1; + 2'h3: Denorm = 1; + 2'h1: Denorm = `BIAS-`D_BIAS+1; + 2'h0: Denorm = `BIAS-`S_BIAS+1; + 2'h2: Denorm = `BIAS-`H_BIAS+1; endcase end @@ -612,20 +612,20 @@ module normalize( end else if (`FPSIZES == 3) begin always_comb begin case (FmtM) - `FMT: assign SumExpTmp = SumExpTmpTmp; - `FMT1: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS1)&{`NE+2{|SumExpTmpTmp}}; - `FMT2: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS2)&{`NE+2{|SumExpTmpTmp}}; - default: assign SumExpTmp = `NE+2'bx; + `FMT: SumExpTmp = SumExpTmpTmp; + `FMT1: SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS1)&{`NE+2{|SumExpTmpTmp}}; + `FMT2: SumExpTmp = (SumExpTmpTmp-`BIAS+`BIAS2)&{`NE+2{|SumExpTmpTmp}}; + default: SumExpTmp = `NE+2'bx; endcase end end else begin always_comb begin case (FmtM) - 2'h3: assign SumExpTmp = SumExpTmpTmp; - 2'h1: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`D_BIAS)&{`NE+2{|SumExpTmpTmp}}; - 2'h0: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`S_BIAS)&{`NE+2{|SumExpTmpTmp}}; - 2'h2: assign SumExpTmp = (SumExpTmpTmp-`BIAS+`H_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h3: SumExpTmp = SumExpTmpTmp; + 2'h1: SumExpTmp = (SumExpTmpTmp-`BIAS+`D_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h0: SumExpTmp = (SumExpTmpTmp-`BIAS+`S_BIAS)&{`NE+2{|SumExpTmpTmp}}; + 2'h2: SumExpTmp = (SumExpTmpTmp-`BIAS+`H_BIAS)&{`NE+2{|SumExpTmpTmp}}; endcase end @@ -657,10 +657,10 @@ module normalize( assign Sum2GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`NF2+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`BIAS2)) | ~|SumExpTmpTmp; always_comb begin case (FmtM) - `FMT: assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; - `FMT1: assign PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; - `FMT2: assign PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; - default: assign PreResultDenorm = 1'bx; + `FMT: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; + `FMT1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; + `FMT2: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; + default: PreResultDenorm = 1'bx; endcase end @@ -676,10 +676,10 @@ module normalize( assign Sum3GEFL = $signed(SumExpTmpTmp) >= $signed(-(`NE+2)'(`H_NF+2)+(`NE+2)'(`BIAS)-(`NE+2)'(`H_BIAS)) | ~|SumExpTmpTmp; always_comb begin case (FmtM) - 2'h3: assign PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; - 2'h1: assign PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; - 2'h0: assign PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; - 2'h2: assign PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero; + 2'h3: PreResultDenorm = Sum0LEZ & Sum0GEFL & ~SumZero; + 2'h1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero; + 2'h0: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero; + 2'h2: PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero; endcase end @@ -830,48 +830,48 @@ module fmaround( case (FmtM) `FMT: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[2]; - assign Round = NormSum[1]; - assign LSBNormSum = NormSum[3]; + Guard = NormSum[2]; + Round = NormSum[1]; + LSBNormSum = NormSum[3]; // used to determine underflow flag - assign UfGuard = NormSum[1]; - assign UfRound = NormSum[0]; - assign UfLSBNormSum = NormSum[2]; + UfGuard = NormSum[1]; + UfRound = NormSum[0]; + UfLSBNormSum = NormSum[2]; // determine sticky - assign Sticky = UfSticky | NormSum[0]; + Sticky = UfSticky | NormSum[0]; end `FMT1: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`NF1+2]; - assign Round = NormSum[`NF-`NF1+1]; - assign LSBNormSum = NormSum[`NF-`NF1+3]; + Guard = NormSum[`NF-`NF1+2]; + Round = NormSum[`NF-`NF1+1]; + LSBNormSum = NormSum[`NF-`NF1+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`NF1+1]; - assign UfRound = NormSum[`NF-`NF1]; - assign UfLSBNormSum = NormSum[`NF-`NF1+2]; + UfGuard = NormSum[`NF-`NF1+1]; + UfRound = NormSum[`NF-`NF1]; + UfLSBNormSum = NormSum[`NF-`NF1+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`NF1]; + Sticky = UfSticky | NormSum[`NF-`NF1]; end `FMT2: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`NF2+2]; - assign Round = NormSum[`NF-`NF2+1]; - assign LSBNormSum = NormSum[`NF-`NF2+3]; + Guard = NormSum[`NF-`NF2+2]; + Round = NormSum[`NF-`NF2+1]; + LSBNormSum = NormSum[`NF-`NF2+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`NF2+1]; - assign UfRound = NormSum[`NF-`NF2]; - assign UfLSBNormSum = NormSum[`NF-`NF2+2]; + UfGuard = NormSum[`NF-`NF2+1]; + UfRound = NormSum[`NF-`NF2]; + UfLSBNormSum = NormSum[`NF-`NF2+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`NF2]; + Sticky = UfSticky | NormSum[`NF-`NF2]; end default: begin - assign Guard = 1'bx; - assign Round = 1'bx; - assign LSBNormSum = 1'bx; - assign UfGuard = 1'bx; - assign UfRound = 1'bx; - assign UfLSBNormSum = 1'bx; - assign Sticky = 1'bx; + Guard = 1'bx; + Round = 1'bx; + LSBNormSum = 1'bx; + UfGuard = 1'bx; + UfRound = 1'bx; + UfLSBNormSum = 1'bx; + Sticky = 1'bx; end endcase end @@ -881,51 +881,51 @@ module fmaround( case (FmtM) 2'h3: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[2]; - assign Round = NormSum[1]; - assign LSBNormSum = NormSum[3]; + Guard = NormSum[2]; + Round = NormSum[1]; + LSBNormSum = NormSum[3]; // used to determine underflow flag - assign UfGuard = NormSum[1]; - assign UfRound = NormSum[0]; - assign UfLSBNormSum = NormSum[2]; + UfGuard = NormSum[1]; + UfRound = NormSum[0]; + UfLSBNormSum = NormSum[2]; // determine sticky - assign Sticky = UfSticky | NormSum[0]; + Sticky = UfSticky | NormSum[0]; end 2'h1: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`D_NF+2]; - assign Round = NormSum[`NF-`D_NF+1]; - assign LSBNormSum = NormSum[`NF-`D_NF+3]; + Guard = NormSum[`NF-`D_NF+2]; + Round = NormSum[`NF-`D_NF+1]; + LSBNormSum = NormSum[`NF-`D_NF+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`D_NF+1]; - assign UfRound = NormSum[`NF-`D_NF]; - assign UfLSBNormSum = NormSum[`NF-`D_NF+2]; + UfGuard = NormSum[`NF-`D_NF+1]; + UfRound = NormSum[`NF-`D_NF]; + UfLSBNormSum = NormSum[`NF-`D_NF+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`D_NF]; + Sticky = UfSticky | NormSum[`NF-`D_NF]; end 2'h0: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`S_NF+2]; - assign Round = NormSum[`NF-`S_NF+1]; - assign LSBNormSum = NormSum[`NF-`S_NF+3]; + Guard = NormSum[`NF-`S_NF+2]; + Round = NormSum[`NF-`S_NF+1]; + LSBNormSum = NormSum[`NF-`S_NF+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`S_NF+1]; - assign UfRound = NormSum[`NF-`S_NF]; - assign UfLSBNormSum = NormSum[`NF-`S_NF+2]; + UfGuard = NormSum[`NF-`S_NF+1]; + UfRound = NormSum[`NF-`S_NF]; + UfLSBNormSum = NormSum[`NF-`S_NF+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`S_NF]; + Sticky = UfSticky | NormSum[`NF-`S_NF]; end 2'h2: begin // determine guard, round, and least significant bit of the result - assign Guard = NormSum[`NF-`H_NF+2]; - assign Round = NormSum[`NF-`H_NF+1]; - assign LSBNormSum = NormSum[`NF-`H_NF+3]; + Guard = NormSum[`NF-`H_NF+2]; + Round = NormSum[`NF-`H_NF+1]; + LSBNormSum = NormSum[`NF-`H_NF+3]; // used to determine underflow flag - assign UfGuard = NormSum[`NF-`H_NF+1]; - assign UfRound = NormSum[`NF-`H_NF]; - assign UfLSBNormSum = NormSum[`NF-`H_NF+2]; + UfGuard = NormSum[`NF-`H_NF+1]; + UfRound = NormSum[`NF-`H_NF]; + UfLSBNormSum = NormSum[`NF-`H_NF+2]; // determine sticky - assign Sticky = UfSticky | NormSum[`NF-`H_NF]; + Sticky = UfSticky | NormSum[`NF-`H_NF]; end endcase end @@ -988,20 +988,20 @@ module fmaround( end else if (`FPSIZES == 3) begin always_comb begin case (FmtM) - `FMT: assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; - `FMT1: assign RoundAdd = Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), Plus1, (`FLEN-1-`NE-`NF1)'(0)}; - `FMT2: assign RoundAdd = Minus1 ? {{`NE+2+`NF2{1'b1}}, (`FLEN-1-`NE-`NF2)'(0)} : {(`NE+1+`NF2)'(0), Plus1, (`FLEN-1-`NE-`NF2)'(0)}; - default: assign RoundAdd = (`FLEN+1)'(0); + `FMT: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; + `FMT1: RoundAdd = Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), Plus1, (`FLEN-1-`NE-`NF1)'(0)}; + `FMT2: RoundAdd = Minus1 ? {{`NE+2+`NF2{1'b1}}, (`FLEN-1-`NE-`NF2)'(0)} : {(`NE+1+`NF2)'(0), Plus1, (`FLEN-1-`NE-`NF2)'(0)}; + default: RoundAdd = (`FLEN+1)'(0); endcase end end else begin always_comb begin case (FmtM) - 2'h3: assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; - 2'h1: assign RoundAdd = Minus1 ? {{`NE+2+`D_NF{1'b1}}, (`FLEN-1-`NE-`D_NF)'(0)} : {(`NE+1+`D_NF)'(0), Plus1, (`FLEN-1-`NE-`D_NF)'(0)}; - 2'h0: assign RoundAdd = Minus1 ? {{`NE+2+`S_NF{1'b1}}, (`FLEN-1-`NE-`S_NF)'(0)} : {(`NE+1+`S_NF)'(0), Plus1, (`FLEN-1-`NE-`S_NF)'(0)}; - 2'h2: assign RoundAdd = Minus1 ? {{`NE+2+`H_NF{1'b1}}, (`FLEN-1-`NE-`H_NF)'(0)} : {(`NE+1+`H_NF)'(0), Plus1, (`FLEN-1-`NE-`H_NF)'(0)}; + 2'h3: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, Plus1}; + 2'h1: RoundAdd = Minus1 ? {{`NE+2+`D_NF{1'b1}}, (`FLEN-1-`NE-`D_NF)'(0)} : {(`NE+1+`D_NF)'(0), Plus1, (`FLEN-1-`NE-`D_NF)'(0)}; + 2'h0: RoundAdd = Minus1 ? {{`NE+2+`S_NF{1'b1}}, (`FLEN-1-`NE-`S_NF)'(0)} : {(`NE+1+`S_NF)'(0), Plus1, (`FLEN-1-`NE-`S_NF)'(0)}; + 2'h2: RoundAdd = Minus1 ? {{`NE+2+`H_NF{1'b1}}, (`FLEN-1-`NE-`H_NF)'(0)} : {(`NE+1+`H_NF)'(0), Plus1, (`FLEN-1-`NE-`H_NF)'(0)}; endcase end @@ -1056,20 +1056,20 @@ module fmaflags( end else if (`FPSIZES == 3) begin always_comb begin case (FmtM) - `FMT: assign GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; - `FMT1: assign GtMaxExp = &FullResultExp[`NE1-1:0] | FullResultExp[`NE1]; - `FMT2: assign GtMaxExp = &FullResultExp[`NE2-1:0] | FullResultExp[`NE2]; - default: assign GtMaxExp = 1'bx; + `FMT: GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; + `FMT1: GtMaxExp = &FullResultExp[`NE1-1:0] | FullResultExp[`NE1]; + `FMT2: GtMaxExp = &FullResultExp[`NE2-1:0] | FullResultExp[`NE2]; + default: GtMaxExp = 1'bx; endcase end end else begin always_comb begin case (FmtM) - 2'h3: assign GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; - 2'h1: assign GtMaxExp = &FullResultExp[`D_NE-1:0] | FullResultExp[`D_NE]; - 2'h0: assign GtMaxExp = &FullResultExp[`S_NE-1:0] | FullResultExp[`S_NE]; - 2'h2: assign GtMaxExp = &FullResultExp[`H_NE-1:0] | FullResultExp[`H_NE]; + 2'h3: GtMaxExp = &FullResultExp[`NE-1:0] | FullResultExp[`NE]; + 2'h1: GtMaxExp = &FullResultExp[`D_NE-1:0] | FullResultExp[`D_NE]; + 2'h0: GtMaxExp = &FullResultExp[`S_NE-1:0] | FullResultExp[`S_NE]; + 2'h2: GtMaxExp = &FullResultExp[`H_NE-1:0] | FullResultExp[`H_NE]; endcase end @@ -1157,68 +1157,68 @@ module resultselect( case (FmtM) `FMT: begin if(`IEEE754) begin - assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; - assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; - assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; - assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; + YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; + ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; + InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin - assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}}; - assign KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; - assign UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; - assign InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; - assign NormResult = {ResultSgn, ResultExp, ResultFrac}; + KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; + UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; + InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; + NormResult = {ResultSgn, ResultExp, ResultFrac}; end `FMT1: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; - assign YNaNResult = {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; - assign ZNaNResult = {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; - assign InvalidResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + XNaNResult = {{`FLEN-`LEN1{1'b1}}, XSgnM, {`NE1{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF1]}; + YNaNResult = {{`FLEN-`LEN1{1'b1}}, YSgnM, {`NE1{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF1]}; + ZNaNResult = {{`FLEN-`LEN1{1'b1}}, ZSgnEffM, {`NE1{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF1]}; + InvalidResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; + XNaNResult = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, ResultSgn, {`NE1{1'b1}}, (`NF1)'(0)}; - assign KillProdResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; - assign NormResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; + KillProdResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE1-2:0], ZManM[`NF-1:`NF-`NF1]} + (RoundAdd[`NF-`NF1+`LEN1-2:`NF-`NF1]&{`LEN1-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`LEN1{1'b1}}, {ResultSgn, (`LEN1-1)'(0)} + {(`LEN1-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`LEN1{1'b1}}, InfSgn, {`NE1{1'b1}}, (`NF1)'(0)}; + NormResult = {{`FLEN-`LEN1{1'b1}}, ResultSgn, ResultExp[`NE1-1:0], ResultFrac[`NF-1:`NF-`NF1]}; end `FMT2: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`LEN2{1'b1}}, XSgnM, {`NE2{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF2]}; - assign YNaNResult = {{`FLEN-`LEN2{1'b1}}, YSgnM, {`NE2{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF2]}; - assign ZNaNResult = {{`FLEN-`LEN2{1'b1}}, ZSgnEffM, {`NE2{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF2]}; - assign InvalidResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; + XNaNResult = {{`FLEN-`LEN2{1'b1}}, XSgnM, {`NE2{1'b1}}, 1'b1, XManM[`NF-2:`NF-`NF2]}; + YNaNResult = {{`FLEN-`LEN2{1'b1}}, YSgnM, {`NE2{1'b1}}, 1'b1, YManM[`NF-2:`NF-`NF2]}; + ZNaNResult = {{`FLEN-`LEN2{1'b1}}, ZSgnEffM, {`NE2{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`NF2]}; + InvalidResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; + XNaNResult = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : {{`FLEN-`LEN2{1'b1}}, ResultSgn, {`NE2{1'b1}}, (`NF2)'(0)}; - assign KillProdResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`NF2]} + (RoundAdd[`NF-`NF2+`LEN2-2:`NF-`NF2]&{`LEN2-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`LEN2{1'b1}}, {ResultSgn, (`LEN2-1)'(0)} + {(`LEN2-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`LEN2{1'b1}}, InfSgn, {`NE2{1'b1}}, (`NF2)'(0)}; - assign NormResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, ResultExp[`NE2-1:0], ResultFrac[`NF-1:`NF-`NF2]}; + KillProdResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`NF2]} + (RoundAdd[`NF-`NF2+`LEN2-2:`NF-`NF2]&{`LEN2-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`LEN2{1'b1}}, {ResultSgn, (`LEN2-1)'(0)} + {(`LEN2-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`LEN2{1'b1}}, InfSgn, {`NE2{1'b1}}, (`NF2)'(0)}; + NormResult = {{`FLEN-`LEN2{1'b1}}, ResultSgn, ResultExp[`NE2-1:0], ResultFrac[`NF-1:`NF-`NF2]}; end default: begin if(`IEEE754) begin - assign XNaNResult = (`FLEN)'(0); - assign YNaNResult = (`FLEN)'(0); - assign ZNaNResult = (`FLEN)'(0); - assign InvalidResult = (`FLEN)'(0); + XNaNResult = (`FLEN)'(0); + YNaNResult = (`FLEN)'(0); + ZNaNResult = (`FLEN)'(0); + InvalidResult = (`FLEN)'(0); end else begin - assign XNaNResult = (`FLEN)'(0); + XNaNResult = (`FLEN)'(0); end - assign OverflowResult = (`FLEN)'(0); - assign KillProdResult = (`FLEN)'(0); - assign UnderflowResult = (`FLEN)'(0); - assign InfResult = (`FLEN)'(0); - assign NormResult = (`FLEN)'(0); + OverflowResult = (`FLEN)'(0); + KillProdResult = (`FLEN)'(0); + UnderflowResult = (`FLEN)'(0); + InfResult = (`FLEN)'(0); + NormResult = (`FLEN)'(0); end endcase end @@ -1228,71 +1228,71 @@ module resultselect( case (FmtM) 2'h3: begin if(`IEEE754) begin - assign XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; - assign YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; - assign ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; - assign InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {XSgnM, {`NE{1'b1}}, 1'b1, XManM[`NF-2:0]}; + YNaNResult = {YSgnM, {`NE{1'b1}}, 1'b1, YManM[`NF-2:0]}; + ZNaNResult = {ZSgnEffM, {`NE{1'b1}}, 1'b1, ZManM[`NF-2:0]}; + InvalidResult = {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end else begin - assign XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; + XNaNResult = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}}; - assign KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; - assign UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; - assign InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; - assign NormResult = {ResultSgn, ResultExp, ResultFrac}; + KillProdResult = {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})}; + UnderflowResult = {ResultSgn, {`FLEN-1{1'b0}}} + {(`FLEN-1)'(0),(CalcPlus1&(AddendStickyM|FrmM[1]))}; + InfResult = {InfSgn, {`NE{1'b1}}, (`NF)'(0)}; + NormResult = {ResultSgn, ResultExp, ResultFrac}; end 2'h1: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`D_LEN{1'b1}}, XSgnM, {`D_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`D_NF]}; - assign YNaNResult = {{`FLEN-`D_LEN{1'b1}}, YSgnM, {`D_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`D_NF]}; - assign ZNaNResult = {{`FLEN-`D_LEN{1'b1}}, ZSgnEffM, {`D_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`D_NF]}; - assign InvalidResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; + XNaNResult = {{`FLEN-`D_LEN{1'b1}}, XSgnM, {`D_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`D_NF]}; + YNaNResult = {{`FLEN-`D_LEN{1'b1}}, YSgnM, {`D_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`D_NF]}; + ZNaNResult = {{`FLEN-`D_LEN{1'b1}}, ZSgnEffM, {`D_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`D_NF]}; + InvalidResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; + XNaNResult = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; - assign KillProdResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`D_NE-2:0], ZManM[`NF-1:`NF-`D_NF]} + (RoundAdd[`NF-`D_NF+`D_LEN-2:`NF-`D_NF]&{`D_LEN-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`D_LEN{1'b1}}, {ResultSgn, (`D_LEN-1)'(0)} + {(`D_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`D_LEN{1'b1}}, InfSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; - assign NormResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, ResultExp[`D_NE-1:0], ResultFrac[`NF-1:`NF-`D_NF]}; + KillProdResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`D_NE-2:0], ZManM[`NF-1:`NF-`D_NF]} + (RoundAdd[`NF-`D_NF+`D_LEN-2:`NF-`D_NF]&{`D_LEN-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`D_LEN{1'b1}}, {ResultSgn, (`D_LEN-1)'(0)} + {(`D_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`D_LEN{1'b1}}, InfSgn, {`D_NE{1'b1}}, (`D_NF)'(0)}; + NormResult = {{`FLEN-`D_LEN{1'b1}}, ResultSgn, ResultExp[`D_NE-1:0], ResultFrac[`NF-1:`NF-`D_NF]}; end 2'h0: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`S_LEN{1'b1}}, XSgnM, {`S_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`S_NF]}; - assign YNaNResult = {{`FLEN-`S_LEN{1'b1}}, YSgnM, {`S_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`S_NF]}; - assign ZNaNResult = {{`FLEN-`S_LEN{1'b1}}, ZSgnEffM, {`S_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`S_NF]}; - assign InvalidResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; + XNaNResult = {{`FLEN-`S_LEN{1'b1}}, XSgnM, {`S_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`S_NF]}; + YNaNResult = {{`FLEN-`S_LEN{1'b1}}, YSgnM, {`S_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`S_NF]}; + ZNaNResult = {{`FLEN-`S_LEN{1'b1}}, ZSgnEffM, {`S_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`S_NF]}; + InvalidResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; + XNaNResult = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; - assign KillProdResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`S_NF]} + (RoundAdd[`NF-`S_NF+`S_LEN-2:`NF-`S_NF]&{`S_LEN-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`S_LEN{1'b1}}, {ResultSgn, (`S_LEN-1)'(0)} + {(`S_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`S_LEN{1'b1}}, InfSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; - assign NormResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, ResultExp[`S_NE-1:0], ResultFrac[`NF-1:`NF-`S_NF]}; + KillProdResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`NE2-2:0], ZManM[`NF-1:`NF-`S_NF]} + (RoundAdd[`NF-`S_NF+`S_LEN-2:`NF-`S_NF]&{`S_LEN-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`S_LEN{1'b1}}, {ResultSgn, (`S_LEN-1)'(0)} + {(`S_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`S_LEN{1'b1}}, InfSgn, {`S_NE{1'b1}}, (`S_NF)'(0)}; + NormResult = {{`FLEN-`S_LEN{1'b1}}, ResultSgn, ResultExp[`S_NE-1:0], ResultFrac[`NF-1:`NF-`S_NF]}; end 2'h2: begin if(`IEEE754) begin - assign XNaNResult = {{`FLEN-`H_LEN{1'b1}}, XSgnM, {`H_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`H_NF]}; - assign YNaNResult = {{`FLEN-`H_LEN{1'b1}}, YSgnM, {`H_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`H_NF]}; - assign ZNaNResult = {{`FLEN-`H_LEN{1'b1}}, ZSgnEffM, {`H_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`H_NF]}; - assign InvalidResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; + XNaNResult = {{`FLEN-`H_LEN{1'b1}}, XSgnM, {`H_NE{1'b1}}, 1'b1, XManM[`NF-2:`NF-`H_NF]}; + YNaNResult = {{`FLEN-`H_LEN{1'b1}}, YSgnM, {`H_NE{1'b1}}, 1'b1, YManM[`NF-2:`NF-`H_NF]}; + ZNaNResult = {{`FLEN-`H_LEN{1'b1}}, ZSgnEffM, {`H_NE{1'b1}}, 1'b1, ZManM[`NF-2:`NF-`H_NF]}; + InvalidResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; end else begin - assign XNaNResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; + XNaNResult = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; end - assign OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : + OverflowResult = ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; - assign KillProdResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`H_NE-2:0], ZManM[`NF-1:`NF-`H_NF]} + (RoundAdd[`NF-`H_NF+`H_LEN-2:`NF-`H_NF]&{`H_LEN-1{AddendStickyM}})}; - assign UnderflowResult = {{`FLEN-`H_LEN{1'b1}}, {ResultSgn, (`H_LEN-1)'(0)} + {(`H_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; - assign InfResult = {{`FLEN-`H_LEN{1'b1}}, InfSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; - assign NormResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, ResultExp[`H_NE-1:0], ResultFrac[`NF-1:`NF-`H_NF]}; + KillProdResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, {ZExpM[`NE-1], ZExpM[`H_NE-2:0], ZManM[`NF-1:`NF-`H_NF]} + (RoundAdd[`NF-`H_NF+`H_LEN-2:`NF-`H_NF]&{`H_LEN-1{AddendStickyM}})}; + UnderflowResult = {{`FLEN-`H_LEN{1'b1}}, {ResultSgn, (`H_LEN-1)'(0)} + {(`H_LEN-1)'(0), (CalcPlus1&(AddendStickyM|FrmM[1]))}}; + InfResult = {{`FLEN-`H_LEN{1'b1}}, InfSgn, {`H_NE{1'b1}}, (`H_NF)'(0)}; + NormResult = {{`FLEN-`H_LEN{1'b1}}, ResultSgn, ResultExp[`H_NE-1:0], ResultFrac[`NF-1:`NF-`H_NF]}; end endcase end diff --git a/pipelined/src/fpu/unpack.sv b/pipelined/src/fpu/unpack.sv index 1625b2fc2..3041cd72f 100644 --- a/pipelined/src/fpu/unpack.sv +++ b/pipelined/src/fpu/unpack.sv @@ -293,7 +293,7 @@ module unpack ( always_comb begin case (FmtE) - `Q_BIAS: begin // if input is quad percision + 2'b11: begin // if input is quad percision // extract sign bit XSgnE = X[`Q_LEN-1]; YSgnE = Y[`Q_LEN-1]; @@ -319,7 +319,7 @@ module unpack ( YExpMaxE = &Y[`Q_LEN-2:`Q_NF]; ZExpMaxE = &Z[`Q_LEN-2:`Q_NF]; end - `D_BIAS: begin // if input is double percision + 2'b01: begin // if input is double percision // extract sign bit XSgnE = XLen1[`D_LEN-1]; YSgnE = YLen1[`D_LEN-1]; @@ -353,7 +353,7 @@ module unpack ( YExpMaxE = &YLen1[`D_LEN-2:`D_NE]; ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE]; end - `S_BIAS: begin // if input is single percision + 2'b00: begin // if input is single percision // extract sign bit XSgnE = XLen2[`S_LEN-1]; YSgnE = YLen2[`S_LEN-1]; @@ -387,7 +387,7 @@ module unpack ( YExpMaxE = &YLen2[`S_LEN-2:`S_NF]; ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF]; end - `H_BIAS: begin // if input is half percision + 2'b10: begin // if input is half percision // extract sign bit XSgnE = XLen3[`H_LEN-1]; YSgnE = YLen3[`H_LEN-1]; From 58668812c1d0922ac2e8541ff9d6b281b18307de Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 23 Mar 2022 14:17:59 -0500 Subject: [PATCH 4/6] Moved WriteDataM register into LSU. --- pipelined/src/ieu/datapath.sv | 4 +--- pipelined/src/ieu/ieu.sv | 4 ++-- pipelined/src/lsu/lsu.sv | 4 +++- pipelined/src/wally/wallypipelinedcore.sv | 6 +++--- pipelined/testbench/testbench-linux.sv | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pipelined/src/ieu/datapath.sv b/pipelined/src/ieu/datapath.sv index 52c0dc208..8178f1656 100644 --- a/pipelined/src/ieu/datapath.sv +++ b/pipelined/src/ieu/datapath.sv @@ -55,7 +55,7 @@ module datapath ( input logic FWriteIntM, input logic [`XLEN-1:0] FIntResM, output logic [`XLEN-1:0] SrcAM, - output logic [`XLEN-1:0] WriteDataM, + output logic [`XLEN-1:0] WriteDataE, // Writeback stage signals input logic StallW, FlushW, (* mark_debug = "true" *) input logic RegWriteW, @@ -83,7 +83,6 @@ module datapath ( logic [`XLEN-1:0] SrcAE2, SrcBE2; logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE; - logic [`XLEN-1:0] WriteDataE; // Memory stage signals logic [`XLEN-1:0] IEUResultM; logic [`XLEN-1:0] IFResultM; @@ -119,7 +118,6 @@ module datapath ( // Memory stage pipeline register flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); flopenrc #(`XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); - flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM); flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM); // Writeback stage pipeline register and logic diff --git a/pipelined/src/ieu/ieu.sv b/pipelined/src/ieu/ieu.sv index 8f85f7596..a10d1f92f 100644 --- a/pipelined/src/ieu/ieu.sv +++ b/pipelined/src/ieu/ieu.sv @@ -52,7 +52,7 @@ module ieu ( output logic [1:0] MemRWM, // read/write control goes to LSU output logic [1:0] AtomicE, // atomic control goes to LSU output logic [1:0] AtomicM, // atomic control goes to LSU - output logic [`XLEN-1:0] WriteDataM, // Address and write data to LSU + output logic [`XLEN-1:0] WriteDataE, // Address and write data to LSU output logic [2:0] Funct3M, // size and signedness to LSU output logic [`XLEN-1:0] SrcAM, // to privilege and fpu @@ -106,7 +106,7 @@ module ieu ( .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .IllegalFPUInstrE, .FWriteDataE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, - .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, + .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataE, .StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .CSRReadValW, .ReadDataM, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 5f1c31ea9..7442aea70 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -50,7 +50,7 @@ module lsu ( // address and write data input logic [`XLEN-1:0] IEUAdrE, (* mark_debug = "true" *)output logic [`XLEN-1:0] IEUAdrM, - input logic [`XLEN-1:0] WriteDataM, + input logic [`XLEN-1:0] WriteDataE, output logic [`XLEN-1:0] ReadDataM, // cpu privilege input logic [1:0] PrivilegeModeW, @@ -105,10 +105,12 @@ module lsu ( logic DataDAPageFaultM; logic [`XLEN-1:0] LSUWriteDataM; logic [(`XLEN-1)/8:0] ByteMaskM; + logic [`XLEN-1:0] WriteDataM; // *** TO DO: Burst mode flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); + flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM); assign IEUAdrExtM = {2'b00, IEUAdrM}; assign LSUStallM = DCacheStallM | InterlockStall | BusStall; diff --git a/pipelined/src/wally/wallypipelinedcore.sv b/pipelined/src/wally/wallypipelinedcore.sv index c8be1116b..336e73f44 100644 --- a/pipelined/src/wally/wallypipelinedcore.sv +++ b/pipelined/src/wally/wallypipelinedcore.sv @@ -127,7 +127,7 @@ module wallypipelinedcore ( // cpu lsu interface logic [2:0] Funct3M; logic [`XLEN-1:0] IEUAdrE; - (* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataM; + (* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataE; (* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM; (* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM; logic [`XLEN-1:0] ReadDataW; @@ -223,7 +223,7 @@ module wallypipelinedcore ( .MemRWM, // read/write control goes to LSU .AtomicE, // atomic control goes to LSU .AtomicM, // atomic control goes to LSU - .WriteDataM, // Write data to LSU + .WriteDataE, // Write data to LSU .Funct3M, // size and signedness to LSU .SrcAM, // to privilege and fpu .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM, @@ -252,7 +252,7 @@ module wallypipelinedcore ( .CommittedM, .DCacheMiss, .DCacheAccess, .SquashSCW, //.DataMisalignedM(DataMisalignedM), - .IEUAdrE, .IEUAdrM, .WriteDataM, + .IEUAdrE, .IEUAdrM, .WriteDataE, .ReadDataM, .FlushDCacheM, // connected to ahb (all stay the same) .LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck, diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 62d13a1a3..6044d124d 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -101,7 +101,7 @@ module testbench; flopenr #(32) InstrWReg(clk, reset, ~`STALLW, `FLUSHW ? nop : dut.core.ifu.InstrM, InstrW); flopenrc #(1) controlregW(clk, reset, `FLUSHW, ~`STALLW, dut.core.ieu.c.InstrValidM, InstrValidW); flopenrc #(`XLEN) IEUAdrWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.IEUAdrM, IEUAdrW); - flopenrc #(`XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.WriteDataM, WriteDataW); + flopenrc #(`XLEN) WriteDataWReg(clk, reset, `FLUSHW, ~`STALLW, dut.core.lsu.WriteDataM, WriteDataW); flopenr #(1) TrapWReg(clk, reset, ~`STALLW, dut.core.hzu.TrapM, TrapW); /////////////////////////////////////////////////////////////////////////////// From 9f60256f22e0f71389498da2f06f1faaad2b46f2 Mon Sep 17 00:00:00 2001 From: bbracker Date: Thu, 24 Mar 2022 17:08:10 -0700 Subject: [PATCH 5/6] 1st attempt at multiple channel PLIC --- linux/testvector-generation/genCheckpoint.sh | 6 +- linux/testvector-generation/parsePlicState.py | 24 +- pipelined/src/privileged/csr.sv | 14 +- pipelined/src/privileged/csri.sv | 30 +- pipelined/src/privileged/privileged.sv | 4 +- pipelined/src/uncore/plic.sv | 229 +++++++++------ pipelined/src/uncore/uncore.sv | 5 +- pipelined/src/wally/wallypipelinedcore.sv | 268 +++++++++--------- pipelined/src/wally/wallypipelinedsoc.sv | 6 +- pipelined/testbench/testbench-linux.sv | 4 +- 10 files changed, 325 insertions(+), 265 deletions(-) diff --git a/linux/testvector-generation/genCheckpoint.sh b/linux/testvector-generation/genCheckpoint.sh index 8f4d0a111..dea4d5551 100755 --- a/linux/testvector-generation/genCheckpoint.sh +++ b/linux/testvector-generation/genCheckpoint.sh @@ -101,10 +101,12 @@ then set logging on # Priority Levels for sources 1 thru 63 x/63xw 0x0C000004 - # Interrupt Enables + # Interrupt Enables for sources 1 thru 63 for contexts 0 and 1 x/2xw 0x0C020000 - # Global Priority Threshold + x/2xw 0x0C020080 + # Global Priority Threshold for contexts 0 and 1 x/1xw 0x0C200000 + x/1xw 0x0C201000 set logging off shell echo \"GDB storing RAM to $rawRamFile\" dump binary memory $rawRamFile 0x80000000 0xffffffff diff --git a/linux/testvector-generation/parsePlicState.py b/linux/testvector-generation/parsePlicState.py index a3c3787c8..35ef00b1d 100755 --- a/linux/testvector-generation/parsePlicState.py +++ b/linux/testvector-generation/parsePlicState.py @@ -1,5 +1,6 @@ #! /usr/bin/python3 import sys, os +from functools import reduce ################ # Helper Funcs # @@ -21,6 +22,9 @@ def tokenize(string): token = token + char return tokens +def strip0x(num): + return num[2:] + def stripZeroes(num): num = num.strip('0') if num=='': @@ -42,7 +46,7 @@ if not os.path.exists(rawPlicStateFile): sys.exit('Error input file '+rawPlicStateFile+'not found') with open(rawPlicStateFile, 'r') as rawPlicStateFile: - plicIntPriorityArray=[] + plicIntPriorityArray = [] # iterates over number of different sources # 0x0C000004 thru 0x0C000010 plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] # 0x0C000014 thru 0x0C000020 @@ -76,20 +80,30 @@ with open(rawPlicStateFile, 'r') as rawPlicStateFile: # 0x0C0000f4 thru 0x0C0000fc plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:] + plicIntEnableArray = [] # iterates over number of different contexts # 0x0C020000 thru 0x0C020004 plicIntEnable = tokenize(rawPlicStateFile.readline())[1:] + plicIntEnable = map(strip0x,plicIntEnable) + plicIntEnableArray.append(reduce(lambda x,y: x+y,plicIntEnable)) + # 0x0C020080 thru 0x0C020084 + plicIntEnable = tokenize(rawPlicStateFile.readline())[1:] + plicIntEnable = map(strip0x,plicIntEnable) + plicIntEnableArray.append(reduce(lambda x,y: x+y,plicIntEnable)) + plicIntPriorityThresholdArray = [] # iterates over number of different contexts # 0x0C200000 - plicIntPriorityThreshold = tokenize(rawPlicStateFile.readline())[1:] + plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:] + # 0x0C201000 + plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:] with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile: for word in plicIntPriorityArray: outFile.write(stripZeroes(word[2:])+'\n') with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile: - for word in plicIntEnable: - outFile.write(stripZeroes(word[2:])) + for word in plicIntEnableArray: + outFile.write(word+'\n') with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile: - for word in plicIntPriorityThreshold: + for word in plicIntPriorityThresholdArray: outFile.write(stripZeroes(word[2:])+'\n') print("Finished parsing PLIC state!") diff --git a/pipelined/src/privileged/csr.sv b/pipelined/src/privileged/csr.sv index cac7aa670..ecdcbe50d 100644 --- a/pipelined/src/privileged/csr.sv +++ b/pipelined/src/privileged/csr.sv @@ -43,13 +43,13 @@ module csr #(parameter input logic [31:0] InstrM, input logic [`XLEN-1:0] PCM, SrcAM, input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, - input logic TimerIntM, ExtIntM, SwIntM, + input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, input logic [63:0] MTIME_CLINT, input logic InstrValidM, FRegWriteM, LoadStallD, - input logic BPPredDirWrongM, - input logic BTBPredPCWrongM, - input logic RASPredPCWrongM, - input logic BPPredClassNonCFIWrongM, + input logic BPPredDirWrongM, + input logic BTBPredPCWrongM, + input logic RASPredPCWrongM, + input logic BPPredClassNonCFIWrongM, input logic [4:0] InstrClassM, input logic DCacheMiss, input logic DCacheAccess, @@ -123,7 +123,7 @@ module csr #(parameter assign CSRUWriteM = CSRWriteM; csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM, - .CSRAdrM, .ExtIntM, .TimerIntM, .SwIntM, + .CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM, .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM); csrsr csrsr(.clk, .reset, .StallW, .WriteMSTATUSM, .WriteSSTATUSM, @@ -167,7 +167,7 @@ module csr #(parameter // merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) | - (CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE); + (CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE); assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM & IllegalCSRSAccessM & IllegalCSRUAccessM | InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM; diff --git a/pipelined/src/privileged/csri.sv b/pipelined/src/privileged/csri.sv index 8a3f42fdf..7eff94962 100644 --- a/pipelined/src/privileged/csri.sv +++ b/pipelined/src/privileged/csri.sv @@ -41,7 +41,7 @@ module csri #(parameter input logic InstrValidNotFlushedM, StallW, input logic CSRMWriteM, CSRSWriteM, input logic [11:0] CSRAdrM, - input logic ExtIntM, TimerIntM, SwIntM, + input logic ExtIntM, ExtIntS, TimerIntM, SwIntM, input logic [`XLEN-1:0] MIDELEG_REGW, output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, input logic [`XLEN-1:0] CSRWriteValM @@ -57,12 +57,12 @@ module csri #(parameter always_comb begin IntInM = 0; - IntInM[11] = ExtIntM;; // MEIP - IntInM[9] = ExtIntM & MIDELEG_REGW[9]; // SEIP - IntInM[7] = TimerIntM; // MTIP - IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP - IntInM[3] = SwIntM; // MSIP - IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP + IntInM[11] = ExtIntM; // MEIP + IntInM[9] = ExtIntS | (ExtIntM & MIDELEG_REGW[9]); // SEIP + IntInM[7] = TimerIntM; // MTIP + IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP + IntInM[3] = SwIntM; // MSIP + IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP end // Interrupt Write Enables @@ -82,21 +82,19 @@ module csri #(parameter assign MIP_WRITE_MASK = 12'h000; assign SIP_WRITE_MASK = 12'h000; end - always @(posedge clk) //, posedge reset) begin // *** I strongly feel that IntInM should go directly to IP_REGW -- Ben 9/7/21 + always @(posedge clk) if (reset) IP_REGW_writeable <= 10'b0; - else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable - else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable -// else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable - else IP_REGW_writeable <= IP_REGW_writeable | IntInM[9:0]; // *** check this turns off interrupts properly even when MIDELEG changes - always @(posedge clk) //, posedge reset) begin + else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable + else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable + else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes + always @(posedge clk) if (reset) IE_REGW <= 12'b0; else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields -// else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field // restricted views of registers - // Add MEIP read-only signal - assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable}; + // Add ExtIntM read-only signal + assign IP_REGW = {ExtIntM,1'b0,ExtIntS,9'b0} | {2'b0,IP_REGW_writeable}; // Machine Mode assign MIP_REGW = IP_REGW; diff --git a/pipelined/src/privileged/privileged.sv b/pipelined/src/privileged/privileged.sv index 8493a15bd..9a8fb9f8a 100644 --- a/pipelined/src/privileged/privileged.sv +++ b/pipelined/src/privileged/privileged.sv @@ -55,7 +55,7 @@ module privileged ( input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD, input logic LoadMisalignedFaultM, input logic StoreAmoMisalignedFaultM, - input logic TimerIntM, ExtIntM, SwIntM, + input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, input logic [63:0] MTIME_CLINT, input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM, input logic [4:0] SetFflagsM, @@ -150,7 +150,7 @@ module privileged ( .StallE, .StallM, .StallW, .InstrM, .PCM, .SrcAM, .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, - .TimerIntM, .ExtIntM, .SwIntM, + .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, diff --git a/pipelined/src/uncore/plic.sv b/pipelined/src/uncore/plic.sv index 2d5459989..cccbe75cf 100644 --- a/pipelined/src/uncore/plic.sv +++ b/pipelined/src/uncore/plic.sv @@ -37,6 +37,15 @@ `include "wally-config.vh" +`define N `PLIC_NUM_SRC +// number of interrupt sources +// does not include source 0, which does not connect to anything according to spec +// up to 63 sources supported; *** in the future, allow up to 1023 sources + +`define C 2 +// number of conexts +// hardcoded to 2 contexts for now; *** later upgrade to arbitrary (up to 15872) contexts + module plic ( input logic HCLK, HRESETn, input logic HSELPLIC, @@ -48,25 +57,26 @@ module plic ( input logic UARTIntr,GPIOIntr, output logic [`XLEN-1:0] HREADPLIC, output logic HRESPPLIC, HREADYPLIC, - output logic ExtIntM); - - localparam N=`PLIC_NUM_SRC; // should not exceed 63; does not inlcude source 0, which does not connect to anything according to spec + output logic ExtIntM, ExtIntS); logic memwrite, memread, initTrans; logic [23:0] entry, entryd; logic [31:0] Din, Dout; - logic [N:1] requests; - logic [2:0] intPriority[N:1]; - logic [2:0] intThreshold; - logic [N:1] intPending, nextIntPending, intEn, intInProgress; - logic [5:0] intClaim; // ID's are 6 bits if we stay within 63 sources - - logic [N:1] pendingArray[7:1]; - logic [7:1] pendingPGrouped; - logic [7:1] pendingMaxP; - logic [N:1] pendingRequestsAtMaxP; - logic [7:1] threshMask; + // context-independent signals + logic [`N:1] requests; + logic [`N:1][2:0] intPriority; + logic [`N:1] intInProgress, intPending, nextIntPending; + + // context-dependent signals + logic [`C-1:0][2:0] intThreshold; + logic [`C-1:0][`N:1] intEn; + logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources + logic [`C-1:0][7:1][`N:1] irqMatrix; + logic [`C-1:0][7:1] priorities_with_irqs; + logic [`C-1:0][7:1] max_priority_with_irqs; + logic [`C-1:0][`N:1] irqs_at_max_priority; + logic [`C-1:0][7:1] threshMask; // ======= // AHB I/O @@ -82,12 +92,12 @@ module plic ( // account for subword read/write circuitry // -- Note PLIC registers are 32 bits no matter what; access them with LW SW. - if (`XLEN == 64) begin + if (`XLEN == 64) begin assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0]; assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout}; end else begin // 32-bit - assign Din = HWDATA[31:0]; assign HREADPLIC = Dout; + assign Din = HWDATA[31:0]; end // ================== @@ -96,43 +106,56 @@ module plic ( always @(posedge HCLK,negedge HRESETn) begin // resetting if (~HRESETn) begin - intPriority <= #1 '{default:3'b0}; - intEn <= #1 {N{1'b0}}; - intThreshold <= #1 3'b0; - intInProgress <= #1 {N{1'b0}}; + intPriority <= #1 {`N{3'b0}}; + intEn <= #1 {2{`N'b0}}; + intThreshold <= #1 {2{3'b0}}; + intInProgress <= #1 `N'b0; // writing end else begin if (memwrite) casez(entryd) 24'h0000??: intPriority[entryd[7:2]] <= #1 Din[2:0]; - `ifdef PLIC_NUM_SRC_LT_32 - 24'h002000: intEn[N:1] <= #1 Din[N:1]; + `ifdef PLIC_NUM_SRC_LT_32 // *** switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources + 24'h002000: intEn[0][`N:1] <= #1 Din[`N:1]; + 24'h002080: intEn[1][`N:1] <= #1 Din[`N:1]; `endif `ifndef PLIC_NUM_SRC_LT_32 - 24'h002000: intEn[31:1] <= #1 Din[31:1]; - 24'h002004: intEn[N:32] <= #1 Din[31:0]; + 24'h002000: intEn[0][31:1] <= #1 Din[31:1]; + 24'h002004: intEn[0][`N:32] <= #1 Din[31:0]; + 24'h002080: intEn[1][31:1] <= #1 Din[31:1]; + 24'h002084: intEn[1][`N:32] <= #1 Din[31:0]; `endif - 24'h200000: intThreshold[2:0] <= #1 Din[2:0]; - 24'h200004: intInProgress <= #1 intInProgress & ~(`PLIC_NUM_SRC'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion + 24'h200000: intThreshold[0] <= #1 Din[2:0]; + 24'h200004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion + 24'h201000: intThreshold[1] <= #1 Din[2:0]; + 24'h201004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion endcase // reading if (memread) casez(entry) 24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]}; `ifdef PLIC_NUM_SRC_LT_32 - 24'h001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0}; - 24'h002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0}; + 24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0}; + 24'h002000: Dout <= #1 {{(31-`N){1'b0}},intEn[0],1'b0}; + 24'h002080: Dout <= #1 {{(31-`N){1'b0}},intEn[1],1'b0}; `endif `ifndef PLIC_NUM_SRC_LT_32 24'h001000: Dout <= #1 {intPending[31:1],1'b0}; - 24'h001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]}; - 24'h002000: Dout <= #1 {intEn[31:1],1'b0}; - 24'h002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]}; + 24'h001004: Dout <= #1 {{(63-`N){1'b0}},intPending[`N:32]}; + 24'h002000: Dout <= #1 {intEn[0][31:1],1'b0}; + 24'h002004: Dout <= #1 {{(63-`N){1'b0}},intEn[0][`N:32]}; + 24'h002080: Dout <= #1 {intEn[0][31:1],1'b0}; + 24'h002084: Dout <= #1 {{(63-`N){1'b0}},intEn[1][`N:32]}; `endif - 24'h200000: Dout <= #1 {29'b0,intThreshold[2:0]}; + 24'h200000: Dout <= #1 {29'b0,intThreshold[0]}; 24'h200004: begin - Dout <= #1 {26'b0,intClaim}; - intInProgress <= #1 intInProgress | (`PLIC_NUM_SRC'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed + Dout <= #1 {26'b0,intClaim[0]}; + intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed + end + 24'h201000: Dout <= #1 {29'b0,intThreshold[1]}; + 24'h201004: begin + Dout <= #1 {26'b0,intClaim[1]}; + intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed end default: Dout <= #1 32'h0; // invalid access endcase @@ -143,7 +166,7 @@ module plic ( // connect sources to requests always_comb begin - requests = {N{1'b0}}; + requests = `N'b0; `ifdef PLIC_GPIO_ID requests[`PLIC_GPIO_ID] = GPIOIntr; `endif @@ -152,66 +175,88 @@ module plic ( `endif end - // pending updates - // *** verify that this matches the expectations of the things that make requests (in terms of timing, edge-triggered vs level-triggered) - assign nextIntPending = (intPending | (requests & ~intInProgress)) & // requests should raise intPending except when their service routine is already in progress - ~({N{((entry == 24'h200004) & memread)}} << (intClaim-1)); // clear pending bit when claim register is read - flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending); + // pending interrupt requests + assign nextIntPending = + (intPending | // existing pending requests + (requests & ~intInProgress)) & // assert new requests (if they aren't already being serviced) + ~({`N{((entry == 24'h200004) & memread)}} << (intClaim[0]-1)) & // deassert requests that just completed + ~({`N{((entry == 24'h201004) & memread)}} << (intClaim[1]-1)); + flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending); - // pending array - indexed by priority_lvl x source_ID - genvar i, j; - for (j=1; j<=7; j++) begin: pending - for (i=1; i<=N; i=i+1) begin: pendingbit - assign pendingArray[j][i] = (intPriority[i]==j) & intEn[i] & intPending[i]; + // context-dependent signals + genvar ctx; + for (ctx=0; ctx<`C; ctx++) begin + // request matrix + // priority level (rows) X source ID (columns) + // + // irqMatrix[ctx][pri][src] is high if source + // has priority level and has an "active" interrupt request + // ("active" meaning it is enabled in context and is pending) + genvar src, pri; + for (pri=1; pri<=7; pri++) begin + for (src=1; src<=`N; src++) begin + assign irqMatrix[ctx][pri][src] = (intPriority[src]==pri) & intPending[src] & intEn[ctx][src]; + end end - end - // pending array, except grouped by priority - assign pendingPGrouped[7:1] = {|pendingArray[7], - |pendingArray[6], - |pendingArray[5], - |pendingArray[4], - |pendingArray[3], - |pendingArray[2], - |pendingArray[1]}; - //assign pendingPGrouped = pendingArray.or; - // pendingPGrouped, except only topmost priority is active - assign pendingMaxP[7:1] = {pendingPGrouped[7], - pendingPGrouped[6] & ~|pendingPGrouped[7], - pendingPGrouped[5] & ~|pendingPGrouped[7:6], - pendingPGrouped[4] & ~|pendingPGrouped[7:5], - pendingPGrouped[3] & ~|pendingPGrouped[7:4], - pendingPGrouped[2] & ~|pendingPGrouped[7:3], - pendingPGrouped[1] & ~|pendingPGrouped[7:2]}; - // select the pending requests at that priority - assign pendingRequestsAtMaxP[N:1] = ({N{pendingMaxP[7]}} & pendingArray[7]) - | ({N{pendingMaxP[6]}} & pendingArray[6]) - | ({N{pendingMaxP[5]}} & pendingArray[5]) - | ({N{pendingMaxP[4]}} & pendingArray[4]) - | ({N{pendingMaxP[3]}} & pendingArray[3]) - | ({N{pendingMaxP[2]}} & pendingArray[2]) - | ({N{pendingMaxP[1]}} & pendingArray[1]); - // find the lowest ID amongst active interrupts at the highest priority - logic [5:0] k; - always_comb begin - intClaim = 6'b0; - for (k=N; k>0; k=k-1) begin - if (pendingRequestsAtMaxP[k]) intClaim = k; + // which prority levels have one or more active requests? + assign priorities_with_irqs[ctx][7:1] = { + |irqMatrix[ctx][7], + |irqMatrix[ctx][6], + |irqMatrix[ctx][5], + |irqMatrix[ctx][4], + |irqMatrix[ctx][3], + |irqMatrix[ctx][2], + |irqMatrix[ctx][1] + }; + + // get the highest priority level that has active requests + assign max_priority_with_irqs[ctx][7:1] = { + priorities_with_irqs[ctx][7], + priorities_with_irqs[ctx][6] & ~|priorities_with_irqs[ctx][7], + priorities_with_irqs[ctx][5] & ~|priorities_with_irqs[ctx][7:6], + priorities_with_irqs[ctx][4] & ~|priorities_with_irqs[ctx][7:5], + priorities_with_irqs[ctx][3] & ~|priorities_with_irqs[ctx][7:4], + priorities_with_irqs[ctx][2] & ~|priorities_with_irqs[ctx][7:3], + priorities_with_irqs[ctx][1] & ~|priorities_with_irqs[ctx][7:2] + }; + + // of the sources at the highest priority level that has active requests, + // which sources have active requests? + assign irqs_at_max_priority[ctx][`N:1] = + ({`N{max_priority_with_irqs[ctx][7]}} & irqMatrix[ctx][7]) | + ({`N{max_priority_with_irqs[ctx][6]}} & irqMatrix[ctx][6]) | + ({`N{max_priority_with_irqs[ctx][5]}} & irqMatrix[ctx][5]) | + ({`N{max_priority_with_irqs[ctx][4]}} & irqMatrix[ctx][4]) | + ({`N{max_priority_with_irqs[ctx][3]}} & irqMatrix[ctx][3]) | + ({`N{max_priority_with_irqs[ctx][2]}} & irqMatrix[ctx][2]) | + ({`N{max_priority_with_irqs[ctx][1]}} & irqMatrix[ctx][1]); + + // of the sources at the highest priority level that has active requests, + // choose the source with the lowest source ID to be the most urgent + // and set intClaim to the source ID of the most urgent active request + integer k; + always_comb begin + intClaim[ctx] = 6'b0; + for (k=`N; k>0; k--) begin + if (irqs_at_max_priority[ctx][k]) intClaim[ctx] = k[5:0]; + end end - end - - // create threshold mask - always_comb begin - threshMask[7] = (intThreshold != 7); - threshMask[6] = (intThreshold != 6) & threshMask[7]; - threshMask[5] = (intThreshold != 5) & threshMask[6]; - threshMask[4] = (intThreshold != 4) & threshMask[5]; - threshMask[3] = (intThreshold != 3) & threshMask[4]; - threshMask[2] = (intThreshold != 2) & threshMask[3]; - threshMask[1] = (intThreshold != 1) & threshMask[2]; - end - // is the max priority > threshold? - // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold? - assign ExtIntM = |(threshMask & pendingPGrouped); + + // create threshold mask + always_comb begin + threshMask[ctx][7] = (intThreshold[ctx] != 7); + threshMask[ctx][6] = (intThreshold[ctx] != 6) & threshMask[ctx][7]; + threshMask[ctx][5] = (intThreshold[ctx] != 5) & threshMask[ctx][6]; + threshMask[ctx][4] = (intThreshold[ctx] != 4) & threshMask[ctx][5]; + threshMask[ctx][3] = (intThreshold[ctx] != 3) & threshMask[ctx][4]; + threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3]; + threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2]; + end + // is the max priority > threshold? + // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold? + end + assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]); + assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]); endmodule diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index d90a30d7c..f48b96963 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -55,7 +55,7 @@ module uncore ( input logic [3:0] HSIZED, input logic HWRITED, // peripheral pins - output logic TimerIntM, SwIntM, ExtIntM, + output logic TimerIntM, SwIntM, ExtIntM, ExtIntS, input logic [31:0] GPIOPinsIn, output logic [31:0] GPIOPinsOut, GPIOPinsEn, input logic UARTSin, @@ -133,9 +133,10 @@ module uncore ( .HWRITE, .HREADY, .HTRANS, .HWDATA, .UARTIntr, .GPIOIntr, .HREADPLIC, .HRESPPLIC, .HREADYPLIC, - .ExtIntM); + .ExtIntM, .ExtIntS); end else begin : plic assign ExtIntM = 0; + assign ExtIntS = 0; end if (`GPIO_SUPPORTED == 1) begin : gpio gpio gpio( diff --git a/pipelined/src/wally/wallypipelinedcore.sv b/pipelined/src/wally/wallypipelinedcore.sv index c8be1116b..366ae2170 100644 --- a/pipelined/src/wally/wallypipelinedcore.sv +++ b/pipelined/src/wally/wallypipelinedcore.sv @@ -32,137 +32,137 @@ /* verilator lint_on UNUSED */ module wallypipelinedcore ( - input logic clk, reset, + input logic clk, reset, // Privileged - input logic TimerIntM, ExtIntM, SwIntM, - input logic [63:0] MTIME_CLINT, + input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, + input logic [63:0] MTIME_CLINT, // Bus Interface input logic [`AHBW-1:0] HRDATA, - input logic HREADY, HRESP, - output logic HCLK, HRESETn, - output logic [31:0] HADDR, + input logic HREADY, HRESP, + output logic HCLK, HRESETn, + output logic [31:0] HADDR, output logic [`AHBW-1:0] HWDATA, - output logic HWRITE, - output logic [2:0] HSIZE, - output logic [2:0] HBURST, - output logic [3:0] HPROT, - output logic [1:0] HTRANS, - output logic HMASTLOCK, + output logic HWRITE, + output logic [2:0] HSIZE, + output logic [2:0] HBURST, + output logic [3:0] HPROT, + output logic [1:0] HTRANS, + output logic HMASTLOCK, // Delayed signals for subword write - output logic [2:0] HADDRD, - output logic [3:0] HSIZED, - output logic HWRITED + output logic [2:0] HADDRD, + output logic [3:0] HSIZED, + output logic HWRITED ); // logic [1:0] ForwardAE, ForwardBE; - logic StallF, StallD, StallE, StallM, StallW; - logic FlushF, FlushD, FlushE, FlushM, FlushW; - logic RetM; + logic StallF, StallD, StallE, StallM, StallW; + logic FlushF, FlushD, FlushE, FlushM, FlushW; + logic RetM; (* mark_debug = "true" *) logic TrapM; // new signals that must connect through DP - logic MDUE, W64E; - logic CSRReadM, CSRWriteM, PrivilegedM; - logic [1:0] AtomicE; - logic [1:0] AtomicM; - logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE; - logic [`XLEN-1:0] SrcAM; - logic [2:0] Funct3E; + logic MDUE, W64E; + logic CSRReadM, CSRWriteM, PrivilegedM; + logic [1:0] AtomicE; + logic [1:0] AtomicM; + logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE; + logic [`XLEN-1:0] SrcAM; + logic [2:0] Funct3E; // logic [31:0] InstrF; - logic [31:0] InstrD, InstrW; - (* mark_debug = "true" *) logic [31:0] InstrM; - logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE; - (* mark_debug = "true" *) logic [`XLEN-1:0] PCM; - logic [`XLEN-1:0] CSRReadValW, MDUResultW; - logic [`XLEN-1:0] PrivilegedNextPCM; - (* mark_debug = "true" *) logic [1:0] MemRWM; - (* mark_debug = "true" *) logic InstrValidM; - logic InstrMisalignedFaultM; - logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD; - logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM; - logic LoadMisalignedFaultM, LoadAccessFaultM; - logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM; - logic [`XLEN-1:0] InstrMisalignedAdrM; + logic [31:0] InstrD, InstrW; + (* mark_debug = "true" *) logic [31:0] InstrM; + logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE; + (* mark_debug = "true" *) logic [`XLEN-1:0] PCM; + logic [`XLEN-1:0] CSRReadValW, MDUResultW; + logic [`XLEN-1:0] PrivilegedNextPCM; + (* mark_debug = "true" *) logic [1:0] MemRWM; + (* mark_debug = "true" *) logic InstrValidM; + logic InstrMisalignedFaultM; + logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD; + logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM; + logic LoadMisalignedFaultM, LoadAccessFaultM; + logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM; + logic [`XLEN-1:0] InstrMisalignedAdrM; logic InvalidateICacheM, FlushDCacheM; - logic PCSrcE; - logic CSRWritePendingDEM; - logic DivBusyE; + logic PCSrcE; + logic CSRWritePendingDEM; + logic DivBusyE; logic DivE; - logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD; - logic SquashSCW; + logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD; + logic SquashSCW; // floating point unit signals - logic [2:0] FRM_REGW; + logic [2:0] FRM_REGW; logic [4:0] RdM, RdW; - logic FStallD; - logic FWriteIntE; - logic [`XLEN-1:0] FWriteDataE; - logic [`XLEN-1:0] FIntResM; - logic FDivBusyE; - logic IllegalFPUInstrD, IllegalFPUInstrE; - logic FRegWriteM; - logic FPUStallD; - logic [4:0] SetFflagsM; + logic FStallD; + logic FWriteIntE; + logic [`XLEN-1:0] FWriteDataE; + logic [`XLEN-1:0] FIntResM; + logic FDivBusyE; + logic IllegalFPUInstrD, IllegalFPUInstrE; + logic FRegWriteM; + logic FPUStallD; + logic [4:0] SetFflagsM; // memory management unit signals - logic ITLBWriteF; - logic ITLBFlushF, DTLBFlushM; - logic ITLBMissF; - logic [`XLEN-1:0] SATP_REGW; + logic ITLBWriteF; + logic ITLBFlushF, DTLBFlushM; + logic ITLBMissF; + logic [`XLEN-1:0] SATP_REGW; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; logic [1:0] STATUS_MPP; - logic [1:0] PrivilegeModeW; - logic [`XLEN-1:0] PTE; - logic [1:0] PageType; + logic [1:0] PrivilegeModeW; + logic [`XLEN-1:0] PTE; + logic [1:0] PageType; // PMA checker signals var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0]; var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0]; // IMem stalls - logic IFUStallF; - logic LSUStallM; + logic IFUStallF; + logic LSUStallM; // cpu lsu interface - logic [2:0] Funct3M; - logic [`XLEN-1:0] IEUAdrE; + logic [2:0] Funct3M; + logic [`XLEN-1:0] IEUAdrE; (* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataM; - (* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM; - (* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM; - logic [`XLEN-1:0] ReadDataW; - logic CommittedM; + (* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM; + (* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM; + logic [`XLEN-1:0] ReadDataW; + logic CommittedM; // AHB ifu interface - logic [`PA_BITS-1:0] IFUBusAdr; - logic [`XLEN-1:0] IFUBusHRDATA; - logic IFUBusRead; - logic IFUBusAck; + logic [`PA_BITS-1:0] IFUBusAdr; + logic [`XLEN-1:0] IFUBusHRDATA; + logic IFUBusRead; + logic IFUBusAck; // AHB LSU interface - logic [`PA_BITS-1:0] LSUBusAdr; - logic LSUBusRead; - logic LSUBusWrite; - logic LSUBusAck; - logic [`XLEN-1:0] LSUBusHRDATA; - logic [`XLEN-1:0] LSUBusHWDATA; + logic [`PA_BITS-1:0] LSUBusAdr; + logic LSUBusRead; + logic LSUBusWrite; + logic LSUBusAck; + logic [`XLEN-1:0] LSUBusHRDATA; + logic [`XLEN-1:0] LSUBusHWDATA; - logic BPPredWrongE; - logic BPPredDirWrongM; - logic BTBPredPCWrongM; - logic RASPredPCWrongM; - logic BPPredClassNonCFIWrongM; - logic [4:0] InstrClassM; - logic InstrAccessFaultF; - logic [2:0] LSUBusSize; + logic BPPredWrongE; + logic BPPredDirWrongM; + logic BTBPredPCWrongM; + logic RASPredPCWrongM; + logic BPPredClassNonCFIWrongM; + logic [4:0] InstrClassM; + logic InstrAccessFaultF; + logic [2:0] LSUBusSize; - logic ExceptionM; - logic PendingInterruptM; - logic DCacheMiss; - logic DCacheAccess; - logic ICacheMiss; - logic ICacheAccess; - logic BreakpointFaultM, EcallFaultM; + logic ExceptionM; + logic PendingInterruptM; + logic DCacheMiss; + logic DCacheAccess; + logic ICacheMiss; + logic ICacheAccess; + logic BreakpointFaultM, EcallFaultM; logic InstrDAPageFaultF; ifu ifu( @@ -203,8 +203,8 @@ module wallypipelinedcore ( .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrDAPageFaultF - - ); // instruction fetch unit: PC, branch prediction, instruction cache + + ); // instruction fetch unit: PC, branch prediction, instruction cache ieu ieu( .clk, .reset, @@ -221,7 +221,7 @@ module wallypipelinedcore ( // Memory stage interface .SquashSCW, // from LSU .MemRWM, // read/write control goes to LSU - .AtomicE, // atomic control goes to LSU + .AtomicE, // atomic control goes to LSU .AtomicM, // atomic control goes to LSU .WriteDataM, // Write data to LSU .Funct3M, // size and signedness to LSU @@ -245,41 +245,41 @@ module wallypipelinedcore ( lsu lsu( .clk, .reset, .StallM, .FlushM, .StallW, - .FlushW, - // CPU interface - .MemRWM, .Funct3M, .Funct7M(InstrM[31:25]), - .AtomicM, .TrapM, - .CommittedM, .DCacheMiss, .DCacheAccess, - .SquashSCW, - //.DataMisalignedM(DataMisalignedM), - .IEUAdrE, .IEUAdrM, .WriteDataM, - .ReadDataM, .FlushDCacheM, - // connected to ahb (all stay the same) - .LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck, - .LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize, + .FlushW, + // CPU interface + .MemRWM, .Funct3M, .Funct7M(InstrM[31:25]), + .AtomicM, .TrapM, + .CommittedM, .DCacheMiss, .DCacheAccess, + .SquashSCW, + //.DataMisalignedM(DataMisalignedM), + .IEUAdrE, .IEUAdrM, .WriteDataM, + .ReadDataM, .FlushDCacheM, + // connected to ahb (all stay the same) + .LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck, + .LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize, - // connect to csr or privilege and stay the same. - .PrivilegeModeW, // connects to csr - .PMPCFG_ARRAY_REGW, // connects to csr - .PMPADDR_ARRAY_REGW, // connects to csr - // hptw keep i/o - .SATP_REGW, // from csr - .STATUS_MXR, // from csr - .STATUS_SUM, // from csr - .STATUS_MPRV, // from csr - .STATUS_MPP, // from csr + // connect to csr or privilege and stay the same. + .PrivilegeModeW, // connects to csr + .PMPCFG_ARRAY_REGW, // connects to csr + .PMPADDR_ARRAY_REGW, // connects to csr + // hptw keep i/o + .SATP_REGW, // from csr + .STATUS_MXR, // from csr + .STATUS_SUM, // from csr + .STATUS_MPRV, // from csr + .STATUS_MPP, // from csr - .DTLBFlushM, // connects to privilege - .LoadPageFaultM, // connects to privilege - .StoreAmoPageFaultM, // connects to privilege - .LoadMisalignedFaultM, // connects to privilege - .LoadAccessFaultM, // connects to privilege - .StoreAmoMisalignedFaultM, // connects to privilege - .StoreAmoAccessFaultM, // connects to privilege + .DTLBFlushM, // connects to privilege + .LoadPageFaultM, // connects to privilege + .StoreAmoPageFaultM, // connects to privilege + .LoadMisalignedFaultM, // connects to privilege + .LoadAccessFaultM, // connects to privilege + .StoreAmoMisalignedFaultM, // connects to privilege + .StoreAmoAccessFaultM, // connects to privilege .InstrDAPageFaultF, - .PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, - .LSUStallM); // change to LSUStallM + .PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, + .LSUStallM); // change to LSUStallM // *** Ross: please make EBU conditional when only supporting internal memories @@ -306,13 +306,13 @@ module wallypipelinedcore ( .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LSUStallM, .IFUStallF, .FPUStallD, .FStallD, - .DivBusyE, .FDivBusyE, - .EcallFaultM, .BreakpointFaultM, + .DivBusyE, .FDivBusyE, + .EcallFaultM, .BreakpointFaultM, .InvalidateICacheM, // Stall & flush outputs - .StallF, .StallD, .StallE, .StallM, .StallW, - .FlushF, .FlushD, .FlushE, .FlushM, .FlushW - ); // global stall and flush control + .StallF, .StallD, .StallE, .StallM, .StallW, + .FlushF, .FlushD, .FlushE, .FlushM, .FlushW + ); // global stall and flush control if (`ZICSR_SUPPORTED) begin:priv privileged priv( @@ -331,7 +331,7 @@ module wallypipelinedcore ( .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, .InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, - .TimerIntM, .ExtIntM, .SwIntM, + .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, .MTIME_CLINT, .InstrMisalignedAdrM, .IEUAdrM, .SetFflagsM, diff --git a/pipelined/src/wally/wallypipelinedsoc.sv b/pipelined/src/wally/wallypipelinedsoc.sv index 1b7f38311..0d844d3cf 100644 --- a/pipelined/src/wally/wallypipelinedsoc.sv +++ b/pipelined/src/wally/wallypipelinedsoc.sv @@ -74,7 +74,7 @@ module wallypipelinedsoc ( logic HRESP; logic TimerIntM, SwIntM; // from CLINT logic [63:0] MTIME_CLINT; // from CLINT to CSRs - logic ExtIntM; // from PLIC + logic ExtIntM,ExtIntS; // from PLIC logic [2:0] HADDRD; logic [3:0] HSIZED; logic HWRITED; @@ -84,7 +84,7 @@ module wallypipelinedsoc ( // instantiate processor and memories wallypipelinedcore core(.clk, .reset, - .TimerIntM, .ExtIntM, .SwIntM, + .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, .MTIME_CLINT, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, @@ -94,7 +94,7 @@ module wallypipelinedsoc ( uncore uncore(.HCLK, .HRESETn, .TIMECLK, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED, - .TimerIntM, .SwIntM, .ExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT, + .TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT, .HSELEXT, .SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 62d13a1a3..8b37bcbc5 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -334,8 +334,8 @@ module testbench; //`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]); `INIT_CHECKPOINT_VAL(UART_SCR, [7:0]); `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1); - `INIT_CHECKPOINT_VAL(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1]); - `INIT_CHECKPOINT_VAL(PLIC_THRESHOLD, [2:0]); + `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0); + `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_THRESHOLD, [2:0],1,0); integer memFile; integer readResult; From b08066381a95d7666014e562add770187f3e99a8 Mon Sep 17 00:00:00 2001 From: bbracker Date: Fri, 25 Mar 2022 01:02:22 +0000 Subject: [PATCH 6/6] fix multiple-context PLIC checkpoint generation --- linux/testvector-generation/parsePlicState.py | 2 +- pipelined/testbench/testbench-linux.sv | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/linux/testvector-generation/parsePlicState.py b/linux/testvector-generation/parsePlicState.py index 35ef00b1d..b917bfdc3 100755 --- a/linux/testvector-generation/parsePlicState.py +++ b/linux/testvector-generation/parsePlicState.py @@ -101,7 +101,7 @@ with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile: outFile.write(stripZeroes(word[2:])+'\n') with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile: for word in plicIntEnableArray: - outFile.write(word+'\n') + outFile.write(stripZeroes(word)+'\n') with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile: for word in plicIntPriorityThresholdArray: outFile.write(stripZeroes(word[2:])+'\n') diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 36153d737..12950b637 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -266,6 +266,19 @@ module testbench; end \ end + `define INIT_CHECKPOINT_PACKED_ARRAY(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ + `MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ + for (i=ARRAY_MIN; i" in the signal name `define INIT_CHECKPOINT_GENBLK_ARRAY(SIGNAL_BASE,SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ @@ -296,6 +309,7 @@ module testbench; end \ end + genvar i; `INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1); `INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0); `INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]); @@ -333,9 +347,9 @@ module testbench; //`INIT_CHECKPOINT_VAL(UART_LSR, [7:0]); //`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]); `INIT_CHECKPOINT_VAL(UART_SCR, [7:0]); - `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1); - `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0); - `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_THRESHOLD, [2:0],1,0); + `INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1); + `INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0); + `INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0); integer memFile; integer readResult;