diff --git a/.gitignore b/.gitignore index 2d1454e3..acaab4b0 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,6 @@ sim/branch.log /fpga/generator/sim/syn-funcsim.v external sim/results +tests/wally-riscv-arch-test/riscv-test-suite/rv*i_m/I/src/*.S +tests/wally-riscv-arch-test/riscv-test-suite/rv*i_m/I/Makefrag + diff --git a/config/buildroot/wally-config.vh b/config/buildroot/wally-config.vh index 783b9d91..f10e11f9 100644 --- a/config/buildroot/wally-config.vh +++ b/config/buildroot/wally-config.vh @@ -40,8 +40,9 @@ `define ZICSR_SUPPORTED 1 `define ZIFENCEI_SUPPORTED 1 `define ZICOUNTERS_SUPPORTED 1 -`define ZFH_SUPPORTED 0 `define COUNTERS 32 +`define ZFH_SUPPORTED 0 +`define SSTC_SUPPORTED 1 // LSU microarchitectural Features `define BUS_SUPPORTED 1 diff --git a/config/fpga/wally-config.vh b/config/fpga/wally-config.vh index c4d9cf62..d0299c4e 100644 --- a/config/fpga/wally-config.vh +++ b/config/fpga/wally-config.vh @@ -43,6 +43,7 @@ `define ZICOUNTERS_SUPPORTED 1 `define ZFH_SUPPORTED 0 `define COUNTERS 32 +`define SSTC_SUPPORTED 1 // LSU microarchitectural Features `define BUS_SUPPORTED 1 diff --git a/config/rv32e/wally-config.vh b/config/rv32e/wally-config.vh index 24242b38..8cd9ca3f 100644 --- a/config/rv32e/wally-config.vh +++ b/config/rv32e/wally-config.vh @@ -44,6 +44,7 @@ `define COUNTERS 0 `define ZICOUNTERS_SUPPORTED 0 `define ZFH_SUPPORTED 0 +`define SSTC_SUPPORTED 0 // LSU microarchitectural Features `define BUS_SUPPORTED 1 diff --git a/config/rv32gc/wally-config.vh b/config/rv32gc/wally-config.vh index 089a9ada..e45c2b09 100644 --- a/config/rv32gc/wally-config.vh +++ b/config/rv32gc/wally-config.vh @@ -43,6 +43,7 @@ `define COUNTERS 32 `define ZICOUNTERS_SUPPORTED 1 `define ZFH_SUPPORTED 0 +`define SSTC_SUPPORTED 0 // LSU microarchitectural Features `define BUS_SUPPORTED 1 diff --git a/config/rv32i/wally-config.vh b/config/rv32i/wally-config.vh index 0a081b41..d400cebe 100644 --- a/config/rv32i/wally-config.vh +++ b/config/rv32i/wally-config.vh @@ -44,6 +44,7 @@ `define COUNTERS 32 `define ZICOUNTERS_SUPPORTED 0 `define ZFH_SUPPORTED 0 +`define SSTC_SUPPORTED 0 // LSU microarchitectural Features `define BUS_SUPPORTED 0 diff --git a/config/rv32imc/wally-config.vh b/config/rv32imc/wally-config.vh index b4293dcc..010b6599 100644 --- a/config/rv32imc/wally-config.vh +++ b/config/rv32imc/wally-config.vh @@ -43,6 +43,7 @@ `define COUNTERS 32 `define ZICOUNTERS_SUPPORTED 1 `define ZFH_SUPPORTED 0 +`define SSTC_SUPPORTED 0 // LSU microarchitectural Features `define BUS_SUPPORTED 1 diff --git a/config/rv64fpquad/wally-config.vh b/config/rv64fpquad/wally-config.vh index 3757175a..23a9aa05 100644 --- a/config/rv64fpquad/wally-config.vh +++ b/config/rv64fpquad/wally-config.vh @@ -44,6 +44,7 @@ `define COUNTERS 32 `define ZICOUNTERS_SUPPORTED 1 `define ZFH_SUPPORTED 1 +`define SSTC_SUPPORTED 0 // LSU microarchitectural Features `define BUS_SUPPORTED 1 diff --git a/config/rv64gc/wally-config.vh b/config/rv64gc/wally-config.vh index c3dd8729..0b8a932d 100644 --- a/config/rv64gc/wally-config.vh +++ b/config/rv64gc/wally-config.vh @@ -44,6 +44,7 @@ `define COUNTERS 32 `define ZICOUNTERS_SUPPORTED 1 `define ZFH_SUPPORTED 0 +`define SSTC_SUPPORTED 0 // LSU microarchitectural Features `define BUS_SUPPORTED 1 diff --git a/config/rv64i/wally-config.vh b/config/rv64i/wally-config.vh index 90d7b404..627cac8f 100644 --- a/config/rv64i/wally-config.vh +++ b/config/rv64i/wally-config.vh @@ -44,6 +44,7 @@ `define COUNTERS 32 `define ZICOUNTERS_SUPPORTED 0 `define ZFH_SUPPORTED 0 +`define SSTC_SUPPORTED 0 // LSU microarchitectural Features `define BUS_SUPPORTED 0 diff --git a/src/generic/mem/ram1p1rwbe.sv b/src/generic/mem/ram1p1rwbe.sv index f1e784c1..4c170745 100644 --- a/src/generic/mem/ram1p1rwbe.sv +++ b/src/generic/mem/ram1p1rwbe.sv @@ -34,7 +34,7 @@ `include "wally-config.vh" -module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) ( +module ram1p1rwbe #(parameter DEPTH=64, WIDTH=128) ( input logic clk, input logic ce, input logic [$clog2(DEPTH)-1:0] addr, @@ -49,7 +49,7 @@ module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) ( // *************************************************************************** // TRUE SRAM macro // *************************************************************************** - if (`USE_SRAM == 1 && WIDTH == 128 && DEPTH == 64) begin + if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray genvar index; // 64 x 128-bit SRAM logic [WIDTH-1:0] BitWriteMask; @@ -59,7 +59,7 @@ module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) ( .A(addr), .D(din), .BWEB(~BitWriteMask), .Q(dout)); - end else if (`USE_SRAM == 1 && WIDTH == 44 && DEPTH == 64) begin + end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag genvar index; // 64 x 44-bit SRAM logic [WIDTH-1:0] BitWriteMask; @@ -69,17 +69,7 @@ module ram1p1rwbe #(parameter DEPTH=128, WIDTH=256) ( .A(addr), .D(din), .BWEB(~BitWriteMask), .Q(dout)); - end else if (`USE_SRAM == 1 && WIDTH == 128 && DEPTH == 32) begin - genvar index; - // 64 x 128-bit SRAM - logic [WIDTH-1:0] BitWriteMask; - for (index=0; index < WIDTH; index++) - assign BitWriteMask[index] = bwe[index/8]; - ram1p1rwbe_128x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we), - .A(addr), .D(din), - .BWEB(~BitWriteMask), .Q(dout)); - - end else if (`USE_SRAM == 1 && WIDTH == 22 && DEPTH == 32) begin + end else if (`USE_SRAM == 1 & WIDTH == 22 & DEPTH == 32) begin // RV32 cache tag genvar index; // 64 x 22-bit SRAM logic [WIDTH-1:0] BitWriteMask; diff --git a/src/generic/mem/ram1p1rwbe_64x128.sv b/src/generic/mem/ram1p1rwbe_64x128.sv index fa8e32f0..84a3e74f 100755 --- a/src/generic/mem/ram1p1rwbe_64x128.sv +++ b/src/generic/mem/ram1p1rwbe_64x128.sv @@ -35,6 +35,7 @@ module ram1p1rwbe_64x128( ); // replace "generic64x128RAM" with "TS1N..64X128.." module from your memory vendor - generic64x128RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); + //generic64x128RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); + TS1N28HPCPSVTB64X128M4SW sramIP(.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); endmodule diff --git a/src/generic/mem/ram1p1rwbe_64x22.sv b/src/generic/mem/ram1p1rwbe_64x22.sv index 84c8d1b7..4df3bc47 100755 --- a/src/generic/mem/ram1p1rwbe_64x22.sv +++ b/src/generic/mem/ram1p1rwbe_64x22.sv @@ -29,12 +29,14 @@ module ram1p1rwbe_64x22( input logic CEB, input logic WEB, input logic [5:0] A, - input logic [127:0] D, - input logic [127:0] BWEB, - output logic [127:0] Q + input logic [21:0] D, + input logic [21:0] BWEB, + output logic [21:0] Q ); // replace "generic64x22RAM" with "TS1N..64X22.." module from your memory vendor - generic64x22RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); + // use part of a larger RAM to avoid generating more flavors of RAM + TS1N28HPCPSVTB64X44M4SW sramIP(.CLK, .CEB, .WEB, .A, .D(D[21:0]), .BWEB(BWEB[21:0]), .Q(Q[21:0])); + // genericRAM #(64, 22) sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); endmodule diff --git a/src/generic/mem/ram1p1rwbe_64x44.sv b/src/generic/mem/ram1p1rwbe_64x44.sv index 7fa71f31..89730a42 100644 --- a/src/generic/mem/ram1p1rwbe_64x44.sv +++ b/src/generic/mem/ram1p1rwbe_64x44.sv @@ -29,12 +29,13 @@ module ram1p1rwbe_64x44( input logic CEB, input logic WEB, input logic [5:0] A, - input logic [127:0] D, - input logic [127:0] BWEB, - output logic [127:0] Q + input logic [43:0] D, + input logic [43:0] BWEB, + output logic [43:0] Q ); // replace "generic64x44RAM" with "TS1N..64X44.." module from your memory vendor - generic64x44RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); + // generic64x44RAM sramIP (.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); + TS1N28HPCPSVTB64X44M4SW sramIP(.CLK, .CEB, .WEB, .A, .D, .BWEB, .Q); endmodule diff --git a/src/generic/mem/ram2p1r1wbe.sv b/src/generic/mem/ram2p1r1wbe.sv index da099cdc..d285dbe1 100644 --- a/src/generic/mem/ram2p1r1wbe.sv +++ b/src/generic/mem/ram2p1r1wbe.sv @@ -52,7 +52,7 @@ module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) ( // TRUE Smem macro // *************************************************************************** - if (`USE_SRAM == 1 && WIDTH == 68 && DEPTH == 1024) begin + if (`USE_SRAM == 1 & WIDTH == 68 & DEPTH == 1024) begin ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk), .CEBA(~ce1), .CEBB(~ce2), @@ -64,7 +64,7 @@ module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) ( .QA(rd1), .QB()); - end else if (`USE_SRAM == 1 && WIDTH == 36 && DEPTH == 1024) begin + end else if (`USE_SRAM == 1 & WIDTH == 36 & DEPTH == 1024) begin ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk), .CEBA(~ce1), .CEBB(~ce2), @@ -76,7 +76,7 @@ module ram2p1r1wbe #(parameter DEPTH=128, WIDTH=256) ( .QA(rd1), .QB()); - end else if (`USE_SRAM == 1 && WIDTH == 2 && DEPTH == 1024) begin + end else if (`USE_SRAM == 1 & WIDTH == 2 & DEPTH == 1024) begin logic [SRAMWIDTH-1:0] SRAMReadData; logic [SRAMWIDTH-1:0] SRAMWriteData; diff --git a/src/generic/mem/ram2p1r1wbe_1024x36.sv b/src/generic/mem/ram2p1r1wbe_1024x36.sv index 0aad7db4..aee2d0aa 100755 --- a/src/generic/mem/ram2p1r1wbe_1024x36.sv +++ b/src/generic/mem/ram2p1r1wbe_1024x36.sv @@ -42,7 +42,11 @@ module ram2p1r1wbe_1024x36( ); // replace "generic1024x36RAM" with "TSDN..1024X36.." module from your memory vendor - generic1024x36RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, - .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); + //generic1024x36RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, + // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); + // use part of a larger RAM to avoid generating more flavors of RAM + TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, + .AA, .AB, .DA(DA[35:0]), .DB(DB[35:0]), + .BWEBA(BWEBA[35:0]), .BWEBB(BWEBB[35:0]), .QA(QA[35:0]), .QB(QB[35:0])); endmodule diff --git a/src/generic/mem/ram2p1r1wbe_1024x68.sv b/src/generic/mem/ram2p1r1wbe_1024x68.sv index e6a6b625..108530be 100755 --- a/src/generic/mem/ram2p1r1wbe_1024x68.sv +++ b/src/generic/mem/ram2p1r1wbe_1024x68.sv @@ -42,7 +42,9 @@ module ram2p1r1wbe_1024x68( ); // replace "generic1024x68RAM" with "TSDN..1024X68.." module from your memory vendor - generic1024x68RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, - .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); + //generic1024x68RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, + // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); + TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, + .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); endmodule diff --git a/src/generic/mem/ram2p1r1wbe_64x32.sv b/src/generic/mem/ram2p1r1wbe_64x32.sv index 8bc19637..e551099f 100755 --- a/src/generic/mem/ram2p1r1wbe_64x32.sv +++ b/src/generic/mem/ram2p1r1wbe_64x32.sv @@ -42,7 +42,8 @@ module ram2p1r1wbe_64x32( ); // replace "generic64x32RAM" with "TSDN..64X32.." module from your memory vendor - generic64x32RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, + //generic64x32RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, + // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); + TSDN28HPCPA64X32M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); - endmodule diff --git a/src/generic/mem/rom1p1r.sv b/src/generic/mem/rom1p1r.sv index 64cb9224..c5c1f8b0 100644 --- a/src/generic/mem/rom1p1r.sv +++ b/src/generic/mem/rom1p1r.sv @@ -38,10 +38,10 @@ module rom1p1r #(parameter ADDR_WIDTH = 8, // Core Memory logic [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0]; - if (`USE_SRAM == 1 && DATA_WIDTH == 64) begin + if ((`USE_SRAM == 1) & (DATA_WIDTH == 64)) begin rom1p1r_128x64 rom1 (.CLK(clk), .CEB(~ce), .A(addr[6:0]), .Q(dout)); - end if (`USE_SRAM == 1 && DATA_WIDTH == 32) begin + end if ((`USE_SRAM == 1) & (DATA_WIDTH == 32)) begin rom1p1r_128x32 rom1 (.CLK(clk), .CEB(~ce), .A(addr[6:0]), .Q(dout)); end else begin diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index ef4d73cb..7b765bae 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -113,6 +113,7 @@ module csr #(parameter logic SelMtvecM; logic [`XLEN-1:0] TVecAlignedM; logic InstrValidNotFlushedM; + logic STimerInt; // only valid unflushed instructions can access CSRs assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; @@ -201,7 +202,7 @@ module csr #(parameter csri csri(.clk, .reset, .InstrValidNotFlushedM, .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, - .MExtInt, .SExtInt, .MTimerInt, .MSwInt, + .MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); csrsr csrsr(.clk, .reset, .StallW, @@ -227,11 +228,12 @@ module csr #(parameter csrs csrs(.clk, .reset, .InstrValidNotFlushedM, .CSRSWriteM, .STrapM, .CSRAdrM, .NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW, - .STATUS_TVM, .CSRWriteValM, .PrivilegeModeW, + .STATUS_TVM, .MCOUNTEREN_TM(MCOUNTEREN_REGW[1]), + .CSRWriteValM, .PrivilegeModeW, .CSRSReadValM, .STVEC_REGW, .SEPC_REGW, .SCOUNTEREN_REGW, - .SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, - .WriteSSTATUSM, .IllegalCSRSAccessM); + .SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, + .WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt); end else begin assign WriteSSTATUSM = 0; assign CSRSReadValM = 0; diff --git a/src/privileged/csri.sv b/src/privileged/csri.sv index 0de65bee..bdbb0f59 100644 --- a/src/privileged/csri.sv +++ b/src/privileged/csri.sv @@ -39,13 +39,14 @@ module csri #(parameter input logic CSRMWriteM, CSRSWriteM, input logic [`XLEN-1:0] CSRWriteValM, input logic [11:0] CSRAdrM, - input logic MExtInt, SExtInt, MTimerInt, MSwInt, + input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt, output logic [11:0] MIP_REGW, MIE_REGW, - output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 + output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 ); logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK; logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM; + logic STIP; // Interrupt Write Enables assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM; @@ -58,7 +59,13 @@ module csri #(parameter // SEIP, STIP, SSIP is writable in MIP if S mode exists // SSIP is writable in SIP if S mode exists if (`S_SUPPORTED) begin:mask - assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9) + if (`SSTC_SUPPORTED) begin + assign MIP_WRITE_MASK = 12'h202; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec) + assign STIP = STimerInt; + end else begin + assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9) + assign STIP = MIP_REGW_writeable[5]; + end assign SIP_WRITE_MASK = 12'h002; // SSIP is writeable in SIP (privileged 20210108-draft 4.1.3) assign MIE_WRITE_MASK = 12'hAAA; end else begin:mask @@ -75,5 +82,8 @@ module csri #(parameter else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (MIE_REGW & 12'h888); // only S fields - assign MIP_REGW = {MExtInt,1'b0,SExtInt|MIP_REGW_writeable[9],1'b0,MTimerInt,1'b0,MIP_REGW_writeable[5],1'b0,MSwInt,1'b0,MIP_REGW_writeable[1],1'b0}; + + assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0, + MTimerInt, 1'b0, STIP, 1'b0, + MSwInt, 1'b0, MIP_REGW_writeable[1], 1'b0}; endmodule diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index 3dfb2cbe..99c56ad1 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -41,22 +41,27 @@ module csrs #(parameter SCAUSE = 12'h142, STVAL = 12'h143, SIP= 12'h144, + STIMECMP = 12'h14D, + STIMECMPH = 12'h15D, SATP = 12'h180) ( - input logic clk, reset, - input logic InstrValidNotFlushedM, - input logic CSRSWriteM, STrapM, - input logic [11:0] CSRAdrM, - input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW, - input logic STATUS_TVM, - input logic [`XLEN-1:0] CSRWriteValM, - input logic [1:0] PrivilegeModeW, + input logic clk, reset, + input logic InstrValidNotFlushedM, + input logic CSRSWriteM, STrapM, + input logic [11:0] CSRAdrM, + input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW, + input logic STATUS_TVM, + input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear + input logic [`XLEN-1:0] CSRWriteValM, + input logic [1:0] PrivilegeModeW, output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW, output logic [`XLEN-1:0] SEPC_REGW, output logic [31:0] SCOUNTEREN_REGW, output logic [`XLEN-1:0] SATP_REGW, - input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, - output logic WriteSSTATUSM, - output logic IllegalCSRSAccessM + input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, + input logic [63:0] MTIME_CLINT, + output logic WriteSSTATUSM, + output logic IllegalCSRSAccessM, + output logic STimerInt ); // Constants @@ -66,10 +71,13 @@ module csrs #(parameter logic WriteSTVECM; logic WriteSSCRATCHM, WriteSEPCM; logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; + logic WriteSTIMECMPM, WriteSTIMECMPHM; logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW; logic [`XLEN-1:0] SCAUSE_REGW; + logic [63:0] STIMECMP_REGW; // write enables + // *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM? assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM; assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC) & InstrValidNotFlushedM; assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH) & InstrValidNotFlushedM; @@ -78,6 +86,8 @@ module csrs #(parameter assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM; assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM; assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN) & InstrValidNotFlushedM; + assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & MCOUNTEREN_TM & InstrValidNotFlushedM; + assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & MCOUNTEREN_TM & (`XLEN == 32) & InstrValidNotFlushedM; // CSRs flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); @@ -90,7 +100,20 @@ module csrs #(parameter else assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW); + if (`XLEN == 64) + flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW); + else begin + flopenr #(`XLEN) STIMECMPreg(clk, reset, WriteSTIMECMPM, CSRWriteValM, STIMECMP_REGW[31:0]); + flopenr #(`XLEN) STIMECMPHreg(clk, reset, WriteSTIMECMPHM, CSRWriteValM, STIMECMP_REGW[63:32]); + end + // Supervisor timer interrupt logic + // Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs + if (`SSTC_SUPPORTED) + assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison + else + assign STimerInt = 0; + // CSR Reads always_comb begin:csrr IllegalCSRSAccessM = 0; @@ -109,10 +132,20 @@ module csrs #(parameter if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1; end SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW}; + STIMECMP: if (MCOUNTEREN_TM) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0]; + else begin + CSRSReadValM = 0; + IllegalCSRSAccessM = 1; + end + STIMECMPH: if (MCOUNTEREN_TM & (`XLEN == 32)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32]; + else begin // not supported for RV64 + CSRSReadValM = 0; + IllegalCSRSAccessM = 1; + end default: begin CSRSReadValM = 0; IllegalCSRSAccessM = 1; - end + end endcase end endmodule diff --git a/src/privileged/csrsr.sv b/src/privileged/csrsr.sv index 1fa1fe8e..a92aca3b 100644 --- a/src/privileged/csrsr.sv +++ b/src/privileged/csrsr.sv @@ -68,7 +68,7 @@ module csrsr ( STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; - assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be. + assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be. end else begin: csrsr32 // RV32 assign MSTATUS_REGW = {STATUS_SD, 8'b0, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, diff --git a/synthDC/.synopsys_dc.setup b/synthDC/.synopsys_dc.setup index ccc0c67c..c516fcf6 100755 --- a/synthDC/.synopsys_dc.setup +++ b/synthDC/.synopsys_dc.setup @@ -32,8 +32,8 @@ if {$tech == "sky130"} { set CAPTABLE $TLU/1p8m/ set MW_REFERENCE_LIBRARY /home/jstine/MW set MW_TECH_FILE tcbn28hpcplusbwp30p140 - set MAX_TLU_FILE $CAPTABLE/crn28hpc+_1p08m+ut-alrdl_5x1z1u_typical.tluplus - set MIN_TLU_FILE $CAPTABLE/crn28hpc+_1p08m+ut-alrdl_5x1z1u_rcworst.tluplus + set MIN_TLU_FILE $CAPTABLE/crn28hpc+_1p08m+ut-alrdl_5x1z1u_rcbest.tluplus + set MAX_TLU_FILE $CAPTABLE/crn28hpc+_1p08m+ut-alrdl_5x1z1u_rcworst.tluplus set PRS_MAP_FILE $MW_REFERENCE_LIBRARY/astro_layername.map } @@ -67,11 +67,13 @@ set cache_read $cache_write lappend search_path ./scripts lappend search_path ./hdl lappend search_path ./mapped -if {$tech == "tsmc28"} { +if {$tech == "tsmc28" || $tech == "tsmc28psyn"} { set memory /home/jstine/WallyMem/rv64gc/ lappend target_library $memory/ts3n28hpcpa128x64m8m_130a/NLDM/ts3n28hpcpa128x64m8m_tt0p9v25c.db lappend target_library $memory/ts1n28hpcpsvtb64x128m4sw_180a/NLDM/ts1n28hpcpsvtb64x128m4sw_tt0p9v25c.db lappend target_library $memory/ts1n28hpcpsvtb64x44m4sw_180a/NLDM/ts1n28hpcpsvtb64x44m4sw_tt0p9v25c.db + lappend target_library $memory/tsdn28hpcpa1024x68m4mw_130a/NLDM/tsdn28hpcpa1024x68m4mw_tt0p9v25c.db + lappend target_library $memory/tsdn28hpcpa64x32m4mw_130a/NLDM/tsdn28hpcpa64x32m4mw_tt0p9v25c.db } # Set up User Information diff --git a/synthDC/Makefile b/synthDC/Makefile index 9dd2b0ab..fbfb459a 100755 --- a/synthDC/Makefile +++ b/synthDC/Makefile @@ -95,6 +95,14 @@ endif endif # adjust config if synthesizing with any modifications +# This code is subtle with ifneq. It successively turns off a larger +# set of features in order of cycle time limiting. +# When mod = orig, all features are ON +# When mod = PMP0, the number of PMP entries is set to 0 +# when mod = noPriv, the privileged unit and PMP are disabled +# when mod = noFPU, the FPU, privileged unit, and PMP are disabled +# when mod = noMulDiv, the MDU, FPU, privileged unit, and PMP are disabled. + ifneq ($(MOD), orig) # PMP 0 sed -i 's/PMP_ENTRIES \(64\|16\|0\)/PMP_ENTRIES 0/' $(CONFIGDIR)/wally-config.vh diff --git a/synthDC/extractSummary.py b/synthDC/extractSummary.py index 3d939644..85bc6f0a 100755 --- a/synthDC/extractSummary.py +++ b/synthDC/extractSummary.py @@ -85,7 +85,7 @@ def freqPlot(tech, width, config): freqsL, delaysL, areasL = ([[], []] for i in range(3)) for oneSynth in allSynths: if (width == oneSynth.width) & (config == oneSynth.config) & (tech == oneSynth.tech) & ('orig' == oneSynth.mod): - ind = (1000/oneSynth.delay < oneSynth.freq) # when delay is within target clock period + ind = (1000/oneSynth.delay < (0.95*oneSynth.freq)) # when delay is within target clock period freqsL[ind] += [oneSynth.freq] delaysL[ind] += [oneSynth.delay] areasL[ind] += [oneSynth.area] @@ -103,7 +103,7 @@ def freqPlot(tech, width, config): freqs = freqsL[ind] freqs, delays, areas = noOutliers(median, freqs, delays, areas) - c = 'blue' if ind else 'green' + c = 'blue' if ind else 'gray' targs = [1000/f for f in freqs] ax1.scatter(targs, delays, color=c) @@ -113,7 +113,7 @@ def freqPlot(tech, width, config): delays = list(flatten(delaysL)) areas = list(flatten(areasL)) - legend_elements = [lines.Line2D([0], [0], color='green', ls='', marker='o', label='timing achieved'), + legend_elements = [lines.Line2D([0], [0], color='gray', ls='', marker='o', label='timing achieved'), lines.Line2D([0], [0], color='blue', ls='', marker='o', label='slack violated')] ax1.legend(handles=legend_elements) @@ -246,8 +246,8 @@ if __name__ == '__main__': TechSpec = namedtuple("TechSpec", "color shape targfreq fo4 add32area add32lpower add32denergy") techdict = {} - techdict['sky90'] = TechSpec('green', 'o', args.skyfreq, 43.2e-3, 1440.600027, 714.057, 0.658023) - techdict['tsmc28'] = TechSpec('blue', 's', args.tsmcfreq, 12.2e-3, 209.286002, 1060.0, .081533) + techdict['sky90'] = TechSpec('gray', 'o', args.skyfreq, 43.2e-3, 1440.600027, 714.057, 0.658023) + techdict['tsmc28psyn'] = TechSpec('blue', 's', args.tsmcfreq, 12.2e-3, 209.286002, 1060.0, .081533) current_directory = os.getcwd() final_directory = os.path.join(current_directory, 'wallyplots') @@ -256,10 +256,10 @@ if __name__ == '__main__': synthsintocsv() synthsfromcsv('Summary.csv') - freqPlot('tsmc28', 'rv32', 'e') + freqPlot('tsmc28psyn', 'rv32', 'e') freqPlot('sky90', 'rv32', 'e') plotFeatures('sky90', 'rv64', 'gc') - plotFeatures('tsmc28', 'rv64', 'gc') + plotFeatures('tsmc28psyn', 'rv64', 'gc') plotConfigs('sky90', mod='orig') - plotConfigs('tsmc28', mod='orig') + plotConfigs('tsmc28psyn', mod='orig') normAreaDelay(mod='orig') diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index 83020352..c4579e5c 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -54,28 +54,16 @@ set MY_LIB_NAME $my_toplevel # Create MW if { [shell_is_in_topographical_mode] } { echo "In Topographical Mode...processing\n" - if {[file isdirectory $MY_LIB_NAME]} { - echo "MW directory already here, deleting/readdding." - [exec rm -rf $my_toplevel] - create_mw_lib -technology $MW_REFERENCE_LIBRARY/$MW_TECH_FILE.tf \ - -mw_reference_library $mw_reference_library $MY_LIB_NAME - } else { - create_mw_lib -technology $MW_REFERENCE_LIBRARY/$MW_TECH_FILE.tf \ - -mw_reference_library $mw_reference_library $MY_LIB_NAME - } - + create_mw_lib -technology $MW_REFERENCE_LIBRARY/$MW_TECH_FILE.tf \ + -mw_reference_library $mw_reference_library $outputDir/$MY_LIB_NAME # Open MW - open_mw_lib $MY_LIB_NAME + open_mw_lib $outputDir/$MY_LIB_NAME # TLU+ set_tlu_plus_files -max_tluplus $MAX_TLU_FILE -min_tluplus $MIN_TLU_FILE \ -tech2itf_map $PRS_MAP_FILE } else { - if {[file isdirectory $MY_LIB_NAME]} { - [exec rm -rf $my_toplevel] - echo "MW directory already here, deleting." - } echo "In normal DC mode...processing\n" } @@ -152,7 +140,7 @@ if {$tech == "sky130"} { } elseif {$drive == "FLOP"} { set_driving_cell -lib_cell scc9gena_dfxbp_1 -pin Q $all_in_ex_clk } -} elseif {$tech == "tsmc28"} { +} elseif {$tech == "tsmc28" || $tech=="tsmc28psyn"} { if {$drive == "INV"} { set_driving_cell -lib_cell INVD1BWP30P140 -pin ZN $all_in_ex_clk } elseif {$drive == "FLOP"} { @@ -178,7 +166,7 @@ if {$tech == "sky130"} { } elseif {$drive == "FLOP"} { set_load [expr [load_of scc9gena_tt_1.2v_25C/scc9gena_dfxbp_1/D] * 1] [all_outputs] } -} elseif {$tech == "tsmc28"} { +} elseif {$tech == "tsmc28" || $tech == "tsmc28psyn"} { if {$drive == "INV"} { set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/INVD4BWP30P140/I] * 1] [all_outputs] } elseif {$drive == "FLOP"} { @@ -186,8 +174,10 @@ if {$tech == "sky130"} { } } -# Set the wire load model -set_wire_load_mode "top" +if {$tech != "tsmc28psyn"} { + # Set the wire load model + set_wire_load_mode "top" +} # Set switching activities # default activity factors are 1 for clocks, 0.1 for others diff --git a/synthDC/wallySynth.py b/synthDC/wallySynth.py index d89964c1..ef93da7f 100755 --- a/synthDC/wallySynth.py +++ b/synthDC/wallySynth.py @@ -19,6 +19,7 @@ if __name__ == '__main__': techs = ['sky90', 'tsmc28', 'tsmc28psyn'] allConfigs = ['rv32gc', 'rv32imc', 'rv64gc', 'rv64imc', 'rv32e', 'rv32i', 'rv64i'] freqVaryPct = [-20, -12, -8, -6, -4, -2, 0, 2, 4, 6, 8, 12, 20] +# freqVaryPct = [-20, -10, 0, 10, 20] pool = Pool() @@ -48,12 +49,12 @@ if __name__ == '__main__': config = args.version if args.version else 'rv32e' for freq in [round(sc+sc*x/100) for x in freqVaryPct]: # rv32e freq sweep runSynth(config, mod, tech, freq, maxopt, usesram, usetopo) - if args.configsweep: + elif args.configsweep: defaultfreq = 1500 if tech == 'sky90' else 5000 freq = args.targetfreq if args.targetfreq else defaultfreq for config in ['rv32i', 'rv64gc', 'rv64i', 'rv32gc', 'rv32imc', 'rv32e']: #configs runSynth(config, mod, tech, freq, maxopt, usesram, usetopo) - if args.featuresweep: + elif args.featuresweep: defaultfreq = 500 if tech == 'sky90' else 1500 freq = args.targetfreq if args.targetfreq else defaultfreq config = args.version if args.version else 'rv64gc' diff --git a/testbench/common/functionName.sv b/testbench/common/functionName.sv index f3cb656f..17b27ec5 100644 --- a/testbench/common/functionName.sv +++ b/testbench/common/functionName.sv @@ -1,33 +1,24 @@ /////////////////////////////////////////// -// datapath.sv +// functionName.sv // -// Written: Ross Thompson -// email: ross1728@gmail.com -// Created: November 9, 2019 -// Modified: March 04, 2021 -// -// Purpose: Finds the current function or global assembly label based on PCE. +// Purpose: decode name of function // // A component of the Wally configurable RISC-V project. // // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // -// MIT LICENSE -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// `include "wally-config.vh" diff --git a/testbench/common/instrNameDecTB.sv b/testbench/common/instrNameDecTB.sv index 4c1a6850..dd993e71 100644 --- a/testbench/common/instrNameDecTB.sv +++ b/testbench/common/instrNameDecTB.sv @@ -1,3 +1,26 @@ +/////////////////////////////////////////// +// instrNameDecTB.sv +// +// Purpose: decode name of function +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + // decode the instruction name, to help the test bench module instrNameDecTB( input logic [31:0] instr, diff --git a/testbench/common/instrTrackerTB.sv b/testbench/common/instrTrackerTB.sv index 2b0ca7c5..429ff848 100644 --- a/testbench/common/instrTrackerTB.sv +++ b/testbench/common/instrTrackerTB.sv @@ -1,3 +1,24 @@ +/////////////////////////////////////////// +// instrTrackerTB.sv +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + module instrTrackerTB( input logic clk, reset, FlushE, input logic [31:0] InstrF, InstrD, diff --git a/testbench/common/riscvassertions.sv b/testbench/common/riscvassertions.sv new file mode 100644 index 00000000..f6cb4c6f --- /dev/null +++ b/testbench/common/riscvassertions.sv @@ -0,0 +1,64 @@ +/////////////////////////////////////////// +// riscvassertions.sv +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module riscvassertions; + initial begin + assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64"); + assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support"); + assert (`IDIV_BITSPERCYCLE == 1 | `IDIV_BITSPERCYCLE==2 | `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4"); + assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)"); + assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)"); + assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)"); + assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN"); + assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported"); + assert (`FLEN<=`XLEN | `DCACHE_SUPPORTED | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported"); + assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); + assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); + assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size"); + assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); + assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled"); + assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size"); + assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2"); + assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); + assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2"); + assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); + assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2"); + assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2"); + assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF"); + assert (`ZICSR_SUPPORTED == 1 | (`PMP_ENTRIES == 0 & `VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported."); + assert (`ZICSR_SUPPORTED == 1 | (`S_SUPPORTED == 0 & `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZICSR not supported"); + assert (`U_SUPPORTED | (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported"); + assert (`VIRTMEM_SUPPORTED == 0 | (`DTIM_SUPPORTED == 0 & `IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses"); + assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache"); + assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache"); + assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS_SUPPORTED."); + assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1"); + assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words"); + assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally."); + assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED"); + assert (`SSTC_SUPPORTED == 0 | (`S_SUPPORTED)) else $error("SSTC requires S_SUPPORTED"); + end + +endmodule + + diff --git a/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index 14b22968..6911ddb5 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -1,3 +1,24 @@ +/////////////////////////////////////////// +// wallyTracer.sv +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + `include "wally-config.vh" `define NUM_REGS 32 @@ -14,7 +35,12 @@ module wallyTracer(rvviTrace rvvi); // wally specific signals logic reset; - + + logic clk; + logic InstrValidD, InstrValidE; + logic StallF, StallD; + logic STATUS_SXL, STATUS_UXL; + logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW; logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; logic InstrValidM, InstrValidW; diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 329d4c60..6b4d8bb8 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -281,7 +281,7 @@ logic [3:0] dummy; // once the test inidicates it's done we need to immediately hold reset for a number of cycles. if(ResetCount < ResetThreshold) ResetCount = ResetCount + 1; else begin // hit reset threshold so we remove reset. - InReset = 0; + InReset = 0; ResetCount = 0; end end else begin @@ -519,47 +519,6 @@ logic [3:0] dummy; endmodule -module riscvassertions; - initial begin - assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64"); - assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support"); - assert (`IDIV_BITSPERCYCLE == 1 | `IDIV_BITSPERCYCLE==2 | `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4"); - assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)"); - assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)"); - assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)"); - assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN"); - assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported"); - assert (`FLEN<=`XLEN | `DCACHE_SUPPORTED | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported"); - assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); - assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size"); - assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled"); - assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size"); - assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2"); - assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2"); - assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF"); - assert (`ZICSR_SUPPORTED == 1 | (`PMP_ENTRIES == 0 & `VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported."); - assert (`ZICSR_SUPPORTED == 1 | (`S_SUPPORTED == 0 & `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZICSR not supported"); - assert (`U_SUPPORTED | (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported"); - assert (`VIRTMEM_SUPPORTED == 0 | (`DTIM_SUPPORTED == 0 & `IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses"); - assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache"); - assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache"); - assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS_SUPPORTED."); - assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1"); - assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words"); - assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally."); - assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED"); - end - - // *** DH 8/23/ -endmodule - - /* verilator lint_on STMTDLY */ /* verilator lint_on WIDTH */ diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv index c7d987b8..d760bf5b 100644 --- a/testbench/testbench_imperas.sv +++ b/testbench/testbench_imperas.sv @@ -322,46 +322,6 @@ module testbench; endmodule -module riscvassertions; - initial begin - assert (`PMP_ENTRIES == 0 | `PMP_ENTRIES==16 | `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64"); - assert (`S_SUPPORTED | `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support"); - assert (`IDIV_BITSPERCYCLE == 1 | `IDIV_BITSPERCYCLE==2 | `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4"); - assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double fp (D) without supporting float (F)"); - assert (`D_SUPPORTED | ~`Q_SUPPORTED) else $error("Can't support quad fp (Q) without supporting double (D)"); - assert (`F_SUPPORTED | ~`ZFH_SUPPORTED) else $error("Can't support half-precision fp (ZFH) without supporting float (F)"); - assert (`DCACHE_SUPPORTED | ~`F_SUPPORTED | `FLEN <= `XLEN) else $error("Data cache required to support FLEN > XLEN because AHB bus width is XLEN"); - assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported"); - assert (`FLEN<=`XLEN | `DCACHE_SUPPORTED | `DTIM_SUPPORTED) else $error("Wally does not support FLEN > XLEN unleses data cache or DTIM is supported"); - assert (`DCACHE_WAYSIZEINBYTES <= 4096 | (!`DCACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (`DCACHE_LINELENINBITS >= 128 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled"); - assert (`DCACHE_LINELENINBITS < `DCACHE_WAYSIZEINBYTES*8) else $error("DCACHE_LINELENINBITS must be smaller than way size"); - assert (`ICACHE_WAYSIZEINBYTES <= 4096 | (!`ICACHE_SUPPORTED) | `VIRTMEM_SUPPORTED == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)"); - assert (`ICACHE_LINELENINBITS >= 32 | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be at least 32 when caches are enabled"); - assert (`ICACHE_LINELENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_LINELENINBITS must be smaller than way size"); - assert (2**$clog2(`DCACHE_LINELENINBITS) == `DCACHE_LINELENINBITS | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES | (!`DCACHE_SUPPORTED)) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(`ICACHE_LINELENINBITS) == `ICACHE_LINELENINBITS | (!`ICACHE_SUPPORTED)) else $error("ICACHE_LINELENINBITS must be a power of 2"); - assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES | (!`ICACHE_SUPPORTED)) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2"); - assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("ITLB_ENTRIES must be a power of 2"); - assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES | `VIRTMEM_SUPPORTED==0) else $error("DTLB_ENTRIES must be a power of 2"); - assert (`UNCORE_RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if UNCORE_RAM_RANGE is less than 56'h07FFFFFF"); - assert (`ZICSR_SUPPORTED == 1 | (`PMP_ENTRIES == 0 & `VIRTMEM_SUPPORTED == 0)) else $error("PMP_ENTRIES and VIRTMEM_SUPPORTED must be zero if ZICSR not supported."); - assert (`ZICSR_SUPPORTED == 1 | (`S_SUPPORTED == 0 & `U_SUPPORTED == 0)) else $error("S and U modes not supported if ZISR not supported"); - assert (`U_SUPPORTED | (`S_SUPPORTED == 0)) else $error ("S mode only supported if U also is supported"); - assert (`VIRTMEM_SUPPORTED == 0 | (`DTIM_SUPPORTED == 0 & `IROM_SUPPORTED == 0)) else $error("Can't simultaneously have virtual memory and DTIM_SUPPORTED/IROM_SUPPORTED because local memories don't translate addresses"); - assert (`DCACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs dcache"); - assert (`ICACHE_SUPPORTED | `VIRTMEM_SUPPORTED ==0) else $error("Virtual memory needs icache"); - assert ((`DCACHE_SUPPORTED == 0 & `ICACHE_SUPPORTED == 0) | `BUS_SUPPORTED) else $error("Dcache and Icache requires DBUS."); - assert (`DCACHE_LINELENINBITS <= `XLEN*16 | (!`DCACHE_SUPPORTED)) else $error("DCACHE_LINELENINBITS must not exceed 16 words because max AHB burst size is 1"); - assert (`DCACHE_LINELENINBITS % 4 == 0) else $error("DCACHE_LINELENINBITS must hold 4, 8, or 16 words"); - assert (`DCACHE_SUPPORTED | `A_SUPPORTED == 0) else $error("Atomic extension (A) requires cache on Wally."); - assert (`IDIV_ON_FPU == 0 | `F_SUPPORTED) else $error("IDIV on FPU needs F_SUPPORTED"); - end - - // *** DH 8/23/ -endmodule - /* verilator lint_on STMTDLY */ /* verilator lint_on WIDTH */ diff --git a/tests/custom/debug/debug.S b/tests/custom/debug/debug.S index 5be3c201..e6e00e86 100644 --- a/tests/custom/debug/debug.S +++ b/tests/custom/debug/debug.S @@ -5,23 +5,38 @@ .global rvtest_entry_point rvtest_entry_point: - lui t0, 0x1e # turn on Floating point and XS + lui t0, 0x02 # turn on Floating point and XS csrs mstatus, t0 - # openhwgroup/cvw Issue #55 la a6, begin_signature la a7, rvtest_data - fadd.d ft0, ft1, ft2 + + # openhwgroup/cvw Issue #55 fld f4, 0(a7) fld f9, 8(a7) -# li x1, 0x7ff0000000000001 -# sd x1, 0(a6) -# fmv.w.x f4, x1 -# li x1, 0x7ff8000000000000 - # fmv.w.x f9, x1 - fsgnjx.s f12,f9,f4 # expected f 0xffffffff7fc00000 + fsgnjx.s f12,f9,f4 # expected f 0xffffffff7fc00000, hdl has been giving fff8000000000000 fsd f12, 0(a6) + # openhwgroup/cvw Issue #56 + fld f4, 16(a7) + fld f14, 24(a7) + fsgnjx.s f10,f4,f14 # expected f 0xffffffff7fc00000, hdl has been giving 0xcfa695b1047553b1 + fsd f19, 8(a6) + + # openhwgroup/cvw Issue #57 + fld f0, 32(a7) + fld f15, 40(a7) + fsgnjx.s f30,f0,f15 # expected f 0xfffffffffb3754ef, hdl has been giving 0xffffffff7b3754ef + fsd f30, 16(a6) + + # openhwgroup/cvw Issue #58 + fld f14, 48(a7) + fclass.s x2, f14 # expected 0x0000000000000200, hdl had been giving 0x0000000000000220 + sd x2, 24(a6) + + # fsgnjx.s, fclass.s, fsgnjn.s, fsgnj.s, fneg.s, fabs.s, fmv.s all treat inputs as dp rather than sp + + ######################### # HTIF and signature ######################### @@ -47,10 +62,14 @@ fromhost: rvtest_data: .dword 0x7ff0000000000001 .dword 0x7ff8000000000000 +.dword 0xcfa695b1047553b1 +.dword 0xffffffff7fc00000 +.dword 0xfffffffffb3754ef +.dword 0x7fefffffffffffff .EQU XLEN,64 begin_signature: - .fill 2*(XLEN/32),4,0xdeadbeef # + .fill 8*(XLEN/32),4,0xdeadbeef # end_signature: # Initialize stack with room for 512 bytes