diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh index 3a75d0795..a4719ec0d 100644 --- a/wally-pipelined/config/rv64ic/wally-config.vh +++ b/wally-pipelined/config/rv64ic/wally-config.vh @@ -27,7 +27,8 @@ // RV32 or RV64: XLEN = 32 or 64 `define XLEN 64 -`define MISA (32'h00000104) +//`define MISA (32'h00000104) +`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20) `define A_SUPPORTED ((`MISA >> 0) % 2 == 1) `define C_SUPPORTED ((`MISA >> 2) % 2 == 1) `define D_SUPPORTED ((`MISA >> 3) % 2 == 1) @@ -68,3 +69,5 @@ /* verilator lint_off STMTDLY */ /* verilator lint_off WIDTH */ +/* verilator lint_off ASSIGNDLY */ +/* verilator lint_off PINCONNECTEMPTY */ diff --git a/wally-pipelined/lint-wally b/wally-pipelined/lint-wally index abcb96fa4..52f82cc60 100755 --- a/wally-pipelined/lint-wally +++ b/wally-pipelined/lint-wally @@ -1 +1,11 @@ +# check for warnings in Verilog code +# The verilator lint tool is faster and better than Modelsim so it is best to run this first. + verilator --lint-only -Iconfig/rv64ic src/*.sv + +# --lint-only just runs lint rather than trying to compile and simulate +# -I points to the include directory where files such as `include wally-config.vh are found + +# For more exhaustive (and sometimes spurious) warnings, run: +# verilator --lint-only -Wall -Iconfig/rv64ic src/* +# Unfortunately, this produces a bunch of UNUSED and UNDRIVEN signal warnings in blocks that are configured to not exist. diff --git a/wally-pipelined/regression/wally-pipelined.do b/wally-pipelined/regression/wally-pipelined.do index 2750cb174..9c510991b 100644 --- a/wally-pipelined/regression/wally-pipelined.do +++ b/wally-pipelined/regression/wally-pipelined.do @@ -26,8 +26,13 @@ vlib work # suppress spurious warnngs about # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt -vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*.sv -suppress 2583 +# default to config/rv64ic, but allow this to be overridden at the command line. For example: +# do wally-pipelined.do ../config/rv32ic +switch $argc { + 0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*.sv -suppress 2583} + 1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*.sv -suppress 2583} +} # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals vopt +acc work.testbench -o workopt @@ -40,34 +45,34 @@ view wave add wave /testbench/clk add wave /testbench/reset add wave -divider -add wave -hex /testbench/dut/hart/dp/PCF -add wave -hex /testbench/dut/hart/dp/InstrF +add wave -hex /testbench/dut/hart/ieu/dp/PCF +add wave -hex /testbench/dut/hart/ieu/dp/InstrF add wave /testbench/InstrFName -#add wave -hex /testbench/dut/hart/dp/PCD -add wave -hex /testbench/dut/hart/dp/InstrD +#add wave -hex /testbench/dut/hart/ieu/dp/PCD +add wave -hex /testbench/dut/hart/ieu/dp/InstrD add wave /testbench/InstrDName add wave -divider -#add wave -hex /testbench/dut/hart/dp/PCE -#add wave -hex /testbench/dut/hart/dp/InstrE +#add wave -hex /testbench/dut/hart/ieu/dp/PCE +#add wave -hex /testbench/dut/hart/ieu/dp/InstrE add wave /testbench/InstrEName -add wave -hex /testbench/dut/hart/dp/SrcAE -add wave -hex /testbench/dut/hart/dp/SrcBE -add wave -hex /testbench/dut/hart/dp/ALUResultE -add wave /testbench/dut/hart/dp/PCSrcE +add wave -hex /testbench/dut/hart/ieu/dp/SrcAE +add wave -hex /testbench/dut/hart/ieu/dp/SrcBE +add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE +add wave /testbench/dut/hart/ieu/dp/PCSrcE add wave -divider -#add wave -hex /testbench/dut/hart/dp/PCM -#add wave -hex /testbench/dut/hart/dp/InstrM +#add wave -hex /testbench/dut/hart/ieu/dp/PCM +#add wave -hex /testbench/dut/hart/ieu/dp/InstrM add wave /testbench/InstrMName add wave /testbench/dut/dmem/dtim/memwrite add wave -hex /testbench/dut/dmem/AdrM add wave -hex /testbench/dut/dmem/WriteDataM add wave -divider -add wave -hex /testbench/dut/hart/dp/PCW -#add wave -hex /testbench/dut/hart/dp/InstrW +add wave -hex /testbench/dut/hart/ieu/dp/PCW +#add wave -hex /testbench/dut/hart/ieu/dp/InstrW add wave /testbench/InstrWName -add wave /testbench/dut/hart/dp/RegWriteW -add wave -hex /testbench/dut/hart/dp/ResultW -add wave -hex /testbench/dut/hart/dp/RdW +add wave /testbench/dut/hart/ieu/dp/RegWriteW +add wave -hex /testbench/dut/hart/ieu/dp/ResultW +add wave -hex /testbench/dut/hart/ieu/dp/RdW add wave -divider #add ww add wave -hex -r /testbench/* diff --git a/wally-pipelined/src/clint.sv b/wally-pipelined/src/clint.sv index dbdd1787d..e7f520fbc 100644 --- a/wally-pipelined/src/clint.sv +++ b/wally-pipelined/src/clint.sv @@ -68,7 +68,7 @@ module clint ( MSIP <= 0; MTIME <= 0; // MTIMECMP is not reset - end else begin + end else if (memwrite) begin if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; if (entry == 16'h4000) MTIMECMP <= MaskedWriteDataM; // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed @@ -91,7 +91,7 @@ module clint ( MSIP <= 0; MTIME <= 0; // MTIMECMP is not reset - end else begin + end else if (memwrite) begin if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; if (entry == 16'h4000) MTIMECMP[31:0] <= MaskedWriteDataM; if (entry == 16'h4004) MTIMECMP[63:32] <= MaskedWriteDataM; diff --git a/wally-pipelined/src/controller.sv b/wally-pipelined/src/controller.sv index 3adf9ad45..c3f4416eb 100644 --- a/wally-pipelined/src/controller.sv +++ b/wally-pipelined/src/controller.sv @@ -167,5 +167,6 @@ module controller( {RegWriteM, ResultSrcM, InstrValidM}, {RegWriteW, ResultSrcW, InstrValidW}); + // *** improve this so CSR reads don't trigger this signal and cause pipeline flushes assign CSRWritePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM; endmodule diff --git a/wally-pipelined/src/csr.sv b/wally-pipelined/src/csr.sv index 37c82450a..9a3586ab0 100644 --- a/wally-pipelined/src/csr.sv +++ b/wally-pipelined/src/csr.sv @@ -55,13 +55,9 @@ module csr ( logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM; - logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM; logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM; - logic [`XLEN-1:0] zero = 0; - logic [`XLEN-1:0] resetExceptionVector = {{(`XLEN-32){1'b0}}, 32'h80000000}; // initial exception vector at reset - logic [11:0] CSRAdrM; logic [11:0] SIP_REGW, SIE_REGW; logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported diff --git a/wally-pipelined/src/csrc.sv b/wally-pipelined/src/csrc.sv index db3bd44e3..678bdc220 100644 --- a/wally-pipelined/src/csrc.sv +++ b/wally-pipelined/src/csrc.sv @@ -78,12 +78,12 @@ module csrc #(parameter // logic [63:0] TIME_REGW, TIMECMP_REGW; logic [63:0] CYCLE_REGW, INSTRET_REGW; logic [63:0] HPMCOUNTER3_REGW, HPMCOUNTER4_REGW; // add more performance counters here if desired - logic [63:0] CYCLEPlusM, TIMEPlusM, INSTRETPlusM; + logic [63:0] CYCLEPlusM, INSTRETPlusM; logic [63:0] HPMCOUNTER3PlusM, HPMCOUNTER4PlusM; // logic [`XLEN-1:0] NextTIMEM; logic [`XLEN-1:0] NextCYCLEM, NextINSTRETM; logic [`XLEN-1:0] NextHPMCOUNTER3M, NextHPMCOUNTER4M; - logic WriteTIMEM, WriteTIMECMPM, WriteCYCLEM, WriteINSTRETM; + logic WriteCYCLEM, WriteINSTRETM; logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M; logic [4:0] CounterNumM; diff --git a/wally-pipelined/src/csri.sv b/wally-pipelined/src/csri.sv index 701dfa85e..f7b8d261d 100644 --- a/wally-pipelined/src/csri.sv +++ b/wally-pipelined/src/csri.sv @@ -44,7 +44,6 @@ module csri #(parameter logic [11:0] IntInM, IP_REGW, IE_REGW; logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK; logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM; - logic [`XLEN-1:0] zero = 0; // Determine which interrupts need to be set // assumes no N-mode user interrupts @@ -78,16 +77,16 @@ module csri #(parameter assign SIP_WRITE_MASK = 12'h000; end always @(posedge clk, posedge reset) begin - if (reset) IP_REGW = zero; - else if (WriteMIPM) IP_REGW = (CSRWriteValM & MIP_WRITE_MASK) | IntInM; // MTIP unclearable - else if (WriteSIPM) IP_REGW = (CSRWriteValM & SIP_WRITE_MASK) | IntInM; // MTIP unclearable + if (reset) IP_REGW <= 12'b0; + else if (WriteMIPM) IP_REGW <= (CSRWriteValM & MIP_WRITE_MASK) | IntInM; // MTIP unclearable + else if (WriteSIPM) IP_REGW <= (CSRWriteValM & SIP_WRITE_MASK) | IntInM; // MTIP unclearable // else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable - else IP_REGW = IP_REGW | IntInM; // *** check this turns off interrupts properly even when MIDELEG changes + else IP_REGW <= IP_REGW | IntInM; // *** check this turns off interrupts properly even when MIDELEG changes end always @(posedge clk, posedge reset) begin - if (reset) IE_REGW = zero; - else if (WriteMIEM) IE_REGW = (CSRWriteValM & 12'hAAA); // MIE controls M and S fields - else if (WriteSIEM) IE_REGW = (CSRWriteValM & 12'h222) | (IE_REGW & 12'h888); // only S fields + if (reset) IE_REGW <= 12'b0; + else if (WriteMIEM) IE_REGW <= (CSRWriteValM & 12'hAAA); // MIE controls M and S fields + else if (WriteSIEM) IE_REGW <= (CSRWriteValM & 12'h222) | (IE_REGW & 12'h888); // only S fields // else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field end endgenerate @@ -104,8 +103,8 @@ module csri #(parameter SIP_REGW = IP_REGW & MIDELEG_REGW & 'h222; // only delegated interrupts visible SIE_REGW = IE_REGW & MIDELEG_REGW & 'h222; end else begin - SIP_REGW = zero; - SIE_REGW = zero; + SIP_REGW = 12'b0; + SIE_REGW = 12'b0; end // User Modes iterrupts depricated @@ -113,8 +112,8 @@ module csri #(parameter UIP_REGW = IP_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible UIE_REGW = IE_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible end else begin - UIP_REGW = zero; - UIE_REGW = zero; + UIP_REGW = 12'b0; + UIE_REGW = 12'b0; end */ end endgenerate diff --git a/wally-pipelined/src/csrm.sv b/wally-pipelined/src/csrm.sv index b4b4660ae..636238cb9 100644 --- a/wally-pipelined/src/csrm.sv +++ b/wally-pipelined/src/csrm.sv @@ -64,14 +64,12 @@ module csrm #(parameter input logic clk, reset, input logic CSRMWriteM, MTrapM, input logic [11:0] CSRAdrM, - input logic [`XLEN-1:0] resetExceptionVector, input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, input logic [`XLEN-1:0] CSRWriteValM, output logic [`XLEN-1:0] CSRMReadValM, MEPC_REGW, MTVEC_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, input logic [11:0] MIP_REGW, MIE_REGW, - output logic WriteMIPM, WriteMIEM, output logic WriteMSTATUSM, output logic IllegalCSRMAccessM ); @@ -95,8 +93,6 @@ module csrm #(parameter assign WriteMTVECM = CSRMWriteM && (CSRAdrM == MTVEC); assign WriteMEDELEGM = CSRMWriteM && (CSRAdrM == MEDELEG); assign WriteMIDELEGM = CSRMWriteM && (CSRAdrM == MIDELEG); - assign WriteMIPM = CSRMWriteM && (CSRAdrM == MIP); - assign WriteMIEM = CSRMWriteM && (CSRAdrM == MIE); assign WriteMSCRATCHM = CSRMWriteM && (CSRAdrM == MSCRATCH); assign WriteMEPCM = MTrapM | (CSRMWriteM && (CSRAdrM == MEPC)); assign WriteMCAUSEM = MTrapM | (CSRMWriteM && (CSRAdrM == MCAUSE)); @@ -105,7 +101,7 @@ module csrm #(parameter assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT); // CSRs - flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, resetExceptionVector, MTVEC_REGW); + flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, `RESET_VECTOR, MTVEC_REGW); generate if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist flopenl #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, zero, MEDELEG_REGW); diff --git a/wally-pipelined/src/csrn.sv b/wally-pipelined/src/csrn.sv index 517f7cea7..4ac39d5aa 100644 --- a/wally-pipelined/src/csrn.sv +++ b/wally-pipelined/src/csrn.sv @@ -38,40 +38,32 @@ module csrn #(parameter input logic clk, reset, input logic CSRNWriteM, UTrapM, input logic [11:0] CSRAdrM, - input logic [`XLEN-1:0] resetExceptionVector, input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, USTATUS_REGW, input logic [`XLEN-1:0] CSRWriteValM, output logic [`XLEN-1:0] CSRNReadValM, UEPC_REGW, UTVEC_REGW, input logic [11:0] UIP_REGW, UIE_REGW, - output logic WriteUIPM, WriteUIEM, output logic WriteUSTATUSM, output logic IllegalCSRNAccessM ); - logic [`XLEN-1:0] zero = 0; - // User mode CSRs below only needed when user mode traps are supported generate if (`N_SUPPORTED) begin logic WriteUTVECM; logic WriteUSCRATCHM, WriteUEPCM; logic WriteUCAUSEM, WriteUTVALM; - logic [`XLEN-1:0] UEDELEG_REGW, UIDELEG_REGW, UIP_REGW, UIE_REGW; + logic [`XLEN-1:0] UEDELEG_REGW, UIDELEG_REGW; logic [`XLEN-1:0] USCRATCH_REGW, UCAUSE_REGW, UTVAL_REGW; // Write enables assign WriteUSTATUSM = CSRNWriteM && (CSRAdrM == USTATUS); assign WriteUTVECM = CSRNWriteM && (CSRAdrM == UTVEC); - assign WriteUIPM = CSRNWriteM && (CSRAdrM == UIP); - assign WriteUIEM = CSRNWriteM && (CSRAdrM == UIE); assign WriteUEPCM = UTrapM | (CSRNWriteM && (CSRAdrM == UEPC)); assign WriteUCAUSEM = UTrapM | (CSRNWriteM && (CSRAdrM == UCAUSE)); assign WriteUTVALM = UTrapM | (CSRNWriteM && (CSRAdrM == UTVAL)); // CSRs - flopenl #(`XLEN) UTVECreg(clk, reset, WriteUTVECM, CSRWriteValM, resetExceptionVector, UTVEC_REGW); - // flopenl #(`XLEN) UIPreg(clk, reset, WriteUIPM, CSRWriteValM, zero, UIP_REGW); - // flopenl #(`XLEN) UIEreg(clk, reset, WriteUIEM, CSRWriteValM, zero, UIE_REGW); + flopenl #(`XLEN) UTVECreg(clk, reset, WriteUTVECM, CSRWriteValM, `RESET_VECTOR, UTVEC_REGW); flopenr #(`XLEN) USCRATCHreg(clk, reset, WriteUSCRATCHM, CSRWriteValM, USCRATCH_REGW); flopenr #(`XLEN) UEPCreg(clk, reset, WriteUEPCM, NextEPCM, UEPC_REGW); flopenr #(`XLEN) UCAUSEreg(clk, reset, WriteUCAUSEM, NextCauseM, UCAUSE_REGW); @@ -97,8 +89,6 @@ module csrn #(parameter end end else begin // if not supported assign WriteUSTATUSM = 0; - assign WriteUIPM = 0; - assign WriteUIEM = 0; assign CSRNReadValM = 0; assign UEPC_REGW = 0; assign UTVEC_REGW = 0; diff --git a/wally-pipelined/src/csrs.sv b/wally-pipelined/src/csrs.sv index 24ea77c6c..4178a8436 100644 --- a/wally-pipelined/src/csrs.sv +++ b/wally-pipelined/src/csrs.sv @@ -43,14 +43,12 @@ module csrs #(parameter input logic clk, reset, input logic CSRSWriteM, STrapM, input logic [11:0] CSRAdrM, - input logic [`XLEN-1:0] resetExceptionVector, input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW, input logic [`XLEN-1:0] CSRWriteValM, output logic [`XLEN-1:0] CSRSReadValM, SEPC_REGW, STVEC_REGW, output logic [31:0] SCOUNTEREN_REGW, output logic [`XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW, input logic [11:0] SIP_REGW, SIE_REGW, - output logic WriteSIPM, WriteSIEM, output logic WriteSSTATUSM, output logic IllegalCSRSAccessM ); @@ -71,8 +69,6 @@ module csrs #(parameter assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC); assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG); assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG); - assign WriteSIEM = CSRSWriteM && (CSRAdrM == SIE); - assign WriteSIPM = CSRSWriteM && (CSRAdrM == SIP); assign WriteSSCRATCHM = CSRSWriteM && (CSRAdrM == SSCRATCH); assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC)); assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE)); @@ -80,9 +76,7 @@ module csrs #(parameter assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN); // CSRs - flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, resetExceptionVector, STVEC_REGW); -// flopenl #(`XLEN) SIPreg(clk, reset, WriteSIPM, CSRWriteValM, zero, SIP_REGW); -// flopenl #(`XLEN) SIEreg(clk, reset, WriteSIEM, CSRWriteValM, zero, SIE_REGW); + flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, `RESET_VECTOR, STVEC_REGW); flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW); flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW); @@ -119,8 +113,6 @@ module csrs #(parameter end end else begin assign WriteSSTATUSM = 0; - assign WriteSIPM = 0; - assign WriteSIEM = 0; assign CSRSReadValM = 0; assign SEPC_REGW = 0; assign STVEC_REGW = 0; diff --git a/wally-pipelined/src/datapath.sv b/wally-pipelined/src/datapath.sv index 77b9b6f10..3db3f222a 100644 --- a/wally-pipelined/src/datapath.sv +++ b/wally-pipelined/src/datapath.sv @@ -76,7 +76,8 @@ module datapath ( logic [`XLEN-1:0] PCPlus2or4F; // Decode stage signals logic [31:0] InstrD; - logic [`XLEN-1:0] PCD, PCPlus2or4D; + logic [`XLEN-1:0] PCD; +// logic [`XLEN-1:0] PCPlus2or4D; logic [`XLEN-1:0] RD1D, RD2D; logic [`XLEN-1:0] ExtImmD; logic [31:0] InstrDecompD; @@ -115,7 +116,7 @@ module datapath ( // Decode stage pipeline register and logic flopenl #(32) InstrDReg(clk, reset, ~StallD, (FlushD ? nop : InstrF), nop, InstrD); flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); - flopenrc #(`XLEN) PCPlus2or4DReg(clk, reset, FlushD, ~StallD, PCPlus2or4F, PCPlus2or4D); +// flopenrc #(`XLEN) PCPlus2or4DReg(clk, reset, FlushD, ~StallD, PCPlus2or4F, PCPlus2or4D); instrDecompress decomp(.*); assign OpD = InstrDecompD[6:0]; diff --git a/wally-pipelined/src/dmem.sv b/wally-pipelined/src/dmem.sv index 2ff0ce50c..fcd1f2de0 100644 --- a/wally-pipelined/src/dmem.sv +++ b/wally-pipelined/src/dmem.sv @@ -43,7 +43,7 @@ module dmem ( logic [`XLEN-1:0] MaskedWriteDataM; logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM; logic TimEnM, CLINTEnM, GPIOEnM, UARTEnM; - logic [1:0] MemRWdtimM, MemRWclintM, MemRWgpioM; + logic [1:0] MemRWdtimM, MemRWclintM, MemRWgpioM, MemRWuartM; logic UARTIntr;// *** will need to tie INTR to an interrupt handler // Address decoding @@ -60,6 +60,7 @@ module dmem ( assign MemRWdtimM = MemRWM & {2{TimEnM}}; assign MemRWclintM = MemRWM & {2{CLINTEnM}}; assign MemRWgpioM = MemRWM & {2{GPIOEnM}}; + assign MemRWuartM = MemRWM & {2{UARTEnM}}; // tightly integrated memory dtim dtim(.AdrM(AdrM[18:0]), .*); @@ -74,8 +75,9 @@ module dmem ( // *** add cache and interface to external memory & other peripherals // merge reads - assign ReadDataM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) | ({`XLEN{GPIOEnM}} & RdGPIOM); - assign DataAccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM); + assign ReadDataM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) | + ({`XLEN{GPIOEnM}} & RdGPIOM) | ({`XLEN{UARTEnM}} & RdUARTM); + assign DataAccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM | UARTEnM); // byte masking // write each byte based on the byte mask diff --git a/wally-pipelined/src/flop.sv b/wally-pipelined/src/flop.sv index a76674621..263a4fb90 100644 --- a/wally-pipelined/src/flop.sv +++ b/wally-pipelined/src/flop.sv @@ -24,6 +24,7 @@ /////////////////////////////////////////// `include "wally-config.vh" +/* verilator lint_off DECLFILENAME */ // ordinary flip-flop module flop #(parameter WIDTH = 8) ( @@ -96,3 +97,5 @@ module floprc #(parameter WIDTH = 8) ( if (clear) q <= #1 0; else q <= #1 d; endmodule + +/* verilator lint_on DECLFILENAME */ diff --git a/wally-pipelined/src/gpio.sv b/wally-pipelined/src/gpio.sv index e1c35c3a6..00bbde09e 100644 --- a/wally-pipelined/src/gpio.sv +++ b/wally-pipelined/src/gpio.sv @@ -30,7 +30,7 @@ module gpio ( input logic clk, reset, input logic [1:0] MemRWgpioM, - input logic [7:0] ByteMaskM, +// input logic [7:0] ByteMaskM, input logic [7:0] AdrM, input logic [`XLEN-1:0] MaskedWriteDataM, output logic [`XLEN-1:0] RdGPIOM, @@ -78,7 +78,7 @@ module gpio ( INPUT_EN <= 0; OUTPUT_EN <= 0; // OUTPUT_VAL <= 0; // spec indicates synchronous rset (software control) - end else begin + end else if (memwrite) begin if (entry == 8'h00) INPUT_EN <= MaskedWriteDataM[63:32]; if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= MaskedWriteDataM; if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM[31:0]; // OUT_XOR @@ -99,7 +99,7 @@ module gpio ( INPUT_EN <= 0; OUTPUT_EN <= 0; //OUTPUT_VAL <= 0;// spec indicates synchronous rset (software control) - end else begin + end else if (memwrite) begin if (entry == 8'h04) INPUT_EN <= MaskedWriteDataM; if (entry == 8'h08) OUTPUT_EN <= MaskedWriteDataM; if (entry == 8'h0C) OUTPUT_VAL <= MaskedWriteDataM; diff --git a/wally-pipelined/src/ieu.sv b/wally-pipelined/src/ieu.sv new file mode 100644 index 000000000..0627cf734 --- /dev/null +++ b/wally-pipelined/src/ieu.sv @@ -0,0 +1,84 @@ +/////////////////////////////////////////// +// ieu.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Integer Execution Unit: datapath and controller +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// 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: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// 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. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module ieu ( + input logic clk, reset, + output logic [`XLEN-1:0] PCF, + input logic [31:0] InstrF, + output logic [1:0] MemRWM, + output logic [7:0] ByteMaskM, + output logic [`XLEN-1:0] ALUResultM, WriteDataM, + input logic [`XLEN-1:0] ReadDataM, + input logic TimerIntM, ExtIntM, SwIntM, + input logic InstrAccessFaultF, + input logic DataAccessFaultM, + input logic [1:0] ForwardAE, ForwardBE, + input logic StallF, StallD, FlushD, FlushE, FlushM, FlushW, + output logic PCSrcE, + output logic RegWriteM, + output logic MemReadE, + output logic RegWriteW, + output logic CSRWritePendingDEM, + output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, + input logic [4:0] SetFflagsM, + output logic [2:0] FRM_REGW, + output logic FloatRegWriteW, + output logic RetM, TrapM, + input logic LoadStallD + +); + + logic [2:0] Funct3D; + logic Funct7b5D; + logic [6:0] OpD; + logic [2:0] ImmSrcD; + logic IllegalCompInstrD; + logic [2:0] FlagsE; +// logic PCSrcE; + logic [4:0] ALUControlE; + logic ALUSrcAE, ALUSrcBE; +// logic MemReadE; +// logic RegWriteM; + logic CSRWriteM; + logic PrivilegedM; + logic IllegalInstrFaultM; + logic InstrAccessFaultM; + logic [2:0] Funct3M; + logic [1:0] ResultSrcW; +// logic RegWriteW; + logic InstrValidW; + // logic LoadStallD; +// logic CSRWritePendingDEM; + logic InstrMisalignedFaultM; + + +// logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW; + logic TargetSrcE; + + controller c(.*); + datapath dp(.*); +endmodule diff --git a/wally-pipelined/src/imem.sv b/wally-pipelined/src/imem.sv index 82bf83f23..dbe84bfe3 100644 --- a/wally-pipelined/src/imem.sv +++ b/wally-pipelined/src/imem.sv @@ -26,13 +26,16 @@ `include "wally-config.vh" module imem ( - input logic [`XLEN-1:0] AdrF, + input logic [`XLEN-1:1] AdrF, output logic [31:0] InstrF, output logic InstrAccessFaultF); + /* verilator lint_off UNDRIVEN */ logic [`XLEN-1:0] RAM[0:65535]; + /* verilator lint_on UNDRIVEN */ logic [15:0] adrbits; - logic [`XLEN-1:0] rd, rd2; + logic [`XLEN-1:0] rd; + logic [15:0] rd2; generate if (`XLEN==32) assign adrbits = AdrF[17:2]; @@ -45,7 +48,7 @@ module imem ( // eventually this will need to cause a stall like a cache miss // when the instruction wraps around a cache line // could be optimized to only stall when the instruction wrapping is 32 bits - assign #2 rd2 = RAM[adrbits+1]; + assign #2 rd2 = RAM[adrbits+1][15:0]; generate if (`XLEN==32) begin assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd; diff --git a/wally-pipelined/src/mux.sv b/wally-pipelined/src/mux.sv index acc07bb6b..2b4f69e0e 100644 --- a/wally-pipelined/src/mux.sv +++ b/wally-pipelined/src/mux.sv @@ -24,6 +24,7 @@ /////////////////////////////////////////// `include "wally-config.vh" +/* verilator lint_off DECLFILENAME */ module mux2 #(parameter WIDTH = 8) ( @@ -50,3 +51,4 @@ module mux4 #(parameter WIDTH = 8) ( assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0); endmodule +/* verilator lint_on DECLFILENAME */ diff --git a/wally-pipelined/src/trap.sv b/wally-pipelined/src/trap.sv index 6c3039ebf..ebac0da66 100644 --- a/wally-pipelined/src/trap.sv +++ b/wally-pipelined/src/trap.sv @@ -27,7 +27,7 @@ `include "wally-config.vh" module trap ( - input logic clk, reset, + input logic reset, input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM, input logic BreakpointFaultM, LoadMisalignedFaultM, StoreMisalignedFaultM, input logic LoadAccessFaultM, StoreAccessFaultM, EcallFaultM, InstrPageFaultM, diff --git a/wally-pipelined/src/uart.sv b/wally-pipelined/src/uart.sv index 084a5c435..04e787d72 100644 --- a/wally-pipelined/src/uart.sv +++ b/wally-pipelined/src/uart.sv @@ -29,7 +29,7 @@ module uart ( input logic clk, reset, - input logic [1:0] MemRWgpioM, + input logic [1:0] MemRWuartM, input logic [7:0] ByteMaskM, input logic [`XLEN-1:0] AdrM, input logic [`XLEN-1:0] MaskedWriteDataM, @@ -42,11 +42,10 @@ module uart ( logic [2:0] A; logic MEMRb, MEMWb; logic [7:0] Din, Dout; - logic SINint; // for loopback testing // rename processor interface signals to match PC16550D and provide one-byte interface - assign MEMRb = ~MemRWgpioM[1]; - assign MEMWb = ~MemRWgpioM[0]; + assign MEMRb = ~MemRWuartM[1]; + assign MEMWb = ~MemRWuartM[0]; assign A = AdrM[2:0]; generate diff --git a/wally-pipelined/src/uartPC16550D.sv b/wally-pipelined/src/uartPC16550D.sv index 59251e854..17ac50a6e 100644 --- a/wally-pipelined/src/uartPC16550D.sv +++ b/wally-pipelined/src/uartPC16550D.sv @@ -30,6 +30,7 @@ /////////////////////////////////////////// `include "wally-config.vh" + /* verilator lint_off UNOPTFLAT */ module uartPC16550D( // Processor Interface @@ -52,7 +53,7 @@ module uartPC16550D( // Registers logic [10:0] RBR; - logic [7:0] IIR, FCR, LCR, LSR, SCR, DLL, DLM; + logic [7:0] FCR, LCR, LSR, SCR, DLL, DLM; logic [3:0] IER, MSR; logic [4:0] MCR; @@ -124,7 +125,6 @@ module uartPC16550D( always_ff @(posedge clk, posedge reset) if (reset) begin // Table 3 Reset Configuration IER <= 4'b0; - IIR <= 8'b1; FCR <= 8'b0; LCR <= 8'b0; MCR <= 5'b0; @@ -157,20 +157,20 @@ module uartPC16550D( /* verilator lint_on CASEINCOMPLETE */ end // Line Status Register (8.6.3) - LSR[0] = rxdataready; // Data ready - if (RXBR[10]) LSR[1] = 1; // overrun error - if (RXBR[9]) LSR[2] = 1; // parity error - if (RXBR[8]) LSR[3] = 1; // framing error - if (rxbreak) LSR[4] = 1; // break indicator - LSR[5] = txhremptyintr ; // THRE - LSR[6] = ~txsrfull & txhremptyintr; // TEMT - if (rxfifohaserr) LSR[7] = 1; // any bits in FIFO have error + LSR[0] <= rxdataready; // Data ready + if (RXBR[10]) LSR[1] <= 1; // overrun error + if (RXBR[9]) LSR[2] <= 1; // parity error + if (RXBR[8]) LSR[3] <= 1; // framing error + if (rxbreak) LSR[4] <= 1; // break indicator + LSR[5] <= txhremptyintr ; // THRE + LSR[6] <= ~txsrfull & txhremptyintr; // TEMT + if (rxfifohaserr) LSR[7] <= 1; // any bits in FIFO have error // Modem Status Register (8.6.8) - MSR[0] |= CTSb2 ^ CTSbsync; // Delta Clear to Send - MSR[1] |= DSRb2 ^ DSRbsync; // Delta Data Set Ready - MSR[2] |= (~RIb2 & RIbsync); // Trailing Edge of Ring Indicator - MSR[3] |= DCDb2 ^ DCDbsync; // Delta Data Carrier Detect + MSR[0] <= MSR[0] | CTSb2 ^ CTSbsync; // Delta Clear to Send + MSR[1] <= MSR[1] | DSRb2 ^ DSRbsync; // Delta Data Set Ready + MSR[2] <= MSR[2] | (~RIb2 & RIbsync); // Trailing Edge of Ring Indicator + MSR[3] <= MSR[3] | DCDb2 ^ DCDbsync; // Delta Data Carrier Detect end always_comb @@ -213,12 +213,12 @@ module uartPC16550D( always_ff @(posedge clk, posedge reset) if (reset) begin rxoversampledcnt <= 0; - rxstate = UART_IDLE; + rxstate <= UART_IDLE; rxbitsreceived <= 0; rxtimeoutcnt <= 0; end else begin if (rxstate == UART_IDLE & ~SINsync) begin // got start bit - rxstate = UART_ACTIVE; + rxstate <= UART_ACTIVE; rxoversampledcnt <= 0; rxbitsreceived <= 0; rxtimeoutcnt <= 0; // reset timeout when new character is arriving @@ -268,16 +268,16 @@ module uartPC16550D( rxfifohead <= 0; rxfifotail <= 0; rxdataready <= 0; RXBR <= 0; end else begin if (rxstate == UART_DONE) begin - RXBR = {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register + RXBR <= {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register if (fifoenabled) begin - rxfifo[rxfifohead] <= RXBR; + rxfifo[rxfifohead] <= {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; rxfifohead <= rxfifohead + 1; end rxdataready <= 1; end else if (~MEMRb && A == 3'b000 && ~DLAB) begin // reading RBR updates ready / pops fifo if (fifoenabled) begin - rxfifotail = rxfifotail + 1; - if (rxfifohead == rxfifotail) rxdataready <= 0; + rxfifotail <= rxfifotail + 1; + if (rxfifohead == rxfifotail +1) rxdataready <= 0; end else rxdataready <= 0; end else if (~MEMWb && A == 3'b010) // writes to FIFO Control Register if (Din[1] | ~Din[0]) begin // rx FIFO reset or FIFO disable clears FIFO contents @@ -293,6 +293,7 @@ module uartPC16550D( assign rxfifotimeout = 0; // disabled pending fix // detect any errors in rx fifo + // although rxfullbit looks like a combinational loop, in one bit rxfifotail == i and breaks the loop generate genvar i; for (i=0; i<16; i++) begin @@ -400,7 +401,7 @@ module uartPC16550D( txsrfull <= 1; end else if (txstate == UART_DONE) txsrfull <= 0; // done transmitting shift register - else if (txstate == UART_ACTIVE && txnextbit) TXHR <= {TXHR[10:0], 1'b1}; // shift txhr + else if (txstate == UART_ACTIVE && txnextbit) txsr <= {txsr[10:0], 1'b1}; // shift txhr if (!MEMWb && A == 3'b010) // writes to FIFO control register if (Din[2] | ~Din[0]) begin // tx FIFO reste or FIFO disable clears FIFO contents txfifohead <= 0; txfifotail <= 0; @@ -423,7 +424,7 @@ module uartPC16550D( else TXRDYb = ~txhremptyintr; // Transmitter pin - assign SOUTbit = TXHR[11]; // transmit most significant bit + assign SOUTbit = txsr[11]; // transmit most significant bit assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break /////////////////////////////////////////// @@ -474,3 +475,5 @@ module uartPC16550D( endcase endmodule + + /* verilator lint_on UNOPTFLAT */ diff --git a/wally-pipelined/src/wallypipelined.sv b/wally-pipelined/src/wallypipelined.sv index 9fe936809..b4ae7aae9 100644 --- a/wally-pipelined/src/wallypipelined.sv +++ b/wally-pipelined/src/wallypipelined.sv @@ -72,6 +72,6 @@ module wallypipelined ( // instantiate processor and memories wallypipelinedhart hart(.ALUResultM(DataAdrM), .*); - imem imem(.AdrF(PCF), .*); + imem imem(.AdrF(PCF[`XLEN-1:1]), .*); dmem dmem(.AdrM(DataAdrM), .*); endmodule \ No newline at end of file diff --git a/wally-pipelined/src/wallypipelinedhart.sv b/wally-pipelined/src/wallypipelinedhart.sv index 25702a84a..e8571ead1 100644 --- a/wally-pipelined/src/wallypipelinedhart.sv +++ b/wally-pipelined/src/wallypipelinedhart.sv @@ -24,6 +24,7 @@ /////////////////////////////////////////// `include "wally-config.vh" +/* verilator lint_on UNUSED */ module wallypipelinedhart ( input logic clk, reset, @@ -37,45 +38,56 @@ module wallypipelinedhart ( input logic InstrAccessFaultF, input logic DataAccessFaultM); - logic [2:0] Funct3D; - logic Funct7b5D; - logic [6:0] OpD; - logic [2:0] ImmSrcD; - logic IllegalCompInstrD; - logic [2:0] FlagsE; - logic PCSrcE; - logic [4:0] ALUControlE; - logic ALUSrcAE, ALUSrcBE; - logic MemReadE; - logic RegWriteM; - logic CSRWriteM; - logic PrivilegedM; - logic IllegalInstrFaultM; +/* +// logic [2:0] Funct3D; +// logic Funct7b5D; +// logic [6:0] OpD; +// logic [2:0] ImmSrcD; +// logic IllegalCompInstrD; +// logic [2:0] FlagsE; +// logic [4:0] ALUControlE; +// logic ALUSrcAE, ALUSrcBE; +// logic CSRWriteM; +// logic PrivilegedM; +// logic IllegalInstrFaultM; logic InstrAccessFaultM; logic [2:0] Funct3M; logic [1:0] ResultSrcW; - logic RegWriteW; - logic InstrValidW, LoadStallD; - logic CSRWritePendingDEM; + logic InstrValidW; logic InstrMisalignedFaultM; - +*/ logic [1:0] ForwardAE, ForwardBE; logic StallF, StallD, FlushD, FlushE, FlushM, FlushW; logic RetM, TrapM; + logic PCSrcE; + logic RegWriteM; + logic MemReadE; + logic RegWriteW; + logic CSRWritePendingDEM; + logic LoadStallD; logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW; - logic TargetSrcE; +// logic TargetSrcE; logic [4:0] SetFflagsM; logic [2:0] FRM_REGW; logic FloatRegWriteW; - controller c(.*); - datapath dp(.*); - hazard hz(.*); + ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller +/* ifu ifu(.*); // instruction fetch unit: PC, branch prediction, instruction cache + mdu mdu(.*); // multiply and divide unit + fpu fpu(.*); // floating point unit + dcu dcu(.*); // data cache unit + ebu ebu(.*); // external bus to memory and peripherals */ +// privileged pcu(.*); // privileged control unit CSRs, traps, privilege mode + hazard hzu(.*); // global stall and flush control + + // Priveleged block operates in M and W stages, handling CSRs and exceptions +// privileged priv(.IllegalInstrFaultInM(IllegalInstrFaultM), .*); + // add FPU here, with SetFflagsM, FRM_REGW // presently stub out SetFlagsM and FloatRegWriteW assign SetFflagsM = 0; - assign FloatRegWriteW = 0; + //assign FloatRegWriteW = 0; endmodule diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index f447d12d8..2d7f2b8d8 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -247,9 +247,9 @@ string tests32i[] = { ); // Track names of instructions - instrTrackerTB it(clk, reset, dut.hart.dp.FlushE, - dut.hart.dp.InstrDecompD, dut.hart.dp.InstrE, - dut.hart.dp.InstrM, InstrW, + instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, + dut.hart.ieu.dp.InstrDecompD, dut.hart.ieu.dp.InstrE, + dut.hart.ieu.dp.InstrM, InstrW, InstrDName, InstrEName, InstrMName, InstrWName); // initialize test @@ -281,8 +281,8 @@ string tests32i[] = { // check results always @(negedge clk) begin - if (dut.hart.dp.priv.EcallFaultM && - (dut.hart.dp.regf.rf[3] == 1 || (dut.hart.dp.regf.we3 && dut.hart.dp.regf.a3 == 3 && dut.hart.dp.regf.wd3 == 1))) begin + if (dut.hart.ieu.dp.priv.EcallFaultM && + (dut.hart.ieu.dp.regf.rf[3] == 1 || (dut.hart.ieu.dp.regf.we3 && dut.hart.ieu.dp.regf.a3 == 3 && dut.hart.ieu.dp.regf.wd3 == 1))) begin $display("Code ended with ecall with gp = 1"); #60; // give time for instructions in pipeline to finish // clear signature to prevent contamination from previous tests