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
						ca2a65770c
					
				| @ -1,5 +1,5 @@ | ||||
| ////////////////////////////////////////// | ||||
| // wally-config.vh | ||||
| // busybear-config.vh | ||||
| // | ||||
| // Written: David_Harris@hmc.edu 4 January 2021 | ||||
| // Modified:  | ||||
| @ -24,6 +24,7 @@ | ||||
| // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| /////////////////////////////////////////// | ||||
| 
 | ||||
| `define BUSYBEAR | ||||
| // RV32 or RV64: XLEN = 32 or 64 | ||||
| `define XLEN 64 | ||||
| 
 | ||||
| @ -61,14 +62,16 @@ | ||||
| // Peripheral memory space extends from BASE to BASE+RANGE | ||||
| // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits | ||||
| 
 | ||||
| `define TIMBASE    64'h0000000080000000 | ||||
| `define TIMRANGE   64'h000000000007FFFF | ||||
| `define CLINTBASE  64'h0000000002000000 | ||||
| `define CLINTRANGE 64'h000000000000FFFF | ||||
| `define GPIOBASE   64'h0000000010012000 | ||||
| `define GPIORANGE  64'h00000000000000FF | ||||
| `define UARTBASE   64'h0000000010000000 | ||||
| `define UARTRANGE  64'h0000000000000007 | ||||
| `define TIMBASE       32'h80000000 | ||||
| `define TIMRANGE      32'h07FFFFFF | ||||
| `define BOOTTIMBASE   32'h00000000 //only needs to go from 0x1000 to 0x2FFF, extending to a power of 2 | ||||
| `define BOOTTIMRANGE  32'h00003FFF | ||||
| `define CLINTBASE     32'h02000000 | ||||
| `define CLINTRANGE    32'h0000BFFF | ||||
| //`define GPIOBASE    32'h10012000 // no GPIO in linux for now | ||||
| //`define GPIORANGE   32'h000000FF | ||||
| `define UARTBASE      32'h10000000 | ||||
| `define UARTRANGE     32'h00000007 | ||||
| // Bus Interface width | ||||
| `define AHBW 64 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										1
									
								
								wally-pipelined/regression/sim-busybear
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								wally-pipelined/regression/sim-busybear
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1 @@ | ||||
| vsim -do wally-busybear.do | ||||
							
								
								
									
										3
									
								
								wally-pipelined/regression/sim-busybear-batch
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								wally-pipelined/regression/sim-busybear-batch
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,3 @@ | ||||
| vsim -c <<! | ||||
| do wally-busybear.do  | ||||
| ! | ||||
| @ -28,10 +28,19 @@ vlib work-busybear | ||||
| # because vsim will run vopt | ||||
| vlog +incdir+../config/busybear ../testbench/*.sv ../src/*/*.sv -suppress 2583 | ||||
| 
 | ||||
| 
 | ||||
| # start and run simulation | ||||
| # remove +acc flag for faster sim during regressions if there is no need to access internal signals | ||||
| vopt +acc work.testbench_busybear -o workopt  | ||||
| vsim workopt | ||||
| vsim workopt -suppress 8852,12070 | ||||
| mem load -startaddress 0 -endaddress 2047 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/uncore/bootdtim/RAM | ||||
| mem load -startaddress 512 -i "/courses/e190ax/busybear_boot/bootmem.txt" -format hex /testbench_busybear/dut/uncore/bootdtim/RAM | ||||
| mem load -startaddress 0 -endaddress 2047 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/imem/bootram | ||||
| mem load -startaddress 512 -i "/courses/e190ax/busybear_boot/bootmem.txt" -format hex /testbench_busybear/dut/imem/bootram | ||||
| mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/uncore/dtim/RAM | ||||
| mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/uncore/dtim/RAM | ||||
| mem load -startaddress 268435456 -endaddress 285212671 -filltype value -fillradix hex -filldata 0 /testbench_busybear/dut/imem/RAM | ||||
| mem load -startaddress 268435456 -i "/courses/e190ax/busybear_boot/ram.txt" -format hex /testbench_busybear/dut/imem/RAM | ||||
| 
 | ||||
| view wave | ||||
| 
 | ||||
| @ -42,80 +51,104 @@ add wave /testbench_busybear/reset | ||||
| add wave -divider | ||||
| add wave -hex /testbench_busybear/PCtext | ||||
| add wave -hex /testbench_busybear/pcExpected | ||||
| add wave -hex /testbench_busybear/dut/ifu/PCF | ||||
| add wave -hex /testbench_busybear/dut/ifu/InstrF | ||||
| add wave /testbench_busybear/lastInstrF | ||||
| add wave -hex /testbench_busybear/dut/hart/ifu/PCF | ||||
| add wave -hex /testbench_busybear/dut/hart/ifu/InstrF | ||||
| add wave -hex /testbench_busybear/dut/InstrF | ||||
| add wave /testbench_busybear/CheckInstrF | ||||
| add wave /testbench_busybear/lastCheckInstrF | ||||
| add wave /testbench_busybear/speculative | ||||
| add wave /testbench_busybear/lastPC2 | ||||
| add wave -divider | ||||
| add wave -divider | ||||
| add wave /testbench_busybear/dut/uncore/HSELBootTim | ||||
| add wave /testbench_busybear/dut/uncore/HSELTim | ||||
| add wave /testbench_busybear/dut/uncore/HREADTim | ||||
| add wave /testbench_busybear/dut/uncore/dtim/HREADTim0 | ||||
| add wave /testbench_busybear/dut/uncore/HREADYTim | ||||
| add wave -divider | ||||
| add wave /testbench_busybear/dut/uncore/HREADBootTim | ||||
| add wave /testbench_busybear/dut/uncore/bootdtim/HREADTim0 | ||||
| add wave /testbench_busybear/dut/uncore/HREADYBootTim | ||||
| add wave /testbench_busybear/dut/uncore/HADDR | ||||
| add wave /testbench_busybear/dut/uncore/HRESP | ||||
| add wave /testbench_busybear/dut/uncore/HREADY | ||||
| add wave /testbench_busybear/dut/uncore/HRDATA | ||||
| #add wave -hex /testbench_busybear/dut/hart/priv/csr/MTVEC_REG | ||||
| #add wave -hex /testbench_busybear/dut/hart/priv/csr/MSTATUS_REG | ||||
| #add wave -hex /testbench_busybear/dut/hart/priv/csr/SCOUNTEREN_REG | ||||
| #add wave -hex /testbench_busybear/dut/hart/priv/csr/MIE_REG | ||||
| #add wave -hex /testbench_busybear/dut/hart/priv/csr/MIDELEG_REG | ||||
| #add wave -hex /testbench_busybear/dut/hart/priv/csr/MEDELEG_REG | ||||
| add wave -divider | ||||
| # registers! | ||||
| add wave -hex /testbench_busybear/regExpected | ||||
| add wave -hex /testbench_busybear/regNumExpected | ||||
| add wave -hex /testbench_busybear/HWRITE | ||||
| add wave -hex /testbench_busybear/dut/MemRWM[1] | ||||
| add wave -hex /testbench_busybear/dut/hart/MemRWM[1] | ||||
| add wave -hex /testbench_busybear/HWDATA | ||||
| add wave -hex /testbench_busybear/HRDATA | ||||
| add wave -hex /testbench_busybear/HADDR | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[1] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[2] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[3] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[4] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[5] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[6] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[7] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[8] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[9] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[10] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[11] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[12] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[13] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[14] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[15] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[16] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[17] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[18] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[19] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[20] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[21] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[22] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[23] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[24] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[25] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[26] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[27] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[28] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[29] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[30] | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/regf/rf[31] | ||||
| add wave -hex /testbench_busybear/readAdrExpected | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[1] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[2] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[3] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[4] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[5] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[6] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[7] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[8] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[9] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[10] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[11] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[12] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[13] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[14] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[15] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[16] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[17] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[18] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[19] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[20] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[21] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[22] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[23] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[24] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[25] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[26] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[27] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[28] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[29] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[30] | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/regf/rf[31] | ||||
| add wave /testbench_busybear/InstrFName | ||||
| add wave -hex /testbench_busybear/dut/ifu/PCD | ||||
| #add wave -hex /testbench_busybear/dut/ifu/InstrD | ||||
| add wave -hex /testbench_busybear/dut/hart/ifu/PCD | ||||
| #add wave -hex /testbench_busybear/dut/hart/ifu/InstrD | ||||
| add wave /testbench_busybear/InstrDName | ||||
| #add wave -divider | ||||
| add wave -hex /testbench_busybear/dut/ifu/PCE | ||||
| ##add wave -hex /testbench_busybear/dut/ifu/InstrE | ||||
| add wave -hex /testbench_busybear/dut/hart/ifu/PCE | ||||
| ##add wave -hex /testbench_busybear/dut/hart/ifu/InstrE | ||||
| add wave /testbench_busybear/InstrEName | ||||
| #add wave -hex /testbench_busybear/dut/ieu/dp/SrcAE | ||||
| #add wave -hex /testbench_busybear/dut/ieu/dp/SrcBE | ||||
| add wave -hex /testbench_busybear/dut/ieu/dp/ALUResultE | ||||
| #add wave /testbench_busybear/dut/ieu/dp/PCSrcE | ||||
| #add wave -hex /testbench_busybear/dut/hart/ieu/dp/SrcAE | ||||
| #add wave -hex /testbench_busybear/dut/hart/ieu/dp/SrcBE | ||||
| add wave -hex /testbench_busybear/dut/hart/ieu/dp/ALUResultE | ||||
| #add wave /testbench_busybear/dut/hart/ieu/dp/PCSrcE | ||||
| #add wave -divider | ||||
| add wave -hex /testbench_busybear/dut/ifu/PCM | ||||
| ##add wave -hex /testbench_busybear/dut/ifu/InstrM | ||||
| add wave -hex /testbench_busybear/dut/hart/ifu/PCM | ||||
| ##add wave -hex /testbench_busybear/dut/hart/ifu/InstrM | ||||
| add wave /testbench_busybear/InstrMName | ||||
| #add wave /testbench_busybear/dut/dmem/dtim/memwrite | ||||
| #add wave -hex /testbench_busybear/dut/dmem/AdrM | ||||
| #add wave -hex /testbench_busybear/dut/dmem/WriteDataM | ||||
| #add wave /testbench_busybear/dut/hart/dmem/dtim/memwrite | ||||
| #add wave -hex /testbench_busybear/dut/hart/dmem/AdrM | ||||
| #add wave -hex /testbench_busybear/dut/hart/dmem/WriteDataM | ||||
| #add wave -divider | ||||
| add wave -hex /testbench_busybear/dut/ifu/PCW | ||||
| ##add wave -hex /testbench_busybear/dut/ifu/InstrW | ||||
| add wave -hex /testbench_busybear/dut/hart/ifu/PCW | ||||
| ##add wave -hex /testbench_busybear/dut/hart/ifu/InstrW | ||||
| add wave /testbench_busybear/InstrWName | ||||
| #add wave /testbench_busybear/dut/ieu/dp/RegWriteW | ||||
| #add wave -hex /testbench_busybear/dut/ieu/dp/ResultW | ||||
| #add wave -hex /testbench_busybear/dut/ieu/dp/RdW | ||||
| #add wave /testbench_busybear/dut/hart/ieu/dp/RegWriteW | ||||
| #add wave -hex /testbench_busybear/dut/hart/ieu/dp/ResultW | ||||
| #add wave -hex /testbench_busybear/dut/hart/ieu/dp/RdW | ||||
| #add wave -divider | ||||
| ##add ww | ||||
| #add wave -hex -r /testbench_busybear/* | ||||
| add wave -hex -r /testbench_busybear/* | ||||
| # | ||||
| #-- Set Wave Output Items  | ||||
| #TreeUpdate [SetDefaultTree] | ||||
| @ -131,6 +164,5 @@ add wave /testbench_busybear/InstrWName | ||||
| #set DefaultRadix hexadecimal | ||||
| # | ||||
| #-- Run the Simulation  | ||||
| run 1483850 | ||||
| #run -all | ||||
| run -all | ||||
| ##quit | ||||
|  | ||||
							
								
								
									
										80
									
								
								wally-pipelined/regression/wally-peripherals-signals.do
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								wally-pipelined/regression/wally-peripherals-signals.do
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| # wally-peripherals-signals.do  | ||||
| # | ||||
| # Created by Ben Bracker (bbracker@hmc.edu) on 4 Mar. 2021 | ||||
| # | ||||
| # I really didn't like having to relaunch and recompile an entire sim | ||||
| # just because some signal names have changed, so I thought this | ||||
| # would be good to factor out. | ||||
| 
 | ||||
| restart -f | ||||
| delete wave /* | ||||
| view wave | ||||
| 
 | ||||
| -- display input and output signals as hexidecimal values | ||||
| # Diplays All Signals recursively | ||||
| add wave /testbench/clk | ||||
| add wave /testbench/reset | ||||
| add wave -divider | ||||
| add wave /testbench/dut/hart/DataStall | ||||
| add wave /testbench/dut/hart/InstrStall | ||||
| add wave /testbench/dut/hart/StallF | ||||
| add wave /testbench/dut/hart/StallD | ||||
| add wave /testbench/dut/hart/FlushD | ||||
| add wave /testbench/dut/hart/FlushE | ||||
| add wave /testbench/dut/hart/FlushM | ||||
| add wave /testbench/dut/hart/FlushW | ||||
| 
 | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/hart/ifu/PCF | ||||
| add wave -hex /testbench/dut/hart/ifu/InstrF | ||||
| add wave /testbench/InstrFName | ||||
| #add wave -hex /testbench/dut/hart/ifu/PCD | ||||
| add wave -hex /testbench/dut/hart/ifu/InstrD | ||||
| add wave /testbench/InstrDName | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/hart/ifu/PCE | ||||
| add wave -hex /testbench/dut/hart/ifu/InstrE | ||||
| add wave /testbench/InstrEName | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/SrcAE | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/SrcBE | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/hart/ifu/PCM | ||||
| add wave -hex /testbench/dut/hart/ifu/InstrM | ||||
| add wave /testbench/InstrMName | ||||
| add wave /testbench/dut/uncore/dtim/memwrite | ||||
| add wave -hex /testbench/dut/uncore/HADDR | ||||
| add wave -hex /testbench/dut/uncore/HWDATA | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/hart/ifu/PCW | ||||
| add wave /testbench/InstrWName | ||||
| add wave /testbench/dut/hart/ieu/dp/RegWriteW | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/ResultW | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/RdW | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/hart/ebu/* | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/uncore/uart/u/* | ||||
| add wave -divider | ||||
| #add ww | ||||
| add wave -hex -r /testbench/* | ||||
| 
 | ||||
| -- Set Wave Output Items  | ||||
| TreeUpdate [SetDefaultTree] | ||||
| WaveRestoreZoom {0 ps} {100 ps} | ||||
| configure wave -namecolwidth 250 | ||||
| configure wave -valuecolwidth 120 | ||||
| configure wave -justifyvalue left | ||||
| configure wave -signalnamewidth 0 | ||||
| configure wave -snapdistance 10 | ||||
| configure wave -datasetprefix 0 | ||||
| configure wave -rowmargin 4 | ||||
| configure wave -childrowmargin 2 | ||||
| set DefaultRadix hexadecimal | ||||
| 
 | ||||
| -- Run the Simulation  | ||||
| #run 5000  | ||||
| run -all | ||||
| #quit | ||||
| noview ../testbench/testbench-peripherals.sv | ||||
| view wave | ||||
| @ -39,70 +39,4 @@ vopt +acc work.testbench -o workopt | ||||
| vsim workopt | ||||
| 
 | ||||
| view wave | ||||
| 
 | ||||
| -- display input and output signals as hexidecimal values | ||||
| # Diplays All Signals recursively | ||||
| add wave /testbench/clk | ||||
| add wave /testbench/reset | ||||
| add wave -divider | ||||
| add wave /testbench/dut/hart/ebu/IReadF | ||||
| add wave /testbench/dut/hart/DataStall | ||||
| add wave /testbench/dut/hart/InstrStall | ||||
| add wave /testbench/dut/hart/StallF | ||||
| add wave /testbench/dut/hart/StallD | ||||
| add wave /testbench/dut/hart/FlushD | ||||
| add wave /testbench/dut/hart/FlushE | ||||
| add wave /testbench/dut/hart/FlushM | ||||
| add wave /testbench/dut/hart/FlushW | ||||
| 
 | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/hart/ifu/PCF | ||||
| add wave -hex /testbench/dut/hart/ifu/InstrF | ||||
| add wave /testbench/InstrFName | ||||
| #add wave -hex /testbench/dut/hart/ifu/PCD | ||||
| add wave -hex /testbench/dut/hart/ifu/InstrD | ||||
| add wave /testbench/InstrDName | ||||
| add wave -divider | ||||
| #add wave -hex /testbench/dut/hart/ifu/PCE | ||||
| #add wave -hex /testbench/dut/hart/ifu/InstrE | ||||
| add wave /testbench/InstrEName | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/SrcAE | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/SrcBE | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE | ||||
| add wave /testbench/dut/hart/ieu/dp/PCSrcE | ||||
| add wave -divider | ||||
| #add wave -hex /testbench/dut/hart/ifu/PCM | ||||
| #add wave -hex /testbench/dut/hart/ifu/InstrM | ||||
| add wave /testbench/InstrMName | ||||
| add wave /testbench/dut/uncore/dtim/memwrite | ||||
| add wave -hex /testbench/dut/uncore/HADDR | ||||
| add wave -hex /testbench/dut/uncore/HWDATA | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/hart/ifu/PCW | ||||
| add wave /testbench/InstrWName | ||||
| add wave /testbench/dut/hart/ieu/dp/RegWriteW | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/ResultW | ||||
| add wave -hex /testbench/dut/hart/ieu/dp/RdW | ||||
| add wave -divider | ||||
| add wave -hex /testbench/dut/uncore/uart/u/* | ||||
| add wave -divider | ||||
| #add ww | ||||
| add wave -hex -r /testbench/* | ||||
| 
 | ||||
| -- Set Wave Output Items  | ||||
| TreeUpdate [SetDefaultTree] | ||||
| WaveRestoreZoom {0 ps} {100 ps} | ||||
| configure wave -namecolwidth 250 | ||||
| configure wave -valuecolwidth 120 | ||||
| configure wave -justifyvalue left | ||||
| configure wave -signalnamewidth 0 | ||||
| configure wave -snapdistance 10 | ||||
| configure wave -datasetprefix 0 | ||||
| configure wave -rowmargin 4 | ||||
| configure wave -childrowmargin 2 | ||||
| set DefaultRadix hexadecimal | ||||
| 
 | ||||
| -- Run the Simulation  | ||||
| run 5000  | ||||
| #run -all | ||||
| #quit | ||||
| do wally-peripherals-signals.do | ||||
|  | ||||
| @ -6,13 +6,12 @@ | ||||
| # Go Cowboys!!!!!! | ||||
| # | ||||
| # Takes 1:10 to run RV64IC tests using gui | ||||
| # 11 seconds to run batch mode | ||||
| 
 | ||||
| # Use this wally-pipelined.do file to run this example. | ||||
| # Use this wally-pipelined-batch.do file to run this example. | ||||
| # Either bring up ModelSim and type the following at the "ModelSim>" prompt: | ||||
| #     do wally-pipelined.do ../config/rv64ic | ||||
| #     do wally-pipelined-batch.do | ||||
| # or, to run from a shell, type the following at the shell prompt: | ||||
| #     vsim -c -do wally-pipelined.do ../config/rv64ic | ||||
| #     vsim -do wally-pipelined-batch.do -c | ||||
| # (omit the "-c" to see the GUI while running from the shell) | ||||
| 
 | ||||
| onbreak {resume} | ||||
| @ -27,12 +26,22 @@ vlib work | ||||
| # suppress spurious warnngs about  | ||||
| # "Extra checking for conflicts with always_comb done at vopt time" | ||||
| # because vsim will run vopt | ||||
| vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583 | ||||
| 
 | ||||
| # default to config/rv64ic, but allow this to be overridden at the command line.  For example: | ||||
| # do wally-pipelined-batch.do ../config/rv32ic | ||||
| switch $argc { | ||||
|     0 {vlog +incdir+../config/rv64ic ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} | ||||
|     1 {vlog +incdir+$1 ../testbench/testbench-imperas.sv ../src/*/*.sv -suppress 2583} | ||||
| } | ||||
| # start and run simulation | ||||
| # remove +acc flag for faster sim during regressions if there is no need to access internal signals | ||||
| vopt work.testbench -o workopt  | ||||
| vopt +acc work.testbench -o workopt  | ||||
| vsim workopt | ||||
| 
 | ||||
| # load the branch predictors with known data. The value of the data is not important for function, but | ||||
| # is important for perventing pessimistic x propagation. | ||||
| mem load -infile twoBitPredictor.txt -format bin testbench/dut/hart/ifu/bpred/DirPredictor/memory/memory | ||||
| mem load -infile BTBPredictor.txt -format bin testbench/dut/hart/ifu/bpred/TargetPredictor/memory/memory | ||||
| 
 | ||||
| run -all | ||||
| quit | ||||
|  | ||||
| @ -108,7 +108,7 @@ module csrm #(parameter | ||||
|   assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT); | ||||
| 
 | ||||
|   // CSRs
 | ||||
|   flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, `RESET_VECTOR, MTVEC_REGW); | ||||
|   flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, `XLEN'b0, MTVEC_REGW); //busybear: changed reset value to 0
 | ||||
|   generate | ||||
|     if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist
 | ||||
|       flopenl #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, zero, MEDELEG_REGW); | ||||
| @ -125,7 +125,11 @@ module csrm #(parameter | ||||
|   flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);  | ||||
|   flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);  | ||||
|   flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); | ||||
|   `ifndef BUSYBEAR | ||||
|   flopenl #(32)   MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], allones, MCOUNTEREN_REGW); | ||||
|   `else | ||||
|   flopenl #(32)   MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW); | ||||
|   `endif | ||||
|   flopenl #(32)   MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], allones, MCOUNTINHIBIT_REGW); | ||||
|   flopenr #(`XLEN) PMPADDR0reg(clk, reset, WritePMPADDR0M, CSRWriteValM, PMPADDR0_REGW);   | ||||
|   // PMPCFG registers are a pair of 64-bit in RV64 and four 32-bit in RV32
 | ||||
|  | ||||
| @ -76,13 +76,17 @@ module csrs #(parameter | ||||
|       assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN); | ||||
| 
 | ||||
|       // CSRs
 | ||||
|       flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, `RESET_VECTOR, STVEC_REGW); | ||||
|       flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, zero, STVEC_REGW); //busybear: change reset to 0
 | ||||
|       flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW); | ||||
|       flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);  | ||||
|       flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW);  | ||||
|       flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW); | ||||
|       flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW); | ||||
|       `ifndef BUSYBEAR | ||||
|       flopenl #(32)   SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], allones, SCOUNTEREN_REGW); | ||||
|       `else | ||||
|       flopenl #(32)   SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW); | ||||
|       `endif | ||||
|       if (`N_SUPPORTED) begin | ||||
|         logic WriteSEDELEGM, WriteSIDELEGM; | ||||
|         assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG); | ||||
|  | ||||
| @ -109,15 +109,15 @@ module csrsr ( | ||||
|     if (reset) begin | ||||
|       STATUS_SUM_INT <= 0; | ||||
|       STATUS_MPRV_INT <= 0; // Per Priv 3.3
 | ||||
|       STATUS_FS_INT <= 2'b01; // initial 
 | ||||
|       STATUS_MPP <= `M_MODE; | ||||
|       STATUS_SPP <= 1'b1; | ||||
|       STATUS_MPIE <= 1; | ||||
|       STATUS_SPIE <= `S_SUPPORTED; | ||||
|       STATUS_UPIE <= `U_SUPPORTED; | ||||
|       STATUS_FS_INT <= 0; //2'b01; // busybear: change all these reset values to 0
 | ||||
|       STATUS_MPP <= 0; //`M_MODE;
 | ||||
|       STATUS_SPP <= 0; //1'b1;
 | ||||
|       STATUS_MPIE <= 0; //1;
 | ||||
|       STATUS_SPIE <= 0; //`S_SUPPORTED;
 | ||||
|       STATUS_UPIE <= 0; // `U_SUPPORTED;
 | ||||
|       STATUS_MIE <= 0; // Per Priv 3.3
 | ||||
|       STATUS_SIE <= `S_SUPPORTED; | ||||
|       STATUS_UIE <= `U_SUPPORTED; | ||||
|       STATUS_SIE <= 0; //`S_SUPPORTED;
 | ||||
|       STATUS_UIE <= 0; //`U_SUPPORTED;
 | ||||
|     end else if (~StallW) begin | ||||
|       if (WriteMSTATUSM) begin | ||||
|         STATUS_SUM_INT <= CSRWriteValM[18]; | ||||
|  | ||||
| @ -28,8 +28,9 @@ | ||||
| 
 | ||||
| module clint ( | ||||
|   input  logic             HCLK, HRESETn, | ||||
|   input  logic [1:0]       MemRWclint, | ||||
|   input  logic             HSELCLINT, | ||||
|   input  logic [15:0]      HADDR, | ||||
|   input  logic             HWRITE, | ||||
|   input  logic [`XLEN-1:0] HWDATA, | ||||
|   output logic [`XLEN-1:0] HREADCLINT, | ||||
|   output logic             HRESPCLINT, HREADYCLINT, | ||||
| @ -41,8 +42,8 @@ module clint ( | ||||
|   logic [15:0] entry; | ||||
|   logic            memread, memwrite; | ||||
| 
 | ||||
|   assign memread  = MemRWclint[1]; | ||||
|   assign memwrite = MemRWclint[0]; | ||||
|   assign memread  = HSELCLINT & ~HWRITE; | ||||
|   assign memwrite = HSELCLINT & HWRITE; | ||||
|   assign HRESPCLINT = 0; // OK
 | ||||
| //  assign HREADYCLINT = 1; // Respond immediately
 | ||||
|   always_ff @(posedge HCLK) // delay response
 | ||||
|  | ||||
| @ -25,18 +25,18 @@ | ||||
| 
 | ||||
| `include "wally-config.vh" | ||||
| 
 | ||||
| module dtim ( | ||||
| module dtim #(parameter BASE=0, RANGE = 65535) ( | ||||
|   input  logic             HCLK, HRESETn,  | ||||
|   input  logic [1:0]       MemRWtim, | ||||
|   input  logic [18:0]      HADDR,  | ||||
|   input  logic [`XLEN-1:0] HWDATA, | ||||
|   input  logic             HSELTim, | ||||
|   input  logic [31:0]      HADDR, | ||||
|   input  logic             HWRITE, | ||||
|   input  logic [`XLEN-1:0] HWDATA, | ||||
|   output logic [`XLEN-1:0] HREADTim, | ||||
|   output logic             HRESPTim, HREADYTim | ||||
| ); | ||||
| 
 | ||||
|   logic [`XLEN-1:0] RAM[0:65535]; | ||||
|   logic [18:0] HWADDR; | ||||
|   logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; | ||||
|   logic [31:0] HWADDR, A; | ||||
|   logic [`XLEN-1:0] HREADTim0; | ||||
| 
 | ||||
| //  logic [`XLEN-1:0] write;
 | ||||
| @ -44,6 +44,12 @@ module dtim ( | ||||
|   logic        memread, memwrite; | ||||
|   logic [3:0]  busycount; | ||||
| 
 | ||||
|   always_ff @(posedge HCLK) begin | ||||
|     memread <= HSELTim & ~ HWRITE; | ||||
|     memwrite <= HSELTim & HWRITE; | ||||
|     A <= HADDR; | ||||
|   end | ||||
| 
 | ||||
|   // busy FSM to extend READY signal
 | ||||
|   always_ff @(posedge HCLK, negedge HRESETn)  | ||||
|     if (~HRESETn) begin | ||||
| @ -61,42 +67,21 @@ module dtim ( | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|  /* always_ff @(posedge HCLK, negedge HRESETn)  | ||||
|     if (~HRESETn) begin | ||||
|       HREADYTim <= 0; | ||||
|     end else begin | ||||
|       HREADYTim <= HSELTim; // always respond one cycle later
 | ||||
|     end */ | ||||
| 
 | ||||
| 
 | ||||
|   assign memread = MemRWtim[1]; | ||||
|   assign memwrite = MemRWtim[0]; | ||||
| //  always_ff @(posedge HCLK)
 | ||||
| //    memwrite <= MemRWtim[0]; // delay memwrite to write phase
 | ||||
|   assign HRESPTim = 0; // OK
 | ||||
| //  assign HREADYTim = 1; // Respond immediately; *** extend this 
 | ||||
| 
 | ||||
| 
 | ||||
|   // Model memory read and write
 | ||||
|    | ||||
|   generate | ||||
|     if (`XLEN == 64)  begin | ||||
| //      always_ff @(negedge HCLK) 
 | ||||
| //        if (memwrite) RAM[HWADDR[17:3]] <= HWDATA;
 | ||||
|       always_ff @(posedge HCLK) begin | ||||
|         //if (memwrite) RAM[HADDR[17:3]] <= HWDATA;  
 | ||||
|         HWADDR <= HADDR; | ||||
|         HREADTim0 <= RAM[HADDR[17:3]]; | ||||
|         if (memwrite && HREADYTim) RAM[HWADDR[17:3]] <= HWDATA; | ||||
|         HWADDR <= A; | ||||
|         HREADTim0 <= RAM[A[31:3]]; | ||||
|         if (memwrite && HREADYTim) RAM[HWADDR[31:3]] <= HWDATA; | ||||
|       end | ||||
|     end else begin  | ||||
| //      always_ff @(negedge HCLK) 
 | ||||
| //        if (memwrite) RAM[HWADDR[17:2]] <= HWDATA;
 | ||||
|       always_ff @(posedge HCLK) begin | ||||
|         //if (memwrite) RAM[HADDR[17:2]] <= HWDATA;
 | ||||
|         HWADDR <= HADDR;   | ||||
|         HREADTim0 <= RAM[HADDR[17:2]]; | ||||
|         if (memwrite && HREADYTim) RAM[HWADDR[17:2]] <= HWDATA; | ||||
|         HWADDR <= A;   | ||||
|         HREADTim0 <= RAM[A[31:2]]; | ||||
|         if (memwrite && HREADYTim) RAM[HWADDR[31:2]] <= HWDATA; | ||||
|       end | ||||
|     end | ||||
|   endgenerate | ||||
|  | ||||
| @ -29,9 +29,10 @@ | ||||
| 
 | ||||
| module gpio ( | ||||
|   input  logic             HCLK, HRESETn, | ||||
|   input  logic [1:0]       MemRWgpio, | ||||
|   input  logic             HSELGPIO, | ||||
|   input  logic [7:0]       HADDR,  | ||||
|   input  logic [`XLEN-1:0] HWDATA, | ||||
|   input  logic             HWRITE, | ||||
|   output logic [`XLEN-1:0] HREADGPIO, | ||||
|   output logic             HRESPGPIO, HREADYGPIO, | ||||
|   input  logic [31:0]      GPIOPinsIn, | ||||
| @ -42,8 +43,8 @@ module gpio ( | ||||
|   logic [7:0] entry; | ||||
|   logic            memread, memwrite; | ||||
| 
 | ||||
|   assign memread  = MemRWgpio[1]; | ||||
|   assign memwrite = MemRWgpio[0]; | ||||
|   assign memread  = HSELGPIO & ~HWRITE; | ||||
|   assign memwrite = HSELGPIO & HWRITE; | ||||
|   assign HRESPGPIO = 0; // OK
 | ||||
|   always_ff @(posedge HCLK) // delay response to data cycle
 | ||||
|     HREADYGPIO <= memread | memwrite; | ||||
|  | ||||
| @ -32,24 +32,35 @@ module imem ( | ||||
|   output logic             InstrAccessFaultF); | ||||
| 
 | ||||
|  /* verilator lint_off UNDRIVEN */ | ||||
|   logic [`XLEN-1:0] RAM[0:65535]; | ||||
|   logic [`XLEN-1:0] RAM[`TIMBASE>>(1+`XLEN/32):(`TIMRANGE+`TIMBASE)>>(1+`XLEN/32)]; | ||||
|   `ifdef BOOTTIMBASE | ||||
|   logic [`XLEN-1:0] bootram[`BOOTTIMBASE>>(1+`XLEN/32):(`BOOTTIMRANGE+`BOOTTIMBASE)>>(1+`XLEN/32)]; | ||||
|   `endif | ||||
|  /* verilator lint_on UNDRIVEN */ | ||||
|   logic [15:0] adrbits; | ||||
|   logic [28:0] adrbits; | ||||
|   logic [`XLEN-1:0] rd; | ||||
| //  logic [15:0] rd2;
 | ||||
|        | ||||
|   generate | ||||
|     if (`XLEN==32) assign adrbits = AdrF[17:2]; | ||||
|     else          assign adrbits = AdrF[18:3]; | ||||
|     if (`XLEN==32) assign adrbits = AdrF[30:2]; | ||||
|     else          assign adrbits = AdrF[31:3]; | ||||
|   endgenerate | ||||
| 
 | ||||
|   `ifndef BOOTTIMBASE | ||||
|   assign #2 rd = RAM[adrbits]; // word aligned
 | ||||
|   `else | ||||
|   assign #2 rd = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits] : RAM[adrbits]; // busybear: 2 memory options
 | ||||
|   `endif | ||||
| 
 | ||||
|   // hack right now for unaligned 32-bit instructions
 | ||||
|   // eventually this will need to cause a stall like a cache miss
 | ||||
|   // when the instruction wraps around a cache line
 | ||||
|   // could be optimized to only stall when the instruction wrapping is 32 bits
 | ||||
|   `ifndef BOOTTIMBASE | ||||
|   assign #2 rd2 = RAM[adrbits+1][15:0]; | ||||
|   `else | ||||
|   assign #2 rd2 = (AdrF < (`TIMBASE >> 1)) ? bootram[adrbits+1][15:0] : RAM[adrbits+1][15:0]; //busybear: 2 memory options
 | ||||
|   `endif | ||||
|   generate  | ||||
|     if (`XLEN==32) begin | ||||
|       assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd; | ||||
| @ -57,7 +68,11 @@ module imem ( | ||||
|     end else begin | ||||
|       assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32]) | ||||
|                           : (AdrF[1] ? rd[47:16] : rd[31:0]); | ||||
|       `ifndef BOOTTIMBASE | ||||
|       assign InstrAccessFaultF = |AdrF[`XLEN-1:32] | ~&({AdrF[31:1],1'b0} ~^ `TIMBASE | `TIMRANGE); | ||||
|       `else | ||||
|       assign InstrAccessFaultF = 0; //busybear: for now, i know we're not doing this
 | ||||
|       `endif | ||||
|     end | ||||
|   endgenerate | ||||
| endmodule | ||||
|  | ||||
| @ -29,8 +29,9 @@ | ||||
| 
 | ||||
| module uart ( | ||||
|   input  logic             HCLK, HRESETn,  | ||||
|   input  logic [1:0]       MemRWuart, | ||||
|   input  logic             HSELUART, | ||||
|   input  logic [2:0]       HADDR, | ||||
|   input  logic             HWRITE, | ||||
|   input  logic [`XLEN-1:0] HWDATA, | ||||
|   output logic [`XLEN-1:0] HREADUART, | ||||
|   output logic             HRESPUART, HREADYUART, | ||||
| @ -44,37 +45,37 @@ module uart ( | ||||
|   logic [7:0]      Din, Dout; | ||||
| 
 | ||||
|   // rename processor interface signals to match PC16550D and provide one-byte interface
 | ||||
|   assign MEMRb = ~MemRWuart[1]; | ||||
|   assign MEMWb = ~MemRWuart[0]; | ||||
|   assign A = HADDR[2:0]; | ||||
|   always_ff @(posedge HCLK) begin | ||||
|     MEMRb <= ~(HSELUART & ~HWRITE); | ||||
|     MEMWb <= ~(HSELUART & HWRITE); | ||||
|     A <= HADDR[2:0]; | ||||
|   end | ||||
|   assign HRESPUART = 0; // OK
 | ||||
|   //assign HREADYUART = 1; // Respond immediately
 | ||||
|   always_ff @(posedge HCLK) // delay response to data cycle
 | ||||
|     HREADYUART <= ~MEMRb | ~MEMWb; | ||||
|   assign HREADYUART = 1; // should idle high during address phase and respond high when done; will need to be modified if UART ever needs more than 1 cycle to do something
 | ||||
| 
 | ||||
|   generate | ||||
|     if (`XLEN == 64) begin | ||||
|       always @(posedge HCLK) begin | ||||
|       always_comb begin | ||||
|         HREADUART = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout}; | ||||
|         case (HADDR) | ||||
|           3'b000: Din <= HWDATA[7:0]; | ||||
|           3'b001: Din <= HWDATA[15:8]; | ||||
|           3'b010: Din <= HWDATA[23:16]; | ||||
|           3'b011: Din <= HWDATA[31:24]; | ||||
|           3'b100: Din <= HWDATA[39:32]; | ||||
|           3'b101: Din <= HWDATA[47:40]; | ||||
|           3'b110: Din <= HWDATA[55:48]; | ||||
|           3'b111: Din <= HWDATA[63:56]; | ||||
|         case (A) | ||||
|           3'b000: Din = HWDATA[7:0]; | ||||
|           3'b001: Din = HWDATA[15:8]; | ||||
|           3'b010: Din = HWDATA[23:16]; | ||||
|           3'b011: Din = HWDATA[31:24]; | ||||
|           3'b100: Din = HWDATA[39:32]; | ||||
|           3'b101: Din = HWDATA[47:40]; | ||||
|           3'b110: Din = HWDATA[55:48]; | ||||
|           3'b111: Din = HWDATA[63:56]; | ||||
|         endcase  | ||||
|       end  | ||||
|     end else begin // 32-bit
 | ||||
|       always @(posedge HCLK) begin | ||||
|       always_comb begin | ||||
|         HREADUART = {Dout, Dout, Dout, Dout}; | ||||
|         case (HADDR[1:0]) | ||||
|           2'b00: Din <= HWDATA[7:0]; | ||||
|           2'b01: Din <= HWDATA[15:8]; | ||||
|           2'b10: Din <= HWDATA[23:16]; | ||||
|           2'b11: Din <= HWDATA[31:24]; | ||||
|         case (A[1:0]) | ||||
|           2'b00: Din = HWDATA[7:0]; | ||||
|           2'b01: Din = HWDATA[15:8]; | ||||
|           2'b10: Din = HWDATA[23:16]; | ||||
|           2'b11: Din = HWDATA[31:24]; | ||||
|         endcase | ||||
|       end | ||||
|     end | ||||
|  | ||||
| @ -376,7 +376,7 @@ module uartPC16550D( | ||||
|           TXHR <= Din; | ||||
|           txhrfull <= 1; | ||||
|         end | ||||
|         $display("UART transmits: %c",Din); // for testbench
 | ||||
|         $write("%c",Din); // for testbench
 | ||||
|       end | ||||
|       if (txstate == UART_IDLE) begin // move data into tx shift register if available
 | ||||
|         if (fifoenabled) begin  | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| // uncore.sv
 | ||||
| //
 | ||||
| // Written: David_Harris@hmc.edu 9 January 2021
 | ||||
| // Modified: 
 | ||||
| // Modified: Ben Bracker 6 Mar 2021 to better fit AMBA 3 AHB-Lite spec
 | ||||
| //
 | ||||
| // Purpose: System-on-Chip components outside the core (hart)
 | ||||
| //          Memories, peripherals, external bus control
 | ||||
| @ -59,58 +59,96 @@ module uncore ( | ||||
|    | ||||
|   logic [`XLEN-1:0] HWDATA; | ||||
|   logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADGPIO, HREADUART; | ||||
| 
 | ||||
|   logic            HSELTim, HSELCLINT, HSELGPIO, PreHSELUART, HSELUART; | ||||
|   logic            HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD; | ||||
|   logic            HRESPTim, HRESPCLINT, HRESPGPIO, HRESPUART; | ||||
|   logic            HREADYTim, HREADYCLINT, HREADYGPIO, HREADYUART;   | ||||
|   logic [1:0]      MemRW; | ||||
|   logic [1:0]      MemRWtim, MemRWclint, MemRWgpio, MemRWuart; | ||||
|   `ifdef BOOTTIMBASE | ||||
|   logic [`XLEN-1:0] HREADBootTim;  | ||||
|   logic            HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim; | ||||
|   logic [1:0]      MemRWboottim; | ||||
|   `endif | ||||
|   logic            UARTIntr;// *** will need to tie INTR to an interrupt handler
 | ||||
|    | ||||
| 
 | ||||
|   // AHB Address decoder
 | ||||
|   adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim); | ||||
|   `ifdef BOOTTIMBASE | ||||
|   adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim); | ||||
|   `endif | ||||
|   adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT); | ||||
|   `ifdef GPIOBASE | ||||
|   adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);  | ||||
|   `endif | ||||
|   adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART); | ||||
|   assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported
 | ||||
| 
 | ||||
|   // Enable read or write based on decoded address
 | ||||
|   assign MemRW = {~HWRITE, HWRITED}; | ||||
|   assign MemRWtim = MemRW & {2{HSELTim}}; | ||||
|   assign MemRWclint = MemRW & {2{HSELCLINT}}; | ||||
|   assign MemRWgpio = MemRW & {2{HSELGPIO}}; | ||||
|   assign MemRWuart = MemRW & {2{HSELUART}}; | ||||
| /*  always_ff @(posedge HCLK) begin | ||||
|     HADDRD <= HADDR; | ||||
|     MemRWtim  <= MemRW & {2{HSELTim}}; | ||||
|     MemRWclint <= MemRW & {2{HSELCLINT}}; | ||||
|     MemRWgpio  <= MemRW & {2{HSELGPIO}}; | ||||
|     MemRWuart  <= MemRW & {2{HSELUART}}; | ||||
|   end */ | ||||
| 
 | ||||
|   // subword accesses: converts HWDATAIN to HWDATA
 | ||||
|   subwordwrite sww(.*); | ||||
| 
 | ||||
|   // tightly integrated memory
 | ||||
|   dtim dtim(.HADDR(HADDR[18:0]), .*); | ||||
|   dtim #(.BASE(`TIMBASE), .RANGE(`TIMRANGE)) dtim (.*); | ||||
|   `ifdef BOOTTIMBASE | ||||
|   dtim #(.BASE(`BOOTTIMBASE), .RANGE(`BOOTTIMRANGE)) bootdtim(.HSELTim(HSELBootTim), .HREADTim(HREADBootTim), .HRESPTim(HRESPBootTim), .HREADYTim(HREADYBootTim), .*); | ||||
|   `endif | ||||
| 
 | ||||
|   // memory-mapped I/O peripherals
 | ||||
|   clint clint(.HADDR(HADDR[15:0]), .*); | ||||
|   `ifdef GPIOBASE | ||||
|   gpio gpio(.HADDR(HADDR[7:0]), .*); // *** may want to add GPIO interrupts
 | ||||
|   `endif | ||||
|   uart uart(.HADDR(HADDR[2:0]), .TXRDYb(), .RXRDYb(), .INTR(UARTIntr), .SIN(UARTSin), .SOUT(UARTSout), | ||||
|             .DSRb(1'b1), .DCDb(1'b1), .CTSb(1'b0), .RIb(1'b1),  | ||||
|             .RTSb(), .DTRb(), .OUT1b(), .OUT2b(), .*); | ||||
| 
 | ||||
|   // mux could also include external memory  
 | ||||
|   // AHB Read Multiplexer
 | ||||
|   assign HRDATA = ({`XLEN{HSELTim}} & HREADTim) | ({`XLEN{HSELCLINT}} & HREADCLINT) |  | ||||
|                      ({`XLEN{HSELGPIO}} & HREADGPIO) | ({`XLEN{HSELUART}} & HREADUART); | ||||
|   assign HRESP = HSELTim & HRESPTim | HSELCLINT & HRESPCLINT | HSELGPIO & HRESPGPIO | HSELUART & HRESPUART; | ||||
|   assign HREADY = HSELTim & HREADYTim | HSELCLINT & HREADYCLINT | HSELGPIO & HREADYGPIO | HSELUART & HREADYUART; | ||||
|   assign HRDATA = ({`XLEN{HSELTimD}} & HREADTim) | ({`XLEN{HSELCLINTD}} & HREADCLINT) |  | ||||
|                     `ifdef GPIOBASE | ||||
|                      ({`XLEN{HSELGPIOD}} & HREADGPIO) | | ||||
|                     `endif | ||||
|                     `ifdef BOOTTIMBASE | ||||
|                      ({`XLEN{HSELBootTimD}} & HREADBootTim) | | ||||
|                     `endif | ||||
|                      ({`XLEN{HSELUARTD}} & HREADUART); | ||||
|   assign HRESP = HSELTimD & HRESPTim | HSELCLINTD & HRESPCLINT |  | ||||
|                  `ifdef GPIOBASE | ||||
|                  HSELGPIOD & HRESPGPIO |  | ||||
|                  `endif | ||||
|                  `ifdef BOOTTIMBASE | ||||
|                  HSELBootTimD & HRESPBootTim |  | ||||
|                  `endif | ||||
|                  HSELUARTD & HRESPUART; | ||||
|   assign HREADY = HSELTimD & HREADYTim | HSELCLINTD & HREADYCLINT |  | ||||
|                   `ifdef GPIOBASE | ||||
|                   HSELGPIOD & HREADYGPIO |  | ||||
|                   `endif | ||||
|                   `ifdef BOOTTIMBASE | ||||
|                   HSELBootTimD & HREADYBootTim |  | ||||
|                   `endif | ||||
|                   HSELUARTD & HREADYUART; | ||||
| 
 | ||||
|   // Faults
 | ||||
|   assign DataAccessFaultM = ~(HSELTim | HSELCLINT | HSELGPIO | HSELUART); | ||||
|   assign DataAccessFaultM = ~(HSELTimD | HSELCLINTD |  | ||||
|                             `ifdef GPIOBASE | ||||
|                             HSELGPIOD | | ||||
|                             `endif | ||||
|                             `ifdef BOOTTIMBASE | ||||
|                             HSELBootTimD | | ||||
|                             `endif | ||||
|                             HSELUARTD); | ||||
| 
 | ||||
| 
 | ||||
|   // Address Decoder Delay (figure 4-2 in spec)
 | ||||
|   flopr #(1) hseltimreg(HCLK, ~HRESETn, HSELTim, HSELTimD); | ||||
|   flopr #(1) hselclintreg(HCLK, ~HRESETn, HSELCLINT, HSELCLINTD); | ||||
|   `ifdef GPIOBASE | ||||
|   flopr #(1) hselgpioreg(HCLK, ~HRESETn, HSELGPIO, HSELGPIOD); | ||||
|   `endif | ||||
|   flopr #(1) hseluartreg(HCLK, ~HRESETn, HSELUART, HSELUARTD); | ||||
|   `ifdef BOOTTIMBASE | ||||
|   flopr #(1) hselboottimreg(HCLK, ~HRESETn, HSELBootTim, HSELBootTimD); | ||||
|   `endif | ||||
| endmodule | ||||
| 
 | ||||
|  | ||||
| @ -7,14 +7,9 @@ module testbench_busybear(); | ||||
|   logic [31:0]     GPIOPinsOut, GPIOPinsEn; | ||||
| 
 | ||||
|   // instantiate device to be tested
 | ||||
|   logic [`XLEN-1:0] PCF;  | ||||
|   logic [31:0] InstrF; | ||||
|   logic        InstrAccessFaultF, DataAccessFaultM; | ||||
|   logic        TimerIntM = 0, SwIntM = 0; // from CLINT
 | ||||
|   logic        ExtIntM = 0; // not yet connected
 | ||||
|   logic [31:0] CheckInstrF; | ||||
| 
 | ||||
|   logic [`AHBW-1:0] HRDATA; | ||||
|   logic             HREADY, HRESP; | ||||
|   logic [31:0]      HADDR; | ||||
|   logic [`AHBW-1:0] HWDATA; | ||||
|   logic             HWRITE; | ||||
| @ -24,19 +19,16 @@ module testbench_busybear(); | ||||
|   logic [1:0]       HTRANS; | ||||
|   logic             HMASTLOCK; | ||||
|   logic             HCLK, HRESETn; | ||||
|   logic [`AHBW-1:0] HRDATAEXT; | ||||
|   logic             HREADYEXT, HRESPEXT; | ||||
|   logic             UARTSout; | ||||
| 
 | ||||
|   assign GPIOPinsIn = 0; | ||||
|   assign UARTSin = 1; | ||||
|   assign HREADY = 1; | ||||
|   assign HRESP = 0; | ||||
|   assign HRDATA = 0; | ||||
| 
 | ||||
|   // for now, seem to need these to be zero until we get a better idea
 | ||||
|   assign InstrAccessFaultF = 0; | ||||
|   assign DataAccessFaultM = 0; | ||||
| 
 | ||||
|   // instantiate processor and memories
 | ||||
|   wallypipelinedhart dut(.*); | ||||
|   wallypipelinedsoc dut(.*); | ||||
| 
 | ||||
| 
 | ||||
|   // initialize test
 | ||||
|   initial | ||||
| @ -47,7 +39,7 @@ module testbench_busybear(); | ||||
|   // read pc trace file
 | ||||
|   integer data_file_PC, scan_file_PC; | ||||
|   initial begin | ||||
|     data_file_PC = $fopen("../busybear-testgen/parsedPC.txt", "r"); | ||||
|     data_file_PC = $fopen("/courses/e190ax/busybear_boot/parsedPC.txt", "r"); | ||||
|     if (data_file_PC == 0) begin | ||||
|       $display("file couldn't be opened"); | ||||
|       $stop; | ||||
| @ -56,7 +48,7 @@ module testbench_busybear(); | ||||
| 
 | ||||
|   integer data_file_PCW, scan_file_PCW; | ||||
|   initial begin | ||||
|     data_file_PCW = $fopen("../busybear-testgen/parsedPC.txt", "r"); | ||||
|     data_file_PCW = $fopen("/courses/e190ax/busybear_boot/parsedPC.txt", "r"); | ||||
|     if (data_file_PCW == 0) begin | ||||
|       $display("file couldn't be opened"); | ||||
|       $stop; | ||||
| @ -66,7 +58,7 @@ module testbench_busybear(); | ||||
|   // read register trace file
 | ||||
|   integer data_file_rf, scan_file_rf; | ||||
|   initial begin | ||||
|     data_file_rf = $fopen("../busybear-testgen/parsedRegs.txt", "r"); | ||||
|     data_file_rf = $fopen("/courses/e190ax/busybear_boot/parsedRegs.txt", "r"); | ||||
|     if (data_file_rf == 0) begin | ||||
|       $display("file couldn't be opened"); | ||||
|       $stop; | ||||
| @ -76,7 +68,7 @@ module testbench_busybear(); | ||||
|   // read CSR trace file
 | ||||
|   integer data_file_csr, scan_file_csr; | ||||
|   initial begin | ||||
|     data_file_csr = $fopen("../busybear-testgen/parsedCSRs.txt", "r"); | ||||
|     data_file_csr = $fopen("/courses/e190ax/busybear_boot/parsedCSRs.txt", "r"); | ||||
|     if (data_file_csr == 0) begin | ||||
|       $display("file couldn't be opened"); | ||||
|       $stop; | ||||
| @ -86,7 +78,7 @@ module testbench_busybear(); | ||||
|   // read memreads trace file
 | ||||
|   integer data_file_memR, scan_file_memR; | ||||
|   initial begin | ||||
|     data_file_memR = $fopen("../busybear-testgen/parsedMemRead.txt", "r"); | ||||
|     data_file_memR = $fopen("/courses/e190ax/busybear_boot/parsedMemRead.txt", "r"); | ||||
|     if (data_file_memR == 0) begin | ||||
|       $display("file couldn't be opened"); | ||||
|       $stop; | ||||
| @ -96,13 +88,47 @@ module testbench_busybear(); | ||||
|   // read memwrite trace file
 | ||||
|   integer data_file_memW, scan_file_memW; | ||||
|   initial begin | ||||
|     data_file_memW = $fopen("../busybear-testgen/parsedMemWrite.txt", "r"); | ||||
|     data_file_memW = $fopen("/courses/e190ax/busybear_boot/parsedMemWrite.txt", "r"); | ||||
|     if (data_file_memW == 0) begin | ||||
|       $display("file couldn't be opened"); | ||||
|       $stop; | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   integer warningCount = 0; | ||||
| 
 | ||||
|   //logic[63:0] adrTranslation[4:0];
 | ||||
|   //string translationType[4:0] = {"rf", "writeAdr", "PCW", "PC", "readAdr"};
 | ||||
|   //initial begin
 | ||||
|   //  for(int i=0; i<5; i++) begin
 | ||||
|   //    adrTranslation[i] = 64'b0;
 | ||||
|   //  end
 | ||||
|   //end
 | ||||
| 
 | ||||
|   //function logic equal(logic[63:0] adr, logic[63:0] adrExpected, integer func);
 | ||||
|   //  if (adr[11:0] !== adrExpected[11:0]) begin
 | ||||
|   //    equal = 1'b0;
 | ||||
|   //  end else begin
 | ||||
|   //    equal = 1'b1;
 | ||||
|   //    if ((adr+adrTranslation[func]) !== adrExpected) begin
 | ||||
|   //      adrTranslation[func] = adrExpected - adr;
 | ||||
|   //      $display("warning: probably new address translation %x for %s at instr %0d", adrTranslation[func], translationType[func], instrs);
 | ||||
|   //      warningCount += 1;
 | ||||
|   //    end
 | ||||
|   //  end
 | ||||
|   //endfunction
 | ||||
| 
 | ||||
|   // pretty sure this isn't necessary anymore, but keeping this for now since its easier
 | ||||
|   function logic equal(logic[63:0] adr, logic[63:0] adrExpected, integer func); | ||||
|     equal = adr === adrExpected; | ||||
|   endfunction | ||||
| 
 | ||||
| 
 | ||||
|   `define ERROR \ | ||||
|     #10; \ | ||||
|     $display("processed %0d instructions with %0d warnings", instrs, warningCount); \ | ||||
|     $stop; | ||||
| 
 | ||||
|   logic [63:0] pcExpected; | ||||
|   logic [63:0] regExpected; | ||||
|   integer regNumExpected; | ||||
| @ -110,115 +136,195 @@ module testbench_busybear(); | ||||
|   genvar i; | ||||
|   generate | ||||
|     for(i=1; i<32; i++) begin | ||||
|       always @(dut.ieu.dp.regf.rf[i]) begin | ||||
|         if ($time != 0) begin | ||||
|       always @(dut.hart.ieu.dp.regf.rf[i]) begin | ||||
|         if ($time == 0) begin | ||||
|           scan_file_rf = $fscanf(data_file_rf, "%x\n", regExpected); | ||||
|           if (dut.hart.ieu.dp.regf.rf[i] != regExpected) begin | ||||
|             $display("%0t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.hart.ieu.dp.regf.rf[i], regExpected); | ||||
|             `ERROR | ||||
|           end | ||||
|         end else begin | ||||
|           scan_file_rf = $fscanf(data_file_rf, "%d\n", regNumExpected); | ||||
|           scan_file_rf = $fscanf(data_file_rf, "%x\n", regExpected); | ||||
|           if (i != regNumExpected) begin | ||||
|             $display("%t ps, instr %0d: wrong register changed: %0d, %0d expected", $time, instrs, i, regNumExpected); | ||||
|             $display("%0t ps, instr %0d: wrong register changed: %0d, %0d expected", $time, instrs, i, regNumExpected); | ||||
|             `ERROR | ||||
|           end | ||||
|           if (dut.ieu.dp.regf.rf[i] != regExpected) begin | ||||
|             $display("%t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.ieu.dp.regf.rf[i], regExpected); | ||||
|           if (~equal(dut.hart.ieu.dp.regf.rf[i],regExpected, 0)) begin | ||||
|             $display("%0t ps, instr %0d: rf[%0d] does not equal rf expected: %x, %x", $time, instrs, i, dut.hart.ieu.dp.regf.rf[i], regExpected); | ||||
|             `ERROR | ||||
|           end | ||||
|           if (dut.hart.ieu.dp.regf.rf[i] !== regExpected) begin | ||||
|             force dut.hart.ieu.dp.regf.rf[i] = regExpected; | ||||
|             release dut.hart.ieu.dp.regf.rf[i]; | ||||
|           end | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   endgenerate | ||||
| 
 | ||||
|   // RAM and bootram are addressed in 64-bit blocks - this logic handles R/W
 | ||||
|   // including subwords. Brief explanation on signals:
 | ||||
|   //
 | ||||
|   // readMask: bitmask of bits to read / write, left-shifted to align with
 | ||||
|   // nearest 64-bit boundary - examples
 | ||||
|   //    HSIZE = 0 -> readMask = 11111111
 | ||||
|   //    HSIZE = 1 -> readMask = 1111111111111111
 | ||||
|   //
 | ||||
|   // In the linux boot, the processor spends the first ~5 instructions in
 | ||||
|   // bootram, before jr jumps to main RAM
 | ||||
| 
 | ||||
|   logic [63:0] readMask; | ||||
|   assign readMask = ((1 << (8*(1 << HSIZE))) - 1) << 8 * HADDR[2:0]; | ||||
| 
 | ||||
|   logic [`XLEN-1:0] readAdrExpected; | ||||
|   // this might need to change
 | ||||
|   always @(dut.MemRWM[1] or HADDR) begin | ||||
|     if (dut.MemRWM[1]) begin | ||||
| 
 | ||||
|   always @(dut.hart.MemRWM[1] or HADDR) begin | ||||
|     if (dut.hart.MemRWM[1] && HADDR != dut.PCF) begin | ||||
|       if($feof(data_file_memR)) begin | ||||
|         $display("no more memR data to read"); | ||||
|         $stop; | ||||
|         `ERROR | ||||
|       end | ||||
|       scan_file_memR = $fscanf(data_file_memR, "%x\n", readAdrExpected); | ||||
|       scan_file_memR = $fscanf(data_file_memR, "%x\n", HRDATA); | ||||
|       #1; | ||||
|       if (HADDR != readAdrExpected) begin | ||||
|         $display("%t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrExpected); | ||||
|       #2; | ||||
|       if (~equal(HADDR,readAdrExpected,4)) begin | ||||
|         $display("%0t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrExpected); | ||||
|         `ERROR | ||||
|       end | ||||
| 
 | ||||
|       if (((readMask & HRDATA) !== (readMask & dut.HRDATA)) && (HADDR >= 'h80000000 && HADDR <= 'h87FFFFFF)) begin | ||||
|         $display("warning %0t ps, instr %0d: HRDATA does not equal dut.HRDATA: %x, %x from address %x, %x", $time, instrs, HRDATA, dut.HRDATA, HADDR, HSIZE); | ||||
|         warningCount += 1; | ||||
|         `ERROR | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   logic [`XLEN-1:0] writeDataExpected, writeAdrExpected; | ||||
| 
 | ||||
|   // this might need to change
 | ||||
|   always @(HWDATA or HADDR or HSIZE) begin | ||||
|     #1; | ||||
|     if (HWRITE) begin | ||||
|   //always @(HWDATA or HADDR or HSIZE or HWRITE) begin
 | ||||
|   always @(negedge HWRITE) begin | ||||
|     //#1;
 | ||||
|     if ($time != 0) begin | ||||
|       if($feof(data_file_memW)) begin | ||||
|         $display("no more memW data to read"); | ||||
|         $stop; | ||||
|         `ERROR | ||||
|       end | ||||
|       scan_file_memW = $fscanf(data_file_memW, "%x\n", writeDataExpected); | ||||
|       scan_file_memW = $fscanf(data_file_memW, "%x\n", writeAdrExpected); | ||||
|       if (writeDataExpected != HWDATA) begin | ||||
|         $display("%t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected); | ||||
|         $display("%0t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected); | ||||
|         `ERROR | ||||
|       end | ||||
|       if (writeAdrExpected != HADDR) begin | ||||
|         $display("%t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrExpected); | ||||
|       if (~equal(writeAdrExpected,HADDR,1)) begin | ||||
|         $display("%0t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrExpected); | ||||
|         `ERROR | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   `define CHECK_CSR(CSR) \ | ||||
|   integer totalCSR = 0; | ||||
|   logic [99:0] StartCSRexpected[63:0]; | ||||
|   string StartCSRname[99:0]; | ||||
|   initial begin | ||||
|     while(1) begin | ||||
|       scan_file_csr = $fscanf(data_file_csr, "%s\n", StartCSRname[totalCSR]); | ||||
|       if(StartCSRname[totalCSR] == "---") begin | ||||
|         break; | ||||
|       end | ||||
|       scan_file_csr = $fscanf(data_file_csr, "%x\n", StartCSRexpected[totalCSR]); | ||||
|       totalCSR = totalCSR + 1; | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   `define CHECK_CSR2(CSR, PATH) \ | ||||
|     string CSR; \ | ||||
|     logic [63:0] expected``CSR``; \ | ||||
|     //CSR checking \ | ||||
|     always @(dut.priv.csr.``CSR``_REGW) begin \ | ||||
|     always @(``PATH``.``CSR``_REGW) begin \ | ||||
|         if ($time > 1) begin \ | ||||
|           scan_file_csr = $fscanf(data_file_csr, "%s\n", CSR); \ | ||||
|           scan_file_csr = $fscanf(data_file_csr, "%x\n", expected``CSR``); \ | ||||
|           if(CSR.icompare(`"CSR`")) begin \ | ||||
|             $display("%t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \ | ||||
|             $display("%0t ps, instr %0d: %s changed, expected %s", $time, instrs, `"CSR`", CSR); \ | ||||
|           end \ | ||||
|           if(``PATH``.``CSR``_REGW != ``expected``CSR) begin \ | ||||
|             $display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", CSR, ``PATH``.``CSR``_REGW, ``expected``CSR); \ | ||||
|             `ERROR \ | ||||
|           end \ | ||||
|         end else begin \ | ||||
|           for(integer j=0; j<totalCSR; j++) begin \ | ||||
|             if(!StartCSRname[j].icompare(`"CSR`")) begin \ | ||||
|               if(``PATH``.``CSR``_REGW != StartCSRexpected[j]) begin \ | ||||
|                 $display("%0t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, `"CSR`", StartCSRname[j], ``PATH``.``CSR``_REGW, StartCSRexpected[j]); \ | ||||
|                 `ERROR \ | ||||
|               end \ | ||||
|             end \ | ||||
|           if(dut.priv.csr.``CSR``_REGW != ``expected``CSR) begin \ | ||||
|             $display("%t ps, instr %0d: %s does not equal %s expected: %x, %x", $time, instrs, CSR, CSR, dut.priv.csr.``CSR``_REGW, ``expected``CSR); \ | ||||
|           end \ | ||||
|         end \ | ||||
|     end | ||||
|   `define CHECK_CSR(CSR) \ | ||||
|      `CHECK_CSR2(CSR, dut.hart.priv.csr) | ||||
|   `define CSRM dut.hart.priv.csr.genblk1.csrm | ||||
|   `define CSRS dut.hart.priv.csr.genblk1.csrs.genblk1 | ||||
| 
 | ||||
|   //`CHECK_CSR(FCSR)
 | ||||
|   `CHECK_CSR2(MCAUSE, `CSRM) | ||||
|   `CHECK_CSR(MCOUNTEREN) | ||||
|   `CHECK_CSR(MEDELEG) | ||||
|   `CHECK_CSR(MEPC) | ||||
|   //`CHECK_CSR(MHARTID)
 | ||||
|   `CHECK_CSR(MIDELEG) | ||||
|   `CHECK_CSR(MIE) | ||||
|   //`CHECK_CSR(MSCRATCH)
 | ||||
|   //`CHECK_CSR(MIP)
 | ||||
|   `CHECK_CSR2(MISA, `CSRM) | ||||
|   `CHECK_CSR2(MSCRATCH, `CSRM) | ||||
|   `CHECK_CSR(MSTATUS) | ||||
|   `CHECK_CSR2(MTVAL, `CSRM) | ||||
|   `CHECK_CSR(MTVEC) | ||||
|   //`CHECK_CSR(SATP)
 | ||||
|   //`CHECK_CSR2(PMPADDR0, `CSRM)
 | ||||
|   //`CHECK_CSR2(PMdut.PCFG0, `CSRM)
 | ||||
|   `CHECK_CSR2(SATP, `CSRS) | ||||
|   `CHECK_CSR2(SCAUSE, `CSRS) | ||||
|   `CHECK_CSR(SCOUNTEREN) | ||||
|   `CHECK_CSR(SEPC) | ||||
|   `CHECK_CSR(SIE) | ||||
|   `CHECK_CSR2(SSCRATCH, `CSRS) | ||||
|   `CHECK_CSR(SSTATUS) | ||||
|   `CHECK_CSR2(STVAL, `CSRS) | ||||
|   `CHECK_CSR(STVEC) | ||||
| 
 | ||||
|   logic speculative; | ||||
|   initial begin | ||||
|     speculative = 0; | ||||
|     speculative = 0; | ||||
|   end | ||||
|   logic [63:0] lastInstrF, lastPC, lastPC2; | ||||
|   logic [63:0] lastCheckInstrF, lastPC, lastPC2; | ||||
| 
 | ||||
|   string PCtextW, PCtext2W; | ||||
|   logic [31:0] InstrWExpected; | ||||
|   logic [63:0] PCWExpected; | ||||
|   always @(dut.ifu.PCW or dut.ieu.InstrValidW) begin | ||||
|    if(dut.ieu.InstrValidW && dut.ifu.PCW != 0) begin | ||||
|   always @(dut.hart.ifu.PCW or dut.hart.ieu.InstrValidW) begin | ||||
|    if(dut.hart.ieu.InstrValidW && dut.hart.ifu.PCW != 0) begin | ||||
|       if($feof(data_file_PCW)) begin | ||||
|         $display("no more PC data to read"); | ||||
|         $stop; | ||||
|         `ERROR | ||||
|       end | ||||
|       scan_file_PCW = $fscanf(data_file_PCW, "%s\n", PCtextW); | ||||
|       if (PCtextW != "ret") begin | ||||
|       if (PCtextW != "ret" && PCtextW != "fence" && PCtextW != "nop" && PCtextW != "mret" && PCtextW != "sfence.vma" && PCtextW != "unimp") begin | ||||
|         scan_file_PC = $fscanf(data_file_PCW, "%s\n", PCtext2W); | ||||
|         PCtextW = {PCtextW, " ", PCtext2W}; | ||||
|       end | ||||
|       scan_file_PCW = $fscanf(data_file_PCW, "%x\n", InstrWExpected); | ||||
|       // then expected PC value
 | ||||
|       scan_file_PCW = $fscanf(data_file_PCW, "%x\n", PCWExpected); | ||||
|       if(dut.ifu.PCW != PCWExpected) begin | ||||
|         $display("%t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, dut.ifu.PCW, PCWExpected); | ||||
|       if(~equal(dut.hart.ifu.PCW,PCWExpected,2)) begin | ||||
|         $display("%0t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, dut.hart.ifu.PCW, PCWExpected); | ||||
|         `ERROR | ||||
|       end | ||||
|       //if(it.InstrW != InstrWExpected) begin
 | ||||
|       //  $display("%t ps, instr %0d: InstrW does not equal InstrW expected: %x, %x", $time, instrs, it.InstrW, InstrWExpected);
 | ||||
|       //  $display("%0t ps, instr %0d: InstrW does not equal InstrW expected: %x, %x", $time, instrs, it.InstrW, InstrWExpected);
 | ||||
|       //end
 | ||||
|     end | ||||
|   end | ||||
| @ -228,60 +334,90 @@ module testbench_busybear(); | ||||
|   initial begin | ||||
|     instrs = 0; | ||||
|   end | ||||
|   always @(PCF) begin | ||||
|     lastInstrF = InstrF; | ||||
|     lastPC <= PCF; | ||||
|   logic [31:0] InstrMask; | ||||
|   logic forcedInstr; | ||||
|   logic [63:0] lastPCF; | ||||
|   always @(dut.PCF or dut.hart.ifu.InstrF or reset) begin | ||||
|     if(~HWRITE) begin | ||||
|     #3; | ||||
|     if (~reset && dut.hart.ifu.InstrF[15:0] !== {16{1'bx}}) begin | ||||
|       if (dut.PCF !== lastPCF) begin | ||||
|         lastCheckInstrF = CheckInstrF; | ||||
|         lastPC <= dut.PCF; | ||||
|         lastPC2 <= lastPC; | ||||
|     if (speculative && lastPC != pcExpected) begin | ||||
|       speculative = (PCF != pcExpected); | ||||
|         if (speculative && (lastPC != pcExpected)) begin | ||||
|           speculative = ~equal(dut.PCF,pcExpected,3); | ||||
|         end | ||||
|         else begin | ||||
|     //if (~speculative) begin
 | ||||
|           if($feof(data_file_PC)) begin | ||||
|             $display("no more PC data to read"); | ||||
|         $stop; | ||||
|             `ERROR | ||||
|           end | ||||
|       // first read instruction
 | ||||
|           scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext); | ||||
|       if (PCtext != "ret") begin | ||||
|           if (PCtext != "ret" && PCtext != "fence" && PCtext != "nop" && PCtext != "mret" && PCtext != "sfence.vma" && PCtext != "unimp") begin | ||||
|             scan_file_PC = $fscanf(data_file_PC, "%s\n", PCtext2); | ||||
|             PCtext = {PCtext, " ", PCtext2}; | ||||
|           end | ||||
|       scan_file_PC = $fscanf(data_file_PC, "%x\n", InstrF); | ||||
|       if(InstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
 | ||||
|         InstrF = 32'b0010011; | ||||
|         $display("warning: NOPing out %s at PC=%0x", PCtext, PCF); | ||||
|           scan_file_PC = $fscanf(data_file_PC, "%x\n", CheckInstrF); | ||||
|           if(CheckInstrF[6:0] == 7'b1010011) begin // for now, NOP out any float instrs
 | ||||
|             CheckInstrF = 32'b0010011; | ||||
|             $display("warning: NOPing out %s at PC=%0x", PCtext, dut.PCF); | ||||
|             warningCount += 1; | ||||
|             forcedInstr = 1; | ||||
|           end | ||||
|           else begin | ||||
|             if(CheckInstrF[28:27] != 2'b11 && CheckInstrF[6:0] == 7'b0101111) begin //for now, replace non-SC A instrs with LD
 | ||||
|               CheckInstrF = {12'b0, CheckInstrF[19:7], 7'b0000011}; | ||||
|               $display("warning: replacing AMO instr %s at PC=%0x with ld", PCtext, dut.PCF); | ||||
|               warningCount += 1; | ||||
|               forcedInstr = 1; | ||||
|             end | ||||
|             else begin | ||||
|               forcedInstr = 0; | ||||
|             end | ||||
|           end | ||||
|           // then expected PC value
 | ||||
|           scan_file_PC = $fscanf(data_file_PC, "%x\n", pcExpected); | ||||
|           if (instrs <= 10 || (instrs <= 100 && instrs % 10 == 0) || | ||||
|              (instrs <= 1000 && instrs % 100 == 0) || (instrs <= 10000 && instrs % 1000 == 0) || | ||||
|          (instrs <= 100000 && instrs % 10000 == 0)) begin | ||||
|              (instrs <= 100000 && instrs % 10000 == 0) || (instrs <= 1000000 && instrs % 100000 == 0)) begin | ||||
|             $display("loaded %0d instructions", instrs); | ||||
|           end | ||||
|           instrs += 1; | ||||
|           // are we at a branch/jump?
 | ||||
|       casex (lastInstrF[15:0])  | ||||
|         16'bXXXXXXXXX1101111, // JAL
 | ||||
|         16'bXXXXXXXXX1100111, // JALR
 | ||||
|         16'bXXXXXXXXX1100011, // B
 | ||||
|         16'b110XXXXXXXXXXX01, // C.BEQZ
 | ||||
|         16'b111XXXXXXXXXXX01, // C.BNEZ
 | ||||
|         16'b101XXXXXXXXXXX01: // C.J
 | ||||
|           casex (lastCheckInstrF[31:0]) | ||||
|             32'b00000000001000000000000001110011, // URET
 | ||||
|             32'b00010000001000000000000001110011, // SRET
 | ||||
|             32'b00110000001000000000000001110011, // MRET
 | ||||
|             32'bXXXXXXXXXXXXXXXXXXXXXXXXX1101111, // JAL
 | ||||
|             32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100111, // JALR
 | ||||
|             32'bXXXXXXXXXXXXXXXXXXXXXXXXX1100011, // B
 | ||||
|             32'bXXXXXXXXXXXXXXXX110XXXXXXXXXXX01, // C.BEQZ
 | ||||
|             32'bXXXXXXXXXXXXXXXX111XXXXXXXXXXX01, // C.BNEZ
 | ||||
|             32'bXXXXXXXXXXXXXXXX101XXXXXXXXXXX01: // C.J
 | ||||
|               speculative = 1; | ||||
|         16'b1001000000000010: // C.EBREAK:
 | ||||
|             32'bXXXXXXXXXXXXXXXX1001000000000010: // C.EBREAK:
 | ||||
|               speculative = 0; // tbh don't really know what should happen here
 | ||||
|         16'b1000XXXXX0000010, // C.JR
 | ||||
|         16'b1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
 | ||||
|             32'bXXXXXXXXXXXXXXXX1000XXXXX0000010, // C.JR
 | ||||
|             32'bXXXXXXXXXXXXXXXX1001XXXXX0000010: // C.JALR //this is RV64 only so no C.JAL
 | ||||
|               speculative = 1; | ||||
|             default: | ||||
|               speculative = 0; | ||||
|           endcase | ||||
| 
 | ||||
|           //check things!
 | ||||
|       if ((~speculative) && (PCF !== pcExpected)) begin | ||||
|         $display("%t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, PCF, pcExpected); | ||||
|       //  $stop;
 | ||||
|           if ((~speculative) && (~equal(dut.PCF,pcExpected,3))) begin | ||||
|             $display("%0t ps, instr %0d: PC does not equal PC expected: %x, %x", $time, instrs, dut.PCF, pcExpected); | ||||
|             `ERROR | ||||
|           end | ||||
|           InstrMask = CheckInstrF[1:0] == 2'b11 ? 32'hFFFFFFFF : 32'h0000FFFF; | ||||
|           if ((~forcedInstr) && (~speculative) && ((InstrMask & dut.hart.ifu.InstrF) !== (InstrMask & CheckInstrF))) begin | ||||
|             $display("%0t ps, instr %0d: InstrF does not equal CheckInstrF: %x, %x, PC: %x", $time, instrs, dut.hart.ifu.InstrF, CheckInstrF, dut.PCF); | ||||
|             `ERROR | ||||
|           end | ||||
|         end | ||||
|       end | ||||
|       lastPCF = dut.PCF; | ||||
|     end | ||||
|     end | ||||
|   end | ||||
| @ -289,10 +425,10 @@ module testbench_busybear(); | ||||
|   // Track names of instructions
 | ||||
|   string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; | ||||
|   logic [31:0] InstrW; | ||||
|   instrNameDecTB dec(InstrF, InstrFName); | ||||
|   instrTrackerTB it(clk, reset, dut.ieu.dp.FlushE, | ||||
|                 dut.ifu.InstrD, dut.ifu.InstrE, | ||||
|                 dut.ifu.InstrM,  InstrW, | ||||
|   instrNameDecTB dec(dut.hart.ifu.InstrF, InstrFName); | ||||
|   instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, | ||||
|                 dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, | ||||
|                 dut.hart.ifu.InstrM,  InstrW, | ||||
|                 InstrDName, InstrEName, InstrMName, InstrWName); | ||||
| 
 | ||||
|   // generate clock to sequence tests
 | ||||
| @ -301,17 +437,4 @@ module testbench_busybear(); | ||||
|       clk <= 1; # 5; clk <= 0; # 5; | ||||
|     end | ||||
| 
 | ||||
|   //// check results
 | ||||
|   //always @(negedge clk)
 | ||||
|   //  begin
 | ||||
|   //    if(MemWrite) begin
 | ||||
|   //      if(DataAdr === 84 & WriteData === 71) begin
 | ||||
|   //        $display("Simulation succeeded");
 | ||||
|   //        $stop;
 | ||||
|   //      end else if (DataAdr !== 80) begin
 | ||||
|   //        $display("Simulation failed");
 | ||||
|   //        $stop;
 | ||||
|   //      end
 | ||||
|   //    end
 | ||||
|   //  end
 | ||||
| endmodule | ||||
|  | ||||
| @ -407,9 +407,9 @@ string tests32i[] = { | ||||
|         i = 0; | ||||
|         errors = 0; | ||||
|         if (`XLEN == 32) | ||||
|           testadr = tests[test+1].atohex()/4; | ||||
|           testadr = (`TIMBASE+tests[test+1].atohex())/4; | ||||
|         else | ||||
|           testadr = tests[test+1].atohex()/8; | ||||
|           testadr = (`TIMBASE+tests[test+1].atohex())/8; | ||||
|         /* verilator lint_off INFINITELOOP */ | ||||
|         while (signature[i] !== 'bx) begin | ||||
|           //$display("signature[%h] = %h", i, signature[i]);
 | ||||
|  | ||||
| @ -136,9 +136,9 @@ module testbench(); | ||||
|         i = 0; | ||||
|         errors = 0; | ||||
|         if (`XLEN == 32) | ||||
|           testadr = tests[test+1].atohex()/4; | ||||
|           testadr = (`TIMBASE+tests[test+1].atohex())/4; | ||||
|         else | ||||
|           testadr = tests[test+1].atohex()/8; | ||||
|           testadr = (`TIMBASE+tests[test+1].atohex())/8; | ||||
|         /* verilator lint_off INFINITELOOP */ | ||||
|         while (signature[i] !== 'bx) begin | ||||
|           //$display("signature[%h] = %h", i, signature[i]);
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user