Repartitioned datapath and controller into ieu

This commit is contained in:
David Harris 2021-01-27 06:40:26 -05:00
parent 91dcffa26f
commit 4318629b32
24 changed files with 233 additions and 132 deletions

View File

@ -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 */

View File

@ -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.

View File

@ -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/*

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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];

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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