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 // RV32 or RV64: XLEN = 32 or 64
`define XLEN 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 A_SUPPORTED ((`MISA >> 0) % 2 == 1)
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1) `define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1) `define D_SUPPORTED ((`MISA >> 3) % 2 == 1)
@ -68,3 +69,5 @@
/* verilator lint_off STMTDLY */ /* verilator lint_off STMTDLY */
/* verilator lint_off WIDTH */ /* 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 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 # suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time" # "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt # 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 # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals
vopt +acc work.testbench -o workopt vopt +acc work.testbench -o workopt
@ -40,34 +45,34 @@ view wave
add wave /testbench/clk add wave /testbench/clk
add wave /testbench/reset add wave /testbench/reset
add wave -divider add wave -divider
add wave -hex /testbench/dut/hart/dp/PCF add wave -hex /testbench/dut/hart/ieu/dp/PCF
add wave -hex /testbench/dut/hart/dp/InstrF add wave -hex /testbench/dut/hart/ieu/dp/InstrF
add wave /testbench/InstrFName add wave /testbench/InstrFName
#add wave -hex /testbench/dut/hart/dp/PCD #add wave -hex /testbench/dut/hart/ieu/dp/PCD
add wave -hex /testbench/dut/hart/dp/InstrD add wave -hex /testbench/dut/hart/ieu/dp/InstrD
add wave /testbench/InstrDName add wave /testbench/InstrDName
add wave -divider add wave -divider
#add wave -hex /testbench/dut/hart/dp/PCE #add wave -hex /testbench/dut/hart/ieu/dp/PCE
#add wave -hex /testbench/dut/hart/dp/InstrE #add wave -hex /testbench/dut/hart/ieu/dp/InstrE
add wave /testbench/InstrEName add wave /testbench/InstrEName
add wave -hex /testbench/dut/hart/dp/SrcAE add wave -hex /testbench/dut/hart/ieu/dp/SrcAE
add wave -hex /testbench/dut/hart/dp/SrcBE add wave -hex /testbench/dut/hart/ieu/dp/SrcBE
add wave -hex /testbench/dut/hart/dp/ALUResultE add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE
add wave /testbench/dut/hart/dp/PCSrcE add wave /testbench/dut/hart/ieu/dp/PCSrcE
add wave -divider add wave -divider
#add wave -hex /testbench/dut/hart/dp/PCM #add wave -hex /testbench/dut/hart/ieu/dp/PCM
#add wave -hex /testbench/dut/hart/dp/InstrM #add wave -hex /testbench/dut/hart/ieu/dp/InstrM
add wave /testbench/InstrMName add wave /testbench/InstrMName
add wave /testbench/dut/dmem/dtim/memwrite add wave /testbench/dut/dmem/dtim/memwrite
add wave -hex /testbench/dut/dmem/AdrM add wave -hex /testbench/dut/dmem/AdrM
add wave -hex /testbench/dut/dmem/WriteDataM add wave -hex /testbench/dut/dmem/WriteDataM
add wave -divider add wave -divider
add wave -hex /testbench/dut/hart/dp/PCW add wave -hex /testbench/dut/hart/ieu/dp/PCW
#add wave -hex /testbench/dut/hart/dp/InstrW #add wave -hex /testbench/dut/hart/ieu/dp/InstrW
add wave /testbench/InstrWName add wave /testbench/InstrWName
add wave /testbench/dut/hart/dp/RegWriteW add wave /testbench/dut/hart/ieu/dp/RegWriteW
add wave -hex /testbench/dut/hart/dp/ResultW add wave -hex /testbench/dut/hart/ieu/dp/ResultW
add wave -hex /testbench/dut/hart/dp/RdW add wave -hex /testbench/dut/hart/ieu/dp/RdW
add wave -divider add wave -divider
#add ww #add ww
add wave -hex -r /testbench/* add wave -hex -r /testbench/*

View File

@ -68,7 +68,7 @@ module clint (
MSIP <= 0; MSIP <= 0;
MTIME <= 0; MTIME <= 0;
// MTIMECMP is not reset // MTIMECMP is not reset
end else begin end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0];
if (entry == 16'h4000) MTIMECMP <= MaskedWriteDataM; if (entry == 16'h4000) MTIMECMP <= MaskedWriteDataM;
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
@ -91,7 +91,7 @@ module clint (
MSIP <= 0; MSIP <= 0;
MTIME <= 0; MTIME <= 0;
// MTIMECMP is not reset // MTIMECMP is not reset
end else begin end else if (memwrite) begin
if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0]; if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0];
if (entry == 16'h4000) MTIMECMP[31:0] <= MaskedWriteDataM; if (entry == 16'h4000) MTIMECMP[31:0] <= MaskedWriteDataM;
if (entry == 16'h4004) MTIMECMP[63:32] <= MaskedWriteDataM; if (entry == 16'h4004) MTIMECMP[63:32] <= MaskedWriteDataM;

View File

@ -167,5 +167,6 @@ module controller(
{RegWriteM, ResultSrcM, InstrValidM}, {RegWriteM, ResultSrcM, InstrValidM},
{RegWriteW, ResultSrcW, InstrValidW}); {RegWriteW, ResultSrcW, InstrValidW});
// *** improve this so CSR reads don't trigger this signal and cause pipeline flushes
assign CSRWritePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM; assign CSRWritePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM;
endmodule endmodule

View File

@ -55,13 +55,9 @@ module csr (
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM; logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM;
logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM; 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] CSRAdrM;
logic [11:0] SIP_REGW, SIE_REGW; logic [11:0] SIP_REGW, SIE_REGW;
logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported 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] TIME_REGW, TIMECMP_REGW;
logic [63:0] CYCLE_REGW, INSTRET_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] 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 [63:0] HPMCOUNTER3PlusM, HPMCOUNTER4PlusM;
// logic [`XLEN-1:0] NextTIMEM; // logic [`XLEN-1:0] NextTIMEM;
logic [`XLEN-1:0] NextCYCLEM, NextINSTRETM; logic [`XLEN-1:0] NextCYCLEM, NextINSTRETM;
logic [`XLEN-1:0] NextHPMCOUNTER3M, NextHPMCOUNTER4M; logic [`XLEN-1:0] NextHPMCOUNTER3M, NextHPMCOUNTER4M;
logic WriteTIMEM, WriteTIMECMPM, WriteCYCLEM, WriteINSTRETM; logic WriteCYCLEM, WriteINSTRETM;
logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M; logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M;
logic [4:0] CounterNumM; logic [4:0] CounterNumM;

View File

@ -44,7 +44,6 @@ module csri #(parameter
logic [11:0] IntInM, IP_REGW, IE_REGW; logic [11:0] IntInM, IP_REGW, IE_REGW;
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK; logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK;
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM; logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
logic [`XLEN-1:0] zero = 0;
// Determine which interrupts need to be set // Determine which interrupts need to be set
// assumes no N-mode user interrupts // assumes no N-mode user interrupts
@ -78,16 +77,16 @@ module csri #(parameter
assign SIP_WRITE_MASK = 12'h000; assign SIP_WRITE_MASK = 12'h000;
end end
always @(posedge clk, posedge reset) begin always @(posedge clk, posedge reset) begin
if (reset) IP_REGW = zero; if (reset) IP_REGW <= 12'b0;
else if (WriteMIPM) IP_REGW = (CSRWriteValM & MIP_WRITE_MASK) | IntInM; // MTIP unclearable 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 (WriteSIPM) IP_REGW <= (CSRWriteValM & SIP_WRITE_MASK) | IntInM; // MTIP unclearable
// else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // 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 end
always @(posedge clk, posedge reset) begin always @(posedge clk, posedge reset) begin
if (reset) IE_REGW = zero; if (reset) IE_REGW <= 12'b0;
else if (WriteMIEM) IE_REGW = (CSRWriteValM & 12'hAAA); // MIE controls M and S fields 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 (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 // else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field
end end
endgenerate endgenerate
@ -104,8 +103,8 @@ module csri #(parameter
SIP_REGW = IP_REGW & MIDELEG_REGW & 'h222; // only delegated interrupts visible SIP_REGW = IP_REGW & MIDELEG_REGW & 'h222; // only delegated interrupts visible
SIE_REGW = IE_REGW & MIDELEG_REGW & 'h222; SIE_REGW = IE_REGW & MIDELEG_REGW & 'h222;
end else begin end else begin
SIP_REGW = zero; SIP_REGW = 12'b0;
SIE_REGW = zero; SIE_REGW = 12'b0;
end end
// User Modes iterrupts depricated // User Modes iterrupts depricated
@ -113,8 +112,8 @@ module csri #(parameter
UIP_REGW = IP_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible 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 UIE_REGW = IE_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible
end else begin end else begin
UIP_REGW = zero; UIP_REGW = 12'b0;
UIE_REGW = zero; UIE_REGW = 12'b0;
end */ end */
end end
endgenerate endgenerate

View File

@ -64,14 +64,12 @@ module csrm #(parameter
input logic clk, reset, input logic clk, reset,
input logic CSRMWriteM, MTrapM, input logic CSRMWriteM, MTrapM,
input logic [11:0] CSRAdrM, 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] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
output logic [`XLEN-1:0] CSRMReadValM, MEPC_REGW, MTVEC_REGW, output logic [`XLEN-1:0] CSRMReadValM, MEPC_REGW, MTVEC_REGW,
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW,
input logic [11:0] MIP_REGW, MIE_REGW, input logic [11:0] MIP_REGW, MIE_REGW,
output logic WriteMIPM, WriteMIEM,
output logic WriteMSTATUSM, output logic WriteMSTATUSM,
output logic IllegalCSRMAccessM output logic IllegalCSRMAccessM
); );
@ -95,8 +93,6 @@ module csrm #(parameter
assign WriteMTVECM = CSRMWriteM && (CSRAdrM == MTVEC); assign WriteMTVECM = CSRMWriteM && (CSRAdrM == MTVEC);
assign WriteMEDELEGM = CSRMWriteM && (CSRAdrM == MEDELEG); assign WriteMEDELEGM = CSRMWriteM && (CSRAdrM == MEDELEG);
assign WriteMIDELEGM = CSRMWriteM && (CSRAdrM == MIDELEG); assign WriteMIDELEGM = CSRMWriteM && (CSRAdrM == MIDELEG);
assign WriteMIPM = CSRMWriteM && (CSRAdrM == MIP);
assign WriteMIEM = CSRMWriteM && (CSRAdrM == MIE);
assign WriteMSCRATCHM = CSRMWriteM && (CSRAdrM == MSCRATCH); assign WriteMSCRATCHM = CSRMWriteM && (CSRAdrM == MSCRATCH);
assign WriteMEPCM = MTrapM | (CSRMWriteM && (CSRAdrM == MEPC)); assign WriteMEPCM = MTrapM | (CSRMWriteM && (CSRAdrM == MEPC));
assign WriteMCAUSEM = MTrapM | (CSRMWriteM && (CSRAdrM == MCAUSE)); assign WriteMCAUSEM = MTrapM | (CSRMWriteM && (CSRAdrM == MCAUSE));
@ -105,7 +101,7 @@ module csrm #(parameter
assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT); assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT);
// CSRs // CSRs
flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, resetExceptionVector, MTVEC_REGW); flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, `RESET_VECTOR, MTVEC_REGW);
generate generate
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist
flopenl #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, zero, MEDELEG_REGW); 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 clk, reset,
input logic CSRNWriteM, UTrapM, input logic CSRNWriteM, UTrapM,
input logic [11:0] CSRAdrM, 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] NextEPCM, NextCauseM, NextMtvalM, USTATUS_REGW,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
output logic [`XLEN-1:0] CSRNReadValM, UEPC_REGW, UTVEC_REGW, output logic [`XLEN-1:0] CSRNReadValM, UEPC_REGW, UTVEC_REGW,
input logic [11:0] UIP_REGW, UIE_REGW, input logic [11:0] UIP_REGW, UIE_REGW,
output logic WriteUIPM, WriteUIEM,
output logic WriteUSTATUSM, output logic WriteUSTATUSM,
output logic IllegalCSRNAccessM output logic IllegalCSRNAccessM
); );
logic [`XLEN-1:0] zero = 0;
// User mode CSRs below only needed when user mode traps are supported // User mode CSRs below only needed when user mode traps are supported
generate generate
if (`N_SUPPORTED) begin if (`N_SUPPORTED) begin
logic WriteUTVECM; logic WriteUTVECM;
logic WriteUSCRATCHM, WriteUEPCM; logic WriteUSCRATCHM, WriteUEPCM;
logic WriteUCAUSEM, WriteUTVALM; 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; logic [`XLEN-1:0] USCRATCH_REGW, UCAUSE_REGW, UTVAL_REGW;
// Write enables // Write enables
assign WriteUSTATUSM = CSRNWriteM && (CSRAdrM == USTATUS); assign WriteUSTATUSM = CSRNWriteM && (CSRAdrM == USTATUS);
assign WriteUTVECM = CSRNWriteM && (CSRAdrM == UTVEC); assign WriteUTVECM = CSRNWriteM && (CSRAdrM == UTVEC);
assign WriteUIPM = CSRNWriteM && (CSRAdrM == UIP);
assign WriteUIEM = CSRNWriteM && (CSRAdrM == UIE);
assign WriteUEPCM = UTrapM | (CSRNWriteM && (CSRAdrM == UEPC)); assign WriteUEPCM = UTrapM | (CSRNWriteM && (CSRAdrM == UEPC));
assign WriteUCAUSEM = UTrapM | (CSRNWriteM && (CSRAdrM == UCAUSE)); assign WriteUCAUSEM = UTrapM | (CSRNWriteM && (CSRAdrM == UCAUSE));
assign WriteUTVALM = UTrapM | (CSRNWriteM && (CSRAdrM == UTVAL)); assign WriteUTVALM = UTrapM | (CSRNWriteM && (CSRAdrM == UTVAL));
// CSRs // CSRs
flopenl #(`XLEN) UTVECreg(clk, reset, WriteUTVECM, CSRWriteValM, resetExceptionVector, UTVEC_REGW); flopenl #(`XLEN) UTVECreg(clk, reset, WriteUTVECM, CSRWriteValM, `RESET_VECTOR, UTVEC_REGW);
// flopenl #(`XLEN) UIPreg(clk, reset, WriteUIPM, CSRWriteValM, zero, UIP_REGW);
// flopenl #(`XLEN) UIEreg(clk, reset, WriteUIEM, CSRWriteValM, zero, UIE_REGW);
flopenr #(`XLEN) USCRATCHreg(clk, reset, WriteUSCRATCHM, CSRWriteValM, USCRATCH_REGW); flopenr #(`XLEN) USCRATCHreg(clk, reset, WriteUSCRATCHM, CSRWriteValM, USCRATCH_REGW);
flopenr #(`XLEN) UEPCreg(clk, reset, WriteUEPCM, NextEPCM, UEPC_REGW); flopenr #(`XLEN) UEPCreg(clk, reset, WriteUEPCM, NextEPCM, UEPC_REGW);
flopenr #(`XLEN) UCAUSEreg(clk, reset, WriteUCAUSEM, NextCauseM, UCAUSE_REGW); flopenr #(`XLEN) UCAUSEreg(clk, reset, WriteUCAUSEM, NextCauseM, UCAUSE_REGW);
@ -97,8 +89,6 @@ module csrn #(parameter
end end
end else begin // if not supported end else begin // if not supported
assign WriteUSTATUSM = 0; assign WriteUSTATUSM = 0;
assign WriteUIPM = 0;
assign WriteUIEM = 0;
assign CSRNReadValM = 0; assign CSRNReadValM = 0;
assign UEPC_REGW = 0; assign UEPC_REGW = 0;
assign UTVEC_REGW = 0; assign UTVEC_REGW = 0;

View File

@ -43,14 +43,12 @@ module csrs #(parameter
input logic clk, reset, input logic clk, reset,
input logic CSRSWriteM, STrapM, input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM, 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] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
output logic [`XLEN-1:0] CSRSReadValM, SEPC_REGW, STVEC_REGW, output logic [`XLEN-1:0] CSRSReadValM, SEPC_REGW, STVEC_REGW,
output logic [31:0] SCOUNTEREN_REGW, output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW, output logic [`XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW,
input logic [11:0] SIP_REGW, SIE_REGW, input logic [11:0] SIP_REGW, SIE_REGW,
output logic WriteSIPM, WriteSIEM,
output logic WriteSSTATUSM, output logic WriteSSTATUSM,
output logic IllegalCSRSAccessM output logic IllegalCSRSAccessM
); );
@ -71,8 +69,6 @@ module csrs #(parameter
assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC); assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC);
assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG); assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG);
assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG); assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG);
assign WriteSIEM = CSRSWriteM && (CSRAdrM == SIE);
assign WriteSIPM = CSRSWriteM && (CSRAdrM == SIP);
assign WriteSSCRATCHM = CSRSWriteM && (CSRAdrM == SSCRATCH); assign WriteSSCRATCHM = CSRSWriteM && (CSRAdrM == SSCRATCH);
assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC)); assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC));
assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE)); assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE));
@ -80,9 +76,7 @@ module csrs #(parameter
assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN); assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN);
// CSRs // CSRs
flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, resetExceptionVector, STVEC_REGW); flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, `RESET_VECTOR, STVEC_REGW);
// flopenl #(`XLEN) SIPreg(clk, reset, WriteSIPM, CSRWriteValM, zero, SIP_REGW);
// flopenl #(`XLEN) SIEreg(clk, reset, WriteSIEM, CSRWriteValM, zero, SIE_REGW);
flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW); flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);
flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW); flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW);
@ -119,8 +113,6 @@ module csrs #(parameter
end end
end else begin end else begin
assign WriteSSTATUSM = 0; assign WriteSSTATUSM = 0;
assign WriteSIPM = 0;
assign WriteSIEM = 0;
assign CSRSReadValM = 0; assign CSRSReadValM = 0;
assign SEPC_REGW = 0; assign SEPC_REGW = 0;
assign STVEC_REGW = 0; assign STVEC_REGW = 0;

View File

@ -76,7 +76,8 @@ module datapath (
logic [`XLEN-1:0] PCPlus2or4F; logic [`XLEN-1:0] PCPlus2or4F;
// Decode stage signals // Decode stage signals
logic [31:0] InstrD; 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] RD1D, RD2D;
logic [`XLEN-1:0] ExtImmD; logic [`XLEN-1:0] ExtImmD;
logic [31:0] InstrDecompD; logic [31:0] InstrDecompD;
@ -115,7 +116,7 @@ module datapath (
// Decode stage pipeline register and logic // Decode stage pipeline register and logic
flopenl #(32) InstrDReg(clk, reset, ~StallD, (FlushD ? nop : InstrF), nop, InstrD); flopenl #(32) InstrDReg(clk, reset, ~StallD, (FlushD ? nop : InstrF), nop, InstrD);
flopenrc #(`XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); 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(.*); instrDecompress decomp(.*);
assign OpD = InstrDecompD[6:0]; assign OpD = InstrDecompD[6:0];

View File

@ -43,7 +43,7 @@ module dmem (
logic [`XLEN-1:0] MaskedWriteDataM; logic [`XLEN-1:0] MaskedWriteDataM;
logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM; logic [`XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM, RdUARTM;
logic TimEnM, CLINTEnM, GPIOEnM, UARTEnM; 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 logic UARTIntr;// *** will need to tie INTR to an interrupt handler
// Address decoding // Address decoding
@ -60,6 +60,7 @@ module dmem (
assign MemRWdtimM = MemRWM & {2{TimEnM}}; assign MemRWdtimM = MemRWM & {2{TimEnM}};
assign MemRWclintM = MemRWM & {2{CLINTEnM}}; assign MemRWclintM = MemRWM & {2{CLINTEnM}};
assign MemRWgpioM = MemRWM & {2{GPIOEnM}}; assign MemRWgpioM = MemRWM & {2{GPIOEnM}};
assign MemRWuartM = MemRWM & {2{UARTEnM}};
// tightly integrated memory // tightly integrated memory
dtim dtim(.AdrM(AdrM[18:0]), .*); dtim dtim(.AdrM(AdrM[18:0]), .*);
@ -74,8 +75,9 @@ module dmem (
// *** add cache and interface to external memory & other peripherals // *** add cache and interface to external memory & other peripherals
// merge reads // merge reads
assign ReadDataM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) | ({`XLEN{GPIOEnM}} & RdGPIOM); assign ReadDataM = ({`XLEN{TimEnM}} & RdTimM) | ({`XLEN{CLINTEnM}} & RdCLINTM) |
assign DataAccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM); ({`XLEN{GPIOEnM}} & RdGPIOM) | ({`XLEN{UARTEnM}} & RdUARTM);
assign DataAccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM | UARTEnM);
// byte masking // byte masking
// write each byte based on the byte mask // write each byte based on the byte mask

View File

@ -24,6 +24,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
`include "wally-config.vh" `include "wally-config.vh"
/* verilator lint_off DECLFILENAME */
// ordinary flip-flop // ordinary flip-flop
module flop #(parameter WIDTH = 8) ( module flop #(parameter WIDTH = 8) (
@ -96,3 +97,5 @@ module floprc #(parameter WIDTH = 8) (
if (clear) q <= #1 0; if (clear) q <= #1 0;
else q <= #1 d; else q <= #1 d;
endmodule endmodule
/* verilator lint_on DECLFILENAME */

View File

@ -30,7 +30,7 @@
module gpio ( module gpio (
input logic clk, reset, input logic clk, reset,
input logic [1:0] MemRWgpioM, input logic [1:0] MemRWgpioM,
input logic [7:0] ByteMaskM, // input logic [7:0] ByteMaskM,
input logic [7:0] AdrM, input logic [7:0] AdrM,
input logic [`XLEN-1:0] MaskedWriteDataM, input logic [`XLEN-1:0] MaskedWriteDataM,
output logic [`XLEN-1:0] RdGPIOM, output logic [`XLEN-1:0] RdGPIOM,
@ -78,7 +78,7 @@ module gpio (
INPUT_EN <= 0; INPUT_EN <= 0;
OUTPUT_EN <= 0; OUTPUT_EN <= 0;
// OUTPUT_VAL <= 0; // spec indicates synchronous rset (software control) // 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'h00) INPUT_EN <= MaskedWriteDataM[63:32];
if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= MaskedWriteDataM; if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= MaskedWriteDataM;
if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM[31:0]; // OUT_XOR if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM[31:0]; // OUT_XOR
@ -99,7 +99,7 @@ module gpio (
INPUT_EN <= 0; INPUT_EN <= 0;
OUTPUT_EN <= 0; OUTPUT_EN <= 0;
//OUTPUT_VAL <= 0;// spec indicates synchronous rset (software control) //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'h04) INPUT_EN <= MaskedWriteDataM;
if (entry == 8'h08) OUTPUT_EN <= MaskedWriteDataM; if (entry == 8'h08) OUTPUT_EN <= MaskedWriteDataM;
if (entry == 8'h0C) OUTPUT_VAL <= 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" `include "wally-config.vh"
module imem ( module imem (
input logic [`XLEN-1:0] AdrF, input logic [`XLEN-1:1] AdrF,
output logic [31:0] InstrF, output logic [31:0] InstrF,
output logic InstrAccessFaultF); output logic InstrAccessFaultF);
/* verilator lint_off UNDRIVEN */
logic [`XLEN-1:0] RAM[0:65535]; logic [`XLEN-1:0] RAM[0:65535];
/* verilator lint_on UNDRIVEN */
logic [15:0] adrbits; logic [15:0] adrbits;
logic [`XLEN-1:0] rd, rd2; logic [`XLEN-1:0] rd;
logic [15:0] rd2;
generate generate
if (`XLEN==32) assign adrbits = AdrF[17:2]; 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 // eventually this will need to cause a stall like a cache miss
// when the instruction wraps around a cache line // when the instruction wraps around a cache line
// could be optimized to only stall when the instruction wrapping is 32 bits // 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 generate
if (`XLEN==32) begin if (`XLEN==32) begin
assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd; assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd;

View File

@ -24,6 +24,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
`include "wally-config.vh" `include "wally-config.vh"
/* verilator lint_off DECLFILENAME */
module mux2 #(parameter WIDTH = 8) ( 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); assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0);
endmodule endmodule
/* verilator lint_on DECLFILENAME */

View File

@ -27,7 +27,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module trap ( module trap (
input logic clk, reset, input logic reset,
input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM, input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
input logic BreakpointFaultM, LoadMisalignedFaultM, StoreMisalignedFaultM, input logic BreakpointFaultM, LoadMisalignedFaultM, StoreMisalignedFaultM,
input logic LoadAccessFaultM, StoreAccessFaultM, EcallFaultM, InstrPageFaultM, input logic LoadAccessFaultM, StoreAccessFaultM, EcallFaultM, InstrPageFaultM,

View File

@ -29,7 +29,7 @@
module uart ( module uart (
input logic clk, reset, input logic clk, reset,
input logic [1:0] MemRWgpioM, input logic [1:0] MemRWuartM,
input logic [7:0] ByteMaskM, input logic [7:0] ByteMaskM,
input logic [`XLEN-1:0] AdrM, input logic [`XLEN-1:0] AdrM,
input logic [`XLEN-1:0] MaskedWriteDataM, input logic [`XLEN-1:0] MaskedWriteDataM,
@ -42,11 +42,10 @@ module uart (
logic [2:0] A; logic [2:0] A;
logic MEMRb, MEMWb; logic MEMRb, MEMWb;
logic [7:0] Din, Dout; logic [7:0] Din, Dout;
logic SINint; // for loopback testing
// rename processor interface signals to match PC16550D and provide one-byte interface // rename processor interface signals to match PC16550D and provide one-byte interface
assign MEMRb = ~MemRWgpioM[1]; assign MEMRb = ~MemRWuartM[1];
assign MEMWb = ~MemRWgpioM[0]; assign MEMWb = ~MemRWuartM[0];
assign A = AdrM[2:0]; assign A = AdrM[2:0];
generate generate

View File

@ -30,6 +30,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
`include "wally-config.vh" `include "wally-config.vh"
/* verilator lint_off UNOPTFLAT */
module uartPC16550D( module uartPC16550D(
// Processor Interface // Processor Interface
@ -52,7 +53,7 @@ module uartPC16550D(
// Registers // Registers
logic [10:0] RBR; 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 [3:0] IER, MSR;
logic [4:0] MCR; logic [4:0] MCR;
@ -124,7 +125,6 @@ module uartPC16550D(
always_ff @(posedge clk, posedge reset) always_ff @(posedge clk, posedge reset)
if (reset) begin // Table 3 Reset Configuration if (reset) begin // Table 3 Reset Configuration
IER <= 4'b0; IER <= 4'b0;
IIR <= 8'b1;
FCR <= 8'b0; FCR <= 8'b0;
LCR <= 8'b0; LCR <= 8'b0;
MCR <= 5'b0; MCR <= 5'b0;
@ -157,20 +157,20 @@ module uartPC16550D(
/* verilator lint_on CASEINCOMPLETE */ /* verilator lint_on CASEINCOMPLETE */
end end
// Line Status Register (8.6.3) // Line Status Register (8.6.3)
LSR[0] = rxdataready; // Data ready LSR[0] <= rxdataready; // Data ready
if (RXBR[10]) LSR[1] = 1; // overrun error if (RXBR[10]) LSR[1] <= 1; // overrun error
if (RXBR[9]) LSR[2] = 1; // parity error if (RXBR[9]) LSR[2] <= 1; // parity error
if (RXBR[8]) LSR[3] = 1; // framing error if (RXBR[8]) LSR[3] <= 1; // framing error
if (rxbreak) LSR[4] = 1; // break indicator if (rxbreak) LSR[4] <= 1; // break indicator
LSR[5] = txhremptyintr ; // THRE LSR[5] <= txhremptyintr ; // THRE
LSR[6] = ~txsrfull & txhremptyintr; // TEMT LSR[6] <= ~txsrfull & txhremptyintr; // TEMT
if (rxfifohaserr) LSR[7] = 1; // any bits in FIFO have error if (rxfifohaserr) LSR[7] <= 1; // any bits in FIFO have error
// Modem Status Register (8.6.8) // Modem Status Register (8.6.8)
MSR[0] |= CTSb2 ^ CTSbsync; // Delta Clear to Send MSR[0] <= MSR[0] | CTSb2 ^ CTSbsync; // Delta Clear to Send
MSR[1] |= DSRb2 ^ DSRbsync; // Delta Data Set Ready MSR[1] <= MSR[1] | DSRb2 ^ DSRbsync; // Delta Data Set Ready
MSR[2] |= (~RIb2 & RIbsync); // Trailing Edge of Ring Indicator MSR[2] <= MSR[2] | (~RIb2 & RIbsync); // Trailing Edge of Ring Indicator
MSR[3] |= DCDb2 ^ DCDbsync; // Delta Data Carrier Detect MSR[3] <= MSR[3] | DCDb2 ^ DCDbsync; // Delta Data Carrier Detect
end end
always_comb always_comb
@ -213,12 +213,12 @@ module uartPC16550D(
always_ff @(posedge clk, posedge reset) always_ff @(posedge clk, posedge reset)
if (reset) begin if (reset) begin
rxoversampledcnt <= 0; rxoversampledcnt <= 0;
rxstate = UART_IDLE; rxstate <= UART_IDLE;
rxbitsreceived <= 0; rxbitsreceived <= 0;
rxtimeoutcnt <= 0; rxtimeoutcnt <= 0;
end else begin end else begin
if (rxstate == UART_IDLE & ~SINsync) begin // got start bit if (rxstate == UART_IDLE & ~SINsync) begin // got start bit
rxstate = UART_ACTIVE; rxstate <= UART_ACTIVE;
rxoversampledcnt <= 0; rxoversampledcnt <= 0;
rxbitsreceived <= 0; rxbitsreceived <= 0;
rxtimeoutcnt <= 0; // reset timeout when new character is arriving rxtimeoutcnt <= 0; // reset timeout when new character is arriving
@ -268,16 +268,16 @@ module uartPC16550D(
rxfifohead <= 0; rxfifotail <= 0; rxdataready <= 0; RXBR <= 0; rxfifohead <= 0; rxfifotail <= 0; rxdataready <= 0; RXBR <= 0;
end else begin end else begin
if (rxstate == UART_DONE) 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 if (fifoenabled) begin
rxfifo[rxfifohead] <= RXBR; rxfifo[rxfifohead] <= {rxoverrunerr, rxparityerr, rxframingerr, rxdata};
rxfifohead <= rxfifohead + 1; rxfifohead <= rxfifohead + 1;
end end
rxdataready <= 1; rxdataready <= 1;
end else if (~MEMRb && A == 3'b000 && ~DLAB) begin // reading RBR updates ready / pops fifo end else if (~MEMRb && A == 3'b000 && ~DLAB) begin // reading RBR updates ready / pops fifo
if (fifoenabled) begin if (fifoenabled) begin
rxfifotail = rxfifotail + 1; rxfifotail <= rxfifotail + 1;
if (rxfifohead == rxfifotail) rxdataready <= 0; if (rxfifohead == rxfifotail +1) rxdataready <= 0;
end else rxdataready <= 0; end else rxdataready <= 0;
end else if (~MEMWb && A == 3'b010) // writes to FIFO Control Register 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 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 assign rxfifotimeout = 0; // disabled pending fix
// detect any errors in rx fifo // detect any errors in rx fifo
// although rxfullbit looks like a combinational loop, in one bit rxfifotail == i and breaks the loop
generate generate
genvar i; genvar i;
for (i=0; i<16; i++) begin for (i=0; i<16; i++) begin
@ -400,7 +401,7 @@ module uartPC16550D(
txsrfull <= 1; txsrfull <= 1;
end end
else if (txstate == UART_DONE) txsrfull <= 0; // done transmitting shift register 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 (!MEMWb && A == 3'b010) // writes to FIFO control register
if (Din[2] | ~Din[0]) begin // tx FIFO reste or FIFO disable clears FIFO contents if (Din[2] | ~Din[0]) begin // tx FIFO reste or FIFO disable clears FIFO contents
txfifohead <= 0; txfifotail <= 0; txfifohead <= 0; txfifotail <= 0;
@ -423,7 +424,7 @@ module uartPC16550D(
else TXRDYb = ~txhremptyintr; else TXRDYb = ~txhremptyintr;
// Transmitter pin // 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 assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break
/////////////////////////////////////////// ///////////////////////////////////////////
@ -474,3 +475,5 @@ module uartPC16550D(
endcase endcase
endmodule endmodule
/* verilator lint_on UNOPTFLAT */

View File

@ -72,6 +72,6 @@ module wallypipelined (
// instantiate processor and memories // instantiate processor and memories
wallypipelinedhart hart(.ALUResultM(DataAdrM), .*); wallypipelinedhart hart(.ALUResultM(DataAdrM), .*);
imem imem(.AdrF(PCF), .*); imem imem(.AdrF(PCF[`XLEN-1:1]), .*);
dmem dmem(.AdrM(DataAdrM), .*); dmem dmem(.AdrM(DataAdrM), .*);
endmodule endmodule

View File

@ -24,6 +24,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
`include "wally-config.vh" `include "wally-config.vh"
/* verilator lint_on UNUSED */
module wallypipelinedhart ( module wallypipelinedhart (
input logic clk, reset, input logic clk, reset,
@ -37,45 +38,56 @@ module wallypipelinedhart (
input logic InstrAccessFaultF, input logic InstrAccessFaultF,
input logic DataAccessFaultM); input logic DataAccessFaultM);
logic [2:0] Funct3D; /*
logic Funct7b5D; // logic [2:0] Funct3D;
logic [6:0] OpD; // logic Funct7b5D;
logic [2:0] ImmSrcD; // logic [6:0] OpD;
logic IllegalCompInstrD; // logic [2:0] ImmSrcD;
logic [2:0] FlagsE; // logic IllegalCompInstrD;
logic PCSrcE; // logic [2:0] FlagsE;
logic [4:0] ALUControlE; // logic [4:0] ALUControlE;
logic ALUSrcAE, ALUSrcBE; // logic ALUSrcAE, ALUSrcBE;
logic MemReadE; // logic CSRWriteM;
logic RegWriteM; // logic PrivilegedM;
logic CSRWriteM; // logic IllegalInstrFaultM;
logic PrivilegedM;
logic IllegalInstrFaultM;
logic InstrAccessFaultM; logic InstrAccessFaultM;
logic [2:0] Funct3M; logic [2:0] Funct3M;
logic [1:0] ResultSrcW; logic [1:0] ResultSrcW;
logic RegWriteW; logic InstrValidW;
logic InstrValidW, LoadStallD;
logic CSRWritePendingDEM;
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
*/
logic [1:0] ForwardAE, ForwardBE; logic [1:0] ForwardAE, ForwardBE;
logic StallF, StallD, FlushD, FlushE, FlushM, FlushW; logic StallF, StallD, FlushD, FlushE, FlushM, FlushW;
logic RetM, TrapM; 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 [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW;
logic TargetSrcE; // logic TargetSrcE;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
logic [2:0] FRM_REGW; logic [2:0] FRM_REGW;
logic FloatRegWriteW; logic FloatRegWriteW;
controller c(.*); ieu ieu(.*); // inteber execution unit: integer register file, datapath and controller
datapath dp(.*); /* ifu ifu(.*); // instruction fetch unit: PC, branch prediction, instruction cache
hazard hz(.*); 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 // add FPU here, with SetFflagsM, FRM_REGW
// presently stub out SetFlagsM and FloatRegWriteW // presently stub out SetFlagsM and FloatRegWriteW
assign SetFflagsM = 0; assign SetFflagsM = 0;
assign FloatRegWriteW = 0; //assign FloatRegWriteW = 0;
endmodule endmodule

View File

@ -247,9 +247,9 @@ string tests32i[] = {
); );
// Track names of instructions // Track names of instructions
instrTrackerTB it(clk, reset, dut.hart.dp.FlushE, instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
dut.hart.dp.InstrDecompD, dut.hart.dp.InstrE, dut.hart.ieu.dp.InstrDecompD, dut.hart.ieu.dp.InstrE,
dut.hart.dp.InstrM, InstrW, dut.hart.ieu.dp.InstrM, InstrW,
InstrDName, InstrEName, InstrMName, InstrWName); InstrDName, InstrEName, InstrMName, InstrWName);
// initialize test // initialize test
@ -281,8 +281,8 @@ string tests32i[] = {
// check results // check results
always @(negedge clk) always @(negedge clk)
begin begin
if (dut.hart.dp.priv.EcallFaultM && if (dut.hart.ieu.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 (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"); $display("Code ended with ecall with gp = 1");
#60; // give time for instructions in pipeline to finish #60; // give time for instructions in pipeline to finish
// clear signature to prevent contamination from previous tests // clear signature to prevent contamination from previous tests