mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Changed to . notation for instantiation, cleaned up dmem
This commit is contained in:
parent
dacc392c95
commit
f9ad54f18c
@ -1 +0,0 @@
|
||||
harris@Tera.Eng.HMC.Edu.6921:1604012407
|
@ -28,22 +28,20 @@
|
||||
|
||||
module clint #(parameter XLEN=32) (
|
||||
input logic clk, reset,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [7:0] ByteMaskM,
|
||||
input logic [1:0] MemRWclintM,
|
||||
input logic [15:0] AdrM,
|
||||
input logic [XLEN-1:0] WdM,
|
||||
output logic [XLEN-1:0] RdM,
|
||||
input logic [XLEN-1:0] MaskedWriteDataM,
|
||||
output logic [XLEN-1:0] RdCLINTM,
|
||||
output logic TimerIntM, SwIntM);
|
||||
|
||||
logic [63:0] MTIMECMP, MTIME;
|
||||
logic MSIP;
|
||||
|
||||
logic [XLEN-1:0] read, write;
|
||||
logic [15:0] entry;
|
||||
logic memread, memwrite;
|
||||
|
||||
assign memread = MemRWM[1];
|
||||
assign memwrite = MemRWM[0];
|
||||
assign memread = MemRWclintM[1];
|
||||
assign memwrite = MemRWclintM[0];
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
@ -59,20 +57,11 @@ module clint #(parameter XLEN=32) (
|
||||
if (XLEN==64) begin
|
||||
always_comb begin
|
||||
case(entry)
|
||||
16'h0000: read = {63'b0, MSIP};
|
||||
16'h4000: read = MTIMECMP;
|
||||
16'hBFF8: read = MTIME;
|
||||
default: read = 0;
|
||||
16'h0000: RdCLINTM = {63'b0, MSIP};
|
||||
16'h4000: RdCLINTM = MTIMECMP;
|
||||
16'hBFF8: RdCLINTM = MTIME;
|
||||
default: RdCLINTM = 0;
|
||||
endcase
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
if (ByteMaskM[4]) write[39:32] = WdM[39:32];
|
||||
if (ByteMaskM[5]) write[47:40] = WdM[47:40];
|
||||
if (ByteMaskM[6]) write[55:48] = WdM[55:48];
|
||||
if (ByteMaskM[7]) write[63:56] = WdM[63:56];
|
||||
end
|
||||
always_ff @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
@ -80,27 +69,22 @@ module clint #(parameter XLEN=32) (
|
||||
MTIME <= 0;
|
||||
// MTIMECMP is not reset
|
||||
end else begin
|
||||
if (entry == 16'h0000) MSIP <= write[0];
|
||||
if (entry == 16'h4000) MTIMECMP <= write;
|
||||
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
|
||||
if (entry == 16'hBFF8) MTIME <= write;
|
||||
if (entry == 16'hBFF8) MTIME <= MaskedWriteDataM;
|
||||
else MTIME <= MTIME + 1;
|
||||
end
|
||||
end else begin // 32-bit
|
||||
always_comb begin
|
||||
case(entry)
|
||||
16'h0000: read = {31'b0, MSIP};
|
||||
16'h4000: read = MTIMECMP[31:0];
|
||||
16'h4004: read = MTIMECMP[63:32];
|
||||
16'hBFF8: read = MTIME[31:0];
|
||||
16'hBFFC: read = MTIME[63:32];
|
||||
default: read = 0;
|
||||
16'h0000: RdCLINTM = {31'b0, MSIP};
|
||||
16'h4000: RdCLINTM = MTIMECMP[31:0];
|
||||
16'h4004: RdCLINTM = MTIMECMP[63:32];
|
||||
16'hBFF8: RdCLINTM = MTIME[31:0];
|
||||
16'hBFFC: RdCLINTM = MTIME[63:32];
|
||||
default: RdCLINTM = 0;
|
||||
endcase
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
end
|
||||
always_ff @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
@ -108,20 +92,17 @@ module clint #(parameter XLEN=32) (
|
||||
MTIME <= 0;
|
||||
// MTIMECMP is not reset
|
||||
end else begin
|
||||
if (entry == 16'h0000) MSIP <= write[0];
|
||||
if (entry == 16'h4000) MTIMECMP[31:0] <= write;
|
||||
if (entry == 16'h4004) MTIMECMP[63:32] <= write;
|
||||
if (entry == 16'h0000) MSIP <= MaskedWriteDataM[0];
|
||||
if (entry == 16'h4000) MTIMECMP[31:0] <= MaskedWriteDataM;
|
||||
if (entry == 16'h4004) MTIMECMP[63:32] <= MaskedWriteDataM;
|
||||
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
|
||||
if (entry == 16'hBFF8) MTIME[31:0] <= write;
|
||||
else if (entry == 16'hBFFC) MTIME[63:32]<= write;
|
||||
if (entry == 16'hBFF8) MTIME[31:0] <= MaskedWriteDataM;
|
||||
else if (entry == 16'hBFFC) MTIME[63:32]<= MaskedWriteDataM;
|
||||
else MTIME <= MTIME + 1;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// read
|
||||
assign RdM = memread ? read: 0;
|
||||
|
||||
// Software interrupt when MSIP is set
|
||||
assign SwIntM = MSIP;
|
||||
// Timer interrupt when MTIME >= MTIMECMP
|
||||
|
@ -75,7 +75,7 @@ module controller(
|
||||
logic InstrValidE, InstrValidM;
|
||||
logic PrivilegedD, PrivilegedE;
|
||||
logic InstrAccessFaultD, InstrAccessFaultE;
|
||||
logic IllegalInstrFaultD, IllegalInstrMergedD, IllegalInstrFaultE;
|
||||
logic IllegalInstrFaultD, IllegalInstrFaultE;
|
||||
logic [18:0] ControlsD;
|
||||
logic PreIllegalInstrFaultD;
|
||||
logic aluc3D;
|
||||
|
@ -95,6 +95,16 @@ module csr #(parameter XLEN = 64, MISA = 0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
assign CSRSWriteM = CSRWriteM && (PrivilegeModeW[0]);
|
||||
assign CSRUWriteM = CSRWriteM;
|
||||
|
||||
csri #(XLEN, MISA) csri(.*);
|
||||
csrsr #(XLEN, MISA) csrsr(.*);
|
||||
csrc #(XLEN, ZCOUNTERS) counters(.*);
|
||||
csrm #(XLEN, MISA) csrm(.*); // Machine Mode CSRs
|
||||
csrs #(XLEN, MISA) csrs(.*);
|
||||
csrn #(XLEN, MISA) csrn(.CSRNWriteM(CSRUWriteM), .*); // User Mode Exception Registers
|
||||
csru #(XLEN, MISA) csru(.*); // Floating Point Flags are part of User MOde
|
||||
|
||||
/*
|
||||
|
||||
csri #(XLEN, MISA) csri(
|
||||
clk, reset, CSRMWriteM, CSRSWriteM, CSRAdrM, ExtIntM, TimerIntM, SwIntM,
|
||||
MIDELEG_REGW, MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, CSRWriteValM);
|
||||
@ -146,6 +156,7 @@ module csr #(parameter XLEN = 64, MISA = 0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
clk, reset, CSRUWriteM, CSRAdrM,
|
||||
CSRWriteValM, CSRUReadValM, SetFflagsM, FRM_REGW, IllegalCSRUAccessM
|
||||
);
|
||||
*/
|
||||
|
||||
// merge CSR Reads
|
||||
assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM | CSRNReadValM;
|
||||
|
@ -36,22 +36,20 @@ module csrn #(parameter XLEN=64, MISA=0,
|
||||
UTVAL = 12'h043,
|
||||
UIP = 12'h044) (
|
||||
input logic clk, reset,
|
||||
input logic CSRUWriteM, UTrapM,
|
||||
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] CSRUReadValM, UEPC_REGW, UTVEC_REGW,
|
||||
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 IllegalCSRUAccessM
|
||||
output logic IllegalCSRNAccessM
|
||||
);
|
||||
|
||||
logic [XLEN-1:0] zero = 0;
|
||||
|
||||
// *** add floating point CSRs here. Maybe move stuff below to csrn to support reading
|
||||
|
||||
// User mode CSRs below only needed when user mode traps are supported
|
||||
generate
|
||||
if (`N_SUPPORTED) begin
|
||||
@ -62,13 +60,13 @@ module csrn #(parameter XLEN=64, MISA=0,
|
||||
logic [XLEN-1:0] USCRATCH_REGW, UCAUSE_REGW, UTVAL_REGW;
|
||||
|
||||
// Write enables
|
||||
assign WriteUSTATUSM = CSRUWriteM && (CSRAdrM == USTATUS);
|
||||
assign WriteUTVECM = CSRUWriteM && (CSRAdrM == UTVEC);
|
||||
assign WriteUIPM = CSRUWriteM && (CSRAdrM == UIP);
|
||||
assign WriteUIEM = CSRUWriteM && (CSRAdrM == UIE);
|
||||
assign WriteUEPCM = UTrapM | (CSRUWriteM && (CSRAdrM == UEPC));
|
||||
assign WriteUCAUSEM = UTrapM | (CSRUWriteM && (CSRAdrM == UCAUSE));
|
||||
assign WriteUTVALM = UTrapM | (CSRUWriteM && (CSRAdrM == UTVAL));
|
||||
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);
|
||||
@ -81,28 +79,30 @@ module csrn #(parameter XLEN=64, MISA=0,
|
||||
|
||||
// CSR Reads
|
||||
always_comb begin
|
||||
IllegalCSRUAccessM = 0;
|
||||
IllegalCSRNAccessM = 0;
|
||||
case (CSRAdrM)
|
||||
USTATUS: CSRUReadValM = USTATUS_REGW;
|
||||
UTVEC: CSRUReadValM = UTVEC_REGW;
|
||||
UIP: CSRUReadValM = {{(XLEN-12){1'b0}}, UIP_REGW};
|
||||
UIE: CSRUReadValM = {{(XLEN-12){1'b0}}, UIE_REGW};
|
||||
USCRATCH: CSRUReadValM = USCRATCH_REGW;
|
||||
UEPC: CSRUReadValM = UEPC_REGW;
|
||||
UCAUSE: CSRUReadValM = UCAUSE_REGW;
|
||||
UTVAL: CSRUReadValM = UTVAL_REGW;
|
||||
USTATUS: CSRNReadValM = USTATUS_REGW;
|
||||
UTVEC: CSRNReadValM = UTVEC_REGW;
|
||||
UIP: CSRNReadValM = {{(XLEN-12){1'b0}}, UIP_REGW};
|
||||
UIE: CSRNReadValM = {{(XLEN-12){1'b0}}, UIE_REGW};
|
||||
USCRATCH: CSRNReadValM = USCRATCH_REGW;
|
||||
UEPC: CSRNReadValM = UEPC_REGW;
|
||||
UCAUSE: CSRNReadValM = UCAUSE_REGW;
|
||||
UTVAL: CSRNReadValM = UTVAL_REGW;
|
||||
default: begin
|
||||
CSRUReadValM = 0;
|
||||
IllegalCSRUAccessM = 1;
|
||||
CSRNReadValM = 0;
|
||||
IllegalCSRNAccessM = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin // if not supported
|
||||
assign WriteUSTATUSM = 0;
|
||||
assign CSRUReadValM = 0;
|
||||
assign WriteUIPM = 0;
|
||||
assign WriteUIEM = 0;
|
||||
assign CSRNReadValM = 0;
|
||||
assign UEPC_REGW = 0;
|
||||
assign UTVEC_REGW = 0;
|
||||
assign IllegalCSRUAccessM = 1;
|
||||
assign IllegalCSRNAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
@ -71,6 +71,8 @@ module csrs #(parameter XLEN=64, MISA=0,
|
||||
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));
|
||||
@ -117,9 +119,14 @@ module csrs #(parameter XLEN=64, MISA=0,
|
||||
end
|
||||
end else begin
|
||||
assign WriteSSTATUSM = 0;
|
||||
assign WriteSIPM = 0;
|
||||
assign WriteSIEM = 0;
|
||||
assign CSRSReadValM = 0;
|
||||
assign SEPC_REGW = 0;
|
||||
assign STVEC_REGW = 0;
|
||||
assign SEDELEG_REGW = 0;
|
||||
assign SIDELEG_REGW = 0;
|
||||
assign SCOUNTEREN_REGW = 0;
|
||||
assign IllegalCSRSAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
|
@ -34,11 +34,11 @@ module csrsr #(parameter XLEN=64, MISA = 0)(
|
||||
input logic [XLEN-1:0] CSRWriteValM,
|
||||
output logic [XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW,
|
||||
output logic [1:0] STATUS_MPP,
|
||||
output logic STATUS_SPP, STAUTS_TSR,
|
||||
output logic STATUS_SPP, STATUS_TSR,
|
||||
output logic STATUS_MIE, STATUS_SIE
|
||||
);
|
||||
|
||||
logic STATUS_SD, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_SUM_INT, STATUS_MPRV, STATUS_MPRV_INT;
|
||||
logic STATUS_SD, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_SUM_INT, STATUS_MPRV, STATUS_MPRV_INT;
|
||||
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT;
|
||||
logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE;
|
||||
|
||||
|
@ -32,9 +32,9 @@ module datapath #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
output logic [XLEN-1:0] PCF,
|
||||
input logic [31:0] InstrF,
|
||||
// Decode stage signals
|
||||
output logic [6:0] opD,
|
||||
output logic [2:0] funct3D,
|
||||
output logic funct7b5D,
|
||||
output logic [6:0] OpD,
|
||||
output logic [2:0] Funct3D,
|
||||
output logic Funct7b5D,
|
||||
input logic StallD, FlushD,
|
||||
input logic [2:0] ImmSrcD,
|
||||
input logic LoadStallD, // for performance counter
|
||||
@ -48,14 +48,14 @@ module datapath #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
input logic TargetSrcE,
|
||||
output logic [2:0] FlagsE,
|
||||
// Memory stage signals
|
||||
input logic FlushM,
|
||||
input logic FlushM,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic CSRWriteM, PrivilegedM,
|
||||
input logic InstrAccessFaultM, IllegalInstrFaultM,
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
output logic InstrMisalignedFaultM,
|
||||
input logic [2:0] Funct3M,
|
||||
output logic [XLEN-1:0] WriteDataExtM, ALUResultM,
|
||||
output logic [XLEN-1:0] WriteDataM, ALUResultM,
|
||||
input logic [XLEN-1:0] ReadDataM,
|
||||
output logic [7:0] ByteMaskM,
|
||||
output logic RetM, TrapM,
|
||||
@ -88,13 +88,13 @@ module datapath #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
logic [XLEN-1:0] PreSrcAE, SrcAE, SrcBE;
|
||||
logic [XLEN-1:0] ALUResultE;
|
||||
logic [XLEN-1:0] WriteDataE;
|
||||
logic [XLEN-1:0] TargetBaseE, PCTargetE;
|
||||
logic [XLEN-1:0] TargetBaseE;
|
||||
// Memory stage signals
|
||||
logic [31:0] InstrM;
|
||||
logic [XLEN-1:0] PCM;
|
||||
logic [XLEN-1:0] SrcAM;
|
||||
logic [XLEN-1:0] ReadDataExtM;
|
||||
logic [XLEN-1:0] WriteDataM;
|
||||
logic [XLEN-1:0] WriteDataFullM;
|
||||
logic [XLEN-1:0] CSRReadValM;
|
||||
logic [XLEN-1:0] PrivilegedNextPCM;
|
||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||
@ -110,25 +110,23 @@ module datapath #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
|
||||
// Fetch stage pipeline register and logic; also Ex stage for branches
|
||||
pclogic #(XLEN, MISA) pclogic(clk, reset, StallF, PCSrcE,
|
||||
InstrF, ExtImmE, TargetBaseE, RetM, TrapM, PrivilegedNextPCM, PCF, PCPlus2or4F,
|
||||
InstrMisalignedFaultM, InstrMisalignedAdrM);
|
||||
pclogic #(XLEN, MISA) pclogic(.*);
|
||||
|
||||
// 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);
|
||||
|
||||
instrDecompress #(XLEN, MISA) decomp(InstrD, InstrDecompD, IllegalCompInstrD);
|
||||
assign opD = InstrDecompD[6:0];
|
||||
assign funct3D = InstrDecompD[14:12];
|
||||
assign funct7b5D = InstrDecompD[30];
|
||||
instrDecompress #(XLEN, MISA) decomp(.*);
|
||||
assign OpD = InstrDecompD[6:0];
|
||||
assign Funct3D = InstrDecompD[14:12];
|
||||
assign Funct7b5D = InstrDecompD[30];
|
||||
assign Rs1D = InstrDecompD[19:15];
|
||||
assign Rs2D = InstrDecompD[24:20];
|
||||
assign RdD = InstrDecompD[11:7];
|
||||
|
||||
regfile #(XLEN) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, RD1D, RD2D);
|
||||
extend #(XLEN) ext(InstrDecompD[31:7], ImmSrcD, ExtImmD);
|
||||
extend #(XLEN) ext(.InstrDecompD(InstrDecompD[31:7]), .*);
|
||||
|
||||
// Execute stage pipeline register and logic
|
||||
floprc #(XLEN) RD1EReg(clk, reset, FlushE, RD1D, RD1E);
|
||||
@ -150,25 +148,15 @@ module datapath #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
// Memory stage pipeline register
|
||||
floprc #(XLEN) SrcAMReg(clk, reset, FlushM, SrcAE, SrcAM);
|
||||
floprc #(XLEN) ALUResultMReg(clk, reset, FlushM, ALUResultE, ALUResultM);
|
||||
floprc #(XLEN) WriteDataMReg(clk, reset, FlushM, WriteDataE, WriteDataM);
|
||||
floprc #(XLEN) WriteDataMReg(clk, reset, FlushM, WriteDataE, WriteDataFullM);
|
||||
floprc #(XLEN) PCMReg(clk, reset, FlushM, PCE, PCM);
|
||||
flopr #(32) InstrMReg(clk, reset, FlushM ? nop : InstrE, InstrM);
|
||||
floprc #(5) RdMEg(clk, reset, FlushM, RdE, RdM);
|
||||
|
||||
memdp #(XLEN) memdp(
|
||||
MemRWM, ReadDataM, ALUResultM, Funct3M, ReadDataExtM, WriteDataM, WriteDataExtM, ByteMaskM,
|
||||
DataAccessFaultM, LoadMisalignedFaultM, LoadAccessFaultM, StoreMisalignedFaultM, StoreAccessFaultM);
|
||||
memdp #(XLEN) memdp(.AdrM(ALUResultM), .*);
|
||||
|
||||
// Priveleged block operates in M and W stages, handling CSRs and exceptions
|
||||
privileged #(XLEN, MISA, ZCSR, ZCOUNTERS) priv(
|
||||
clk, reset, CSRWriteM, SrcAM, InstrM, PCM,
|
||||
CSRReadValM, PrivilegedNextPCM, RetM, TrapM,
|
||||
InstrValidW, FloatRegWriteW, LoadStallD, PrivilegedM,
|
||||
InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
|
||||
LoadMisalignedFaultM, LoadAccessFaultM, StoreMisalignedFaultM, StoreAccessFaultM,
|
||||
TimerIntM, ExtIntM, SwIntM,
|
||||
InstrMisalignedAdrM, ALUResultM,
|
||||
SetFflagsM, FRM_REGW);
|
||||
privileged #(XLEN, MISA, ZCSR, ZCOUNTERS) priv(.IllegalInstrFaultInM(IllegalInstrFaultM), .*);
|
||||
|
||||
// Writeback stage pipeline register and logic
|
||||
floprc #(XLEN) ALUResultWReg(clk, reset, FlushW, ALUResultM, ALUResultW);
|
||||
|
@ -31,36 +31,64 @@ module dmem #(parameter XLEN=32) (
|
||||
input logic clk, reset,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [7:0] ByteMaskM,
|
||||
input logic [XLEN-1:0] AdrM, WdM,
|
||||
output logic [XLEN-1:0] RdM,
|
||||
output logic AccessFaultM,
|
||||
input logic [XLEN-1:0] AdrM, WriteDataM,
|
||||
output logic [XLEN-1:0] ReadDataM,
|
||||
output logic DataAccessFaultM,
|
||||
output logic TimerIntM, SwIntM,
|
||||
input logic [31:0] GPIOPinsIn,
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn);
|
||||
input logic [31:0] GPIOPinsIn,
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn);
|
||||
|
||||
logic [XLEN-1:0] MaskedWriteDataM;
|
||||
logic [XLEN-1:0] RdTimM, RdCLINTM, RdGPIOM;
|
||||
logic TimEnM, CLINTEnM, GPIOEnM;
|
||||
logic [1:0] MemRWdtimM, MemRWclintM, MemRWgpioM;
|
||||
|
||||
// Address decoding
|
||||
// *** need to check top bits
|
||||
assign TimEnM = AdrM[31] & ~(|AdrM[30:19]); // 0x80000000 - 0x8007FFFF *** check top bits too
|
||||
assign TimEnM = ~(|AdrM[XLEN-1:32]) & AdrM[31] & ~(|AdrM[30:19]); // 0x80000000 - 0x8007FFFF *** check top bits too
|
||||
assign CLINTEnM = ~(|AdrM[XLEN-1:26]) & AdrM[25] & ~(|AdrM[24:16]); // 0x02000000-0x0200FFFF
|
||||
assign GPIOEnM = (AdrM[31:8] == 24'h10012); // 0x10012000-0x100120FF
|
||||
|
||||
assign MemRWdtimM = MemRWM & {2{TimEnM}};
|
||||
assign MemRWclintM = MemRWM & {2{CLINTEnM}};
|
||||
assign MemRWgpioM = MemRWM & {2{GPIOEnM}};
|
||||
|
||||
// tightly integrated memory
|
||||
dtim #(XLEN) dtim(clk, MemRWM & {2{TimEnM}}, ByteMaskM, AdrM[18:0], WdM, RdTimM);
|
||||
dtim #(XLEN) dtim(.AdrM(AdrM[18:0]), .*);
|
||||
|
||||
// memory-mapped I/O peripherals
|
||||
clint #(XLEN) clint(clk, reset, MemRWM & {2{CLINTEnM}}, ByteMaskM, AdrM[15:0], WdM, RdCLINTM,
|
||||
TimerIntM, SwIntM);
|
||||
gpio #(XLEN) gpio(clk, reset, MemRWM & {2{GPIOEnM}}, ByteMaskM, AdrM[7:0], WdM, RdGPIOM,
|
||||
GPIOPinsIn, GPIOPinsOut, GPIOPinsEn);
|
||||
clint #(XLEN) clint(.AdrM(AdrM[15:0]), .*);
|
||||
gpio #(XLEN) gpio(.AdrM(AdrM[7:0]), .*);
|
||||
|
||||
// *** add cache and interface to external memory & other peripherals
|
||||
|
||||
// merge reads
|
||||
assign RdM = RdTimM | RdCLINTM | RdGPIOM;
|
||||
assign AccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM);
|
||||
assign ReadDataM = ({XLEN{TimEnM}} & RdTimM) | ({XLEN{CLINTEnM}} & RdCLINTM) | ({XLEN{GPIOEnM}} & RdGPIOM);
|
||||
assign DataAccessFaultM = ~(|TimEnM | CLINTEnM | GPIOEnM);
|
||||
|
||||
// byte masking
|
||||
// write each byte based on the byte mask
|
||||
generate
|
||||
if (XLEN==64) begin
|
||||
always_comb begin
|
||||
MaskedWriteDataM=ReadDataM;
|
||||
if (ByteMaskM[0]) MaskedWriteDataM[7:0] = WriteDataM[7:0];
|
||||
if (ByteMaskM[1]) MaskedWriteDataM[15:8] = WriteDataM[15:8];
|
||||
if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataM[23:16];
|
||||
if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataM[31:24];
|
||||
if (ByteMaskM[4]) MaskedWriteDataM[39:32] = WriteDataM[39:32];
|
||||
if (ByteMaskM[5]) MaskedWriteDataM[47:40] = WriteDataM[47:40];
|
||||
if (ByteMaskM[6]) MaskedWriteDataM[55:48] = WriteDataM[55:48];
|
||||
if (ByteMaskM[7]) MaskedWriteDataM[63:56] = WriteDataM[63:56];
|
||||
end
|
||||
end else begin // 32-bit
|
||||
always_comb begin
|
||||
if (ByteMaskM[0]) MaskedWriteDataM[7:0] = WriteDataM[7:0];
|
||||
if (ByteMaskM[1]) MaskedWriteDataM[15:8] = WriteDataM[15:8];
|
||||
if (ByteMaskM[2]) MaskedWriteDataM[23:16] = WriteDataM[23:16];
|
||||
if (ByteMaskM[3]) MaskedWriteDataM[31:24] = WriteDataM[31:24];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -27,20 +27,19 @@
|
||||
|
||||
module dtim #(parameter XLEN=32) (
|
||||
input logic clk,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [1:0] MemRWdtimM,
|
||||
input logic [7:0] ByteMaskM,
|
||||
input logic [18:0] AdrM,
|
||||
// input logic [XLEN-1:0] AdrM,
|
||||
input logic [XLEN-1:0] WdM,
|
||||
output logic [XLEN-1:0] RdM);
|
||||
input logic [XLEN-1:0] WriteDataM,
|
||||
output logic [XLEN-1:0] RdTimM);
|
||||
|
||||
logic [XLEN-1:0] RAM[0:65535];
|
||||
logic [XLEN-1:0] read, write;
|
||||
logic [XLEN-1:0] write;
|
||||
logic [15:0] entry;
|
||||
logic memread, memwrite;
|
||||
|
||||
assign memread = MemRWM[1];
|
||||
assign memwrite = MemRWM[0];
|
||||
assign memread = MemRWdtimM[1];
|
||||
assign memwrite = MemRWdtimM[0];
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
@ -49,33 +48,35 @@ module dtim #(parameter XLEN=32) (
|
||||
else
|
||||
assign #2 entry = AdrM[17:2];
|
||||
endgenerate
|
||||
assign read = RAM[entry];
|
||||
assign RdM = memread ? read: 0;
|
||||
assign RdTimM = RAM[entry];
|
||||
|
||||
// write each byte based on the byte mask
|
||||
// UInstantiate a byte-writable memory here if possible
|
||||
// and drop tihs masking logic. Otherwise, use the masking
|
||||
// from dmem
|
||||
generate
|
||||
|
||||
if (XLEN==64) begin
|
||||
always_comb begin
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
if (ByteMaskM[4]) write[39:32] = WdM[39:32];
|
||||
if (ByteMaskM[5]) write[47:40] = WdM[47:40];
|
||||
if (ByteMaskM[6]) write[55:48] = WdM[55:48];
|
||||
if (ByteMaskM[7]) write[63:56] = WdM[63:56];
|
||||
write=RdTimM;
|
||||
if (ByteMaskM[0]) write[7:0] = WriteDataM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WriteDataM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WriteDataM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WriteDataM[31:24];
|
||||
if (ByteMaskM[4]) write[39:32] = WriteDataM[39:32];
|
||||
if (ByteMaskM[5]) write[47:40] = WriteDataM[47:40];
|
||||
if (ByteMaskM[6]) write[55:48] = WriteDataM[55:48];
|
||||
if (ByteMaskM[7]) write[63:56] = WriteDataM[63:56];
|
||||
end
|
||||
always_ff @(posedge clk)
|
||||
if (memwrite) RAM[AdrM[18:3]] <= write;
|
||||
end else begin // 32-bit
|
||||
always_comb begin
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
write=RdTimM;
|
||||
if (ByteMaskM[0]) write[7:0] = WriteDataM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WriteDataM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WriteDataM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WriteDataM[31:24];
|
||||
end
|
||||
always_ff @(posedge clk)
|
||||
if (memwrite) RAM[AdrM[17:2]] <= write;
|
||||
|
@ -26,24 +26,24 @@
|
||||
`include "wally-macros.sv"
|
||||
|
||||
module extend #(parameter XLEN=32) (
|
||||
input logic [31:7] instr,
|
||||
input logic [2:0] immsrc,
|
||||
output logic [XLEN-1:0] immext);
|
||||
input logic [31:7] InstrDecompD,
|
||||
input logic [2:0] ImmSrcD,
|
||||
output logic [XLEN-1:0] ExtImmD);
|
||||
|
||||
always_comb
|
||||
case(immsrc)
|
||||
case(ImmSrcD)
|
||||
// I-type
|
||||
3'b000: immext = {{(XLEN-12){instr[31]}}, instr[31:20]};
|
||||
3'b000: ExtImmD = {{(XLEN-12){InstrDecompD[31]}}, InstrDecompD[31:20]};
|
||||
// S-type (stores)
|
||||
3'b001: immext = {{(XLEN-12){instr[31]}}, instr[31:25], instr[11:7]};
|
||||
3'b001: ExtImmD = {{(XLEN-12){InstrDecompD[31]}}, InstrDecompD[31:25], InstrDecompD[11:7]};
|
||||
// B-type (branches)
|
||||
3'b010: immext = {{(XLEN-12){instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0};
|
||||
3'b010: ExtImmD = {{(XLEN-12){InstrDecompD[31]}}, InstrDecompD[7], InstrDecompD[30:25], InstrDecompD[11:8], 1'b0};
|
||||
// J-type (jal)
|
||||
3'b011: immext = {{(XLEN-20){instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0};
|
||||
3'b011: ExtImmD = {{(XLEN-20){InstrDecompD[31]}}, InstrDecompD[19:12], InstrDecompD[20], InstrDecompD[30:21], 1'b0};
|
||||
// U-type (lui, auipc)
|
||||
3'b100: immext = {{(XLEN-31){instr[31]}}, instr[30:12], 12'b0};
|
||||
3'b100: ExtImmD = {{(XLEN-31){InstrDecompD[31]}}, InstrDecompD[30:12], 12'b0};
|
||||
/* verilator lint_off WIDTH */
|
||||
default: immext = 'bx; // undefined
|
||||
default: ExtImmD = 'bx; // undefined
|
||||
/* verilator lint_on WIDTH */
|
||||
endcase
|
||||
endmodule
|
||||
|
@ -29,22 +29,21 @@
|
||||
|
||||
module gpio #(parameter XLEN=32) (
|
||||
input logic clk, reset,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [1:0] MemRWgpioM,
|
||||
input logic [7:0] ByteMaskM,
|
||||
input logic [7:0] AdrM,
|
||||
input logic [XLEN-1:0] WdM,
|
||||
output logic [XLEN-1:0] RdM,
|
||||
input logic [XLEN-1:0] MaskedWriteDataM,
|
||||
output logic [XLEN-1:0] RdGPIOM,
|
||||
input logic [31:0] GPIOPinsIn,
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn);
|
||||
|
||||
logic [31:0] INPUT_VAL, INPUT_EN, OUTPUT_EN, OUTPUT_VAL;
|
||||
|
||||
logic [XLEN-1:0] read, write;
|
||||
logic [15:0] entry;
|
||||
logic [7:0] entry;
|
||||
logic memread, memwrite;
|
||||
|
||||
assign memread = MemRWM[1];
|
||||
assign memwrite = MemRWM[0];
|
||||
assign memread = MemRWgpioM[1];
|
||||
assign memwrite = MemRWgpioM[0];
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
@ -63,20 +62,11 @@ module gpio #(parameter XLEN=32) (
|
||||
if (XLEN==64) begin
|
||||
always_comb begin
|
||||
case(entry)
|
||||
8'h00: read = {INPUT_EN, INPUT_VAL};
|
||||
8'h08: read = {OUTPUT_VAL, OUTPUT_EN};
|
||||
8'h40: read = 0; // OUT_XOR reads as 0
|
||||
default: read = 0;
|
||||
8'h00: RdGPIOM = {INPUT_EN, INPUT_VAL};
|
||||
8'h08: RdGPIOM = {OUTPUT_VAL, OUTPUT_EN};
|
||||
8'h40: RdGPIOM = 0; // OUT_XOR reads as 0
|
||||
default: RdGPIOM = 0;
|
||||
endcase
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
if (ByteMaskM[4]) write[39:32] = WdM[39:32];
|
||||
if (ByteMaskM[5]) write[47:40] = WdM[47:40];
|
||||
if (ByteMaskM[6]) write[55:48] = WdM[55:48];
|
||||
if (ByteMaskM[7]) write[63:56] = WdM[63:56];
|
||||
end
|
||||
always_ff @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
@ -84,25 +74,20 @@ module gpio #(parameter XLEN=32) (
|
||||
OUTPUT_EN <= 0;
|
||||
// OUTPUT_VAL <= 0; // spec indicates synchronous rset (software control)
|
||||
end else begin
|
||||
if (entry == 8'h00) INPUT_EN <= write[63:32];
|
||||
if (entry == 8'h08) {OUTPUT_VAL, OUTPUT_EN} <= write;
|
||||
if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ write[31:0]; // OUT_XOR
|
||||
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
|
||||
end
|
||||
end else begin // 32-bit
|
||||
always_comb begin
|
||||
case(entry)
|
||||
8'h00: read = INPUT_VAL;
|
||||
8'h04: read = INPUT_EN;
|
||||
8'h08: read = OUTPUT_EN;
|
||||
8'h0C: read = OUTPUT_VAL;
|
||||
8'h40: read = 0; // OUT_XOR reads as 0
|
||||
default: read = 0;
|
||||
8'h00: RdGPIOM = INPUT_VAL;
|
||||
8'h04: RdGPIOM = INPUT_EN;
|
||||
8'h08: RdGPIOM = OUTPUT_EN;
|
||||
8'h0C: RdGPIOM = OUTPUT_VAL;
|
||||
8'h40: RdGPIOM = 0; // OUT_XOR reads as 0
|
||||
default: RdGPIOM = 0;
|
||||
endcase
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
end
|
||||
always_ff @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
@ -110,15 +95,12 @@ module gpio #(parameter XLEN=32) (
|
||||
OUTPUT_EN <= 0;
|
||||
//OUTPUT_VAL <= 0;// spec indicates synchronous rset (software control)
|
||||
end else begin
|
||||
if (entry == 8'h04) INPUT_EN <= write;
|
||||
if (entry == 8'h08) OUTPUT_EN <= write;
|
||||
if (entry == 8'h0C) OUTPUT_VAL <= write;
|
||||
if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ write; // OUT_XOR
|
||||
if (entry == 8'h04) INPUT_EN <= MaskedWriteDataM;
|
||||
if (entry == 8'h08) OUTPUT_EN <= MaskedWriteDataM;
|
||||
if (entry == 8'h0C) OUTPUT_VAL <= MaskedWriteDataM;
|
||||
if (entry == 8'h40) OUTPUT_VAL <= OUTPUT_VAL ^ MaskedWriteDataM; // OUT_XOR
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// read
|
||||
assign RdM = memread ? read: 0;
|
||||
endmodule
|
||||
|
||||
|
@ -31,7 +31,7 @@ module hazard(
|
||||
input logic RegWriteM, RegWriteW, CSRWritePendingDEM, RetM, TrapM,
|
||||
output logic [1:0] ForwardAE, ForwardBE,
|
||||
output logic StallF, StallD, FlushD, FlushE, FlushM, FlushW,
|
||||
output logic loadStallD);
|
||||
output logic LoadStallD);
|
||||
|
||||
// forwarding logic
|
||||
always_comb begin
|
||||
@ -54,11 +54,11 @@ module hazard(
|
||||
// Exceptions: flush entire pipeline
|
||||
// Ret instructions: occur in M stage. Might be possible to move earlier, but be careful about hazards
|
||||
|
||||
assign loadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE));
|
||||
assign StallD = loadStallD;
|
||||
assign StallF = loadStallD | CSRWritePendingDEM;
|
||||
assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE));
|
||||
assign StallD = LoadStallD;
|
||||
assign StallF = LoadStallD | CSRWritePendingDEM;
|
||||
assign FlushD = PCSrcE | CSRWritePendingDEM | RetM | TrapM;
|
||||
assign FlushE = loadStallD | PCSrcE | RetM | TrapM;
|
||||
assign FlushE = LoadStallD | PCSrcE | RetM | TrapM;
|
||||
assign FlushM = RetM | TrapM;
|
||||
assign FlushW = TrapM;
|
||||
endmodule
|
||||
|
@ -31,8 +31,8 @@ module memdp #(parameter XLEN=32) (
|
||||
input logic [XLEN-1:0] AdrM,
|
||||
input logic [2:0] Funct3M,
|
||||
output logic [XLEN-1:0] ReadDataExtM,
|
||||
input logic [XLEN-1:0] WriteDataM,
|
||||
output logic [XLEN-1:0] WriteDataExtM,
|
||||
input logic [XLEN-1:0] WriteDataFullM,
|
||||
output logic [XLEN-1:0] WriteDataM,
|
||||
output logic [7:0] ByteMaskM,
|
||||
input logic DataAccessFaultM,
|
||||
output logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||
@ -40,7 +40,7 @@ module memdp #(parameter XLEN=32) (
|
||||
|
||||
logic [7:0] bytM;
|
||||
logic [15:0] HalfwordM;
|
||||
logic UnalignedM, AccessFaultM;
|
||||
logic UnalignedM;
|
||||
|
||||
generate
|
||||
if (XLEN == 64) begin
|
||||
@ -109,11 +109,11 @@ module memdp #(parameter XLEN=32) (
|
||||
// Handle subword writes
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: WriteDataExtM = {8{WriteDataM[7:0]}}; // sb
|
||||
3'b001: WriteDataExtM = {4{WriteDataM[15:0]}}; // sh
|
||||
3'b010: WriteDataExtM = {2{WriteDataM[31:0]}}; // sw
|
||||
3'b011: WriteDataExtM = WriteDataM; // sw
|
||||
default: WriteDataExtM = 64'b0;
|
||||
3'b000: WriteDataM = {8{WriteDataFullM[7:0]}}; // sb
|
||||
3'b001: WriteDataM = {4{WriteDataFullM[15:0]}}; // sh
|
||||
3'b010: WriteDataM = {2{WriteDataFullM[31:0]}}; // sw
|
||||
3'b011: WriteDataM = WriteDataFullM; // sw
|
||||
default: WriteDataM = 64'b0;
|
||||
endcase
|
||||
|
||||
end else begin // 32-bit
|
||||
@ -160,10 +160,10 @@ module memdp #(parameter XLEN=32) (
|
||||
// Handle subword writes
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: WriteDataExtM = {4{WriteDataM[7:0]}}; // sb
|
||||
3'b001: WriteDataExtM = {2{WriteDataM[15:0]}}; // sh
|
||||
3'b010: WriteDataExtM = WriteDataM; // sw
|
||||
default: WriteDataExtM = 32'b0;
|
||||
3'b000: WriteDataM = {4{WriteDataFullM[7:0]}}; // sb
|
||||
3'b001: WriteDataM = {2{WriteDataFullM[15:0]}}; // sh
|
||||
3'b010: WriteDataM = WriteDataFullM; // sw
|
||||
default: WriteDataM = 32'b0;
|
||||
endcase
|
||||
end
|
||||
endgenerate
|
||||
|
@ -1,50 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// pcadder.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Determine next PC = PC+2 or PC+4
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module pcadder #(parameter XLEN=32) (
|
||||
input logic [XLEN-1:0] pc,
|
||||
input logic [31:0] instr,
|
||||
output logic [XLEN-1:0] pcplus);
|
||||
|
||||
logic [1:0] op;
|
||||
logic [XLEN-3:0] pcplusupper;
|
||||
logic compressed;
|
||||
|
||||
// add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
|
||||
assign op = instr[1:0];
|
||||
assign compressed = (op != 2'b11); // is it a 16-bit compressed instruction?
|
||||
|
||||
assign pcplusupper = pc[XLEN-1:2] + 1; // add 4 to PC
|
||||
|
||||
// choose PC+2 or PC+4
|
||||
always_comb
|
||||
if (compressed) // add 2
|
||||
if (pc[1]) pcplus = {pcplusupper, 2'b00};
|
||||
else pcplus = {pc[XLEN-1:2], 2'b10};
|
||||
else pcplus = {pcplusupper, pc[1:0]}; // add 4
|
||||
endmodule
|
||||
|
@ -42,16 +42,29 @@ module pclogic #(parameter XLEN=64, MISA=0) (
|
||||
logic [XLEN-1:0] ResetVector = {{(XLEN-32){1'b0}}, 32'h80000000};
|
||||
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
|
||||
logic StallExceptResolveBranchesF, PrivilegedChangePCM;
|
||||
logic [XLEN-3:0] PCPlusUpperF;
|
||||
logic CompressedF;
|
||||
|
||||
assign PrivilegedChangePCM = RetM | TrapM;
|
||||
|
||||
assign StallExceptResolveBranchesF = StallF & ~(PCSrcE | PrivilegedChangePCM);
|
||||
|
||||
assign PCTargetE = ExtImmE + TargetBaseE;
|
||||
assign PCTargetE = ExtImmE + TargetBaseE;
|
||||
mux3 #(XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF);
|
||||
assign PCNextF = {UnalignedPCNextF[XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
||||
flopenl #(XLEN) pcreg(clk, reset, ~StallExceptResolveBranchesF, PCNextF, ResetVector, PCF);
|
||||
pcadder #(XLEN) pcadd(PCF, InstrF, PCPlus2or4F);
|
||||
|
||||
// pcadder
|
||||
// add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
|
||||
assign CompressedF = (InstrF[1:0] != 2'b11); // is it a 16-bit compressed instruction?
|
||||
assign PCPlusUpperF = PCF[XLEN-1:2] + 1; // add 4 to PC
|
||||
|
||||
// choose PC+2 or PC+4
|
||||
always_comb
|
||||
if (CompressedF) // add 2
|
||||
if (PCF[1]) PCPlus2or4F = {PCPlusUpperF, 2'b00};
|
||||
else PCPlus2or4F = {PCF[XLEN-1:2], 2'b10};
|
||||
else PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4
|
||||
|
||||
// Misaligned PC logic
|
||||
|
||||
|
@ -54,9 +54,8 @@ module privileged #(parameter XLEN=32, MISA = 0, ZCSR = 1, ZCOUNTERS = 1)(
|
||||
// logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW;
|
||||
|
||||
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
|
||||
logic IllegalCSRAccess, IllegalInstrFaultM;
|
||||
logic IllegalCSRAccessM, IllegalInstrFaultM;
|
||||
|
||||
logic SwInt, TimerInt, ExtInt;
|
||||
logic BreakpointFaultM, EcallFaultM;
|
||||
logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM;
|
||||
logic MTrapM, STrapM, UTrapM;
|
||||
@ -67,13 +66,10 @@ module privileged #(parameter XLEN=32, MISA = 0, ZCSR = 1, ZCOUNTERS = 1)(
|
||||
logic [11:0] MIP_REGW, MIE_REGW;
|
||||
|
||||
// track the current privilege level
|
||||
privilegeModeReg #(XLEN, MISA) pmr (clk, reset, mretM, sretM, uretM, TrapM,
|
||||
STATUS_MPP, STATUS_SPP, MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW,
|
||||
CauseM, NextPrivilegeModeM, PrivilegeModeW);
|
||||
privilegeModeReg #(XLEN, MISA) pmr (.*);
|
||||
|
||||
// decode privileged instructions
|
||||
privilegeDecoder #(MISA) pmd(InstrM[31:20], PrivilegedM, IllegalInstrFaultInM, IllegalCSRAccess, PrivilegeModeW, STATUS_TSR,
|
||||
IllegalInstrFaultM, uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
|
||||
privilegeDecoder #(MISA) pmd(.InstrM(InstrM[31:20]), .*);
|
||||
|
||||
// Extract exceptions by name and handle them
|
||||
assign BreakpointFaultM = ebreakM; // could have other causes too
|
||||
@ -81,35 +77,10 @@ module privileged #(parameter XLEN=32, MISA = 0, ZCSR = 1, ZCOUNTERS = 1)(
|
||||
assign InstrPageFaultM = 0;
|
||||
assign LoadPageFaultM = 0;
|
||||
assign StorePageFaultM = 0;
|
||||
trap #(XLEN, MISA) trap(clk, reset, InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
|
||||
BreakpointFaultM, LoadMisalignedFaultM, StoreMisalignedFaultM,
|
||||
LoadAccessFaultM, StoreAccessFaultM, EcallFaultM, InstrPageFaultM,
|
||||
LoadPageFaultM, StorePageFaultM,
|
||||
mretM, sretM, uretM, PrivilegeModeW, NextPrivilegeModeM,
|
||||
MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
|
||||
MIP_REGW, MIE_REGW, STATUS_MIE, STATUS_SIE,
|
||||
InstrMisalignedAdrM, ALUResultM, InstrM,
|
||||
TrapM, MTrapM, STrapM, UTrapM, RetM,
|
||||
PrivilegedNextPCM, CauseM, NextFaultMtvalM
|
||||
// MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
);
|
||||
trap #(XLEN, MISA) trap(.*);
|
||||
|
||||
// Control and Status Registers
|
||||
csr #(XLEN, MISA, ZCSR, ZCOUNTERS) csr(clk, reset,
|
||||
InstrM, PCM, SrcAM,
|
||||
CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
|
||||
TimerIntM, ExtIntM, SwIntM,
|
||||
InstrValidW, FloatRegWriteW, LoadStallD,
|
||||
NextPrivilegeModeM, PrivilegeModeW,
|
||||
CauseM, NextFaultMtvalM,
|
||||
STATUS_MPP, STATUS_SPP, STATUS_TSR,
|
||||
MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
|
||||
MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW,
|
||||
MIP_REGW, MIE_REGW, STATUS_MIE, STATUS_SIE,
|
||||
SetFflagsM, FRM_REGW,
|
||||
// MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
CSRReadValM, IllegalCSRAccess
|
||||
);
|
||||
csr #(XLEN, MISA, ZCSR, ZCOUNTERS) csr(.*);
|
||||
endmodule
|
||||
|
||||
|
||||
|
@ -234,6 +234,7 @@ string tests32i[] = {
|
||||
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
|
||||
|
||||
// instantiate device to be tested
|
||||
assign GPIOPinsIn = 0;
|
||||
wallypipelined #(XLEN, MISA, ZCSR, ZCOUNTERS) dut(
|
||||
clk, reset, WriteData, DataAdr, MemRW,
|
||||
GPIOPinsIn, GPIOPinsOut, GPIOPinsEn
|
||||
|
@ -68,11 +68,8 @@ module wallypipelined #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
logic ExtIntM = 0; // not yet connected
|
||||
|
||||
// instantiate processor and memories
|
||||
wallypipelinedhart #(XLEN, MISA, ZCSR, ZCOUNTERS) hart(
|
||||
clk, reset, PCF, InstrF, MemRWM, ByteMaskM, DataAdrM,
|
||||
WriteDataM, ReadDataM, TimerIntM, ExtIntM, SwIntM, InstrAccessFaultF, DataAccessFaultM);
|
||||
wallypipelinedhart #(XLEN, MISA, ZCSR, ZCOUNTERS) hart(.ALUResultM(DataAdrM), .*);
|
||||
|
||||
imem #(XLEN) imem(PCF, InstrF, InstrAccessFaultF);
|
||||
dmem #(XLEN) dmem(clk, reset, MemRWM, ByteMaskM, DataAdrM, WriteDataM, ReadDataM,
|
||||
DataAccessFaultM, TimerIntM, SwIntM, GPIOPinsIn, GPIOPinsOut, GPIOPinsEn);
|
||||
imem #(XLEN) imem(.AdrF(PCF), .*);
|
||||
dmem #(XLEN) dmem(.AdrM(DataAdrM), .*);
|
||||
endmodule
|
@ -37,9 +37,9 @@ module wallypipelinedhart #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1)
|
||||
input logic InstrAccessFaultF,
|
||||
input logic DataAccessFaultM);
|
||||
|
||||
logic [6:0] opD;
|
||||
logic [2:0] funct3D;
|
||||
logic funct7b5D;
|
||||
logic [2:0] Funct3D;
|
||||
logic Funct7b5D;
|
||||
logic [6:0] OpD;
|
||||
logic [2:0] ImmSrcD;
|
||||
logic IllegalCompInstrD;
|
||||
logic [2:0] FlagsE;
|
||||
@ -61,40 +61,21 @@ module wallypipelinedhart #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1)
|
||||
|
||||
logic [1:0] ForwardAE, ForwardBE;
|
||||
logic StallF, StallD, FlushD, FlushE, FlushM, FlushW;
|
||||
logic PrivilegedChangePCM, TrapM;
|
||||
logic RetM, TrapM;
|
||||
|
||||
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW;
|
||||
logic TargetSrcE;
|
||||
logic [4:0] SetFflagsM;
|
||||
logic [2:0] FRM_REGW;
|
||||
logic FloatRegWriteW;
|
||||
|
||||
controller c(clk, reset,
|
||||
opD, funct3D, funct7b5D, ImmSrcD,
|
||||
StallD, FlushD, IllegalCompInstrD,
|
||||
FlushE, FlagsE, PCSrcE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, MemReadE,
|
||||
FlushM, MemRWM, CSRWriteM, PrivilegedM, IllegalInstrFaultM, Funct3M, RegWriteM,
|
||||
FlushW, RegWriteW, ResultSrcW, InstrValidW, CSRWritePendingDEM,
|
||||
InstrAccessFaultF, InstrAccessFaultM);
|
||||
|
||||
datapath #(XLEN, MISA, ZCSR, ZCOUNTERS)
|
||||
dp(clk, reset,
|
||||
StallF, PCF, InstrF,
|
||||
opD, funct3D, funct7b5D, StallD, FlushD, ImmSrcD, LoadStallD, IllegalCompInstrD,
|
||||
FlushE, ForwardAE, ForwardBE, PCSrcE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, FlagsE,
|
||||
FlushM, MemRWM, CSRWriteM, PrivilegedM, InstrAccessFaultM, IllegalInstrFaultM,
|
||||
TimerIntM, ExtIntM, SwIntM, InstrMisalignedFaultM,
|
||||
Funct3M, WriteDataM, ALUResultM, ReadDataM, ByteMaskM, PrivilegedChangePCM, TrapM,
|
||||
SetFflagsM, DataAccessFaultM,
|
||||
FlushW, RegWriteW, ResultSrcW, InstrValidW, FloatRegWriteW, FRM_REGW,
|
||||
Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW);
|
||||
|
||||
controller c(.*);
|
||||
datapath #(XLEN, MISA, ZCSR, ZCOUNTERS) dp(.*);
|
||||
hazard hz(.*);
|
||||
|
||||
// add FPU here, with SetFflagsM, FRM_REGW
|
||||
// presently stub out SetFlagsM and FloatRegWriteW
|
||||
assign SetFflagsM = 0;
|
||||
assign FloatRegWriteW = 0;
|
||||
|
||||
hazard hz(Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
|
||||
PCSrcE, MemReadE, RegWriteM, RegWriteW, CSRWritePendingDEM, PrivilegedChangePCM, TrapM,
|
||||
ForwardAE, ForwardBE, StallF, StallD, FlushD, FlushE, FlushM, FlushW, LoadStallD);
|
||||
|
||||
endmodule
|
||||
|
@ -60,7 +60,7 @@ add wave -divider
|
||||
add wave /testbench/InstrMName
|
||||
add wave /testbench/dut/dmem/dtim/memwrite
|
||||
add wave -hex /testbench/dut/dmem/AdrM
|
||||
add wave -hex /testbench/dut/dmem/WdM
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user