mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						07eba7df45
					
				
										
											Binary file not shown.
										
									
								
							| @ -1 +1 @@ | ||||
| Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9 | ||||
| Subproject commit 2d2aaa7b85c60219c591555b647dfa1785ffe1b3 | ||||
| @ -1 +1 @@ | ||||
| Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 | ||||
| Subproject commit effd553a6a91ed9b0ba251796a8a44505a45174f | ||||
| @ -1 +1 @@ | ||||
| Subproject commit a7e27bc046405f0dbcde091be99f5a5d564e2172 | ||||
| Subproject commit cb4295f9ce5da2881d7746015a6105adb8f09071 | ||||
| @ -1 +1 @@ | ||||
| Subproject commit cf04274f50621fd9ef9147793cca6dd1657985c7 | ||||
| Subproject commit 3e2bf06b071a77ae62c09bf07c5229d1f9397d94 | ||||
| @ -1,4 +1,5 @@ | ||||
| for index in {450..500} | ||||
| #!/bin/bash | ||||
| for index in {450..500}; | ||||
| do  | ||||
|     instrs=$(($index*1000000)) | ||||
|     echo "y" | nice -n 5 ./genCheckpoint.sh $instrs | ||||
|  | ||||
| @ -70,7 +70,7 @@ for test in tests64gc: | ||||
|         cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!", | ||||
|         grepstr="All tests ran without failures") | ||||
|   configs.append(tc) | ||||
| tests32gc = ["arch32i", "arch32priv", "arch32c",  "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a",  "imperas32c", "wally32priv"]  #, "imperas32mmu""wally32i",  | ||||
| tests32gc = ["arch32i", "arch32priv", "arch32c",  "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a",  "imperas32c"]  #, "imperas32mmu""wally32i",  | ||||
| for test in tests32gc: | ||||
|   tc = TestCase( | ||||
|         name=test, | ||||
| @ -79,6 +79,25 @@ for test in tests32gc: | ||||
|         grepstr="All tests ran without failures") | ||||
|   configs.append(tc) | ||||
| 
 | ||||
| 
 | ||||
| tests64ia = ["wally64priv"] | ||||
| for test in tests64ia: | ||||
|   tc = TestCase( | ||||
|         name=test, | ||||
|         variant="rv64ia", | ||||
|         cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64ia "+test+"\n!", | ||||
|         grepstr="All tests ran without failures") | ||||
|   configs.append(tc) | ||||
| 
 | ||||
| tests32ia = ["wally32priv"] | ||||
| for test in tests32ia: | ||||
|   tc = TestCase( | ||||
|         name=test, | ||||
|         variant="rv32ia", | ||||
|         cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv32ia "+test+"\n!", | ||||
|         grepstr="All tests ran without failures") | ||||
|   configs.append(tc) | ||||
| 
 | ||||
| tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c"]  | ||||
| for test in tests32ic: | ||||
|   tc = TestCase( | ||||
|  | ||||
							
								
								
									
										15
									
								
								pipelined/src/cache/sram1p1rw.sv
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								pipelined/src/cache/sram1p1rw.sv
									
									
									
									
										vendored
									
									
								
							| @ -47,7 +47,8 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) ( | ||||
| 
 | ||||
|   always_ff @(posedge clk)       AdrD <= Adr; | ||||
| 
 | ||||
|   genvar                          index; | ||||
|   integer                          index; | ||||
| /* -----\/----- EXCLUDED -----\/----- | ||||
|   for(index = 0; index < WIDTH/8; index++) begin | ||||
|     always_ff @(posedge clk) begin | ||||
|       if (WriteEnable & ByteMask[index]) begin | ||||
| @ -55,6 +56,18 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) ( | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  -----/\----- EXCLUDED -----/\----- */ | ||||
| 
 | ||||
|   always_ff @(posedge clk) begin | ||||
|     if (WriteEnable) begin | ||||
|       for(index = 0; index < WIDTH/8; index++) begin | ||||
|         if(ByteMask[index]) begin | ||||
|         StoredData[Adr][index*8 +: 8] <= #1 CacheWriteData[index*8 +: 8]; | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|    | ||||
|   // if not a multiple of 8, MSByte is not 8 bits long.
 | ||||
|   if(WIDTH%8 != 0) begin | ||||
|     always_ff @(posedge clk) begin | ||||
|  | ||||
| @ -23,40 +23,32 @@ module fcmp ( | ||||
|    output logic [`FLEN-1:0]   CmpResE         // compare resilt
 | ||||
|    ); | ||||
| 
 | ||||
|    logic LT, EQ; // is X < or > or = Y
 | ||||
|    logic LTabs, LT, EQ; // is X < or > or = Y
 | ||||
|    logic BothZeroE, EitherNaNE, EitherSNaNE; | ||||
|     | ||||
|    // X is less than Y:
 | ||||
|    //    Signs:
 | ||||
|    //       X      Y    answer
 | ||||
|    //      pos    pos    idk - keep checking
 | ||||
|    //      pos    neg    no
 | ||||
|    //      neg    pos    yes
 | ||||
|    //      neg    neg    idk - keep checking
 | ||||
|    //    Exponent 
 | ||||
|    //       - if XExp < YExp
 | ||||
|    //             - if negitive - no
 | ||||
|    //             - if positive - yes
 | ||||
|    //       - otherwise keep checking
 | ||||
|    //    Mantissa
 | ||||
|    //       - XMan < YMan then
 | ||||
|    //             - if negitive - no
 | ||||
|    //             - if positive - yes
 | ||||
|    // note: LT does -0 < 0
 | ||||
|    //*** compare Exp and Man together
 | ||||
|    assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE; | ||||
|    assign LTabs= {1'b0, XExpE, XManE} < {1'b0, YExpE, YManE}; // unsigned comparison, treating FP as integers
 | ||||
|    assign LT = (XSgnE & ~YSgnE) | (XSgnE & YSgnE & ~LTabs & ~EQ) | (~XSgnE & ~YSgnE & LTabs); | ||||
|    //assign LT = $signed({XSgnE, XExpE, XManE[`NF-1:0]}) < $signed({YSgnE, YExpE, YManE[`NF-1:0]});
 | ||||
|    //assign LT = XInt < YInt;
 | ||||
| //   assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
 | ||||
|    assign EQ = (FSrcXE == FSrcYE); | ||||
| 
 | ||||
|    assign BothZeroE = XZeroE&YZeroE; | ||||
|    assign EitherNaNE = XNaNE|YNaNE; | ||||
|    assign EitherSNaNE = XSNaNE|YSNaNE; | ||||
| 
 | ||||
| 
 | ||||
|    // flags
 | ||||
|    //    Min/Max - if an input is a signaling NaN set invalid flag
 | ||||
|    //    LT/LE - signaling - sets invalid if NaN input
 | ||||
|    //    EQ - quiet - sets invalid if signaling NaN input
 | ||||
|    always_comb begin | ||||
|       case (FOpCtrlE[2:0]) | ||||
|          3'b111: CmpNVE = XSNaNE|YSNaNE;//min 
 | ||||
|          3'b101: CmpNVE = XSNaNE|YSNaNE;//max
 | ||||
|          3'b010: CmpNVE = XSNaNE|YSNaNE;//equal
 | ||||
|          3'b001: CmpNVE = XNaNE|YNaNE;//less than
 | ||||
|          3'b011: CmpNVE = XNaNE|YNaNE;//less than or equal
 | ||||
|          3'b111: CmpNVE = EitherSNaNE;//min 
 | ||||
|          3'b101: CmpNVE = EitherSNaNE;//max
 | ||||
|          3'b010: CmpNVE = EitherSNaNE;//equal
 | ||||
|          3'b001: CmpNVE = EitherNaNE;//less than
 | ||||
|          3'b011: CmpNVE = EitherNaNE;//less than or equal
 | ||||
|          default: CmpNVE = 1'b0; | ||||
|       endcase | ||||
|    end  | ||||
| @ -71,24 +63,22 @@ module fcmp ( | ||||
|    //    - inf = inf and -inf = -inf
 | ||||
|    //    - return 0 if comparison with NaN (unordered)
 | ||||
| 
 | ||||
|    logic [`FLEN-1:0] QNaNX, QNaNY; | ||||
|     if(`IEEE754) begin | ||||
|         assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]}; | ||||
|         assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]}; | ||||
|     end else begin | ||||
|         assign QNaNX = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0}; | ||||
|         assign QNaNY = FmtE ? {1'b0, YExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpE[7:0], 1'b1, 22'b0}; | ||||
|     end | ||||
|    logic [`FLEN-1:0] QNaN; | ||||
|    // fmin/fmax of two NaNs returns a quiet NaN of the appropriate size
 | ||||
|    // for IEEE, return the payload of X
 | ||||
|    // for RISC-V, return the canonical NaN
 | ||||
|    if(`IEEE754) assign QNaN = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]}; | ||||
|    else         assign QNaN = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0}; | ||||
|   | ||||
|    always_comb begin | ||||
|       case (FOpCtrlE[2:0]) | ||||
|          3'b111: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Min
 | ||||
|          3'b111: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Min
 | ||||
|                                  : YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE; | ||||
|          3'b101: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Max
 | ||||
|          3'b101: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Max
 | ||||
|                                  : YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE; | ||||
|          3'b010: CmpResE = {63'b0, (EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Equal
 | ||||
|          3'b001: CmpResE = {63'b0, LT&~(XZeroE&YZeroE)&~(XNaNE|YNaNE)}; // Less than
 | ||||
|          3'b011: CmpResE = {63'b0, (LT|EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Less than or equal
 | ||||
|          3'b010: CmpResE = {63'b0, (EQ|BothZeroE) & ~EitherNaNE}; // Equal
 | ||||
|          3'b001: CmpResE = {63'b0, LT & ~BothZeroE & ~EitherNaNE}; // Less than
 | ||||
|          3'b011: CmpResE = {63'b0, (LT|EQ|BothZeroE) & ~EitherNaNE}; // Less than or equal
 | ||||
|          default: CmpResE = 64'b0; | ||||
|       endcase | ||||
|    end  | ||||
|  | ||||
							
								
								
									
										71
									
								
								pipelined/src/generic/flop/bram1p1rw.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								pipelined/src/generic/flop/bram1p1rw.sv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| ///////////////////////////////////////////
 | ||||
| // block ram model should be equivalent to srsam.
 | ||||
| //
 | ||||
| // Written: Ross Thompson
 | ||||
| // March 29, 2022
 | ||||
| // Modified: Based on UG901 vivado documentation.
 | ||||
| //
 | ||||
| // Purpose: On-chip SIMPLERAM, external to core
 | ||||
| // 
 | ||||
| // A component of the Wally configurable RISC-V project.
 | ||||
| // 
 | ||||
| // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | ||||
| //
 | ||||
| // MIT LICENSE
 | ||||
| // 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.
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| // This model actually works correctly with vivado.
 | ||||
| 
 | ||||
| `include "wally-config.vh" | ||||
| 
 | ||||
| module bram1p1rw | ||||
|   #( | ||||
| 	//--------------------------------------------------------------------------
 | ||||
| 	parameter NUM_COL = 8, | ||||
| 	parameter COL_WIDTH = 8, | ||||
| 	parameter ADDR_WIDTH = 10, | ||||
| 	// Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth
 | ||||
| 	parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits
 | ||||
| 	//----------------------------------------------------------------------
 | ||||
| 	) ( | ||||
| 	   input logic 					 clk, | ||||
| 	   input logic 					 ena, | ||||
| 	   input logic [NUM_COL-1:0] 	 we, | ||||
| 	   input logic [ADDR_WIDTH-1:0]  addr, | ||||
| 	   output logic [DATA_WIDTH-1:0] dout, | ||||
| 	   input logic [DATA_WIDTH-1:0]  din | ||||
| 	   ); | ||||
|   // Core Memory
 | ||||
|   logic [DATA_WIDTH-1:0] 			 RAM [(2**ADDR_WIDTH)-1:0]; | ||||
|   integer 							 i; | ||||
| 
 | ||||
|   initial begin | ||||
| 	$readmemh("big64.txt", RAM); | ||||
|   end | ||||
| 
 | ||||
|   always @ (posedge clk) begin | ||||
| 	dout <= RAM[addr];     | ||||
| 	if(ena) begin | ||||
| 	  for(i=0;i<NUM_COL;i=i+1) begin | ||||
| 		if(we[i]) begin | ||||
| 		  RAM[addr][i*COL_WIDTH +: COL_WIDTH] <= din[i*COL_WIDTH +:COL_WIDTH]; | ||||
| 		end | ||||
| 	  end | ||||
| 	end | ||||
|   end | ||||
| endmodule // bytewrite_tdp_ram_rf
 | ||||
							
								
								
									
										82
									
								
								pipelined/src/generic/flop/bram2p1r1w.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								pipelined/src/generic/flop/bram2p1r1w.sv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| ///////////////////////////////////////////
 | ||||
| // block ram model should be equivalent to srsam.
 | ||||
| //
 | ||||
| // Written: Ross Thompson
 | ||||
| // March 29, 2022
 | ||||
| // Modified: Based on UG901 vivado documentation.
 | ||||
| //
 | ||||
| // Purpose: On-chip SIMPLERAM, external to core
 | ||||
| // 
 | ||||
| // A component of the Wally configurable RISC-V project.
 | ||||
| // 
 | ||||
| // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | ||||
| //
 | ||||
| // MIT LICENSE
 | ||||
| // 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.
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| // This model actually works correctly with vivado.
 | ||||
| 
 | ||||
| `include "wally-config.vh" | ||||
| 
 | ||||
| module bram2p1r1w | ||||
|   #( | ||||
| 	//--------------------------------------------------------------------------
 | ||||
| 	parameter NUM_COL = 8, | ||||
| 	parameter COL_WIDTH = 8, | ||||
| 	parameter ADDR_WIDTH = 10, | ||||
|     parameter PRELOAD_ENABLED = 0, | ||||
|     parameter PRELOAD_FILE = "bootrom.txt", | ||||
| 	// Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth
 | ||||
| 	parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits
 | ||||
| 	//----------------------------------------------------------------------
 | ||||
| 	) ( | ||||
| 	   input logic 					 clk, | ||||
| 	   input logic 					 enaA, | ||||
| 	   input logic [ADDR_WIDTH-1:0]  addrA, | ||||
| 	   output logic [DATA_WIDTH-1:0] doutA, | ||||
| 	   input logic 					 enaB, | ||||
| 	   input logic [NUM_COL-1:0] 	 weB, | ||||
| 	   input logic [ADDR_WIDTH-1:0]  addrB, | ||||
| 	   input logic [DATA_WIDTH-1:0]  dinB | ||||
| 	   ); | ||||
|   // Core Memory
 | ||||
|   logic [DATA_WIDTH-1:0] 			 RAM [(2**ADDR_WIDTH)-1:0]; | ||||
|   integer 							 i; | ||||
| 
 | ||||
|   initial begin | ||||
|     if(PRELOAD_ENABLED) | ||||
| 	  $readmemh(PRELOAD_FILE, RAM); | ||||
|   end | ||||
| 
 | ||||
|   // Port-A Operation
 | ||||
|   always @ (posedge clk) begin | ||||
| 	if(enaA) begin | ||||
| 	  doutA <= RAM[addrA]; | ||||
| 	end | ||||
|   end | ||||
|   // Port-B Operation:
 | ||||
|   always @ (posedge clk) begin | ||||
| 	if(enaB) begin | ||||
| 	  for(i=0;i<NUM_COL;i=i+1) begin | ||||
| 		if(weB[i]) begin | ||||
| 		  RAM[addrB][i*COL_WIDTH +: COL_WIDTH] <= dinB[i*COL_WIDTH +:COL_WIDTH]; | ||||
| 		end | ||||
| 	  end | ||||
| 	end | ||||
|   end | ||||
| endmodule // bytewrite_tdp_ram_rf
 | ||||
| @ -39,6 +39,14 @@ module simpleram #(parameter BASE=0, RANGE = 65535) ( | ||||
|   output logic [`XLEN-1:0] rd | ||||
| ); | ||||
| 
 | ||||
|   localparam ADDR_WDITH = $clog2(RANGE/8); | ||||
|   localparam OFFSET = $clog2(`XLEN/8); | ||||
| 
 | ||||
| 
 | ||||
|   bram1p1rw #(`XLEN/8, 8, ADDR_WDITH)  | ||||
|   memory(.clk, .ena(we), .we(ByteMask), .addr(a[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(rd), .din(wd)); | ||||
|    | ||||
| /* -----\/----- EXCLUDED -----\/----- | ||||
|   logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; | ||||
|    | ||||
|   // discard bottom 2 or 3 bits of address offset within word or doubleword
 | ||||
| @ -55,5 +63,6 @@ module simpleram #(parameter BASE=0, RANGE = 65535) ( | ||||
|       if (we & ByteMask[index]) RAM[adrmsbs][8*(index+1)-1:8*index] <= #1 wd[8*(index+1)-1:8*index]; | ||||
|     end | ||||
|   end | ||||
|  -----/\----- EXCLUDED -----/\----- */ | ||||
| endmodule | ||||
| 
 | ||||
|  | ||||
| @ -102,6 +102,7 @@ module BTBPredictor | ||||
|   // Another optimization may be using a PC relative address.
 | ||||
|   // *** need to add forwarding.
 | ||||
| 
 | ||||
|   // *** optimize for byte write enables
 | ||||
|   SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk), | ||||
|           .reset(reset), | ||||
|           .RA1(LookUpPCIndex), | ||||
|  | ||||
| @ -66,7 +66,7 @@ module ifu ( | ||||
| 	output logic 				IllegalIEUInstrFaultD, | ||||
| 	output logic 				InstrMisalignedFaultM, | ||||
| 	output logic [`XLEN-1:0] 	InstrMisalignedAdrM, | ||||
| 	input logic 				ExceptionM, PendingInterruptM, | ||||
| 	input logic 				ExceptionM, | ||||
| 	// mmu management
 | ||||
| 	input logic [1:0] 			PrivilegeModeW, | ||||
| 	input logic [`XLEN-1:0] 	PTE, | ||||
| @ -142,8 +142,7 @@ module ifu ( | ||||
|     mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) | ||||
|     immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, | ||||
|          .PrivilegeModeW, .DisableTranslation(1'b0), | ||||
|          .PAdr(PCFExt[`PA_BITS-1:0]), | ||||
|          .VAdr(PCFSpill), | ||||
|          .VAdr(PCFExt), | ||||
|          .Size(2'b10), | ||||
|          .PTE(PTE), | ||||
|          .PageTypeWriteVal(PageType), | ||||
|  | ||||
| @ -91,7 +91,7 @@ module lsu ( | ||||
|   logic [2:0]               LSUFunct3M; | ||||
|   logic [6:0]               LSUFunct7M; | ||||
|   logic [1:0]               LSUAtomicM; | ||||
|   (* mark_debug = "true" *)  logic [`PA_BITS-1:0] 		   PreLSUPAdrM; | ||||
|   (* mark_debug = "true" *)  logic [`XLEN+1:0] 		   PreLSUPAdrM; | ||||
|   logic [11:0]              PreLSUAdrE, LSUAdrE;   | ||||
|   logic                     CPUBusy; | ||||
|   logic                     DCacheStallM; | ||||
| @ -132,7 +132,7 @@ module lsu ( | ||||
|     assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0; | ||||
|     assign IgnoreRequestTrapM = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM;  | ||||
|     assign LSUAdrE = PreLSUAdrE; assign PreLSUAdrE = IEUAdrE[11:0];  | ||||
|     assign PreLSUPAdrM = IEUAdrExtM[`PA_BITS-1:0]; | ||||
|     assign PreLSUPAdrM = IEUAdrExtM; | ||||
|     assign LSUFunct3M = Funct3M;  assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM; | ||||
|     assign LSUWriteDataM = WriteDataM; | ||||
|    end | ||||
| @ -151,8 +151,7 @@ module lsu ( | ||||
|     mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0)) | ||||
|     dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, | ||||
|       .PrivilegeModeW, .DisableTranslation, | ||||
|       .PAdr(PreLSUPAdrM), | ||||
|       .VAdr(IEUAdrM), | ||||
|       .VAdr(PreLSUPAdrM), | ||||
|       .Size(LSUFunct3M[1:0]), | ||||
|       .PTE, | ||||
|       .PageTypeWriteVal(PageType), | ||||
|  | ||||
| @ -59,7 +59,7 @@ module lsuvirtmem( | ||||
|   output logic [1:0]          PreLSURWM, | ||||
|   output logic [1:0]          LSUAtomicM, | ||||
|   output logic [11:0]         LSUAdrE, | ||||
|   output logic [`PA_BITS-1:0] PreLSUPAdrM, | ||||
|   output logic [`XLEN+1:0] PreLSUPAdrM, | ||||
|   input logic [`XLEN+1:0]     IEUAdrExtM, // *** can move internally.
 | ||||
|                    | ||||
|   output logic                InterlockStall, | ||||
| @ -71,12 +71,14 @@ module lsuvirtmem( | ||||
| 
 | ||||
|   logic                       AnyCPUReqM; | ||||
|   logic [`PA_BITS-1:0]        HPTWAdr; | ||||
|   logic [`XLEN+1:0]           HPTWAdrExt; | ||||
|   logic [1:0]                 HPTWRW; | ||||
|   logic [2:0]                 HPTWSize; | ||||
|   logic                       SelReplayMemE; | ||||
|   logic [11:0]                PreLSUAdrE;   | ||||
|   logic                       ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF; | ||||
|   logic                       DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM; | ||||
|   logic                       SelHPTWAdr; | ||||
|    | ||||
|   assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); | ||||
|   assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);   | ||||
| @ -94,13 +96,22 @@ module lsuvirtmem( | ||||
|     .DCacheStallM, .HPTWAdr, .HPTWRW, .HPTWSize); | ||||
|   // *** possible future optimization of simplifying page table entry with precomputed misalignment (Ross) low priority
 | ||||
| 
 | ||||
|   // Once the walk is done and it is time to update the DTLB we need to switch back 
 | ||||
|   // to the orignal data virtual address.
 | ||||
|   assign SelHPTWAdr = SelHPTW & ~DTLBWriteM; | ||||
|    | ||||
|   // multiplex the outputs to LSU
 | ||||
|   if(`XLEN+2-`PA_BITS > 0) begin | ||||
|     logic [(`XLEN+2-`PA_BITS)-1:0] zeros; | ||||
|     assign zeros = '0; | ||||
|     assign HPTWAdrExt = {zeros, HPTWAdr}; | ||||
|   end else assign HPTWAdrExt = HPTWAdr; | ||||
|   mux2 #(2) rwmux(MemRWM, HPTWRW, SelHPTW, PreLSURWM); | ||||
|   mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); | ||||
|   mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M);     | ||||
|   mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); | ||||
|   mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE); | ||||
|   mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLSUPAdrM); | ||||
|   mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, PreLSUPAdrM); | ||||
|   if(`HPTW_WRITES_SUPPORTED) | ||||
|     mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, LSUWriteDataM); | ||||
|   else assign LSUWriteDataM = WriteDataM; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| ///////////////////////////////////////////
 | ||||
| // ram.sv
 | ||||
| // swbytemask.sv
 | ||||
| //
 | ||||
| // Written: David_Harris@hmc.edu 9 January 2021
 | ||||
| // Modified: 
 | ||||
|  | ||||
| @ -49,16 +49,10 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries | ||||
|   // 11 - TLB is accessed for both read and write
 | ||||
|   input logic                 DisableTranslation, | ||||
| 
 | ||||
|   // VAdr goes to the TLB only. Virtual if the TLB is active.
 | ||||
|   // PAdr goes to address mux bypassing the TLB.  PAdr used when there is no translation.
 | ||||
|   // Comes from either the program address (instruction address or load/store address)
 | ||||
|   // or from the hardware pagetable walker.
 | ||||
|   // PAdr is intended to used as a phsycial address.  Discarded by the address mux when translation is
 | ||||
|   // performed.  
 | ||||
|   // VAdr is the virtual/physical address from IEU or physical address from HPTW.
 | ||||
|   // PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr)
 | ||||
|   // when there is translation.
 | ||||
|   input logic [`PA_BITS-1:0]  PAdr, // *** consider renaming this.
 | ||||
|   input logic [`XLEN-1:0]     VAdr, | ||||
|   input logic [`XLEN+1:0]     VAdr, | ||||
|   input logic [1:0]           Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
 | ||||
| 
 | ||||
|   // Controls for writing a new entry to the TLB
 | ||||
| @ -106,7 +100,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries | ||||
|       tlb(.clk, .reset, | ||||
|           .SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), | ||||
|           .SATP_ASID(SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE]), | ||||
|           .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, | ||||
|           .VAdr(VAdr[`XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, | ||||
|           .PrivilegeModeW, .ReadAccess, .WriteAccess, | ||||
|           .DisableTranslation, .PTE, .PageTypeWriteVal, | ||||
|           .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,  | ||||
| @ -122,8 +116,8 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries | ||||
|   // the lower 12 bits are the page offset. These are never changed from the orginal
 | ||||
|   // non translated address.
 | ||||
|   //mux2 #(`PA_BITS) addressmux(PAdr, TLBPAdr, Translate, PhysicalAddress);
 | ||||
|   mux2 #(`PA_BITS-12) addressmux(PAdr[`PA_BITS-1:12], TLBPAdr[`PA_BITS-1:12], Translate, PhysicalAddress[`PA_BITS-1:12]); | ||||
|   assign PhysicalAddress[11:0] = PAdr[11:0]; | ||||
|   mux2 #(`PA_BITS-12) addressmux(VAdr[`PA_BITS-1:12], TLBPAdr[`PA_BITS-1:12], Translate, PhysicalAddress[`PA_BITS-1:12]); | ||||
|   assign PhysicalAddress[11:0] = VAdr[11:0]; | ||||
|    | ||||
|    | ||||
|   ///////////////////////////////////////////
 | ||||
|  | ||||
| @ -43,7 +43,7 @@ module csr #(parameter | ||||
|   input  logic [31:0]      InstrM,  | ||||
|   input  logic [`XLEN-1:0] PCM, SrcAM, | ||||
|   input  logic             CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,  | ||||
|   input  logic             TimerIntM, ExtIntM, ExtIntS, SwIntM, | ||||
|   input  logic             TimerIntM, MExtIntM, SExtIntM, SwIntM, | ||||
|   input  logic [63:0]      MTIME_CLINT,  | ||||
|   input  logic             InstrValidM, FRegWriteM, LoadStallD, | ||||
|   input  logic             BPPredDirWrongM, | ||||
| @ -60,9 +60,9 @@ module csr #(parameter | ||||
|   output logic [1:0]       STATUS_MPP, | ||||
|   output logic             STATUS_SPP, STATUS_TSR, | ||||
|   output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, | ||||
|   output logic [`XLEN-1:0]      MEDELEG_REGW, MIDELEG_REGW,  | ||||
|   output logic [`XLEN-1:0]      MEDELEG_REGW,  | ||||
|   output logic [`XLEN-1:0] SATP_REGW, | ||||
|   output logic [11:0]      MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, | ||||
|   output logic [11:0]      MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW, | ||||
|   output logic             STATUS_MIE, STATUS_SIE, | ||||
|   output logic             STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, | ||||
|   output var logic [7:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], | ||||
| @ -122,9 +122,10 @@ module csr #(parameter | ||||
|   assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW); | ||||
|   assign CSRUWriteM = CSRWriteM;   | ||||
| 
 | ||||
|   csri  csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM, | ||||
|              .CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM, | ||||
|              .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM); | ||||
|   csri   csri(.clk, .reset, .InstrValidNotFlushedM, .StallW,  | ||||
|               .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,  | ||||
|               .MExtIntM, .SExtIntM, .TimerIntM, .SwIntM, | ||||
|               .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW); | ||||
|   csrsr csrsr(.clk, .reset, .StallW, | ||||
|               .WriteMSTATUSM, .WriteSSTATUSM,  | ||||
|               .TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW, | ||||
|  | ||||
| @ -32,39 +32,26 @@ | ||||
| `include "wally-config.vh" | ||||
| 
 | ||||
| module csri #(parameter  | ||||
|   // Machine CSRs
 | ||||
|     MIE = 12'h304, | ||||
|     MIP = 12'h344, | ||||
|     SIE = 12'h104, | ||||
|   SIP = 12'h144) ( | ||||
|     SIP = 12'h144 | ||||
|   ) ( | ||||
|     input  logic             clk, reset,  | ||||
|     input  logic             InstrValidNotFlushedM, StallW, | ||||
|     input  logic             CSRMWriteM, CSRSWriteM, | ||||
|     input  logic [`XLEN-1:0] CSRWriteValM, | ||||
|     input  logic [11:0]      CSRAdrM, | ||||
|     input  logic             ExtIntM, ExtIntS, TimerIntM, SwIntM, | ||||
|     input  logic [`XLEN-1:0]      MIDELEG_REGW, | ||||
|     output logic [11:0]      MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, | ||||
|     input  logic [`XLEN-1:0] CSRWriteValM | ||||
|     input  logic             MExtIntM, SExtIntM, TimerIntM, SwIntM, | ||||
|     input  logic [11:0]      MIDELEG_REGW, | ||||
|     output logic [11:0]      MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW | ||||
|   ); | ||||
| 
 | ||||
|   logic [9:0]      IP_REGW_writeable; | ||||
|   logic [11:0]     IntInM, IP_REGW, IE_REGW; | ||||
|   logic [11:0]     MIP_WRITE_MASK, SIP_WRITE_MASK; | ||||
|   logic [11:0]     IP_REGW_writeable; // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
 | ||||
|   logic [11:0]     IP_REGW, IE_REGW; | ||||
|   logic [11:0]     MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK; | ||||
|   logic            WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM; | ||||
| 
 | ||||
|   // Determine which interrupts need to be set
 | ||||
|   // assumes no N-mode user interrupts
 | ||||
| 
 | ||||
|   always_comb begin | ||||
|     IntInM     = 0;  | ||||
|     IntInM[11] = ExtIntM;                               // MEIP
 | ||||
|     IntInM[9]  = (ExtIntM & MIDELEG_REGW[9]);           // SEIP
 | ||||
|     IntInM[7]  = TimerIntM;                             // MTIP
 | ||||
|     IntInM[5]  = TimerIntM &  MIDELEG_REGW[5];          // STIP
 | ||||
|     IntInM[3]  = SwIntM;                                // MSIP
 | ||||
|     IntInM[1]  = SwIntM &  MIDELEG_REGW[1];             // SSIP
 | ||||
|    end | ||||
| 
 | ||||
|   // Interrupt Write Enables
 | ||||
|   assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM; | ||||
|   assign WriteMIEM = CSRMWriteM & (CSRAdrM == MIE) & InstrValidNotFlushedM; | ||||
| @ -78,32 +65,29 @@ module csri #(parameter | ||||
|   if (`S_SUPPORTED) begin:mask | ||||
|     assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9)
 | ||||
|     assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
 | ||||
|     assign MIE_WRITE_MASK = 12'hAAA; | ||||
|   end else begin:mask | ||||
|     assign MIP_WRITE_MASK = 12'h000; | ||||
|     assign SIP_WRITE_MASK = 12'h000; | ||||
|     assign MIE_WRITE_MASK = 12'h888; | ||||
|   end | ||||
|   always @(posedge clk) | ||||
|     if (reset)          IP_REGW_writeable <= 10'b0; | ||||
|     else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
 | ||||
|     else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
 | ||||
|     else                IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes
 | ||||
|     if (reset)          IP_REGW_writeable <= 12'b0; | ||||
|     else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK); | ||||
|     else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK); | ||||
|   always @(posedge clk) | ||||
|     if (reset)          IE_REGW <= 12'b0; | ||||
|     else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
 | ||||
|     else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
 | ||||
|     else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
 | ||||
| 
 | ||||
|   // restricted views of registers
 | ||||
|   // Add ExtIntM read-only signal
 | ||||
|   assign IP_REGW = {ExtIntM,1'b0,ExtIntS,9'b0} | {2'b0,IP_REGW_writeable}; | ||||
|   assign IP_REGW = {MExtIntM,1'b0,SExtIntM|IP_REGW_writeable[9],1'b0,TimerIntM,1'b0,IP_REGW_writeable[5],1'b0,SwIntM,1'b0,IP_REGW_writeable[1],1'b0}; | ||||
| 
 | ||||
|     // Machine Mode
 | ||||
|   assign MIP_REGW = IP_REGW; | ||||
|   assign MIE_REGW = IE_REGW; | ||||
| 
 | ||||
|   // Supervisor mode
 | ||||
|   if (`S_SUPPORTED) begin | ||||
|     assign SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible
 | ||||
|     assign SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; | ||||
|     assign SIP_REGW = IP_REGW & 12'h222; | ||||
|     assign SIE_REGW = IE_REGW & 12'h222; | ||||
|   end else begin | ||||
|     assign SIP_REGW = 12'b0; | ||||
|     assign SIE_REGW = 12'b0; | ||||
|  | ||||
| @ -67,7 +67,7 @@ module csrm #(parameter | ||||
|     // Constants
 | ||||
|     ZERO = {(`XLEN){1'b0}}, | ||||
|     MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), | ||||
|    MIDELEG_MASK = {{(`XLEN-12){1'b0}}, 12'h222} | ||||
|     MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable
 | ||||
|   ) ( | ||||
|     input logic 	     clk, reset,  | ||||
|     input logic 	     InstrValidNotFlushedM, StallW, | ||||
| @ -78,7 +78,8 @@ module csrm #(parameter | ||||
|     output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW, | ||||
|     (* mark_debug = "true" *)  output logic [`XLEN-1:0] MEPC_REGW,     | ||||
|     output logic [31:0]      MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,  | ||||
|     output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, | ||||
|     output logic [`XLEN-1:0] MEDELEG_REGW, | ||||
|     output logic [11:0]      MIDELEG_REGW, | ||||
|     // 64-bit registers in RV64, or two 32-bit registers in RV32
 | ||||
|     //output var logic [63:0]      PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
 | ||||
|     output 		     var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], | ||||
| @ -148,7 +149,7 @@ module csrm #(parameter | ||||
|   flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW);  | ||||
|   if (`S_SUPPORTED) begin:deleg // DELEG registers should exist
 | ||||
|     flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW); | ||||
|     flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); | ||||
|     flopenr #(12)    MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); | ||||
|   end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0; | ||||
| 
 | ||||
|   flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); | ||||
| @ -188,7 +189,7 @@ module csrm #(parameter | ||||
|       MSTATUSH:  CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported
 | ||||
|       MTVEC:     CSRMReadValM = MTVEC_REGW; | ||||
|       MEDELEG:   CSRMReadValM = MEDELEG_REGW; | ||||
|       MIDELEG:   CSRMReadValM = MIDELEG_REGW; | ||||
|       MIDELEG:   CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW}; | ||||
|       MIP:       CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW}; | ||||
|       MIE:       CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW}; | ||||
|       MSCRATCH:  CSRMReadValM = MSCRATCH_REGW; | ||||
|  | ||||
| @ -55,7 +55,7 @@ module privileged ( | ||||
|   input  logic             InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD, | ||||
|   input  logic             LoadMisalignedFaultM, | ||||
|   input  logic             StoreAmoMisalignedFaultM, | ||||
|   input  logic             TimerIntM, ExtIntM, ExtIntS, SwIntM, | ||||
|   input  logic             TimerIntM, MExtIntM, SExtIntM, SwIntM, | ||||
|   input  logic [63:0]      MTIME_CLINT,  | ||||
|   input  logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM, | ||||
|   input  logic [4:0]       SetFflagsM, | ||||
| @ -69,7 +69,6 @@ module privileged ( | ||||
|   input logic StoreAmoAccessFaultM, | ||||
| 
 | ||||
|   output logic 		   ExceptionM, | ||||
|   output logic 		   PendingInterruptM, | ||||
|   output logic		   IllegalFPUInstrE, | ||||
|   output logic [1:0]       PrivilegeModeW, | ||||
|   output logic [`XLEN-1:0] SATP_REGW, | ||||
| @ -86,7 +85,8 @@ module privileged ( | ||||
| 
 | ||||
|   logic [`XLEN-1:0] CauseM, NextFaultMtvalM; | ||||
|   logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW; | ||||
|   logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW; | ||||
|   logic [`XLEN-1:0] MEDELEG_REGW; | ||||
|   logic [11:0]      MIDELEG_REGW; | ||||
| 
 | ||||
|   logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM; | ||||
|   logic IllegalCSRAccessM; | ||||
| @ -111,7 +111,7 @@ module privileged ( | ||||
|   ///////////////////////////////////////////
 | ||||
| 
 | ||||
|   // get bits of DELEG registers based on CAUSE
 | ||||
|   assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; | ||||
|   assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; | ||||
|    | ||||
|   // PrivilegeMode FSM
 | ||||
|   always_comb begin | ||||
| @ -150,7 +150,7 @@ module privileged ( | ||||
|           .StallE, .StallM, .StallW, | ||||
|           .InstrM, .PCM, .SrcAM, | ||||
|           .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,  | ||||
|           .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, | ||||
|           .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, | ||||
|           .MTIME_CLINT,  | ||||
|           .InstrValidM, .FRegWriteM, .LoadStallD, | ||||
|           .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,  | ||||
| @ -159,9 +159,9 @@ module privileged ( | ||||
|           .CauseM, .NextFaultMtvalM, .STATUS_MPP, | ||||
|           .STATUS_SPP, .STATUS_TSR, | ||||
|           .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, | ||||
|           .MEDELEG_REGW, .MIDELEG_REGW,  | ||||
|           .MEDELEG_REGW,  | ||||
|           .SATP_REGW, | ||||
|           .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, | ||||
|           .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, | ||||
|           .STATUS_MIE, .STATUS_SIE, | ||||
|           .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, | ||||
|           .PMPCFG_ARRAY_REGW, | ||||
| @ -210,7 +210,7 @@ module privileged ( | ||||
|             .mretM, .sretM,  | ||||
|             .PrivilegeModeW, .NextPrivilegeModeM, | ||||
|             .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, | ||||
|             .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, | ||||
|             .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW, | ||||
|             .STATUS_MIE, .STATUS_SIE, | ||||
|             .PCM, | ||||
|             .InstrMisalignedAdrM, .IEUAdrM,  | ||||
| @ -219,7 +219,6 @@ module privileged ( | ||||
|             .TrapM, .MTrapM, .STrapM, .UTrapM, .RetM, | ||||
|             .InterruptM, | ||||
|             .ExceptionM, | ||||
|             .PendingInterruptM, | ||||
|             .PrivilegedNextPCM, .CauseM, .NextFaultMtvalM); | ||||
| endmodule | ||||
| 
 | ||||
|  | ||||
| @ -41,7 +41,7 @@ module trap ( | ||||
|   (* mark_debug = "true" *) input logic 		   mretM, sretM,  | ||||
|   input logic [1:0] 	   PrivilegeModeW, NextPrivilegeModeM, | ||||
|   (* mark_debug = "true" *) input logic [`XLEN-1:0]  MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, | ||||
|   (* mark_debug = "true" *) input logic [11:0] 	   MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, | ||||
|   (* mark_debug = "true" *) input logic [11:0] 	   MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW, | ||||
|   input logic 		   STATUS_MIE, STATUS_SIE, | ||||
|   input logic [`XLEN-1:0]  PCM, | ||||
|   input logic [`XLEN-1:0]  InstrMisalignedAdrM, IEUAdrM,  | ||||
| @ -50,15 +50,13 @@ module trap ( | ||||
|   output logic 		   TrapM, MTrapM, STrapM, UTrapM, RetM, | ||||
|   output logic 		   InterruptM, | ||||
|   output logic 		   ExceptionM, | ||||
|   output logic 		   PendingInterruptM, | ||||
| 
 | ||||
|   output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM | ||||
| //  output logic [11:0]     MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
 | ||||
| //  input  logic            WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
 | ||||
| ); | ||||
| 
 | ||||
|   logic MIntGlobalEnM, SIntGlobalEnM; | ||||
|   (* mark_debug = "true" *) logic [11:0] PendingIntsM;  | ||||
|   (* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM;  | ||||
|   //logic InterruptM;
 | ||||
|   logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector; | ||||
|   logic Exception1M; | ||||
| @ -67,11 +65,13 @@ module trap ( | ||||
|   // interrupt if any sources are pending
 | ||||
|   // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage)
 | ||||
|   // & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice
 | ||||
|   // MPendingIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i]
 | ||||
|   // Sinterrupt[i] = ((priv == S & sstatus.SIE) | (priv < S)) & sip[i] & sie[i]
 | ||||
|   assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9
 | ||||
|   assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9
 | ||||
|   assign PendingIntsM = ((MIP_REGW & MIE_REGW) & ({12{MIntGlobalEnM}} & 12'h888)) | ((SIP_REGW & SIE_REGW) & ({12{SIntGlobalEnM}} & 12'h222)); | ||||
|   assign PendingInterruptM = (|PendingIntsM) & InstrValidM;   | ||||
|   assign InterruptM = PendingInterruptM & ~(CommittedM);  // *** RT. temporary hack to prevent integer division from having an interrupt during divide.
 | ||||
|   assign MPendingIntsM = {12{MIntGlobalEnM}} & MIP_REGW & MIE_REGW & ~MIDELEG_REGW; | ||||
|   assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW; | ||||
|   assign InterruptM = (|MPendingIntsM || |SPendingIntsM) && InstrValidM && ~(CommittedM);  // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
 | ||||
| 
 | ||||
|   // Trigger Traps and RET
 | ||||
|   // According to RISC-V Spec Section 1.6, exceptions are caused by instructions.  Interrupts are external asynchronous.
 | ||||
| @ -102,7 +102,7 @@ module trap ( | ||||
|   if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec | ||||
|       always_comb | ||||
|         if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1) | ||||
|           PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + {CauseM[`XLEN-5:0], 2'b00}, 2'b00}; | ||||
|           PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + CauseM[`XLEN-3:0], 2'b00}; | ||||
|         else | ||||
|           PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00}; | ||||
|   end | ||||
| @ -119,12 +119,15 @@ module trap ( | ||||
|   // Exceptions are of lower priority than all interrupts (3.1.9)
 | ||||
|   always_comb | ||||
|     if      (reset)                 CauseM = 0; // hard reset 3.3
 | ||||
|     else if (PendingIntsM[11])      CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
 | ||||
|     else if (PendingIntsM[3])       CauseM = (1 << (`XLEN-1)) + 3;  // Machine Sw Int
 | ||||
|     else if (PendingIntsM[7])       CauseM = (1 << (`XLEN-1)) + 7;  // Machine Timer Int
 | ||||
|     else if (PendingIntsM[9])       CauseM = (1 << (`XLEN-1)) + 9;  // Supervisor External Int
 | ||||
|     else if (PendingIntsM[1])       CauseM = (1 << (`XLEN-1)) + 1;  // Supervisor Sw Int
 | ||||
|     else if (PendingIntsM[5])       CauseM = (1 << (`XLEN-1)) + 5;  // Supervisor Timer Int
 | ||||
|     else if (MPendingIntsM[11])     CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
 | ||||
|     else if (MPendingIntsM[3])      CauseM = (1 << (`XLEN-1)) + 3;  // Machine Sw Int
 | ||||
|     else if (MPendingIntsM[7])      CauseM = (1 << (`XLEN-1)) + 7;  // Machine Timer Int
 | ||||
|     else if (MPendingIntsM[9])      CauseM = (1 << (`XLEN-1)) + 9;  // Supervisor External Int handled by M-mode
 | ||||
|     else if (MPendingIntsM[1])      CauseM = (1 << (`XLEN-1)) + 1;  // Supervisor Sw Int       handled by M-mode
 | ||||
|     else if (MPendingIntsM[5])      CauseM = (1 << (`XLEN-1)) + 5;  // Supervisor Timer Int    handled by M-mode
 | ||||
|     else if (SPendingIntsM[9])      CauseM = (1 << (`XLEN-1)) + 9;  // Supervisor External Int handled by S-mode
 | ||||
|     else if (SPendingIntsM[1])      CauseM = (1 << (`XLEN-1)) + 1;  // Supervisor Sw Int       handled by S-mode
 | ||||
|     else if (SPendingIntsM[5])      CauseM = (1 << (`XLEN-1)) + 5;  // Supervisor Timer Int    handled by S-mode
 | ||||
|     else if (InstrPageFaultM)       CauseM = 12; | ||||
|     else if (InstrAccessFaultM)     CauseM = 1; | ||||
|     else if (InstrMisalignedFaultM) CauseM = 0; | ||||
|  | ||||
| @ -57,7 +57,7 @@ module plic ( | ||||
|   input  logic             UARTIntr,GPIOIntr, | ||||
|   output logic [`XLEN-1:0] HREADPLIC, | ||||
|   output logic             HRESPPLIC, HREADYPLIC, | ||||
|   output logic             ExtIntM, ExtIntS); | ||||
|   output logic             MExtIntM, SExtIntM); | ||||
| 
 | ||||
|   logic memwrite, memread, initTrans; | ||||
|   logic [23:0] entry, entryd; | ||||
| @ -253,10 +253,10 @@ module plic ( | ||||
|       threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3]; | ||||
|       threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2]; | ||||
|     end | ||||
|   end | ||||
|   // is the max priority > threshold?
 | ||||
|   // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
 | ||||
|     end | ||||
|   assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]); | ||||
|   assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]); | ||||
|   assign MExtIntM = |(threshMask[0] & priorities_with_irqs[0]); | ||||
|   assign SExtIntM = |(threshMask[1] & priorities_with_irqs[1]); | ||||
| endmodule | ||||
| 
 | ||||
|  | ||||
| @ -43,78 +43,22 @@ module ram #(parameter BASE=0, RANGE = 65535) ( | ||||
|   output logic             HRESPRam, HREADYRam | ||||
| ); | ||||
| 
 | ||||
|   localparam MemStartAddr = BASE>>(1+`XLEN/32); | ||||
|   localparam MemEndAddr = (RANGE+BASE)>>1+(`XLEN/32); | ||||
|    | ||||
|   logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; | ||||
|   logic [`XLEN/8-1:0] 		  ByteMaskM; | ||||
|   logic [31:0]        HWADDR, A; | ||||
| 
 | ||||
|   logic				  prevHREADYRam, risingHREADYRam; | ||||
|   logic				  initTrans; | ||||
|   logic				  memwrite; | ||||
|   logic [3:0] 		  busycount; | ||||
|   logic [`XLEN/8-1:0] ByteMaskM; | ||||
|    | ||||
|   if(`FPGA) begin:ram | ||||
|     initial begin | ||||
|       // *** need to address this preload for fpga.  It should work as a preload file
 | ||||
|       // but for some reason vivado is not synthesizing the preload.
 | ||||
|       //$readmemh(PRELOAD, RAM);
 | ||||
|       RAM[BASE+0] =  64'h94e1819300002197;  | ||||
|       RAM[BASE+1] =  64'h4281420141014081;  | ||||
|       RAM[BASE+2] =  64'h4481440143814301;  | ||||
|       RAM[BASE+3] =  64'h4681460145814501;  | ||||
|       RAM[BASE+4] =  64'h4881480147814701;  | ||||
|       RAM[BASE+5] =  64'h4a814a0149814901;  | ||||
|       RAM[BASE+6] =  64'h4c814c014b814b01;  | ||||
|       RAM[BASE+7] =  64'h4e814e014d814d01;  | ||||
|       RAM[BASE+8] =  64'h0110011b4f814f01;  | ||||
|       RAM[BASE+9] =  64'h059b45011161016e;  | ||||
|       RAM[BASE+10] = 64'h0004063705fe0010;  | ||||
|       RAM[BASE+11] = 64'h05a000ef8006061b;  | ||||
|       RAM[BASE+12] = 64'h0ff003930000100f;  | ||||
|       RAM[BASE+13] = 64'h4e952e3110060e37;  | ||||
|       RAM[BASE+14] = 64'hc602829b0053f2b7;  | ||||
|       RAM[BASE+15] = 64'h2023fe02dfe312fd;  | ||||
|       RAM[BASE+16] = 64'h829b0053f2b7007e;  | ||||
|       RAM[BASE+17] = 64'hfe02dfe312fdc602;  | ||||
|       RAM[BASE+18] = 64'h4de31efd000e2023;  | ||||
|       RAM[BASE+19] = 64'h059bf1402573fdd0;  | ||||
|       RAM[BASE+20] = 64'h0000061705e20870;  | ||||
|       RAM[BASE+21] = 64'h0010029b01260613;  | ||||
|       RAM[BASE+22] = 64'h11010002806702fe;  | ||||
|       RAM[BASE+23] = 64'h84b2842ae426e822;  | ||||
|       RAM[BASE+24] = 64'h892ee04aec064505;  | ||||
|       RAM[BASE+25] = 64'h06e000ef07e000ef;  | ||||
|       RAM[BASE+26] = 64'h979334fd02905563;  | ||||
|       RAM[BASE+27] = 64'h07930177d4930204;  | ||||
|       RAM[BASE+28] = 64'h4089093394be2004;  | ||||
|       RAM[BASE+29] = 64'h04138522008905b3;  | ||||
|       RAM[BASE+30] = 64'h19e3014000ef2004;  | ||||
|       RAM[BASE+31] = 64'h64a2644260e2fe94;  | ||||
|       RAM[BASE+32] = 64'h6749808261056902;  | ||||
|       RAM[BASE+33] = 64'hdfed8b8510472783;  | ||||
|       RAM[BASE+34] = 64'h2423479110a73823;  | ||||
|       RAM[BASE+35] = 64'h10472783674910f7;  | ||||
|       RAM[BASE+36] = 64'h20058693ffed8b89;  | ||||
|       RAM[BASE+37] = 64'h05a1118737836749;  | ||||
|       RAM[BASE+38] = 64'hfed59be3fef5bc23;  | ||||
|       RAM[BASE+39] = 64'h1047278367498082;  | ||||
|       RAM[BASE+40] = 64'h67c98082dfed8b85;  | ||||
|       RAM[BASE+41] = 64'h0000808210a7a023;  | ||||
|     end // initial begin
 | ||||
|   end // if (FPGA)
 | ||||
| 
 | ||||
|   swbytemask swbytemask(.HSIZED, .HADDRD(A[2:0]), .ByteMask(ByteMaskM)); | ||||
|   swbytemask swbytemask(.HSIZED, .HADDRD(HWADDR[2:0]), .ByteMask(ByteMaskM)); | ||||
| 
 | ||||
|   assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00); | ||||
| 
 | ||||
|   // *** this seems like a weird way to use reset
 | ||||
|   flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam &  HWRITE, memwrite); | ||||
|   flopenr #(32)   haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A); | ||||
| 
 | ||||
|   // busy FSM to extend READY signal
 | ||||
|   always_ff @(posedge HCLK, negedge HRESETn)  | ||||
|   always @(posedge HCLK, negedge HRESETn)  | ||||
|     if (~HRESETn) begin | ||||
|       busycount <= 0; | ||||
|       HREADYRam <= #1 0; | ||||
| @ -132,46 +76,25 @@ module ram #(parameter BASE=0, RANGE = 65535) ( | ||||
|     end | ||||
|   assign HRESPRam = 0; // OK
 | ||||
| 
 | ||||
|   localparam ADDR_WDITH = $clog2(RANGE/8); | ||||
|   localparam OFFSET = $clog2(`XLEN/8); | ||||
|    | ||||
|   // Rising HREADY edge detector
 | ||||
|   //   Indicates when ram is finishing up
 | ||||
|   //   Needed because HREADY may go high for other reasons,
 | ||||
|   //   and we only want to write data when finishing up.
 | ||||
|   flopr #(1) prevhreadyRamreg(HCLK,~HRESETn,HREADYRam,prevHREADYRam); | ||||
|   flopenr #(1) prevhreadyRamreg(HCLK,~HRESETn, 1'b1, HREADYRam,prevHREADYRam); | ||||
|   assign risingHREADYRam = HREADYRam & ~prevHREADYRam; | ||||
| 
 | ||||
|   // Model memory read and write
 | ||||
| /* -----\/----- EXCLUDED -----\/----- | ||||
|   integer       index; | ||||
| 
 | ||||
|   initial begin | ||||
|     for(index = MemStartAddr; index < MemEndAddr; index = index + 1) begin | ||||
|       RAM[index] <= {`XLEN{1'b0}}; | ||||
|     end | ||||
|   end | ||||
|  -----/\----- EXCLUDED -----/\----- */ | ||||
|    | ||||
|   /* verilator lint_off WIDTH */ | ||||
|   genvar index; | ||||
|   always_ff @(posedge HCLK) | ||||
|   always @(posedge HCLK) | ||||
|     HWADDR <= #1 A; | ||||
|   if (`XLEN == 64)  begin:ramrw | ||||
|     always_ff @(posedge HCLK)  | ||||
|       HREADRam <= #1 RAM[A[31:3]]; | ||||
|     for(index = 0; index < `XLEN/8; index++) begin | ||||
|       always_ff @(posedge HCLK) begin | ||||
|         if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:3]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index]; | ||||
|       end | ||||
|     end | ||||
|   end else begin  | ||||
|     always_ff @(posedge HCLK)  | ||||
|       HREADRam <= #1 RAM[A[31:2]]; | ||||
|     for(index = 0; index < `XLEN/8; index++) begin | ||||
|       always_ff @(posedge HCLK) begin:ramrw | ||||
|         if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:2]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index]; | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|   /* verilator lint_on WIDTH */ | ||||
| 
 | ||||
|   bram2p1r1w #(`XLEN/8, 8, ADDR_WDITH, `FPGA) | ||||
|   memory(.clk(HCLK), .enaA(1'b1), | ||||
| 		 .addrA(A[ADDR_WDITH+OFFSET-1:OFFSET]), .doutA(HREADRam), | ||||
| 		 .enaB(memwrite & risingHREADYRam), .weB(ByteMaskM), | ||||
| 		 .addrB(HWADDR[ADDR_WDITH+OFFSET-1:OFFSET]), .dinB(HWDATA)); | ||||
| 		  | ||||
|    | ||||
| endmodule | ||||
|    | ||||
|  | ||||
| @ -55,7 +55,7 @@ module uncore ( | ||||
|   input  logic [3:0]       HSIZED, | ||||
|   input  logic             HWRITED, | ||||
|   // peripheral pins
 | ||||
|   output logic             TimerIntM, SwIntM, ExtIntM, ExtIntS, | ||||
|   output logic             TimerIntM, SwIntM, MExtIntM, SExtIntM, | ||||
|   input  logic [31:0]      GPIOPinsIn, | ||||
|   output logic [31:0]      GPIOPinsOut, GPIOPinsEn,  | ||||
|   input  logic             UARTSin, | ||||
| @ -133,10 +133,10 @@ module uncore ( | ||||
|         .HWRITE, .HREADY, .HTRANS, .HWDATA, | ||||
|         .UARTIntr, .GPIOIntr, | ||||
|         .HREADPLIC, .HRESPPLIC, .HREADYPLIC, | ||||
|         .ExtIntM, .ExtIntS); | ||||
|         .MExtIntM, .SExtIntM); | ||||
|     end else begin : plic | ||||
|       assign ExtIntM = 0; | ||||
|       assign ExtIntS = 0; | ||||
|       assign MExtIntM = 0; | ||||
|       assign SExtIntM = 0; | ||||
|     end | ||||
|     if (`GPIO_SUPPORTED == 1) begin : gpio | ||||
|       gpio gpio( | ||||
|  | ||||
| @ -34,7 +34,7 @@ | ||||
| module wallypipelinedcore ( | ||||
|    input logic             clk, reset, | ||||
|    // Privileged
 | ||||
|    input logic             TimerIntM, ExtIntM, ExtIntS, SwIntM, | ||||
|    input logic             TimerIntM, MExtIntM, SExtIntM, SwIntM, | ||||
|    input logic [63:0]         MTIME_CLINT,  | ||||
|    // Bus Interface
 | ||||
|    input logic [`AHBW-1:0]  HRDATA, | ||||
| @ -157,7 +157,6 @@ module wallypipelinedcore ( | ||||
|   logic [2:0]             LSUBusSize; | ||||
|    | ||||
|   logic             ExceptionM; | ||||
|   logic             PendingInterruptM; | ||||
|   logic             DCacheMiss; | ||||
|   logic             DCacheAccess; | ||||
|   logic             ICacheMiss; | ||||
| @ -170,7 +169,7 @@ module wallypipelinedcore ( | ||||
|     .StallF, .StallD, .StallE, .StallM, .StallW, | ||||
|     .FlushF, .FlushD, .FlushE, .FlushM, .FlushW, | ||||
| 
 | ||||
|     .ExceptionM, .PendingInterruptM, | ||||
|     .ExceptionM, | ||||
|     // Fetch
 | ||||
|     .IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr, | ||||
|     .IFUBusRead, .IFUStallF, | ||||
| @ -331,7 +330,7 @@ module wallypipelinedcore ( | ||||
|          .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, | ||||
|          .InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD, | ||||
|          .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, | ||||
|          .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, | ||||
|          .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, | ||||
|          .MTIME_CLINT,  | ||||
|          .InstrMisalignedAdrM, .IEUAdrM, | ||||
|          .SetFflagsM, | ||||
| @ -339,7 +338,7 @@ module wallypipelinedcore ( | ||||
|          // *** do these need to be split up into one for dmem and one for ifu?
 | ||||
|          // instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem?
 | ||||
|          .InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, | ||||
|          .ExceptionM, .PendingInterruptM, .IllegalFPUInstrE, | ||||
|          .ExceptionM, .IllegalFPUInstrE, | ||||
|          .PrivilegeModeW, .SATP_REGW, | ||||
|          .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, | ||||
|          .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,  | ||||
|  | ||||
| @ -74,7 +74,7 @@ module wallypipelinedsoc ( | ||||
|   logic             HRESP; | ||||
|   logic             TimerIntM, SwIntM; // from CLINT
 | ||||
|   logic [63:0]      MTIME_CLINT; // from CLINT to CSRs
 | ||||
|   logic             ExtIntM,ExtIntS; // from PLIC
 | ||||
|   logic             MExtIntM,SExtIntM; // from PLIC
 | ||||
|   logic [2:0]       HADDRD; | ||||
|   logic [3:0]       HSIZED; | ||||
|   logic             HWRITED; | ||||
| @ -84,7 +84,7 @@ module wallypipelinedsoc ( | ||||
|     | ||||
|   // instantiate processor and memories
 | ||||
|   wallypipelinedcore core(.clk, .reset, | ||||
|     .TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,  | ||||
|     .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM,  | ||||
|     .MTIME_CLINT, | ||||
|     .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, | ||||
|     .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, | ||||
| @ -94,7 +94,7 @@ module wallypipelinedsoc ( | ||||
|   uncore uncore(.HCLK, .HRESETn, .TIMECLK, | ||||
|     .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT, | ||||
|     .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED, | ||||
|     .TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,  | ||||
|     .TimerIntM, .SwIntM, .MExtIntM, .SExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,  | ||||
| 		.HSELEXT, | ||||
| 		.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK | ||||
| 		 | ||||
|  | ||||
| @ -357,7 +357,7 @@ module testbench; | ||||
|   initial begin | ||||
|     force dut.core.priv.priv.SwIntM = 0; | ||||
|     force dut.core.priv.priv.TimerIntM = 0; | ||||
|     force dut.core.priv.priv.ExtIntM = 0;     | ||||
|     force dut.core.priv.priv.MExtIntM = 0;     | ||||
|     $sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR); | ||||
|     $sformat(linuxImageDir,"%s/buildroot/output/images/",RISCV_DIR); | ||||
|     if (CHECKPOINT!=0) | ||||
| @ -368,14 +368,14 @@ module testbench; | ||||
|     ProgramLabelMapFile = {linuxImageDir,"disassembly/vmlinux.objdump.lab"}; | ||||
|     // initialize bootrom
 | ||||
|     memFile = $fopen({testvectorDir,"bootmem.bin"}, "rb"); | ||||
|     readResult = $fread(dut.uncore.bootrom.bootrom.RAM,memFile); | ||||
|     readResult = $fread(dut.uncore.bootrom.bootrom.memory.RAM,memFile); | ||||
|     $fclose(memFile); | ||||
|     // initialize RAM
 | ||||
|     if (CHECKPOINT==0)  | ||||
|       memFile = $fopen({testvectorDir,"ram.bin"}, "rb"); | ||||
|     else | ||||
|       memFile = $fopen({checkpointDir,"ram.bin"}, "rb"); | ||||
|     readResult = $fread(dut.uncore.ram.ram.RAM,memFile); | ||||
|     readResult = $fread(dut.uncore.ram.ram.memory.RAM,memFile); | ||||
|     $fclose(memFile); | ||||
|     if (CHECKPOINT==0) begin // normal
 | ||||
|       traceFileM = $fopen({testvectorDir,"all.txt"}, "r"); | ||||
| @ -383,7 +383,7 @@ module testbench; | ||||
|       InstrCountW = '0; | ||||
|       AttemptedInstructionCount = '0; | ||||
|     end else begin // checkpoint
 | ||||
|       //$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.RAM);
 | ||||
|       //$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.memory.RAM);
 | ||||
|       traceFileE = $fopen({checkpointDir,"all.txt"}, "r"); | ||||
|       traceFileM = $fopen({checkpointDir,"all.txt"}, "r"); | ||||
|       InstrCountW = CHECKPOINT; | ||||
| @ -791,9 +791,9 @@ module testbench; | ||||
|         BaseAdr = SATP[43:0] << 12; | ||||
|         for (i = 2; i >= 0; i--) begin | ||||
|           PAdr = BaseAdr + (VPN[i] << 3); | ||||
|           // ram.RAM is 64-bit addressed. PAdr specifies a byte. We right shift
 | ||||
|           // ram.memory.RAM is 64-bit addressed. PAdr specifies a byte. We right shift
 | ||||
|           // by 3 (the PTE size) to get the requested 64-bit PTE.
 | ||||
|           PTE = dut.uncore.ram.ram.RAM[PAdr >> 3]; | ||||
|           PTE = dut.uncore.ram.ram.memory.RAM[PAdr >> 3]; | ||||
|           PTE_R = PTE[1]; | ||||
|           PTE_X = PTE[3]; | ||||
|           if (PTE_R | PTE_X) begin | ||||
|  | ||||
| @ -44,7 +44,7 @@ module testbench; | ||||
|   int test, i, errors, totalerrors; | ||||
|   logic [31:0] sig32[0:SIGNATURESIZE]; | ||||
|   logic [`XLEN-1:0] signature[0:SIGNATURESIZE]; | ||||
|   logic [`XLEN-1:0] testadr; | ||||
|   logic [`XLEN-1:0] testadr, testadrNoBase; | ||||
|   string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; | ||||
|   logic [31:0] InstrW; | ||||
| 
 | ||||
| @ -170,6 +170,7 @@ logic [3:0] dummy; | ||||
|       test = 1; | ||||
|       totalerrors = 0; | ||||
|       testadr = 0; | ||||
|       testadrNoBase = 0; | ||||
|       // fill memory with defined values to reduce Xs in simulation
 | ||||
|       // Quick note the memory will need to be initialized.  The C library does not
 | ||||
|       //  guarantee the  initialized reads.  For example a strcmp can read 6 byte
 | ||||
| @ -178,7 +179,7 @@ logic [3:0] dummy; | ||||
|       // the design.
 | ||||
|       if (TEST == "coremark")  | ||||
|         for (i=MemStartAddr; i<MemEndAddr; i = i+1)  | ||||
|           dut.uncore.ram.ram.RAM[i] = 64'h0;  | ||||
|           dut.uncore.ram.ram.memory.RAM[i] = 64'h0;  | ||||
| 
 | ||||
|       // read test vectors into memory
 | ||||
|       pathname = tvpaths[tests[0].atoi()]; | ||||
| @ -186,9 +187,9 @@ logic [3:0] dummy; | ||||
|         pathname = tvpaths[0]; | ||||
|       else pathname = tvpaths[1]; */ | ||||
|       memfilename = {pathname, tests[test], ".elf.memfile"}; | ||||
|       if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); | ||||
|       else              $readmemh(memfilename, dut.uncore.ram.ram.RAM); | ||||
|       if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); | ||||
|       if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM); | ||||
|       else              $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); | ||||
|       if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM); | ||||
| 
 | ||||
|       ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; | ||||
|       ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; | ||||
| @ -243,14 +244,15 @@ logic [3:0] dummy; | ||||
|         errors = (i == SIGNATURESIZE+1); // error if file is empty
 | ||||
|         i = 0; | ||||
|         testadr = (`RAM_BASE+tests[test+1].atohex())/(`XLEN/8); | ||||
|         testadrNoBase = (tests[test+1].atohex())/(`XLEN/8); | ||||
|         /* verilator lint_off INFINITELOOP */ | ||||
|         while (signature[i] !== 'bx) begin | ||||
|           logic [`XLEN-1:0] sig; | ||||
|           if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.RAM[testadr+i]; | ||||
|           else                   sig = dut.uncore.ram.ram.RAM[testadr+i]; | ||||
|           if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.memory.RAM[testadrNoBase+i]; | ||||
|           else                   sig = dut.uncore.ram.ram.memory.RAM[testadrNoBase+i]; | ||||
|           //$display("signature[%h] = %h sig = %h", i, signature[i], sig);
 | ||||
|           if (signature[i] !== sig & | ||||
|           //if (signature[i] !== dut.core.lsu.dtim.ram.RAM[testadr+i] &
 | ||||
|           //if (signature[i] !== dut.core.lsu.dtim.ram.memory.RAM[testadr+i] &
 | ||||
| 	      (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin  // ***i+1?
 | ||||
|             if ((signature[i] !== '0 | signature[i+4] !== 'x)) begin | ||||
| //            if (signature[i+4] !== 'bx | (signature[i] !== 32'hFFFFFFFF & signature[i] !== 32'h00000000)) begin
 | ||||
| @ -260,7 +262,7 @@ logic [3:0] dummy; | ||||
|               errors = errors+1; | ||||
|               $display("  Error on test %s result %d: adr = %h sim (D$) %h sim (DMEM) = %h, signature = %h",  | ||||
|                     tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]); | ||||
|                     //   tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.ram.RAM[testadr+i], signature[i]);
 | ||||
|                     //   tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.ram.memory.RAM[testadr+i], signature[i]);
 | ||||
|               $stop;//***debug
 | ||||
|             end | ||||
|           end | ||||
| @ -283,10 +285,10 @@ logic [3:0] dummy; | ||||
|         else begin | ||||
|             //pathname = tvpaths[tests[0]];
 | ||||
|             memfilename = {pathname, tests[test], ".elf.memfile"}; | ||||
|             //$readmemh(memfilename, dut.uncore.ram.ram.RAM);
 | ||||
|             if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); | ||||
|             else                   $readmemh(memfilename, dut.uncore.ram.ram.RAM); | ||||
|             if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); | ||||
|             //$readmemh(memfilename, dut.uncore.ram.ram.memory.RAM);
 | ||||
|             if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM); | ||||
|             else                   $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM); | ||||
|             if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM); | ||||
| 
 | ||||
|             ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; | ||||
|             ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; | ||||
|  | ||||
| @ -959,7 +959,7 @@ string imperas32f[] = '{ | ||||
|     "rv64i_m/I/andi-01", "6010", | ||||
|     "rv64i_m/I/auipc-01", "2010", | ||||
|     "rv64i_m/I/beq-01", "47010", | ||||
|     "rv64i_m/I/bge-01", "47010", | ||||
|     "rv64i_m/I/bge-01", "46010", | ||||
|     "rv64i_m/I/bgeu-01", "56010", | ||||
|     "rv64i_m/I/blt-01", "4d010", | ||||
|     "rv64i_m/I/bltu-01", "57010", | ||||
| @ -1479,7 +1479,7 @@ string imperas32f[] = '{ | ||||
| 
 | ||||
|  string wally64periph[] = '{ | ||||
|     `WALLYTEST, | ||||
|     "rv64i_m/privilege/WALLY-PERIPH", "22f0" | ||||
|     "rv64i_m/privilege/WALLY-PERIPH", "3310" | ||||
|  }; | ||||
| 
 | ||||
|  string wally32e[] = '{ | ||||
|  | ||||
| @ -50,10 +50,47 @@ | ||||
| // Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries) | ||||
| `define PMPCFG_ENTRIES (`PMP_ENTRIES/8) | ||||
| 
 | ||||
| 
 | ||||
| // Floating-point half-precision | ||||
| `define ZFH_SUPPORTED 0 | ||||
| 
 | ||||
| // Floating point constants for Quad, Double, Single, and Half precisions | ||||
| `define Q_LEN 128 | ||||
| `define Q_NE 15 | ||||
| `define Q_NF 112 | ||||
| `define Q_BIAS 16383 | ||||
| `define D_LEN 64 | ||||
| `define D_NE 11 | ||||
| `define D_NF 52 | ||||
| `define D_BIAS 1023 | ||||
| `define S_LEN 32 | ||||
| `define S_NE 8 | ||||
| `define S_NF 23 | ||||
| `define S_BIAS 127 | ||||
| `define H_LEN 16 | ||||
| `define H_NE 5 | ||||
| `define H_NF 10 | ||||
| `define H_BIAS 15 | ||||
| 
 | ||||
| // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits | ||||
| `define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32) | ||||
| `define NE   11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8) | ||||
| `define NF   52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23) | ||||
| `define FLEN (`Q_SUPPORTED ? `Q_LEN  : `D_SUPPORTED ? `D_LEN  : `F_SUPPORTED ? `S_LEN  : `H_LEN) | ||||
| `define NE   (`Q_SUPPORTED ? `Q_NE   : `D_SUPPORTED ? `D_NE   : `F_SUPPORTED ? `S_NE   : `H_NE) | ||||
| `define NF   (`Q_SUPPORTED ? `Q_NF   : `D_SUPPORTED ? `D_NF   : `F_SUPPORTED ? `S_NF   : `H_NF) | ||||
| `define FMT  (`Q_SUPPORTED ? 3       : `D_SUPPORTED ? 1       : `F_SUPPORTED ? 0       : 2) | ||||
| `define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS) | ||||
| 
 | ||||
| // Floating point constants needed for FPU paramerterization | ||||
| `define FPSIZES (`Q_SUPPORTED+`D_SUPPORTED+`F_SUPPORTED+`ZFH_SUPPORTED) | ||||
| `define LEN1  ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_LEN   : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_LEN  : `H_LEN) | ||||
| `define NE1   ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NE   : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NE  : `H_NE) | ||||
| `define NF1   ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NF  : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NF : `H_NF) | ||||
| `define FMT1  ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? 1        : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? 0       : 2) | ||||
| `define BIAS1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_BIAS  : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_BIAS : `H_BIAS) | ||||
| `define LEN2  ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_LEN   : `H_LEN) | ||||
| `define NE2   ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NE   : `H_NE) | ||||
| `define NF2   ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NF  : `H_NF) | ||||
| `define FMT2  ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? 0        : 2) | ||||
| `define BIAS2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_BIAS  : `H_BIAS) | ||||
| 
 | ||||
| // Disable spurious Verilator warnings | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user