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