forked from Github_Repos/cvw
		
	Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						6e5fc107d9
					
				@ -1,11 +1,14 @@
 | 
				
			|||||||
# check for warnings in Verilog code
 | 
					# check for warnings in Verilog code
 | 
				
			||||||
# The verilator lint tool is faster and better than Modelsim so it is best to run this first.
 | 
					# The verilator lint tool is faster and better than Modelsim so it is best to run this first.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "rv64ic linting..."
 | 
					for config in rv64ic rv32ic; do
 | 
				
			||||||
verilator --lint-only "$@" --top-module wallypipelinedsoc -Iconfig/rv64ic src/*/*.sv 
 | 
					    echo "$config linting..."
 | 
				
			||||||
echo "rv32ic linting..."
 | 
					    if !(verilator --lint-only "$@" --top-module wallypipelinedsoc "-Iconfig/$config" src/*/*.sv); then
 | 
				
			||||||
verilator --lint-only "$@" --top-module wallypipelinedsoc -Iconfig/rv32ic src/*/*.sv 
 | 
					        echo "Exiting after $config lint due to errors or warnings"
 | 
				
			||||||
#verilator --lint-only --top-module wallypipelinedsoc -Iconfig/rv64ic src/*/*.sv src/*/div/*.sv
 | 
					        exit 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					echo "All lints run with no errors or warnings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# --lint-only just runs lint rather than trying to compile and simulate
 | 
					# --lint-only just runs lint rather than trying to compile and simulate
 | 
				
			||||||
# -I points to the include directory where files such as `include wally-config.vh  are found
 | 
					# -I points to the include directory where files such as `include wally-config.vh  are found
 | 
				
			||||||
 | 
				
			|||||||
@ -30,34 +30,43 @@ vlib work
 | 
				
			|||||||
# default to config/rv64ic, but allow this to be overridden at the command line.  For example:
 | 
					# default to config/rv64ic, but allow this to be overridden at the command line.  For example:
 | 
				
			||||||
# do wally-pipelined.do ../config/rv32ic
 | 
					# do wally-pipelined.do ../config/rv32ic
 | 
				
			||||||
switch $argc {
 | 
					switch $argc {
 | 
				
			||||||
    0 {vlog +incdir+../config/rv64ic ../testbench/testbench-privileged.sv ../src/*/*.sv -suppress 2583}
 | 
					    0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583}
 | 
				
			||||||
    1 {vlog +incdir+$1 ../testbench/testbench-privileged.sv ../testbench/function_radix.sv ../src/*/*.sv -suppress 2583}
 | 
					    1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../testbench/function_radix.sv ../src/*/*.sv -suppress 2583}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
# start and run simulation
 | 
					# start and run simulation
 | 
				
			||||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
 | 
					# remove +acc flag for faster sim during regressions if there is no need to access internal signals
 | 
				
			||||||
vopt +acc work.testbench -o workopt 
 | 
					vopt +acc work.testbench -o workopt 
 | 
				
			||||||
vsim workopt
 | 
					vsim workopt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
view wave
 | 
					view wave
 | 
				
			||||||
 | 
					 | 
				
			||||||
-- display input and output signals as hexidecimal values
 | 
					-- display input and output signals as hexidecimal values
 | 
				
			||||||
do ./wave-dos/default-waves.do
 | 
					onerror {resume}
 | 
				
			||||||
 | 
					add wave -noupdate /testbench/clk
 | 
				
			||||||
-- Set Wave Output Items 
 | 
					add wave -noupdate /testbench/reset
 | 
				
			||||||
 | 
					add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE
 | 
				
			||||||
 | 
					quietly WaveActivateNextPane {} 0
 | 
				
			||||||
TreeUpdate [SetDefaultTree]
 | 
					TreeUpdate [SetDefaultTree]
 | 
				
			||||||
WaveRestoreZoom {0 ps} {100 ps}
 | 
					WaveRestoreCursors {{Cursor 2} {12215488 ns} 0} {{Cursor 4} {22127 ns} 0}
 | 
				
			||||||
 | 
					quietly wave cursor active 2
 | 
				
			||||||
configure wave -namecolwidth 250
 | 
					configure wave -namecolwidth 250
 | 
				
			||||||
configure wave -valuecolwidth 140
 | 
					configure wave -valuecolwidth 513
 | 
				
			||||||
configure wave -justifyvalue left
 | 
					configure wave -justifyvalue left
 | 
				
			||||||
configure wave -signalnamewidth 0
 | 
					configure wave -signalnamewidth 1
 | 
				
			||||||
configure wave -snapdistance 10
 | 
					configure wave -snapdistance 10
 | 
				
			||||||
configure wave -datasetprefix 0
 | 
					configure wave -datasetprefix 0
 | 
				
			||||||
configure wave -rowmargin 4
 | 
					configure wave -rowmargin 4
 | 
				
			||||||
configure wave -childrowmargin 2
 | 
					configure wave -childrowmargin 2
 | 
				
			||||||
set DefaultRadix hexadecimal
 | 
					configure wave -gridoffset 0
 | 
				
			||||||
 | 
					configure wave -gridperiod 1
 | 
				
			||||||
 | 
					configure wave -griddelta 40
 | 
				
			||||||
 | 
					configure wave -timeline 0
 | 
				
			||||||
 | 
					configure wave -timelineunits ns
 | 
				
			||||||
 | 
					update
 | 
				
			||||||
 | 
					WaveRestoreZoom {21993 ns} {22181 ns}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Run the Simulation 
 | 
					-- Run the Simulation 
 | 
				
			||||||
#run 4100
 | 
					#run 5000 
 | 
				
			||||||
run -all
 | 
					run -all
 | 
				
			||||||
#quit
 | 
					#quit
 | 
				
			||||||
 | 
					noview ../testbench/testbench-imperas.sv
 | 
				
			||||||
 | 
					view wave
 | 
				
			||||||
 | 
				
			|||||||
@ -63,4 +63,4 @@ configure wave -snapdistance 10
 | 
				
			|||||||
configure wave -datasetprefix 0
 | 
					configure wave -datasetprefix 0
 | 
				
			||||||
configure wave -rowmargin 4
 | 
					configure wave -rowmargin 4
 | 
				
			||||||
configure wave -childrowmargin 2
 | 
					configure wave -childrowmargin 2
 | 
				
			||||||
set DefaultRadix hexadecimal
 | 
					set DefaultRadix hexadecimal
 | 
				
			||||||
 | 
				
			|||||||
@ -41,13 +41,13 @@ module globalHistoryPredictor
 | 
				
			|||||||
   input logic [1:0] 	   UpdatePrediction
 | 
					   input logic [1:0] 	   UpdatePrediction
 | 
				
			||||||
   
 | 
					   
 | 
				
			||||||
   );
 | 
					   );
 | 
				
			||||||
   logic [k-1:0] GHRF, GHRD, GHRE, GHRENext;
 | 
					   logic [k-1:0] GHRF, GHRFNext;
 | 
				
			||||||
   assign GHRENext = {PCSrcE, GHRE[k-1:1]}; 
 | 
					   assign GHRFNext = {PCSrcE, GHRF[k-1:1]}; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    flopenr #(k) GlobalHistoryRegister(.clk(clk),
 | 
					    flopenr #(k) GlobalHistoryRegister(.clk(clk),
 | 
				
			||||||
            .reset(reset),
 | 
					            .reset(reset),
 | 
				
			||||||
            .en(UpdateEN),
 | 
					            .en(UpdateEN),
 | 
				
			||||||
            .d(GHRENext),
 | 
					            .d(GHRFNext),
 | 
				
			||||||
            .q(GHRF));
 | 
					            .q(GHRF));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -65,7 +65,7 @@ module globalHistoryPredictor
 | 
				
			|||||||
				.RA1(GHRF),
 | 
									.RA1(GHRF),
 | 
				
			||||||
				.RD1(PredictionMemory),
 | 
									.RD1(PredictionMemory),
 | 
				
			||||||
				.REN1(~StallF),
 | 
									.REN1(~StallF),
 | 
				
			||||||
				.WA1(GHRENext),
 | 
									.WA1(GHRFNext),
 | 
				
			||||||
				.WD1(UpdatePrediction),
 | 
									.WD1(UpdatePrediction),
 | 
				
			||||||
				.WEN1(UpdateEN),
 | 
									.WEN1(UpdateEN),
 | 
				
			||||||
				.BitWEN1(2'b11));
 | 
									.BitWEN1(2'b11));
 | 
				
			||||||
@ -73,7 +73,7 @@ module globalHistoryPredictor
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // need to forward when updating to the same address as reading.
 | 
					  // need to forward when updating to the same address as reading.
 | 
				
			||||||
  // first we compare to see if the update and lookup addreses are the same
 | 
					  // first we compare to see if the update and lookup addreses are the same
 | 
				
			||||||
  assign DoForwarding = GHRF == GHRE;
 | 
					  assign DoForwarding = GHRF == GHRFNext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // register the update value and the forwarding signal into the Fetch stage
 | 
					  // register the update value and the forwarding signal into the Fetch stage
 | 
				
			||||||
  // TODO: add stall logic ***
 | 
					  // TODO: add stall logic ***
 | 
				
			||||||
@ -90,7 +90,7 @@ module globalHistoryPredictor
 | 
				
			|||||||
  assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
 | 
					  assign Prediction = DoForwardingF ? UpdatePredictionF : PredictionMemory;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  //pipeline for GHR
 | 
					  //pipeline for GHR
 | 
				
			||||||
  flopenrc #(k) GHRDReg(.clk(clk),
 | 
					  /*flopenrc #(k) GHRDReg(.clk(clk),
 | 
				
			||||||
      .reset(reset),
 | 
					      .reset(reset),
 | 
				
			||||||
      .en(~StallD),
 | 
					      .en(~StallD),
 | 
				
			||||||
      .clear(FlushD),
 | 
					      .clear(FlushD),
 | 
				
			||||||
@ -103,5 +103,5 @@ module globalHistoryPredictor
 | 
				
			|||||||
        .clear(FlushE),
 | 
					        .clear(FlushE),
 | 
				
			||||||
        .d(GHRD),
 | 
					        .d(GHRD),
 | 
				
			||||||
        .q(GHRE));
 | 
					        .q(GHRE));
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
 | 
				
			|||||||
@ -42,24 +42,24 @@ module gsharePredictor
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
   );
 | 
					   );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic [k-1:0] 	   GHRF, GHRD, GHRE, GHRENext;
 | 
					  logic [k-1:0] 	   GHRF, GHRFNext;
 | 
				
			||||||
  //logic [k-1:0] 	   LookUpPCIndexD, LookUpPCIndexE;
 | 
					  //logic [k-1:0] 	   LookUpPCIndexD, LookUpPCIndexE;
 | 
				
			||||||
  logic [k-1:0] 	   LookUpPCIndex, UpdatePCIndex;
 | 
					  logic [k-1:0] 	   LookUpPCIndex, UpdatePCIndex;
 | 
				
			||||||
  logic [1:0] 		   PredictionMemory;
 | 
					  logic [1:0] 		   PredictionMemory;
 | 
				
			||||||
  logic 		   DoForwarding, DoForwardingF;
 | 
					  logic 		   DoForwarding, DoForwardingF;
 | 
				
			||||||
  logic [1:0] 		   UpdatePredictionF;
 | 
					  logic [1:0] 		   UpdatePredictionF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assign GHRENext = {PCSrcE, GHRE[k-1:1]};
 | 
					  assign GHRFNext = {PCSrcE, GHRF[k-1:1]};
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  flopenr #(k) GlobalHistoryRegister(.clk(clk),
 | 
					  flopenr #(k) GlobalHistoryRegister(.clk(clk),
 | 
				
			||||||
				     .reset(reset),
 | 
									     .reset(reset),
 | 
				
			||||||
				     .en(UpdateEN),
 | 
									     .en(UpdateEN),
 | 
				
			||||||
				     .d(GHRENext),
 | 
									     .d(GHRFNext),
 | 
				
			||||||
				     .q(GHRF));
 | 
									     .q(GHRF));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // for gshare xor the PC with the GHR 
 | 
					  // for gshare xor the PC with the GHR 
 | 
				
			||||||
  assign UpdatePCIndex = GHRENext ^ UpdatePC[k:1];
 | 
					  assign UpdatePCIndex = GHRFNext ^ UpdatePC[k:1];
 | 
				
			||||||
  assign LookUpPCIndex = GHRF ^ LookUpPC[k:1];  
 | 
					  assign LookUpPCIndex = GHRF ^ LookUpPC[k:1];  
 | 
				
			||||||
  // Make Prediction by reading the correct address in the PHT and also update the new address in the PHT 
 | 
					  // Make Prediction by reading the correct address in the PHT and also update the new address in the PHT 
 | 
				
			||||||
  // GHR referes to the address that the past k branches points to in the prediction stage 
 | 
					  // GHR referes to the address that the past k branches points to in the prediction stage 
 | 
				
			||||||
@ -110,7 +110,7 @@ module gsharePredictor
 | 
				
			|||||||
			   .q(LookUpPCIndexE));
 | 
								   .q(LookUpPCIndexE));
 | 
				
			||||||
 -----/\----- EXCLUDED -----/\----- */
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  flopenrc #(k) GHRRegD(.clk(clk),
 | 
					/*  flopenrc #(k) GHRRegD(.clk(clk),
 | 
				
			||||||
			.reset(reset),
 | 
								.reset(reset),
 | 
				
			||||||
			.en(~StallD),
 | 
								.en(~StallD),
 | 
				
			||||||
			.clear(FlushD),
 | 
								.clear(FlushD),
 | 
				
			||||||
@ -124,5 +124,5 @@ module gsharePredictor
 | 
				
			|||||||
			.d(GHRD),
 | 
								.d(GHRD),
 | 
				
			||||||
			.q(GHRE));
 | 
								.q(GHRE));
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
 | 
				
			|||||||
@ -44,13 +44,13 @@ module localHistoryPredictor
 | 
				
			|||||||
   );
 | 
					   );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   logic [2**m-1:0][k-1:0] LHRNextF;
 | 
					   logic [2**m-1:0][k-1:0] LHRNextF;
 | 
				
			||||||
   logic [k-1:0]       LHRF, LHRD, LHRE, LHRENext, ForwardLHRNext;
 | 
					   logic [k-1:0]       LHRF, ForwardLHRNext;
 | 
				
			||||||
   logic [m-1:0] 	   LookUpPCIndex, UpdatePCIndex;
 | 
					   logic [m-1:0] 	   LookUpPCIndex, UpdatePCIndex;
 | 
				
			||||||
   logic [1:0] 		   PredictionMemory;
 | 
					   logic [1:0] 		   PredictionMemory;
 | 
				
			||||||
   logic 		   DoForwarding, DoForwardingF, DoForwardingPHT, DoForwardingPHTF;
 | 
					   logic 		   DoForwarding, DoForwardingF, DoForwardingPHT, DoForwardingPHTF;
 | 
				
			||||||
   logic [1:0] 		   UpdatePredictionF;
 | 
					   logic [1:0] 		   UpdatePredictionF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   assign LHRENext = {PCSrcE, LHRE[k-1:1]}; 
 | 
					   assign LHRFNext = {PCSrcE, LHRF[k-1:1]}; 
 | 
				
			||||||
   assign UpdatePCIndex = {UpdatePC[m+1] ^ UpdatePC[1], UpdatePC[m:2]};
 | 
					   assign UpdatePCIndex = {UpdatePC[m+1] ^ UpdatePC[1], UpdatePC[m:2]};
 | 
				
			||||||
   assign LookUpPCIndex = {LookUpPC[m+1] ^ LookUpPC[1], LookUpPC[m:2]};  
 | 
					   assign LookUpPCIndex = {LookUpPC[m+1] ^ LookUpPC[1], LookUpPC[m:2]};  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -72,7 +72,7 @@ generate
 | 
				
			|||||||
        flopenr #(k) LocalHistoryRegister(.clk(clk),
 | 
					        flopenr #(k) LocalHistoryRegister(.clk(clk),
 | 
				
			||||||
                .reset(reset),
 | 
					                .reset(reset),
 | 
				
			||||||
                .en(UpdateEN && (index == UpdatePCIndex)),
 | 
					                .en(UpdateEN && (index == UpdatePCIndex)),
 | 
				
			||||||
                .d(LHRENext),
 | 
					                .d(LHRFNext),
 | 
				
			||||||
                .q(LHRNextF[index]));
 | 
					                .q(LHRNextF[index]));
 | 
				
			||||||
    end 
 | 
					    end 
 | 
				
			||||||
endgenerate
 | 
					endgenerate
 | 
				
			||||||
@ -80,7 +80,7 @@ endgenerate
 | 
				
			|||||||
// need to forward when updating to the same address as reading.
 | 
					// need to forward when updating to the same address as reading.
 | 
				
			||||||
// first we compare to see if the update and lookup addreses are the same
 | 
					// first we compare to see if the update and lookup addreses are the same
 | 
				
			||||||
assign DoForwarding = LookUpPCIndex == UpdatePCIndex;
 | 
					assign DoForwarding = LookUpPCIndex == UpdatePCIndex;
 | 
				
			||||||
assign ForwardLHRNext = DoForwarding ? LHRENext :LHRNextF[LookUpPCIndex]; 
 | 
					assign ForwardLHRNext = DoForwarding ? LHRFNext :LHRNextF[LookUpPCIndex]; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Make Prediction by reading the correct address in the PHT and also update the new address in the PHT 
 | 
					  // Make Prediction by reading the correct address in the PHT and also update the new address in the PHT 
 | 
				
			||||||
  // LHR referes to the address that the past k branches points to in the prediction stage 
 | 
					  // LHR referes to the address that the past k branches points to in the prediction stage 
 | 
				
			||||||
@ -90,14 +90,14 @@ assign ForwardLHRNext = DoForwarding ? LHRENext :LHRNextF[LookUpPCIndex];
 | 
				
			|||||||
				.RA1(ForwardLHRNext),
 | 
									.RA1(ForwardLHRNext),
 | 
				
			||||||
				.RD1(PredictionMemory),
 | 
									.RD1(PredictionMemory),
 | 
				
			||||||
				.REN1(~StallF),
 | 
									.REN1(~StallF),
 | 
				
			||||||
				.WA1(LHRENext),
 | 
									.WA1(LHRFNext),
 | 
				
			||||||
				.WD1(UpdatePrediction),
 | 
									.WD1(UpdatePrediction),
 | 
				
			||||||
				.WEN1(UpdateEN),
 | 
									.WEN1(UpdateEN),
 | 
				
			||||||
				.BitWEN1(2'b11));
 | 
									.BitWEN1(2'b11));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
assign DoForwardingPHT = LHRENext == ForwardLHRNext; 
 | 
					assign DoForwardingPHT = LHRFNext == ForwardLHRNext; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // register the update value and the forwarding signal into the Fetch stage
 | 
					  // register the update value and the forwarding signal into the Fetch stage
 | 
				
			||||||
  // TODO: add stall logic ***
 | 
					  // TODO: add stall logic ***
 | 
				
			||||||
@ -120,7 +120,7 @@ assign DoForwardingPHT = LHRENext == ForwardLHRNext;
 | 
				
			|||||||
      .clear(FlushF),
 | 
					      .clear(FlushF),
 | 
				
			||||||
      .d(ForwardLHRNext),
 | 
					      .d(ForwardLHRNext),
 | 
				
			||||||
      .q(LHRF));
 | 
					      .q(LHRF));
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
  flopenrc #(k) LHRDReg(.clk(clk),
 | 
					  flopenrc #(k) LHRDReg(.clk(clk),
 | 
				
			||||||
        .reset(reset),
 | 
					        .reset(reset),
 | 
				
			||||||
        .en(~StallD),
 | 
					        .en(~StallD),
 | 
				
			||||||
@ -134,5 +134,5 @@ assign DoForwardingPHT = LHRENext == ForwardLHRNext;
 | 
				
			|||||||
        .clear(FlushE),
 | 
					        .clear(FlushE),
 | 
				
			||||||
        .d(LHRD),
 | 
					        .d(LHRD),
 | 
				
			||||||
        .q(LHRE));
 | 
					        .q(LHRE));
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,7 @@ module csr #(parameter
 | 
				
			|||||||
  input  logic             FlushW, StallD, StallE, StallM, StallW,
 | 
					  input  logic             FlushW, StallD, StallE, StallM, StallW,
 | 
				
			||||||
  input  logic [31:0]      InstrM, 
 | 
					  input  logic [31:0]      InstrM, 
 | 
				
			||||||
  input  logic [`XLEN-1:0] PCM, SrcAM,
 | 
					  input  logic [`XLEN-1:0] PCM, SrcAM,
 | 
				
			||||||
 | 
					  input  logic             InterruptM,
 | 
				
			||||||
  input  logic             CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
 | 
					  input  logic             CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
 | 
				
			||||||
  input  logic             TimerIntM, ExtIntM, SwIntM,
 | 
					  input  logic             TimerIntM, ExtIntM, SwIntM,
 | 
				
			||||||
  input  logic             InstrValidW, FloatRegWriteW, LoadStallD,
 | 
					  input  logic             InstrValidW, FloatRegWriteW, LoadStallD,
 | 
				
			||||||
@ -71,7 +72,14 @@ module csr #(parameter
 | 
				
			|||||||
  logic            WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
 | 
					  logic            WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
 | 
				
			||||||
  logic            CSRMWriteM, CSRSWriteM, CSRUWriteM;
 | 
					  logic            CSRMWriteM, CSRSWriteM, CSRUWriteM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
 | 
					  logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, preservedPCM, readPCM, NextCauseM, NextMtvalM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  always_ff @(posedge clk) begin
 | 
				
			||||||
 | 
					      preservedPCM <= PCM;
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mux2 #(`XLEN) pcmux(PCM, preservedPCM, InterruptM, readPCM);
 | 
				
			||||||
 | 
					  //flop #(`XLEN) CSRReadPCMreg(clk, reset, PCM, readPCM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic [11:0] CSRAdrM;
 | 
					  logic [11:0] CSRAdrM;
 | 
				
			||||||
  logic [11:0] SIP_REGW, SIE_REGW;
 | 
					  logic [11:0] SIP_REGW, SIE_REGW;
 | 
				
			||||||
@ -100,7 +108,7 @@ module csr #(parameter
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      // write CSRs
 | 
					      // write CSRs
 | 
				
			||||||
      assign CSRAdrM = InstrM[31:20];
 | 
					      assign CSRAdrM = InstrM[31:20];
 | 
				
			||||||
      assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM;
 | 
					      assign UnalignedNextEPCM = TrapM ? readPCM : CSRWriteValM;
 | 
				
			||||||
      assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment
 | 
					      assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment
 | 
				
			||||||
      assign NextCauseM = TrapM ? CauseM : CSRWriteValM;
 | 
					      assign NextCauseM = TrapM ? CauseM : CSRWriteValM;
 | 
				
			||||||
      assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
 | 
					      assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
 | 
				
			||||||
 | 
				
			|||||||
@ -85,7 +85,8 @@ module privileged (
 | 
				
			|||||||
  logic IllegalInstrFaultM;
 | 
					  logic IllegalInstrFaultM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic BreakpointFaultM, EcallFaultM;
 | 
					  logic BreakpointFaultM, EcallFaultM;
 | 
				
			||||||
  logic MTrapM, STrapM, UTrapM; 
 | 
					  logic MTrapM, STrapM, UTrapM;
 | 
				
			||||||
 | 
					  logic InterruptM; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic [1:0] STATUS_MPP;
 | 
					  logic [1:0] STATUS_MPP;
 | 
				
			||||||
  logic       STATUS_SPP, STATUS_TSR;
 | 
					  logic       STATUS_SPP, STATUS_TSR;
 | 
				
			||||||
 | 
				
			|||||||
@ -41,13 +41,14 @@ module trap (
 | 
				
			|||||||
  input  logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, 
 | 
					  input  logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM, 
 | 
				
			||||||
  input  logic [31:0]      InstrM,
 | 
					  input  logic [31:0]      InstrM,
 | 
				
			||||||
  output logic             TrapM, MTrapM, STrapM, UTrapM, RetM,
 | 
					  output logic             TrapM, MTrapM, STrapM, UTrapM, RetM,
 | 
				
			||||||
 | 
					  output logic             InterruptM,
 | 
				
			||||||
  output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
 | 
					  output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
 | 
				
			||||||
//  output logic [11:0]     MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
 | 
					//  output logic [11:0]     MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
 | 
				
			||||||
//  input  logic            WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
 | 
					//  input  logic            WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logic [11:0] MIntGlobalEnM, SIntGlobalEnM, PendingIntsM; 
 | 
					  logic [11:0] MIntGlobalEnM, SIntGlobalEnM, PendingIntsM; 
 | 
				
			||||||
  logic InterruptM;
 | 
					  //logic InterruptM;
 | 
				
			||||||
  logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
 | 
					  logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Determine pending enabled interrupts
 | 
					  // Determine pending enabled interrupts
 | 
				
			||||||
 | 
				
			|||||||
@ -354,7 +354,9 @@ module testbench();
 | 
				
			|||||||
    "rv64p/WALLY-MARCHID", "4000",
 | 
					    "rv64p/WALLY-MARCHID", "4000",
 | 
				
			||||||
    "rv64p/WALLY-MIMPID", "4000",
 | 
					    "rv64p/WALLY-MIMPID", "4000",
 | 
				
			||||||
    "rv64p/WALLY-MHARTID", "4000",
 | 
					    "rv64p/WALLY-MHARTID", "4000",
 | 
				
			||||||
    "rv64p/WALLY-MVENDORID", "4000"
 | 
					    "rv64p/WALLY-MVENDORID", "4000",
 | 
				
			||||||
 | 
					    "rv64p/WALLY-MIE", "3000",
 | 
				
			||||||
 | 
					    "rv64p/WALLY-MEDELEG", "4000"
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  string tests32p[] = '{
 | 
					  string tests32p[] = '{
 | 
				
			||||||
@ -368,6 +370,7 @@ module testbench();
 | 
				
			|||||||
    "rv32p/WALLY-MIMPID", "4000",
 | 
					    "rv32p/WALLY-MIMPID", "4000",
 | 
				
			||||||
    "rv32p/WALLY-MHARTID", "4000",
 | 
					    "rv32p/WALLY-MHARTID", "4000",
 | 
				
			||||||
    "rv32p/WALLY-MVENDORID", "4000"
 | 
					    "rv32p/WALLY-MVENDORID", "4000"
 | 
				
			||||||
 | 
					    //"rv32p/WALLY-MEDELEG", "4000" // all 32 bit tests are currently failing, so haven't been able to confirm this test works yet. It should, though.
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  string tests64periph[] = '{
 | 
					  string tests64periph[] = '{
 | 
				
			||||||
 | 
				
			|||||||
@ -58,8 +58,44 @@ def writeVectors(storecmd, returningInstruction):
 | 
				
			|||||||
  # """)
 | 
					  # """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # User Timer Interrupt: True, 4
 | 
					  # User Timer Interrupt: True, 4
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  # Supervior timer interrupt: True, 5
 | 
					  # Supervior timer interrupt: True, 5
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Machine timer interrupt: True, 7
 | 
					  # Machine timer interrupt: True, 7
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # if fromMode == "m":
 | 
				
			||||||
 | 
					  #   clintAddr = "0x2004000"
 | 
				
			||||||
 | 
					  #   writeTest(storecmd, f, r, f"""
 | 
				
			||||||
 | 
					  #     li x1, 0x8
 | 
				
			||||||
 | 
					  #     csrrs x0, {fromMode}status, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #     la x18, {clintAddr}
 | 
				
			||||||
 | 
					  #     lw x11, 0(x18)
 | 
				
			||||||
 | 
					  #     li x1, 1
 | 
				
			||||||
 | 
					  #     # {storecmd} x1, 0(x18)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #     li x1, 0x80
 | 
				
			||||||
 | 
					  #     csrrs x0, {fromMode}ie, x1
 | 
				
			||||||
 | 
					  #     nop
 | 
				
			||||||
 | 
					  #     nop
 | 
				
			||||||
 | 
					  #     nop
 | 
				
			||||||
 | 
					  #     nop
 | 
				
			||||||
 | 
					  #     nop
 | 
				
			||||||
 | 
					  #     nop
 | 
				
			||||||
 | 
					  #     nop
 | 
				
			||||||
 | 
					  #   """, True, 4, f"""
 | 
				
			||||||
 | 
					  #     li x1, 0x80
 | 
				
			||||||
 | 
					  #     # csrrc x0, {fromMode}ie, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #     li x1, 0x8
 | 
				
			||||||
 | 
					  #     # csrrc x0, {fromMode}status, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #     la x18, {clintAddr}
 | 
				
			||||||
 | 
					  #     {storecmd} x11, 0(x18)
 | 
				
			||||||
 | 
					  #   """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # writeTest(storecmd, f, r, f"""
 | 
					  # writeTest(storecmd, f, r, f"""
 | 
				
			||||||
  #   li x10, MASK_XLEN(0x8)
 | 
					  #   li x10, MASK_XLEN(0x8)
 | 
				
			||||||
@ -121,10 +157,17 @@ def writeVectors(storecmd, returningInstruction):
 | 
				
			|||||||
  # """)
 | 
					  # """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # User external input: True, 8
 | 
					  # User external input: True, 8
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Supervisor external input: True, 9
 | 
					  # Supervisor external input: True, 9
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Machine externa input: True, 11
 | 
					  # Machine externa input: True, 11
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Instruction address misaligned: False, 0
 | 
					  # Instruction address misaligned: False, 0
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # looks like this is giving us an infinite loop for wally
 | 
					  # looks like this is giving us an infinite loop for wally
 | 
				
			||||||
  # BUG: jumping to a misaligned instruction address doesn't cause an exception: we actually jump...
 | 
					  # BUG: jumping to a misaligned instruction address doesn't cause an exception: we actually jump...
 | 
				
			||||||
  # Either that, or somehow at the end we always end up at 0x80004002
 | 
					  # Either that, or somehow at the end we always end up at 0x80004002
 | 
				
			||||||
@ -135,6 +178,7 @@ def writeVectors(storecmd, returningInstruction):
 | 
				
			|||||||
  # """, False, 0)
 | 
					  # """, False, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Instruction access fault: False, 1
 | 
					  # Instruction access fault: False, 1
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Illegal Instruction 
 | 
					  # Illegal Instruction 
 | 
				
			||||||
  writeTest(storecmd, f, r, f"""
 | 
					  writeTest(storecmd, f, r, f"""
 | 
				
			||||||
@ -153,16 +197,14 @@ def writeVectors(storecmd, returningInstruction):
 | 
				
			|||||||
  """, False, 4)
 | 
					  """, False, 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Load Access fault: False, 5
 | 
					  # Load Access fault: False, 5
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Store/AMO address misaligned
 | 
					  # Store/AMO address misaligned
 | 
				
			||||||
  writeTest(storecmd, f, r, f"""
 | 
					  writeTest(storecmd, f, r, f"""
 | 
				
			||||||
    sw x0, 11(x0)
 | 
					    sw x0, 11(x0)
 | 
				
			||||||
  """, False, 6)
 | 
					  """, False, 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Environment call from u-mode: only for when only M and U mode enabled?
 | 
					  # Environment call
 | 
				
			||||||
  # writeTest(storecmd, f, r, f"""
 | 
					 | 
				
			||||||
  #   ecall
 | 
					 | 
				
			||||||
  # """, False, 8, "u")
 | 
					 | 
				
			||||||
  if returningInstruction != "ecall":
 | 
					  if returningInstruction != "ecall":
 | 
				
			||||||
    if fromMode == "u":
 | 
					    if fromMode == "u":
 | 
				
			||||||
      writeTest(storecmd, f, r, f"""
 | 
					      writeTest(storecmd, f, r, f"""
 | 
				
			||||||
@ -182,8 +224,13 @@ def writeVectors(storecmd, returningInstruction):
 | 
				
			|||||||
      """, False, 11, "m")  
 | 
					      """, False, 11, "m")  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Instruction page fault: 12
 | 
					  # Instruction page fault: 12
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Load page fault: 13
 | 
					  # Load page fault: 13
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Store/AMO page fault: 15
 | 
					  # Store/AMO page fault: 15
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@ -194,7 +241,7 @@ def writeTest(storecmd, f, r, test, interrupt, code, mode = "m", resetHander = "
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  expected = code
 | 
					  expected = code
 | 
				
			||||||
  if(interrupt):
 | 
					  if(interrupt):
 | 
				
			||||||
    expected+=(1 << (wordsize - 1))
 | 
					    expected+=(1 << (xlen - 1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  trapEnd = ""
 | 
					  trapEnd = ""
 | 
				
			||||||
@ -316,6 +363,8 @@ for xlen in xlens:
 | 
				
			|||||||
          csrs sedeleg, x9
 | 
					          csrs sedeleg, x9
 | 
				
			||||||
          """
 | 
					          """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      clintAddr = "0x2004000"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      lines += f"""
 | 
					      lines += f"""
 | 
				
			||||||
        li x30, 0
 | 
					        li x30, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -328,6 +377,32 @@ for xlen in xlens:
 | 
				
			|||||||
        j _j_t_begin_{returningInstruction}
 | 
					        j _j_t_begin_{returningInstruction}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _j_m_trap_{returningInstruction}:
 | 
					        _j_m_trap_{returningInstruction}:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #li x1, 0x20
 | 
				
			||||||
 | 
					        #csrrw x0, mie, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        li x11, 0x3fffffffffffffff
 | 
				
			||||||
 | 
					        la x18, {clintAddr}
 | 
				
			||||||
 | 
					        {storecmd} x11, 0(x18)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        li x1, 0x8
 | 
				
			||||||
 | 
					        csrrc x0, mstatus, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					        sub x1, x2, x3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        csrrs x1, mepc, x0
 | 
					        csrrs x1, mepc, x0
 | 
				
			||||||
        {"csrr x25, mcause" if testMode == "m" else "li x25, 0xBAD00003"}
 | 
					        {"csrr x25, mcause" if testMode == "m" else "li x25, 0xBAD00003"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										291
									
								
								wally-pipelined/testgen/privileged/testgen-DELEG.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										291
									
								
								wally-pipelined/testgen/privileged/testgen-DELEG.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,291 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/python3
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					# testgen-CAUSE.py
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# dottolia@hmc.edu 27 Apr 2021
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Generate directed and random test vectors for RISC-V Design Validation.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					# DOCUMENTATION:
 | 
				
			||||||
 | 
					# Most of the comments explaining what everything
 | 
				
			||||||
 | 
					# does can be found in testgen-TVAL.py
 | 
				
			||||||
 | 
					###################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					# libraries
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					from datetime import datetime
 | 
				
			||||||
 | 
					from random import randint 
 | 
				
			||||||
 | 
					from random import seed
 | 
				
			||||||
 | 
					from random import getrandbits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					# functions
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#For instruction-fetch access or page-fault exceptions on systems with variable-length instructions, mtval will contain the virtual address of the portion of the instruction that caused the fault while mepc will point to the beginning of the instruction.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def randRegs():
 | 
				
			||||||
 | 
					  reg1 = randint(1,20)
 | 
				
			||||||
 | 
					  reg2 = randint(1,20)
 | 
				
			||||||
 | 
					  reg3 = randint(1,20)
 | 
				
			||||||
 | 
					  if (reg1 == 6 or reg2 == 6 or reg3 == 6 or reg1 == reg2):
 | 
				
			||||||
 | 
					    return randRegs()
 | 
				
			||||||
 | 
					  else:
 | 
				
			||||||
 | 
					      return str(reg1), str(reg2), str(reg3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def writeVectors(storecmd):
 | 
				
			||||||
 | 
					  global testnum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # User Software Interrupt: True, 0
 | 
				
			||||||
 | 
					  # Supervisor Software Interrupt: True, 1
 | 
				
			||||||
 | 
					  # Machine Software Interrupt: True, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # User external input: True, 8
 | 
				
			||||||
 | 
					  # Supervisor external input: True, 9
 | 
				
			||||||
 | 
					  # Machine externa input: True, 11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Instruction address misaligned: False, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Instruction access fault: False, 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Illegal Instruction 
 | 
				
			||||||
 | 
					  #writeTest(storecmd, f, r, "ecall", False, 11)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  writeTest(storecmd, f, r, f"""
 | 
				
			||||||
 | 
					    .fill 1, 4, 0
 | 
				
			||||||
 | 
					  """, False, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Breakpoint
 | 
				
			||||||
 | 
					  writeTest(storecmd, f, r, "ebreak", False, 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Load Address Misaligned 
 | 
				
			||||||
 | 
					  writeTest(storecmd, f, r, f"""
 | 
				
			||||||
 | 
					    lw x0, 11(x0)
 | 
				
			||||||
 | 
					  """, False, 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # # Load Access fault: False, 5
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # # Store/AMO address misaligned
 | 
				
			||||||
 | 
					  writeTest(storecmd, f, r, f"""
 | 
				
			||||||
 | 
					    sw x0, 11(x0)
 | 
				
			||||||
 | 
					  """, False, 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Breakpoint: codes 8, 9, 11
 | 
				
			||||||
 | 
					  writeTest(storecmd, f, r, "ecall", False, -1) # code determined inside of writeTest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Instruction page fault: 12
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Load page fault: 13
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Store/AMO page fault: 15
 | 
				
			||||||
 | 
					  # TODO: THIS NEEDS TO BE IMPLEMENTED
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #writeTest(storecmd, f, r, "ecall", False, 11, "m")
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""):
 | 
				
			||||||
 | 
					  global testnum
 | 
				
			||||||
 | 
					  global testMode
 | 
				
			||||||
 | 
					  global isInterrupts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if interrupt != isInterrupts:
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  delegateType = "i" if interrupt else "e"
 | 
				
			||||||
 | 
					  for mode in (["m", "s", "u"] if testMode == "m" else ["s", "u"]):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if test == "ecall":
 | 
				
			||||||
 | 
					      if mode == "m":
 | 
				
			||||||
 | 
					        code = 11
 | 
				
			||||||
 | 
					      elif mode == "s":
 | 
				
			||||||
 | 
					        code = 9
 | 
				
			||||||
 | 
					      else:
 | 
				
			||||||
 | 
					        code = 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mask = 1 << code
 | 
				
			||||||
 | 
					    for delegated in [True, False]:
 | 
				
			||||||
 | 
					      labelSuffix = testnum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      f.write(f"""
 | 
				
			||||||
 | 
					        _start_{labelSuffix}:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        la x1, _j_m_trap_{labelSuffix}
 | 
				
			||||||
 | 
					        csrw mtvec, x1
 | 
				
			||||||
 | 
					        la x1, _j_s_trap_{labelSuffix}
 | 
				
			||||||
 | 
					        csrw stvec, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        j _j_test_{labelSuffix}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _j_m_trap_{labelSuffix}:
 | 
				
			||||||
 | 
					        li x25, 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        csrr x1, mepc
 | 
				
			||||||
 | 
					        addi x1, x1, 4
 | 
				
			||||||
 | 
					        csrrw x0, mepc, x1
 | 
				
			||||||
 | 
					        bnez x30, _j_finished_{labelSuffix}
 | 
				
			||||||
 | 
					        mret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _j_s_trap_{labelSuffix}:
 | 
				
			||||||
 | 
					        li x25, 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        csrr x1, sepc
 | 
				
			||||||
 | 
					        addi x1, x1, 4
 | 
				
			||||||
 | 
					        csrrw x0, sepc, x1
 | 
				
			||||||
 | 
					        bnez x30, _j_goto_machine_mode_{labelSuffix}
 | 
				
			||||||
 | 
					        sret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _j_goto_machine_mode_{labelSuffix}:
 | 
				
			||||||
 | 
					        li x30, 1
 | 
				
			||||||
 | 
					        {"ebreak" if test is not "ebreak" else "ecall"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _j_test_{labelSuffix}:
 | 
				
			||||||
 | 
					      """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      original = f"""
 | 
				
			||||||
 | 
					        li x1, {mask if delegated else 0}
 | 
				
			||||||
 | 
					        csrw m{delegateType}deleg, x1
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      lines = original + "\n" + test
 | 
				
			||||||
 | 
					      if mode != "m":
 | 
				
			||||||
 | 
					        lines = f"""
 | 
				
			||||||
 | 
					          {original}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          li x1, 0b110000000000
 | 
				
			||||||
 | 
					          csrrc x28, {testMode}status, x1
 | 
				
			||||||
 | 
					          li x1, 0b{"01" if mode == "s" else "00"}00000000000
 | 
				
			||||||
 | 
					          csrrs x28, {testMode}status, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          auipc x1, 0
 | 
				
			||||||
 | 
					          addi x1, x1, 16 # x1 is now right after the ret instruction
 | 
				
			||||||
 | 
					          csrrw x27, {testMode}epc, x1
 | 
				
			||||||
 | 
					          {testMode}ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          # From {testMode}, we're now in {mode} mode...
 | 
				
			||||||
 | 
					          {test}
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        writeTestInner(storecmd, f, r, lines, 1 if delegated else 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f.write(f"""
 | 
				
			||||||
 | 
					          j _j_goto_machine_mode_{labelSuffix}
 | 
				
			||||||
 | 
					        """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      else:
 | 
				
			||||||
 | 
					        writeTestInner(storecmd, f, r, lines, 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      f.write(f"""
 | 
				
			||||||
 | 
					        _j_finished_{labelSuffix}:
 | 
				
			||||||
 | 
					        li x30, 0
 | 
				
			||||||
 | 
					      """)
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def writeTestInner(storecmd, f, r, lines, expected):
 | 
				
			||||||
 | 
					  global testnum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  lines = f"""
 | 
				
			||||||
 | 
					    li x25, 0xDEADBEA7
 | 
				
			||||||
 | 
					    {lines}
 | 
				
			||||||
 | 
					  """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  lines += storecmd + " x25, " + str(testnum * wordsize) + "(x6)\n"
 | 
				
			||||||
 | 
					  f.write(lines)
 | 
				
			||||||
 | 
					  if (xlen == 32):
 | 
				
			||||||
 | 
					    line = formatrefstr.format(expected)+"\n"
 | 
				
			||||||
 | 
					  else:
 | 
				
			||||||
 | 
					    line = formatrefstr.format(expected % 2**32)+"\n" + formatrefstr.format(expected >> 32) + "\n"
 | 
				
			||||||
 | 
					  r.write(line)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  testnum = testnum+1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					# main body
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# change these to suite your tests
 | 
				
			||||||
 | 
					author = "dottolia@hmc.edu"
 | 
				
			||||||
 | 
					xlens = [32, 64]
 | 
				
			||||||
 | 
					numrand = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# setup
 | 
				
			||||||
 | 
					seed(0xD0C0_D0C0_D0C0_D0C0) # make tests reproducible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# generate files for each test
 | 
				
			||||||
 | 
					for xlen in xlens:
 | 
				
			||||||
 | 
					  formatstrlen = str(int(xlen/4))
 | 
				
			||||||
 | 
					  formatstr = "0x{:0" + formatstrlen + "x}" # format as xlen-bit hexadecimal number
 | 
				
			||||||
 | 
					  formatrefstr = "{:08x}" # format as xlen-bit hexadecimal number with no leading 0x
 | 
				
			||||||
 | 
					  if (xlen == 32):
 | 
				
			||||||
 | 
					    storecmd = "sw"
 | 
				
			||||||
 | 
					    wordsize = 4
 | 
				
			||||||
 | 
					  else:
 | 
				
			||||||
 | 
					    storecmd = "sd"
 | 
				
			||||||
 | 
					    wordsize = 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for testMode in ["m"]:
 | 
				
			||||||
 | 
					    for isInterrupts in [True, False]:
 | 
				
			||||||
 | 
					      imperaspath = "../../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "p/"
 | 
				
			||||||
 | 
					      basename = "WALLY-" + testMode.upper() + ("I" if isInterrupts else "E") + "DELEG"
 | 
				
			||||||
 | 
					      fname = imperaspath + "src/" + basename + ".S"
 | 
				
			||||||
 | 
					      refname = imperaspath + "references/" + basename + ".reference_output"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # print custom header part
 | 
				
			||||||
 | 
					      f = open(fname, "w")
 | 
				
			||||||
 | 
					      r = open(refname, "w")
 | 
				
			||||||
 | 
					      line = "///////////////////////////////////////////\n"
 | 
				
			||||||
 | 
					      f.write(line)
 | 
				
			||||||
 | 
					      lines="// "+fname+ "\n// " + author + "\n"
 | 
				
			||||||
 | 
					      f.write(lines)
 | 
				
			||||||
 | 
					      line ="// Created " + str(datetime.now()) 
 | 
				
			||||||
 | 
					      f.write(line)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # insert generic header
 | 
				
			||||||
 | 
					      h = open("../testgen_header.S", "r")
 | 
				
			||||||
 | 
					      for line in h:  
 | 
				
			||||||
 | 
					        f.write(line)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # All registers used:
 | 
				
			||||||
 | 
					      # x19: mtvec old value
 | 
				
			||||||
 | 
					      # x18: medeleg old value
 | 
				
			||||||
 | 
					      # x17: mideleg old value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      f.write(f"""
 | 
				
			||||||
 | 
					        add x7, x6, x0
 | 
				
			||||||
 | 
					        csrr x19, mtvec
 | 
				
			||||||
 | 
					        csrr x18, medeleg
 | 
				
			||||||
 | 
					        csrr x17, medeleg
 | 
				
			||||||
 | 
					      """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      testnum = 0
 | 
				
			||||||
 | 
					      for i in range(0, 2):
 | 
				
			||||||
 | 
					        writeVectors(storecmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      f.write(f"""
 | 
				
			||||||
 | 
					        csrw mtvec, x19
 | 
				
			||||||
 | 
					        csrw medeleg, x18
 | 
				
			||||||
 | 
					        csrw mideleg, x17
 | 
				
			||||||
 | 
					      """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # if we're in supervisor mode, this leaves the ebreak instruction untested (we need a way to)
 | 
				
			||||||
 | 
					      # get back to machine mode. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # print footer
 | 
				
			||||||
 | 
					      h = open("../testgen_footer.S", "r")
 | 
				
			||||||
 | 
					      for line in h:  
 | 
				
			||||||
 | 
					        f.write(line)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # Finish
 | 
				
			||||||
 | 
					      lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
 | 
				
			||||||
 | 
					      lines = lines + "\nRV_COMPLIANCE_DATA_END\n" 
 | 
				
			||||||
 | 
					      f.write(lines)
 | 
				
			||||||
 | 
					      f.close()
 | 
				
			||||||
 | 
					      r.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -20,84 +20,91 @@ from random import getrandbits
 | 
				
			|||||||
# functions
 | 
					# functions
 | 
				
			||||||
##################################
 | 
					##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def writeTrapHandlers(storecmd):
 | 
					def writeTrapHandlers(storecmd, mode):
 | 
				
			||||||
  global testnum
 | 
					  global testnum
 | 
				
			||||||
  [reg1, reg2, reg3] = [30, 29, 28]
 | 
					  [reg1, reg2, reg3] = [30, 29, 28]
 | 
				
			||||||
  [reg4, reg5] = [27, 26]
 | 
					  [reg4, reg5] = [27, 26]
 | 
				
			||||||
  lines = "\n# Trap Handler: Machine Timer Interupt\n"
 | 
					  if mode == "M":
 | 
				
			||||||
  lines += "_timerM_trap_handler:\n"
 | 
					    lines = "\n# Trap Handler: Machine Timer Interupt\n"
 | 
				
			||||||
  lines += "li x" + str(reg1) + ", MASK_XLEN(0x2A)\n"
 | 
					    lines += "_timerM_trap_handler:\n"
 | 
				
			||||||
  lines += "la x" + str(reg2) + ", 0x2004000\n"
 | 
					    lines += "li x" + str(reg1) + ", MASK_XLEN(0xFFFF)\n"
 | 
				
			||||||
  lines += str(storecmd) + " x" + str(reg1) + ",  0(x" + str(reg2) + ")\n"
 | 
					    lines += "la x" + str(reg2) + ", 0x2004000\n"
 | 
				
			||||||
  lines += "csrrw x" + str(reg3) + ", mepc, x0\n"
 | 
					    lines += str(storecmd) + " x" + str(reg1) + ",  0(x" + str(reg2) + ")\n"
 | 
				
			||||||
  lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n"
 | 
					    lines += "csrrc x" + str(reg3) + ", mepc, x0\n"
 | 
				
			||||||
  lines += "mret\n"
 | 
					    lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
 | 
					    lines += "csrrw x0, mepc, x" + str(reg3) + "\n"
 | 
				
			||||||
 | 
					    # clear machine timer interupt enable bit in mie
 | 
				
			||||||
 | 
					    lines += "li x" + str(reg4) + ", MASK_XLEN(" + str(0x80) + ")\n"
 | 
				
			||||||
 | 
					    lines += "csrrc x0, mie, x" + str(reg4) + "\n"
 | 
				
			||||||
 | 
					    lines += "mret\n"
 | 
				
			||||||
 | 
					  elif mode == "S":
 | 
				
			||||||
 | 
					    lines = "\n# Trap Handler: Supervisor Timer Interupt\n"
 | 
				
			||||||
 | 
					    lines += "_timerS_trap_handler:\n"
 | 
				
			||||||
 | 
					    lines += "li x" + str(reg4) + ", MASK_XLEN(0x20)\n"
 | 
				
			||||||
 | 
					    lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
				
			||||||
 | 
					    lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
				
			||||||
 | 
					    lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
 | 
					    lines += "mret\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lines += "\n# Trap Handler: Supervisor Timer Interupt\n"
 | 
					  #lines += "\n# Trap Handler: User Timer Interupt\n"
 | 
				
			||||||
  lines += "_timerS_trap_handler:\n"
 | 
					  #lines += "_timerU_trap_handler:\n"
 | 
				
			||||||
  lines += "li x" + str(reg4) + ", MASK_XLEN(0x20)\n"
 | 
					  #lines += "li x" + str(reg4) + ", MASK_XLEN(0x10)\n"
 | 
				
			||||||
  lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
					  #lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
				
			||||||
  lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
					  #lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
				
			||||||
  lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
					  #lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
  lines += "mret\n"
 | 
					  #lines += "mret\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lines += "\n# Trap Handler: User Timer Interupt\n"
 | 
					  #lines += "\n# Trap Handler: Machine Software Interupt\n"
 | 
				
			||||||
  lines += "_timerU_trap_handler:\n"
 | 
					  #lines += "_softwareM_trap_handler:\n"
 | 
				
			||||||
  lines += "li x" + str(reg4) + ", MASK_XLEN(0x10)\n"
 | 
					 | 
				
			||||||
  lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
					 | 
				
			||||||
  lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
					 | 
				
			||||||
  lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
					 | 
				
			||||||
  lines += "mret\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  lines += "\n# Trap Handler: Machine Software Interupt\n"
 | 
					 | 
				
			||||||
  lines += "_softwareM_trap_handler:\n"
 | 
					 | 
				
			||||||
  lines += "li x" + str(reg1) + ", MASK_XLEN(0x0)\n" # clear MSIP bit in CLINT
 | 
					 | 
				
			||||||
  lines += "la x" + str(reg2) + ", 0x2000000\n"
 | 
					 | 
				
			||||||
  lines += str(storecmd) + " x" + str(reg1) + ",  0(x" + str(reg2) + ")\n"
 | 
					 | 
				
			||||||
  lines += "csrrw x" + str(reg3) + ", mepc, x0\n"
 | 
					 | 
				
			||||||
  lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n"
 | 
					 | 
				
			||||||
  lines += "mret\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  lines += "\n# Trap Handler: Supervisor Software Interupt\n"
 | 
					 | 
				
			||||||
  lines += "_softwareS_trap_handler:\n"
 | 
					 | 
				
			||||||
  lines += "li x" + str(reg4) + ", MASK_XLEN(0x2)\n"
 | 
					 | 
				
			||||||
  lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
					 | 
				
			||||||
  lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
					 | 
				
			||||||
  lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
					 | 
				
			||||||
  lines += "mret\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  lines += "\n# Trap Handler: User Software Interupt\n"
 | 
					 | 
				
			||||||
  lines += "_softwareU_trap_handler:\n"
 | 
					 | 
				
			||||||
  lines += "li x" + str(reg4) + ", MASK_XLEN(0x1)\n"
 | 
					 | 
				
			||||||
  lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
					 | 
				
			||||||
  lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
					 | 
				
			||||||
  lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
					 | 
				
			||||||
  lines += "mret\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  lines += "\n# Trap Handler: Machine External Interupt\n"
 | 
					 | 
				
			||||||
  lines += "_externalM_trap_handler:\n"
 | 
					 | 
				
			||||||
  #lines += "li x" + str(reg1) + ", MASK_XLEN(0x0)\n" # clear MSIP bit in CLINT
 | 
					  #lines += "li x" + str(reg1) + ", MASK_XLEN(0x0)\n" # clear MSIP bit in CLINT
 | 
				
			||||||
  #lines += "la x" + str(reg2) + ", 0x2000000\n"
 | 
					  #lines += "la x" + str(reg2) + ", 0x2000000\n"
 | 
				
			||||||
  #lines += str(storecmd) + " x" + str(reg1) + ",  0(x" + str(reg2) + ")\n"
 | 
					  #lines += str(storecmd) + " x" + str(reg1) + ",  0(x" + str(reg2) + ")\n"
 | 
				
			||||||
  lines += "csrrw x" + str(reg3) + ", mepc, x0\n"
 | 
					  ##lines += "csrrs x" + str(reg3) + ", mepc, x0\n"
 | 
				
			||||||
  lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n"
 | 
					  #lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
  lines += "mret\n"
 | 
					  #lines += "csrrw x0, mepc, x" + str(reg3) + "\n"
 | 
				
			||||||
 | 
					  #lines += "mret\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lines += "\n# Trap Handler: Supervisor External Interupt\n"
 | 
					  """lines += "\n# Trap Handler: Supervisor Software Interupt\n"
 | 
				
			||||||
  lines += "_externalS_trap_handler:\n"
 | 
					  lines += "_softwareS_trap_handler:\n"
 | 
				
			||||||
  lines += "li x" + str(reg4) + ", MASK_XLEN(0x200)\n"
 | 
					  lines += "li x" + str(reg4) + ", MASK_XLEN(0x2)\n"
 | 
				
			||||||
  lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
					  lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
				
			||||||
  lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
					  lines += "csrrs x" + str(reg5) + ", mepc, x0\n"
 | 
				
			||||||
  lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
					  lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
 | 
					  lines += "csrrw x0, mepc, x" + str(reg5) + "\n"
 | 
				
			||||||
  lines += "mret\n"
 | 
					  lines += "mret\n"
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					  #lines += "\n# Trap Handler: User Software Interupt\n"
 | 
				
			||||||
 | 
					  #lines += "_softwareU_trap_handler:\n"
 | 
				
			||||||
 | 
					  #lines += "li x" + str(reg4) + ", MASK_XLEN(0x1)\n"
 | 
				
			||||||
 | 
					  #lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
				
			||||||
 | 
					  #lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
				
			||||||
 | 
					  #lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
 | 
					  #lines += "mret\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lines += "\n# Trap Handler: User External Interupt\n"
 | 
					  #lines += "\n# Trap Handler: Machine External Interupt\n"
 | 
				
			||||||
  lines += "_externalU_trap_handler:\n"
 | 
					  #lines += "_externalM_trap_handler:\n"
 | 
				
			||||||
  lines += "li x" + str(reg4) + ", MASK_XLEN(0x100)\n"
 | 
					  #lines += "li x" + str(reg1) + ", MASK_XLEN(0x0)\n" # clear MSIP bit in CLINT
 | 
				
			||||||
  lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
					  #lines += "la x" + str(reg2) + ", 0x2000000\n"
 | 
				
			||||||
  lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
					  #lines += str(storecmd) + " x" + str(reg1) + ",  0(x" + str(reg2) + ")\n"
 | 
				
			||||||
  lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
					  #lines += "csrrw x" + str(reg3) + ", mepc, x0\n"
 | 
				
			||||||
  lines += "mret\n"
 | 
					  #lines += "addi x"+ str(reg3) + ", x" + str(reg3) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
 | 
					  #lines += "mret\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #lines += "\n# Trap Handler: Supervisor External Interupt\n"
 | 
				
			||||||
 | 
					  #lines += "_externalS_trap_handler:\n"
 | 
				
			||||||
 | 
					  #lines += "li x" + str(reg4) + ", MASK_XLEN(0x200)\n"
 | 
				
			||||||
 | 
					  #lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
				
			||||||
 | 
					  #lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
				
			||||||
 | 
					  #lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
 | 
					  #lines += "mret\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #lines += "\n# Trap Handler: User External Interupt\n"
 | 
				
			||||||
 | 
					  #lines += "_externalU_trap_handler:\n"
 | 
				
			||||||
 | 
					  #lines += "li x" + str(reg4) + ", MASK_XLEN(0x100)\n"
 | 
				
			||||||
 | 
					  #lines += "csrrc x0, mip, x" + str(reg4) + "\n"
 | 
				
			||||||
 | 
					  #lines += "csrrw x" + str(reg5) + ", mepc, x0\n"
 | 
				
			||||||
 | 
					  #lines += "addi x"+ str(reg5) + ", x" + str(reg5) + ", MASK_XLEN(0x4)\n"
 | 
				
			||||||
 | 
					  #lines += "mret\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  f.write(lines)
 | 
					  f.write(lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -156,26 +163,32 @@ def getMcause():
 | 
				
			|||||||
def writeVectors(a, xlen, storecmd):
 | 
					def writeVectors(a, xlen, storecmd):
 | 
				
			||||||
  global testnum
 | 
					  global testnum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [reg1, reg2, reg3] = [1, 2, 3]
 | 
					  # Registers used:
 | 
				
			||||||
 | 
					  # x13 ---> read mcause value
 | 
				
			||||||
 | 
					  # x12 ---> save old value of mtvec
 | 
				
			||||||
 | 
					  # x8  ---> holds mieE
 | 
				
			||||||
 | 
					  # x5  ---> holds value of trap handler
 | 
				
			||||||
 | 
					  # x3  ---> holds mstatusE
 | 
				
			||||||
 | 
					  # remaining registers (not used by mode management) are free to be used by tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [reg2, reg3] = [2, 3]
 | 
				
			||||||
  [reg5, reg8] = [5, 8]
 | 
					  [reg5, reg8] = [5, 8]
 | 
				
			||||||
  [reg9, reg10, reg11, reg12] = [9, 10, 11, 12]
 | 
					  [reg10, reg11, reg12] = [10, 11, 12]
 | 
				
			||||||
 | 
					  [reg13, reg14, reg15] = [13, 14, 15]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lines = f"\n# Testcase {testnum}: {test} Interupt\n"
 | 
					  lines = f"\n# Testcase {testnum}: {test} Interupt\n"
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  # mcause code
 | 
					  # mcause code
 | 
				
			||||||
  expected = getMcause()
 | 
					  expected = getMcause()
 | 
				
			||||||
  lines = lines + "li x" + str(reg1) + ", MASK_XLEN(" + formatstr.format(expected) + ")\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (testnum == 0): expected = 0
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [mstatusE, mieE] = getInteruptEnableValues()
 | 
					  [mstatusE, mieE] = getInteruptEnableValues()
 | 
				
			||||||
  # set interupt enable bit in mstatus
 | 
					  # ensure interupt enable bit in mie is low
 | 
				
			||||||
  lines += "li x" + str(reg3) + ", MASK_XLEN(" + str(mstatusE) + ")\n"
 | 
					  lines += "li x" + str(reg8) + ", MASK_XLEN(" + formatstr.format(mieE) + ")\n"
 | 
				
			||||||
  lines += "csrrs x0, mstatus, x" + str(reg3) + "\n"
 | 
					  lines += "csrrc x0, mie, x" + str(reg8) + "\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # set timer interupt enable bit in mie
 | 
					  # set interupt enable bit in mstatus
 | 
				
			||||||
  lines += "li x" + str(reg9) + ", MASK_XLEN(" + str(mieE) + ")\n"
 | 
					  lines += "li x" + str(reg3) + ", MASK_XLEN(" + formatstr.format(mstatusE) + ")\n"
 | 
				
			||||||
  lines += "csrrs x0, mie, x" + str(reg3) + "\n"
 | 
					  lines += "csrrs x0, mstatus, x" + str(reg3) + "\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Save and set trap handler address for interrupt
 | 
					  # Save and set trap handler address for interrupt
 | 
				
			||||||
  lines += "la x" + str(reg5) + ", _" + test + "_trap_handler\n"
 | 
					  lines += "la x" + str(reg5) + ", _" + test + "_trap_handler\n"
 | 
				
			||||||
@ -185,59 +198,50 @@ def writeVectors(a, xlen, storecmd):
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  # cause timer interupt
 | 
					  # cause timer interupt
 | 
				
			||||||
  if test == "timerM":
 | 
					  if test == "timerM":
 | 
				
			||||||
    lines += "li x" + str(reg8) + ", MASK_XLEN(0)\n"
 | 
					 | 
				
			||||||
    lines += str(storecmd) + " x" + str(reg8) + ", " + str(wordsize*testnum)+ "(x6)\n"
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    lines += "la x" + str(reg8) + ", 0x2004000\n"
 | 
					    # load MTIMECMP register address
 | 
				
			||||||
 | 
					    lines += "la x" + str(reg2) + ", 0x2004000\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0)\n"
 | 
					    # to be stored in MTIMECMP
 | 
				
			||||||
 | 
					    lines += "li x" + str(reg10) + ", MASK_XLEN(0)\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # save old value of mtimecmp and then set mtimecmp to zero
 | 
					    # save old value of mtimecmp and then set mtimecmp to zero
 | 
				
			||||||
    lines += "lw x" + str(reg11) + ", 0(x" + str(reg8) + ")\n"
 | 
					    if xlens == 64:
 | 
				
			||||||
    lines += str(storecmd) + " x" + str(reg3) + ",  0(x" + str(reg8) + ")\n"
 | 
					      lines += "lw x" + str(reg11) + ", 0(x" + str(reg2) + ")\n"
 | 
				
			||||||
 | 
					      lines += str(storecmd) + " x" + str(reg10) + ",  0(x" + str(reg2) + ")\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    elif xlen == 32:
 | 
				
			||||||
 | 
					      lines += "lw x" + str(reg11) + ", 0(x" + str(reg2) + ")\n"
 | 
				
			||||||
 | 
					      lines += str(storecmd) + " x" + str(reg10) + ",  0(x" + str(reg2) + ")\n"
 | 
				
			||||||
 | 
					      lines += str(storecmd) + " x" + str(reg10) + ",  4(x" + str(reg2) + ")\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  elif test == "timerS":
 | 
					  elif test == "timerS":
 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0x20)\n"
 | 
					    lines += "li x" + str(reg3) + ", MASK_XLEN(0x20)\n"
 | 
				
			||||||
    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
					    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
				
			||||||
  elif test == "timerU":
 | 
					 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0x10)\n"
 | 
					 | 
				
			||||||
    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  # cause software interupt
 | 
					  # cause software interupt
 | 
				
			||||||
  if test == "softwareM":
 | 
					  if test == "softwareM":
 | 
				
			||||||
    lines += "la x" + str(reg8) + ", 0x2000000\n" # Write to the MSIP bit in CLINT
 | 
					    lines += "la x" + str(reg8) + ", 0x2000000\n" # Write to the MSIP bit in CLINT
 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0x1)\n"
 | 
					    lines += "li x" + str(reg11) + ", MASK_XLEN(0x1)\n"
 | 
				
			||||||
    lines += str(storecmd) + " x" + str(reg3) + ",  0(x" + str(reg8) + ")\n"
 | 
					    lines += str(storecmd) + " x" + str(reg11) + ",  0(x" + str(reg8) + ")\n"
 | 
				
			||||||
  elif test == "softwareS":
 | 
					  elif test == "softwareS":
 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0x2)\n"
 | 
					    lines += "li x" + str(reg3) + ", MASK_XLEN(0x2)\n"
 | 
				
			||||||
    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
					    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
				
			||||||
  elif test == "softwareU":
 | 
					 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0x1)\n"
 | 
					 | 
				
			||||||
    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  # cause external interupt
 | 
					 | 
				
			||||||
  # Not sure how to cause an external machine interupt yet
 | 
					 | 
				
			||||||
  # will writing to PLIC just cause it? (where is the ExtIntM located in PLIC)
 | 
					 | 
				
			||||||
  #if test == "externalM":
 | 
					 | 
				
			||||||
    #lines += "la x" + str(reg8) + ", 0x2000000\n" # Write to the MSIP bit in CLINT
 | 
					 | 
				
			||||||
    #lines += "li x" + str(reg3) + ", MASK_XLEN(0x1)\n"
 | 
					 | 
				
			||||||
    #lines += str(storecmd) + " x" + str(reg3) + ",  0(x" + str(reg8) + ")\n"
 | 
					 | 
				
			||||||
  if test == "externalS":
 | 
					 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0x200)\n"
 | 
					 | 
				
			||||||
    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
					 | 
				
			||||||
  elif test == "externalU":
 | 
					 | 
				
			||||||
    lines += "li x" + str(reg3) + ", MASK_XLEN(0x100)\n"
 | 
					 | 
				
			||||||
    lines += "csrrs x0, mip, x" + str(reg3) + "\n"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #lines += "wfi\n" # wait for interupt to be taken
 | 
					  # set timer interupt enable bit in mie
 | 
				
			||||||
 | 
					  lines += "csrrs x0, mie, x" + str(reg8) + "\n"
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  # wait for interupt to be taken
 | 
				
			||||||
  lines += "nop\nnop\n"
 | 
					  lines += "nop\nnop\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lines += "csrrw " + " x" + str(reg2) + ", mcause, x" + str(reg1) + "\n"
 | 
					  lines += "csrrs " + " x" + str(reg13) + ", mcause, x0\n"
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  # reset mtvec
 | 
					  # reset mtvec
 | 
				
			||||||
  lines += "csrrw x0, mtvec, x" + str(reg12) + "\n"
 | 
					  lines += "csrrw x0, mtvec, x" + str(reg12) + "\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lines += storecmd + " x" + str(reg2) + ", " + str(wordsize*testnum) + "(x6)\n"
 | 
					  lines += storecmd + " x" + str(reg13) + ", " + str(wordsize*testnum) + "(x6)\n"
 | 
				
			||||||
  lines += "RVTEST_IO_ASSERT_GPR_EQ(x7, x" + str(reg2) +", "+formatstr.format(expected)+")\n"
 | 
					  lines += "RVTEST_IO_ASSERT_GPR_EQ(x7, x" + str(reg13) +", "+formatstr.format(expected)+")\n"
 | 
				
			||||||
  f.write(lines)
 | 
					  f.write(lines)
 | 
				
			||||||
  if (xlen == 32):
 | 
					  if (xlen == 32):
 | 
				
			||||||
    line = formatrefstr.format(expected)+"\n"
 | 
					    line = formatrefstr.format(expected)+"\n"
 | 
				
			||||||
@ -251,9 +255,10 @@ def writeVectors(a, xlen, storecmd):
 | 
				
			|||||||
##################################
 | 
					##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# change these to suite your tests
 | 
					# change these to suite your tests
 | 
				
			||||||
tests = ["timerM"] #, "timerS", "timerU", "softwareM", "softwareS", "softwareU"]
 | 
					tests = ["timerM"] #, "timerM", "timerS", "softwareM", "softwareS"]
 | 
				
			||||||
author = "ushakya@hmc.edu"
 | 
					author = "ushakya@hmc.edu"
 | 
				
			||||||
xlens = [64, 32]
 | 
					xlens = [64] #, 32]
 | 
				
			||||||
 | 
					modes = ["M"]#, "S"]
 | 
				
			||||||
numrand = 100;
 | 
					numrand = 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# setup
 | 
					# setup
 | 
				
			||||||
@ -270,9 +275,9 @@ for xlen in xlens:
 | 
				
			|||||||
  else:
 | 
					  else:
 | 
				
			||||||
    storecmd = "sd"
 | 
					    storecmd = "sd"
 | 
				
			||||||
    wordsize = 8
 | 
					    wordsize = 8
 | 
				
			||||||
  for test in tests:
 | 
					  for mode in modes:
 | 
				
			||||||
    imperaspath = "../../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "p/"
 | 
					    imperaspath = "../../../imperas-riscv-tests/riscv-test-suite/rv" + str(xlen) + "p/"
 | 
				
			||||||
    basename = "WALLY-IE" 
 | 
					    basename = "WALLY-" + mode + "IE"
 | 
				
			||||||
    fname = imperaspath + "src/" + basename + ".S"
 | 
					    fname = imperaspath + "src/" + basename + ".S"
 | 
				
			||||||
    refname = imperaspath + "references/" + basename + ".reference_output"
 | 
					    refname = imperaspath + "references/" + basename + ".reference_output"
 | 
				
			||||||
    testnum = 0
 | 
					    testnum = 0
 | 
				
			||||||
@ -291,13 +296,99 @@ for xlen in xlens:
 | 
				
			|||||||
    h = open("../testgen_header.S", "r")
 | 
					    h = open("../testgen_header.S", "r")
 | 
				
			||||||
    for line in h:  
 | 
					    for line in h:  
 | 
				
			||||||
      f.write(line)
 | 
					      f.write(line)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    line = "\n"
 | 
				
			||||||
 | 
					    # Registers used for dropping down to supervisor mode:
 | 
				
			||||||
 | 
					    # x30 ---> set to 1 if we should return to & stay in machine mode after trap, 0 otherwise
 | 
				
			||||||
 | 
					    # x20 ---> hold address of _j_all_end_{returningInstruction}
 | 
				
			||||||
 | 
					    # x19 ---> save old value of mtvec
 | 
				
			||||||
 | 
					    # x18 ---> save old value of medeleg
 | 
				
			||||||
 | 
					    # x16 ---> save old value of mideleg
 | 
				
			||||||
 | 
					    # x9  ---> bit mask for mideleg and medeleg
 | 
				
			||||||
 | 
					    # x1  ---> used to go down to supervisor mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # print directed and random test vectors
 | 
					    # We need to leave at least one bit in medeleg unset so that we have a way to get
 | 
				
			||||||
    for i in range(0,numrand):
 | 
					    # back to machine mode when the tests are complete (otherwise we'll only ever be able
 | 
				
			||||||
      a = getrandbits(xlen)
 | 
					    # to get up to supervisor mode). 
 | 
				
			||||||
      writeVectors(a, xlen, storecmd)
 | 
					    #
 | 
				
			||||||
 | 
					    # So, we define a returning instruction which will be used to cause the exception that
 | 
				
			||||||
 | 
					    # brings us into machine mode. The bit for this returning instruction is NOT set in
 | 
				
			||||||
 | 
					    # medeleg. However, this also means that we can't test that instruction. So, we have
 | 
				
			||||||
 | 
					    # two different returning instructions.
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # Current code is written to only support ebreak and ecall.
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    # For testgen-IE, we don't need to test ebreak, so we can use that as the sole
 | 
				
			||||||
 | 
					    # returning instruction.
 | 
				
			||||||
 | 
					    returningInstruction = "ebreak"
 | 
				
			||||||
 | 
					    if mode == "S":
 | 
				
			||||||
 | 
					      # need to move down to supervisor mode (based on code in testgen-TVAL)
 | 
				
			||||||
 | 
					      lines += f"""
 | 
				
			||||||
 | 
					        # Reset x30 to 0 so we can run the tests. We'll set this to 1 when tests are completed so we stay in machine mode
 | 
				
			||||||
 | 
					        li x30, 0
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    writeTrapHandlers(storecmd)
 | 
					      # We don't want to delegate our returning instruction. Otherwise, we'll have no way of getting
 | 
				
			||||||
 | 
					      # back to machine mode at the end! (and we need to be in machine mode to complete the tests)
 | 
				
			||||||
 | 
					      medelegMask = "0b1111111111110111" if returningInstruction == "ebreak" else "0b1111000011111111"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # Set medeleg and mideleg
 | 
				
			||||||
 | 
					      lines += f"""
 | 
				
			||||||
 | 
					        csrr x18, medeleg
 | 
				
			||||||
 | 
					        li x9, {medelegMask if testMode == "s" or testMode == "u" else "0"}
 | 
				
			||||||
 | 
					        csrw medeleg, x9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        csrr x16, mideleg
 | 
				
			||||||
 | 
					        li x9, {"0xffffffff" if testMode == "s" or testMode == "u" else "0"}
 | 
				
			||||||
 | 
					        csrw mideleg, x9
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # bring down to supervisor mode
 | 
				
			||||||
 | 
					      lines += f"""
 | 
				
			||||||
 | 
					            li x1, 0b110000000000
 | 
				
			||||||
 | 
					            csrrc x28, mstatus, x1
 | 
				
			||||||
 | 
					            li x1, 0b0100000000000
 | 
				
			||||||
 | 
					            csrrs x28, mstatus, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            auipc x1, 0
 | 
				
			||||||
 | 
					            addi x1, x1, 16 # x1 is now right after the mret instruction
 | 
				
			||||||
 | 
					            csrw mepc, x1
 | 
				
			||||||
 | 
					            mret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # We're now in supervisor mode...
 | 
				
			||||||
 | 
					          """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for test in tests:
 | 
				
			||||||
 | 
					      # print directed and random test vectors
 | 
				
			||||||
 | 
					      for i in range(0,numrand):
 | 
				
			||||||
 | 
					        a = getrandbits(xlen)
 | 
				
			||||||
 | 
					        writeVectors(a, xlen, storecmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if mode == "S":
 | 
				
			||||||
 | 
					      # Bring us back up to machine mode!
 | 
				
			||||||
 | 
					      # Creates a new trap handler that just jumps to _j_all_end_{returningInstruction}
 | 
				
			||||||
 | 
					      #
 | 
				
			||||||
 | 
					      # Get into the trap handler by running returningInstruction (in this case its ebreak) 
 | 
				
			||||||
 | 
					      f.write(f"""
 | 
				
			||||||
 | 
					        li x30, 1 #may not need this 
 | 
				
			||||||
 | 
					        csrr x19, mtvec # save old value of mtvec
 | 
				
			||||||
 | 
					        la x20 _j_all_end_{returningInstruction}
 | 
				
			||||||
 | 
					        csrw mtvec, x20
 | 
				
			||||||
 | 
					        {returningInstruction}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _returnMachineMode_handler:
 | 
				
			||||||
 | 
					        j _j_all_end_{returningInstruction}
 | 
				
			||||||
 | 
					        mret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        _j_all_end_{returningInstruction}:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Reset trap handling csrs to old values
 | 
				
			||||||
 | 
					        csrw mtvec, x19
 | 
				
			||||||
 | 
					        csrw medeleg, x18
 | 
				
			||||||
 | 
					        csrw mideleg, x16
 | 
				
			||||||
 | 
					      """)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    f.write(lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # print footer
 | 
					    # print footer
 | 
				
			||||||
    h = open("../testgen_footer.S", "r")
 | 
					    h = open("../testgen_footer.S", "r")
 | 
				
			||||||
@ -308,5 +399,8 @@ for xlen in xlens:
 | 
				
			|||||||
    lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
 | 
					    lines = ".fill " + str(testnum) + ", " + str(wordsize) + ", -1\n"
 | 
				
			||||||
    lines = lines + "\nRV_COMPLIANCE_DATA_END\n" 
 | 
					    lines = lines + "\nRV_COMPLIANCE_DATA_END\n" 
 | 
				
			||||||
    f.write(lines)
 | 
					    f.write(lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    writeTrapHandlers(storecmd, mode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    f.close()
 | 
					    f.close()
 | 
				
			||||||
    r.close()
 | 
					    r.close()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
#!/usr/bin/python3
 | 
					#!/usr/bin/python3
 | 
				
			||||||
##################################
 | 
					##################################
 | 
				
			||||||
# testgen-CAUSE.py (new)
 | 
					# testgen-TVEC.py (new)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# dottolia@hmc.edu 1 Mar 2021
 | 
					# dottolia@hmc.edu 1 Mar 2021
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@ -25,6 +25,12 @@ from random import randint
 | 
				
			|||||||
from random import seed
 | 
					from random import seed
 | 
				
			||||||
from random import getrandbits
 | 
					from random import getrandbits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					# setup
 | 
				
			||||||
 | 
					##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					areVectoredTrapsSupported = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##################################
 | 
					##################################
 | 
				
			||||||
# functions
 | 
					# functions
 | 
				
			||||||
##################################
 | 
					##################################
 | 
				
			||||||
@ -43,29 +49,6 @@ def randRegs():
 | 
				
			|||||||
def writeVectors(storecmd, returningInstruction):
 | 
					def writeVectors(storecmd, returningInstruction):
 | 
				
			||||||
  global testnum
 | 
					  global testnum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if fromMode == "m":
 | 
					 | 
				
			||||||
    expectedCode = 7 if fromMode == "m" else 5
 | 
					 | 
				
			||||||
    clintAddr = "0x2004000"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    writeTest(storecmd, f, r, f"""
 | 
					 | 
				
			||||||
      li x1, 0x8
 | 
					 | 
				
			||||||
      csrrs x0, {fromMode}status, x1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      la x18, {clintAddr}
 | 
					 | 
				
			||||||
      lw x11, 0(x18)
 | 
					 | 
				
			||||||
      li x1, 1
 | 
					 | 
				
			||||||
      {storecmd} x1, 0(x18)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      li x1, 0x80
 | 
					 | 
				
			||||||
      csrrs x0, {fromMode}ie, x1
 | 
					 | 
				
			||||||
    """, True, expectedCode, f"""
 | 
					 | 
				
			||||||
      la x18, {clintAddr}
 | 
					 | 
				
			||||||
      {storecmd} x11, 0(x18)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      li x1, 0x80
 | 
					 | 
				
			||||||
      csrrc x0, {fromMode}ie, x1
 | 
					 | 
				
			||||||
    """)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Illegal Instruction 
 | 
					  # Illegal Instruction 
 | 
				
			||||||
  writeTest(storecmd, f, r, f"""
 | 
					  writeTest(storecmd, f, r, f"""
 | 
				
			||||||
@ -112,6 +95,35 @@ def writeVectors(storecmd, returningInstruction):
 | 
				
			|||||||
        ecall
 | 
					        ecall
 | 
				
			||||||
      """, False, 0)  
 | 
					      """, False, 0)  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if fromMode == "m":
 | 
				
			||||||
 | 
					    expectedCode = 7 if fromMode == "m" else 5
 | 
				
			||||||
 | 
					    clintAddr = "0x2004000"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    writeTest(storecmd, f, r, f"""
 | 
				
			||||||
 | 
					      li x1, 0x8
 | 
				
			||||||
 | 
					      csrrs x0, {fromMode}status, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      la x18, {clintAddr}
 | 
				
			||||||
 | 
					      lw x11, 0(x18)
 | 
				
			||||||
 | 
					      li x1, 0x3fffffffffffffff
 | 
				
			||||||
 | 
					      {storecmd} x1, 0(x18)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      li x1, 0x80
 | 
				
			||||||
 | 
					      csrrs x0, {fromMode}ie, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      {storecmd} x0, 0(x18)
 | 
				
			||||||
 | 
					    """, True, expectedCode, f"""
 | 
				
			||||||
 | 
					      li x1, 0x80
 | 
				
			||||||
 | 
					      csrrc x0, {fromMode}ie, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      li x1, 0x8
 | 
				
			||||||
 | 
					      csrrc x0, {fromMode}status, x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      la x18, {clintAddr}
 | 
				
			||||||
 | 
					      {storecmd} x0, 0(x18)
 | 
				
			||||||
 | 
					    """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Instruction page fault: 12
 | 
					  # Instruction page fault: 12
 | 
				
			||||||
  # Load page fault: 13
 | 
					  # Load page fault: 13
 | 
				
			||||||
  # Store/AMO page fault: 15
 | 
					  # Store/AMO page fault: 15
 | 
				
			||||||
@ -144,14 +156,13 @@ def writeTest(storecmd, f, r, test, interrupt, code, resetHander = ""):
 | 
				
			|||||||
    {test}
 | 
					    {test}
 | 
				
			||||||
  """
 | 
					  """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # We expect x25 to be 0 always. This is because of the code we wrote at the begining
 | 
					 | 
				
			||||||
  # of this function
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  # Store the expected value of x25 to memory and in the .reference_output file
 | 
					 | 
				
			||||||
  lines += f"""
 | 
					  lines += f"""
 | 
				
			||||||
    {storecmd} x25, {testnum * wordsize}(x6)
 | 
					    {storecmd} x25, {testnum * wordsize}(x6)
 | 
				
			||||||
  """
 | 
					  """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if not areVectoredTrapsSupported:
 | 
				
			||||||
 | 
					    expected = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  f.write(lines)
 | 
					  f.write(lines)
 | 
				
			||||||
  if (xlen == 32):
 | 
					  if (xlen == 32):
 | 
				
			||||||
    line = formatrefstr.format(expected)+"\n"
 | 
					    line = formatrefstr.format(expected)+"\n"
 | 
				
			||||||
@ -291,7 +302,7 @@ for xlen in xlens:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Set up 
 | 
					        # Set up 
 | 
				
			||||||
        la x1, _j_m_trap_{returningInstruction}
 | 
					        la x1, _j_m_trap_{returningInstruction}
 | 
				
			||||||
        addi x1, 1
 | 
					        #addi x1, 1
 | 
				
			||||||
        csrw mtvec, x1
 | 
					        csrw mtvec, x1
 | 
				
			||||||
        la x1, _j_s_trap_{returningInstruction}
 | 
					        la x1, _j_s_trap_{returningInstruction}
 | 
				
			||||||
        csrw stvec, x1
 | 
					        csrw stvec, x1
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user