mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Created new linux test bench and parsing scripts.
This commit is contained in:
		
							parent
							
								
									c60a1fed69
								
							
						
					
					
						commit
						b9f8c25280
					
				
							
								
								
									
										205
									
								
								wally-pipelined/linux-testgen/testvector-generation/parseNew.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										205
									
								
								wally-pipelined/linux-testgen/testvector-generation/parseNew.py
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,205 @@
 | 
				
			|||||||
 | 
					#! /usr/bin/python3
 | 
				
			||||||
 | 
					import sys, fileinput, re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ross Thompson
 | 
				
			||||||
 | 
					# July 27, 2021
 | 
				
			||||||
 | 
					# Rewrite of the linux trace parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					InstrStartDelim = '=>'
 | 
				
			||||||
 | 
					InstrEndDelim = '-----'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					InputFile = 'noparse.txt'
 | 
				
			||||||
 | 
					#InputFile = 'temp.txt'
 | 
				
			||||||
 | 
					OutputFile = 'parsedAll.txt'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HUMAN_READABLE = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def toDict(lst):
 | 
				
			||||||
 | 
					    'Converts the list of register values to a dictionary'
 | 
				
			||||||
 | 
					    dct= {}
 | 
				
			||||||
 | 
					    for item in lst:
 | 
				
			||||||
 | 
					        regTup = item.split()
 | 
				
			||||||
 | 
					        dct[regTup[0]] = int(regTup[2], 10)
 | 
				
			||||||
 | 
					    del dct['pc']
 | 
				
			||||||
 | 
					    return dct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def whichClass(text, Regs):
 | 
				
			||||||
 | 
					    'Which instruction class?'
 | 
				
			||||||
 | 
					    #print(text, Regs)
 | 
				
			||||||
 | 
					    if text[0:2] == 'ld' or text[0:2] == 'lw' or text[0:2] == 'lh' or text[0:2] == 'lb':
 | 
				
			||||||
 | 
					        return ('load', WhatAddr(text, Regs), None, WhatMemDestSource(text))
 | 
				
			||||||
 | 
					    elif text[0:2] == 'sd' or text[0:2] == 'sw' or text[0:2] == 'sh' or text[0:2] == 'sb':
 | 
				
			||||||
 | 
					        return ('store', WhatAddr(text, Regs), WhatMemDestSource(text), None)
 | 
				
			||||||
 | 
					    elif text[0:3] == 'amo':
 | 
				
			||||||
 | 
					        return ('amo', WhatAddrAMO(text, Regs), WhatMemDestSource(text), WhatMemDestSource(text))
 | 
				
			||||||
 | 
					    elif text[0:2] == 'lr':
 | 
				
			||||||
 | 
					        return ('lr', WhatAddrLR(text, Regs), None, WhatMemDestSource(text))
 | 
				
			||||||
 | 
					    elif text[0:2] == 'sc':
 | 
				
			||||||
 | 
					        return ('sc', WhatAddrSC(text, Regs), WhatMemDestSource(text), None)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return ('other', None, None, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def whatChanged(dct0, dct1):
 | 
				
			||||||
 | 
					    'Compares two dictionaries of instrution registers and indicates which registers changed'
 | 
				
			||||||
 | 
					    dct = {}
 | 
				
			||||||
 | 
					    for key in dct0:
 | 
				
			||||||
 | 
					        if (dct1[key] != dct0[key]):
 | 
				
			||||||
 | 
					            dct[key] = dct1[key]
 | 
				
			||||||
 | 
					    return dct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def WhatMemDestSource(text):
 | 
				
			||||||
 | 
					    ''''What is the destination register. Used to compute where the read data is 
 | 
				
			||||||
 | 
					    on a load or the write data on a store.'''
 | 
				
			||||||
 | 
					    return text.split()[1].split(',')[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def WhatAddr(text, Regs):
 | 
				
			||||||
 | 
					    'What is the data memory address?'
 | 
				
			||||||
 | 
					    Imm = text.split(',')[1]
 | 
				
			||||||
 | 
					    (Imm, Src) = Imm.split('(')
 | 
				
			||||||
 | 
					    Imm = int(Imm.strip(), 10)
 | 
				
			||||||
 | 
					    Src = Src.strip(')').strip()
 | 
				
			||||||
 | 
					    RegVal = Regs[Src]
 | 
				
			||||||
 | 
					    return Imm + RegVal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def WhatAddrAMO(text, Regs):
 | 
				
			||||||
 | 
					    'What is the data memory address?'
 | 
				
			||||||
 | 
					    Src = text.split('(')[1]
 | 
				
			||||||
 | 
					    Src = Src.strip(')').strip()
 | 
				
			||||||
 | 
					    return Regs[Src]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def WhatAddrLR(text, Regs):
 | 
				
			||||||
 | 
					    'What is the data memory address?'
 | 
				
			||||||
 | 
					    Src = text.split('(')[1]
 | 
				
			||||||
 | 
					    Src = Src.strip(')').strip()
 | 
				
			||||||
 | 
					    return Regs[Src]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def WhatAddrSC(text, Regs):
 | 
				
			||||||
 | 
					    'What is the data memory address?'
 | 
				
			||||||
 | 
					    Src = text.split('(')[1]
 | 
				
			||||||
 | 
					    Src = Src.strip(')').strip()
 | 
				
			||||||
 | 
					    return Regs[Src]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def PrintInstr(instr, fp):
 | 
				
			||||||
 | 
					    if instr[2] == None:
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    ChangedRegisters = instr[4]
 | 
				
			||||||
 | 
					    GPR = ''
 | 
				
			||||||
 | 
					    CSR = []
 | 
				
			||||||
 | 
					    for key in ChangedRegisters:
 | 
				
			||||||
 | 
					        if(RegNumber[key] < 32):
 | 
				
			||||||
 | 
					            # GPR
 | 
				
			||||||
 | 
					            if(HUMAN_READABLE):
 | 
				
			||||||
 | 
					                GPR = '{:-2d} {:016x}'.format(RegNumber[key], ChangedRegisters[key])
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                GPR = '{:d} {:x}'.format(RegNumber[key], ChangedRegisters[key])
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if(HUMAN_READABLE):
 | 
				
			||||||
 | 
					                CSR.extend([key, '{:016x}'.format(ChangedRegisters[key])])
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                CSR.extend([key, '{:x}'.format(ChangedRegisters[key])])                
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CSRStr = ' '.join(CSR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #print(instr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (HUMAN_READABLE == True):
 | 
				
			||||||
 | 
					        fp.write('{:016x} {:08x} {:25s}'.format(instr[0], instr[1], instr[2]))
 | 
				
			||||||
 | 
					        if(len(GPR) != 0):
 | 
				
			||||||
 | 
					            fp.write(' GPR {}'.format(GPR))
 | 
				
			||||||
 | 
					        if(instr[3] == 'load' or instr[3] == 'lr'):
 | 
				
			||||||
 | 
					            fp.write(' MemR {:016x} {:016x} {:016x}'.format(instr[5], 0, instr[7]))
 | 
				
			||||||
 | 
					        if(instr[3] == 'store'):
 | 
				
			||||||
 | 
					            fp.write('\t\t\t    MemW {:016x} {:016x} {:016x}'.format(instr[5], instr[6], 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(len(CSR) != 0):
 | 
				
			||||||
 | 
					            fp.write(' CSR {}'.format(CSRStr))
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        fp.write('{:x} {:x} {:s}'.format(instr[0], instr[1], instr[2].replace(' ', '_')))
 | 
				
			||||||
 | 
					        if(len(GPR) != 0):
 | 
				
			||||||
 | 
					            fp.write(' GPR {}'.format(GPR))
 | 
				
			||||||
 | 
					        if(instr[3] == 'load' or instr[3] == 'lr'):
 | 
				
			||||||
 | 
					            fp.write(' MemR {:x} {:x} {:x}'.format(instr[5], 0, instr[7]))
 | 
				
			||||||
 | 
					        if(instr[3] == 'store'):
 | 
				
			||||||
 | 
					            fp.write(' MemW {:x} {:x} {:x}'.format(instr[5], instr[6], 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(len(CSR) != 0):
 | 
				
			||||||
 | 
					            fp.write(' CSR {}'.format(CSRStr))
 | 
				
			||||||
 | 
					    fp.write('\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# reg number
 | 
				
			||||||
 | 
					RegNumber = {'zero': 0, 'ra': 1, 'sp': 2, 'gp': 3, 'tp': 4, 't0': 5, 't1': 6, 't2': 7, 's0': 8, 's1': 9, 'a0': 10, 'a1': 11, 'a2': 12, 'a3': 13, 'a4': 14, 'a5': 15, 'a6': 16, 'a7': 17, 's2': 18, 's3': 19, 's4': 20, 's5': 21, 's6': 22, 's7': 23, 's8': 24, 's9': 25, 's10': 26, 's11': 27, 't3': 28, 't4': 29, 't5': 30, 't6': 31, 'mhartid': 32, 'mstatus': 33, 'mip': 34, 'mie': 35, 'mideleg': 36, 'medeleg': 37, 'mtvec': 38, 'stvec': 39, 'mepc': 40, 'sepc': 41, 'mcause': 42, 'scause': 43, 'mtval': 44, 'stval': 45}
 | 
				
			||||||
 | 
					# initial state
 | 
				
			||||||
 | 
					CurrentInstr = ['0', '0', None, 'other', {'zero': 0, 'ra': 0, 'sp': 0, 'gp': 0, 'tp': 0, 't0': 0, 't1': 0, 't2': 0, 's0': 0, 's1': 0, 'a0': 0, 'a1': 0, 'a2': 0, 'a3': 0, 'a4': 0, 'a5': 0, 'a6': 0, 'a7': 0, 's2': 0, 's3': 0, 's4': 0, 's5': 0, 's6': 0, 's7': 0, 's8': 0, 's9': 0, 's10': 0, 's11': 0, 't3': 0, 't4': 0, 't5': 0, 't6': 0, 'mhartid': 0, 'mstatus': 0, 'mip': 0, 'mie': 0, 'mideleg': 0, 'medeleg': 0, 'mtvec': 0, 'stvec': 0, 'mepc': 0, 'sepc': 0, 'mcause': 0, 'scause': 0, 'mtval': 0, 'stval': 0}, {}, None, None, None]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					with open (InputFile, 'r') as InputFileFP:
 | 
				
			||||||
 | 
					    #lines = InputFileFP.readlines()
 | 
				
			||||||
 | 
					    lineNum = 0
 | 
				
			||||||
 | 
					    StartLine = 0
 | 
				
			||||||
 | 
					    EndLine = 0
 | 
				
			||||||
 | 
					    #instructions = []
 | 
				
			||||||
 | 
					    MemAdr = 0
 | 
				
			||||||
 | 
					    lines = []
 | 
				
			||||||
 | 
					    for line in InputFileFP:
 | 
				
			||||||
 | 
					        lines.insert(lineNum, line)
 | 
				
			||||||
 | 
					        if InstrStartDelim in line:
 | 
				
			||||||
 | 
					            lineNum = 0
 | 
				
			||||||
 | 
					            StartLine = lineNum
 | 
				
			||||||
 | 
					        elif InstrEndDelim in line:
 | 
				
			||||||
 | 
					            EndLine = lineNum
 | 
				
			||||||
 | 
					            (InstrBits, text) = lines[StartLine].split(':')
 | 
				
			||||||
 | 
					            InstrBits = int(InstrBits.strip('=> '), 16)
 | 
				
			||||||
 | 
					            text = text.strip()
 | 
				
			||||||
 | 
					            PC = int(lines[StartLine+1].split(':')[0][2:], 16)
 | 
				
			||||||
 | 
					            Regs = toDict(lines[StartLine+2:EndLine])
 | 
				
			||||||
 | 
					            (Class, Addr, WriteReg, ReadReg) = whichClass(text, Regs)
 | 
				
			||||||
 | 
					            #print("CWR", Class, WriteReg, ReadReg)
 | 
				
			||||||
 | 
					            PreviousInstr = CurrentInstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Changed = whatChanged(PreviousInstr[4], Regs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (ReadReg !=None): ReadData = ReadReg
 | 
				
			||||||
 | 
					            else: ReadData = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (WriteReg !=None): WriteData = WriteReg
 | 
				
			||||||
 | 
					            else: WriteData = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CurrentInstr = [PC, InstrBits, text, Class, Regs, Changed, Addr, WriteData, ReadData]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            #print(CurrentInstr[0:4], PreviousInstr[5], CurrentInstr[6:7], PreviousInstr[8])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # pc, instrbits, text and class come from the last line.
 | 
				
			||||||
 | 
					            MoveInstrToRegWriteLst = PreviousInstr[0:4]
 | 
				
			||||||
 | 
					            # updated registers come from the current line.
 | 
				
			||||||
 | 
					            MoveInstrToRegWriteLst.append(CurrentInstr[5])   # destination regs
 | 
				
			||||||
 | 
					            # memory address if present comes from the last line.
 | 
				
			||||||
 | 
					            MoveInstrToRegWriteLst.append(PreviousInstr[6])  # MemAdrM
 | 
				
			||||||
 | 
					            # write data from the previous line
 | 
				
			||||||
 | 
					            #MoveInstrToRegWriteLst.append(PreviousInstr[7])   # WriteDataM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (PreviousInstr[7] != None):
 | 
				
			||||||
 | 
					                MoveInstrToRegWriteLst.append(Regs[PreviousInstr[7]])   # WriteDataM
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                MoveInstrToRegWriteLst.append(None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # read data from the current line
 | 
				
			||||||
 | 
					            #MoveInstrToRegWriteLst.append(PreviousInstr[8])   # ReadDataM
 | 
				
			||||||
 | 
					            if (PreviousInstr[8] != None):
 | 
				
			||||||
 | 
					                MoveInstrToRegWriteLst.append(Regs[PreviousInstr[8]])   # ReadDataM
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                MoveInstrToRegWriteLst.append(None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            lines.clear()
 | 
				
			||||||
 | 
					            #instructions.append(MoveInstrToRegWriteLst)
 | 
				
			||||||
 | 
					            PrintInstr(MoveInstrToRegWriteLst, sys.stdout)
 | 
				
			||||||
 | 
					        lineNum += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#for instruction in instructions[1::]:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#with open(OutputFile, 'w') as OutputFileFP:
 | 
				
			||||||
 | 
					#    print('opened file')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -25,6 +25,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
`include "wally-config.vh"
 | 
					`include "wally-config.vh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`define DEBUG_TRACE 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module testbench();
 | 
					module testbench();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  parameter waveOnICount = `BUSYBEAR*140000 + `BUILDROOT*3080000; // # of instructions at which to turn on waves in graphical sim
 | 
					  parameter waveOnICount = `BUSYBEAR*140000 + `BUILDROOT*3080000; // # of instructions at which to turn on waves in graphical sim
 | 
				
			||||||
@ -81,8 +83,10 @@ module testbench();
 | 
				
			|||||||
  integer data_file_PCD, scan_file_PCD;
 | 
					  integer data_file_PCD, scan_file_PCD;
 | 
				
			||||||
  integer data_file_PCM, scan_file_PCM;
 | 
					  integer data_file_PCM, scan_file_PCM;
 | 
				
			||||||
  integer data_file_PCW, scan_file_PCW;
 | 
					  integer data_file_PCW, scan_file_PCW;
 | 
				
			||||||
 | 
					  integer data_file_all;
 | 
				
			||||||
  string PCtextF, PCtextF2;
 | 
					  string PCtextF, PCtextF2;
 | 
				
			||||||
  string PCtextD, PCtextD2;
 | 
					  string PCtextD, PCtextD2;
 | 
				
			||||||
 | 
					  string PCtextW2;
 | 
				
			||||||
  string PCtextE;
 | 
					  string PCtextE;
 | 
				
			||||||
  string PCtextM;
 | 
					  string PCtextM;
 | 
				
			||||||
  string PCtextW;
 | 
					  string PCtextW;
 | 
				
			||||||
@ -105,6 +109,33 @@ module testbench();
 | 
				
			|||||||
  integer data_file_csr, scan_file_csr;
 | 
					  integer data_file_csr, scan_file_csr;
 | 
				
			||||||
  logic IllegalInstrFaultd;
 | 
					  logic IllegalInstrFaultd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  logic checkInstrW;
 | 
				
			||||||
 | 
					  logic [`XLEN-1:0] ExpectedPCW;
 | 
				
			||||||
 | 
					  logic [31:0] 	    ExpectedInstrW;
 | 
				
			||||||
 | 
					  string 	    textW;
 | 
				
			||||||
 | 
					  integer 	    matchCount;
 | 
				
			||||||
 | 
					  string 	    line;
 | 
				
			||||||
 | 
					  string 	    token;
 | 
				
			||||||
 | 
					  string 	    ExpectedTokens [31:0];
 | 
				
			||||||
 | 
					  integer 	    index;
 | 
				
			||||||
 | 
					  integer 	    StartIndex, EndIndex;
 | 
				
			||||||
 | 
					  string 	    command;
 | 
				
			||||||
 | 
					  integer 	    TokenIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  integer 	    MarkerIndex;
 | 
				
			||||||
 | 
					  integer 	    RegAdr;
 | 
				
			||||||
 | 
					  logic [`XLEN-1:0] RegValue;
 | 
				
			||||||
 | 
					  logic [`XLEN-1:0] ExpectedMemAdr, ExpectedMemReadData, ExpectedMemWriteData;
 | 
				
			||||||
 | 
					  logic [`XLEN-1:0] MemAdrW, WriteDataW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  logic [`XLEN-1:0] CSRMap [string];
 | 
				
			||||||
 | 
					  logic [`XLEN-1:0] ExpectedCSRValue;
 | 
				
			||||||
 | 
					  string 	    ExpectedCSR;
 | 
				
			||||||
 | 
					  integer 	    tempIndex;
 | 
				
			||||||
 | 
					  integer 	    processingCSR;
 | 
				
			||||||
 | 
					  integer 	    fault;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  // -----------
 | 
					  // -----------
 | 
				
			||||||
  // Error Macro
 | 
					  // Error Macro
 | 
				
			||||||
  // -----------
 | 
					  // -----------
 | 
				
			||||||
@ -113,6 +144,244 @@ module testbench();
 | 
				
			|||||||
    $display("processed %0d instructions with %0d warnings", instrs, warningCount); \
 | 
					    $display("processed %0d instructions with %0d warnings", instrs, warningCount); \
 | 
				
			||||||
    $stop;
 | 
					    $stop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  initial begin
 | 
				
			||||||
 | 
					    data_file_all = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r");
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assign checkInstrW = dut.hart.ieu.InstrValidW & ~dut.hart.StallW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  flopenrc #(`XLEN) MemAdrWReg(clk, reset, dut.hart.FlushW, ~dut.hart.StallW, dut.hart.ieu.dp.MemAdrM, MemAdrW);
 | 
				
			||||||
 | 
					  flopenrc #(`XLEN) WriteDataWReg(clk, reset, dut.hart.FlushW, ~dut.hart.StallW, dut.hart.WriteDataM, WriteDataW);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  always @(negedge clk) begin
 | 
				
			||||||
 | 
					    // always check PC, instruction bits
 | 
				
			||||||
 | 
					    if (checkInstrW) begin
 | 
				
			||||||
 | 
					      // read 1 line of the trace file
 | 
				
			||||||
 | 
					      matchCount =  $fgets(line, data_file_all);
 | 
				
			||||||
 | 
					      if(`DEBUG_TRACE > 0) $display("line %x", line);
 | 
				
			||||||
 | 
					      matchCount = $sscanf(line, "%x %x %s", ExpectedPCW, ExpectedInstrW, textW);
 | 
				
			||||||
 | 
					      //$display("matchCount %d, PCW %x ExpectedInstrW %x textW %x", matchCount, ExpectedPCW, ExpectedInstrW, textW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // for the life of me I cannot get any build in C or C++ string parsing functions/methods to work.
 | 
				
			||||||
 | 
					      // Just going to do this char by char.
 | 
				
			||||||
 | 
					      StartIndex = 0;
 | 
				
			||||||
 | 
					      TokenIndex = 0;
 | 
				
			||||||
 | 
					      //$display("len = %d", line.len());
 | 
				
			||||||
 | 
					      for(index = 0; index < line.len(); index++) begin
 | 
				
			||||||
 | 
						//$display("char = %s", line[index]);
 | 
				
			||||||
 | 
						if (line[index] == " " || line[index] == "\n") begin
 | 
				
			||||||
 | 
						  EndIndex = index;
 | 
				
			||||||
 | 
						  ExpectedTokens[TokenIndex] = line.substr(StartIndex, EndIndex-1);
 | 
				
			||||||
 | 
						  //$display("In Tokenizer %s", line.substr(StartIndex, EndIndex-1));
 | 
				
			||||||
 | 
						  StartIndex = EndIndex + 1;
 | 
				
			||||||
 | 
						  TokenIndex++;
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // check PCW
 | 
				
			||||||
 | 
					      if(PCW != ExpectedPCW) begin
 | 
				
			||||||
 | 
						$display("PCW: %016x does not equal ExpectedPCW: %016x", PCW, ExpectedPCW);
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // check instruction value
 | 
				
			||||||
 | 
					      if(dut.hart.ifu.InstrW != ExpectedInstrW) begin
 | 
				
			||||||
 | 
						$display("InstrW: %x does not equal ExpectedInstrW: %x", dut.hart.ifu.InstrW, ExpectedInstrW);
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      MarkerIndex = 3;
 | 
				
			||||||
 | 
					      processingCSR = 0;
 | 
				
			||||||
 | 
					      fault = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      #2;
 | 
				
			||||||
 | 
					      while(TokenIndex > MarkerIndex) begin
 | 
				
			||||||
 | 
						// check GPR
 | 
				
			||||||
 | 
						if (ExpectedTokens[MarkerIndex] == "GPR") begin
 | 
				
			||||||
 | 
						  matchCount = $sscanf(ExpectedTokens[MarkerIndex+1], "%d", RegAdr);
 | 
				
			||||||
 | 
						  matchCount = $sscanf(ExpectedTokens[MarkerIndex+2], "%x", RegValue);
 | 
				
			||||||
 | 
						  if(`DEBUG_TRACE > 1) begin
 | 
				
			||||||
 | 
						    $display("Reg Write Address: %02d ? expected value: %02d", dut.hart.ieu.dp.regf.a3, RegAdr);
 | 
				
			||||||
 | 
						    $display("RF[%02d]: %016x ? expected value: %016x", RegAdr, dut.hart.ieu.dp.regf.rf[RegAdr], RegValue);
 | 
				
			||||||
 | 
						  end
 | 
				
			||||||
 | 
						  if (dut.hart.ieu.dp.regf.a3 != RegAdr) begin
 | 
				
			||||||
 | 
						    $display("Reg Write Address: %02d does not equal expected value: %016x", dut.hart.ieu.dp.regf.a3, RegAdr);
 | 
				
			||||||
 | 
						    fault = 1;
 | 
				
			||||||
 | 
						  end
 | 
				
			||||||
 | 
						  
 | 
				
			||||||
 | 
						  if (dut.hart.ieu.dp.regf.rf[RegAdr] != RegValue) begin
 | 
				
			||||||
 | 
						    $display("RF[%02d] does not equal expected value: %016x", RegAdr, RegValue);
 | 
				
			||||||
 | 
						    fault = 1;
 | 
				
			||||||
 | 
						  end
 | 
				
			||||||
 | 
						  MarkerIndex += 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  // check memory address, read data, and/or write data
 | 
				
			||||||
 | 
						end else if(ExpectedTokens[MarkerIndex].substr(0, 2) == "Mem") begin
 | 
				
			||||||
 | 
						  matchCount = $sscanf(ExpectedTokens[MarkerIndex+1], "%x", ExpectedMemAdr);
 | 
				
			||||||
 | 
						  matchCount = $sscanf(ExpectedTokens[MarkerIndex+2], "%x", ExpectedMemWriteData);
 | 
				
			||||||
 | 
						  matchCount = $sscanf(ExpectedTokens[MarkerIndex+3], "%x", ExpectedMemReadData);	  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  if(`DEBUG_TRACE > 2) $display("\tMemAdrW: %016x ? expected: %016x", MemAdrW, ExpectedMemAdr);
 | 
				
			||||||
 | 
						  
 | 
				
			||||||
 | 
						  // always check address
 | 
				
			||||||
 | 
						  if (MemAdrW != ExpectedMemAdr) begin
 | 
				
			||||||
 | 
						    $display("MemAdrW: %016x does not equal expected value: %016x", MemAdrW, ExpectedMemAdr);
 | 
				
			||||||
 | 
						    fault = 1;
 | 
				
			||||||
 | 
						  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  // check read data
 | 
				
			||||||
 | 
						  if(ExpectedTokens[MarkerIndex] == "MemR" || ExpectedTokens[MarkerIndex] == "MemRW") begin
 | 
				
			||||||
 | 
						    if(`DEBUG_TRACE > 2) $display("\tReadDataW: %016x ? expected: %016x", dut.hart.ieu.dp.ReadDataW, ExpectedMemReadData);
 | 
				
			||||||
 | 
						    if (dut.hart.ieu.dp.ReadDataW != ExpectedMemReadData) begin
 | 
				
			||||||
 | 
						      $display("ReadDataW: %016x does not equal expected value: %016x", dut.hart.ieu.dp.ReadDataW, ExpectedMemReadData);
 | 
				
			||||||
 | 
						      fault = 1;
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  // check write data
 | 
				
			||||||
 | 
						  else if(ExpectedTokens[MarkerIndex] == "MemW" || ExpectedTokens[MarkerIndex] == "MemRW") begin
 | 
				
			||||||
 | 
						    if(`DEBUG_TRACE > 2) $display("\tWriteDataW: %016x ? expected: %016x", WriteDataW, ExpectedMemWriteData);
 | 
				
			||||||
 | 
						    if (WriteDataW != ExpectedMemWriteData) begin
 | 
				
			||||||
 | 
						      $display("WriteDataW: %016x does not equal expected value: %016x", WriteDataW, ExpectedMemWriteData);
 | 
				
			||||||
 | 
						      fault = 1;
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						  end
 | 
				
			||||||
 | 
						  MarkerIndex += 4;
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						else if(ExpectedTokens[MarkerIndex] == "CSR" || processingCSR) begin
 | 
				
			||||||
 | 
						  MarkerIndex++;
 | 
				
			||||||
 | 
						  processingCSR = 1;
 | 
				
			||||||
 | 
						  matchCount = $sscanf(ExpectedTokens[MarkerIndex], "%s", ExpectedCSR);
 | 
				
			||||||
 | 
						  matchCount = $sscanf(ExpectedTokens[MarkerIndex+1], "%x", ExpectedCSRValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  case(ExpectedCSR) 
 | 
				
			||||||
 | 
						    "mhartid": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MHARTID_REGW, ExpectedCSRValue);	      
 | 
				
			||||||
 | 
						      end 
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MHARTID_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MHARTID_REGW, ExpectedCSRValue);	      
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "mstatus": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MSTATUS_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MSTATUS_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MSTATUS_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "mtvec": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							 $display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MTVEC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MTVEC_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MTVEC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "mip": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							  $display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MIP_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MIP_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MIP_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "mie": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							  $display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MIE_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MIE_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MIE_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "mideleg": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							  $display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MIDELEG_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MIDELEG_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MIDELEG_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "medeleg": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MEDELEG_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MEDELEG_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MEDELEG_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "mepc": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							  $display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MEPC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MEPC_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MEPC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "mtval": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MTVAL_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrm.MTVAL_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrm.MTVAL_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    "sepc": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.SEPC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrs.SEPC_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.SEPC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "scause": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.genblk1.SCAUSE_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrs.genblk1.SCAUSE_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.genblk1.SCAUSE_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "stvec": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.STVEC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrs.STVEC_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.STVEC_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						    "stval": begin
 | 
				
			||||||
 | 
						      if(`DEBUG_TRACE > 3) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, expected = %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.genblk1.STVAL_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						      if (dut.hart.priv.csr.genblk1.csrs.genblk1.STVAL_REGW != ExpectedCSRValue) begin
 | 
				
			||||||
 | 
							$display("CSR: %s = %016x, does not equal expected value %016x", ExpectedCSR, dut.hart.priv.csr.genblk1.csrs.genblk1.STVAL_REGW, ExpectedCSRValue);
 | 
				
			||||||
 | 
							fault = 1;
 | 
				
			||||||
 | 
						      end
 | 
				
			||||||
 | 
						    end
 | 
				
			||||||
 | 
						  endcase
 | 
				
			||||||
 | 
						  MarkerIndex += 2;
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					      end // while (TokenIndex > MarkerIndex)
 | 
				
			||||||
 | 
					      if (fault == 1) begin
 | 
				
			||||||
 | 
						`ERROR
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  // ----------------
 | 
					  // ----------------
 | 
				
			||||||
  // PC Updater Macro
 | 
					  // PC Updater Macro
 | 
				
			||||||
  // ----------------
 | 
					  // ----------------
 | 
				
			||||||
@ -160,6 +429,7 @@ module testbench();
 | 
				
			|||||||
  always @(posedge clk)
 | 
					  always @(posedge clk)
 | 
				
			||||||
    IllegalInstrFaultd = dut.hart.priv.IllegalInstrFaultM;
 | 
					    IllegalInstrFaultd = dut.hart.priv.IllegalInstrFaultM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  // -------------------------------------
 | 
					  // -------------------------------------
 | 
				
			||||||
  // Special warnings for important faults
 | 
					  // Special warnings for important faults
 | 
				
			||||||
  // -------------------------------------
 | 
					  // -------------------------------------
 | 
				
			||||||
@ -172,10 +442,13 @@ module testbench();
 | 
				
			|||||||
      $display("Warning: illegal physical memory access exception at %0t ps, InstrNum %0d, PCM %x, InstrM %s", $time, instrs, dut.hart.ifu.PCM, PCtextM);
 | 
					      $display("Warning: illegal physical memory access exception at %0t ps, InstrNum %0d, PCM %x, InstrM %s", $time, instrs, dut.hart.ifu.PCM, PCtextM);
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // *** BUG BUG BUG Come back to this.
 | 
				
			||||||
  // -----------------------
 | 
					  // -----------------------
 | 
				
			||||||
  // RegFile Write Hijacking
 | 
					  // RegFile Write Hijacking
 | 
				
			||||||
  // -----------------------
 | 
					  // -----------------------
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  always @(PCW or dut.hart.ieu.InstrValidW) begin
 | 
					  always @(PCW or dut.hart.ieu.InstrValidW) begin
 | 
				
			||||||
    if(dut.hart.ieu.InstrValidW && PCW != 0) begin
 | 
					    if(dut.hart.ieu.InstrValidW && PCW != 0) begin
 | 
				
			||||||
      // Hack to compensate for how Wally's MTIME may diverge from QEMU's MTIME (and that is okay)
 | 
					      // Hack to compensate for how Wally's MTIME may diverge from QEMU's MTIME (and that is okay)
 | 
				
			||||||
@ -200,10 +473,12 @@ module testbench();
 | 
				
			|||||||
      end else release dut.hart.ieu.dp.WriteDataW;
 | 
					      end else release dut.hart.ieu.dp.WriteDataW;
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // ----------------
 | 
					  // ----------------
 | 
				
			||||||
  // Big Chunky Block
 | 
					  // Big Chunky Block
 | 
				
			||||||
  // ----------------
 | 
					  // ----------------
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  always @(reset or dut.hart.ifu.InstrRawD or dut.hart.ifu.PCD) begin// or negedge dut.hart.ifu.StallE) begin // Why do we care about StallE? Everything seems to run fine without it.
 | 
					  always @(reset or dut.hart.ifu.InstrRawD or dut.hart.ifu.PCD) begin// or negedge dut.hart.ifu.StallE) begin // Why do we care about StallE? Everything seems to run fine without it.
 | 
				
			||||||
    #2;
 | 
					    #2;
 | 
				
			||||||
    // If PCD/InstrD aren't garbage
 | 
					    // If PCD/InstrD aren't garbage
 | 
				
			||||||
@ -263,7 +538,7 @@ module testbench();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          // Check if PCD is going to be flushed due to a branch or jump
 | 
					          // Check if PCD is going to be flushed due to a branch or jump
 | 
				
			||||||
          if (`BPRED_ENABLED) begin
 | 
					          if (`BPRED_ENABLED) begin
 | 
				
			||||||
            PCDwrong = dut.hart.hzu.FlushD || (PCtextE.substr(0,3) == "mret") || dut.hart.priv.InstrPageFaultF || dut.hart.priv.InstrPageFaultD || dut.hart.priv.InstrPageFaultE || dut.hart.priv.InstrPageFaultM;
 | 
					            PCDwrong = dut.hart.hzu.FlushD || (PCtextE.substr(0,3) == "mret") || (PCtextE.substr(0,4) == "ecall")  || dut.hart.priv.InstrPageFaultF || dut.hart.priv.InstrPageFaultD || dut.hart.priv.InstrPageFaultE || dut.hart.priv.InstrPageFaultM;
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // Check PCD, InstrD
 | 
					          // Check PCD, InstrD
 | 
				
			||||||
@ -296,6 +571,7 @@ module testbench();
 | 
				
			|||||||
      lastPCD = dut.hart.ifu.PCD;
 | 
					      lastPCD = dut.hart.ifu.PCD;
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
  ///////////////////////////// PC,Instr Checking ///////////////////////////////
 | 
					  ///////////////////////////// PC,Instr Checking ///////////////////////////////
 | 
				
			||||||
@ -304,11 +580,13 @@ module testbench();
 | 
				
			|||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
  // Initialization
 | 
					  // Initialization
 | 
				
			||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  initial begin
 | 
					  initial begin
 | 
				
			||||||
    data_file_PCF = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
					    data_file_PCF = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
				
			||||||
    data_file_PCD = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
					    data_file_PCD = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
				
			||||||
    data_file_PCM = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
					    data_file_PCM = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
				
			||||||
    data_file_PCW = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
					    data_file_PCW = $fopen({`LINUX_TEST_VECTORS,"parsedPC.txt"}, "r");
 | 
				
			||||||
 | 
					    data_file_all = $fopen({`LINUX_TEST_VECTORS,"all.txt"}, "r");
 | 
				
			||||||
    if (data_file_PCW == 0) begin
 | 
					    if (data_file_PCW == 0) begin
 | 
				
			||||||
      $display("file couldn't be opened");
 | 
					      $display("file couldn't be opened");
 | 
				
			||||||
      $stop;
 | 
					      $stop;
 | 
				
			||||||
@ -318,6 +596,7 @@ module testbench();
 | 
				
			|||||||
    // This makes sure PCM is one instr ahead of PCW
 | 
					    // This makes sure PCM is one instr ahead of PCW
 | 
				
			||||||
    `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
					    `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Removed because this is MMU's job
 | 
					  // Removed because this is MMU's job
 | 
				
			||||||
  // and it'd take some work to upgrade away from Bus to Cache signals)
 | 
					  // and it'd take some work to upgrade away from Bus to Cache signals)
 | 
				
			||||||
@ -338,6 +617,7 @@ module testbench();
 | 
				
			|||||||
  // ------------
 | 
					  // ------------
 | 
				
			||||||
  // PCW Checking
 | 
					  // PCW Checking
 | 
				
			||||||
  // ------------
 | 
					  // ------------
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  always @(PCW or dut.hart.ieu.InstrValidW) begin
 | 
					  always @(PCW or dut.hart.ieu.InstrValidW) begin
 | 
				
			||||||
   if(dut.hart.ieu.InstrValidW && PCW != 0) begin
 | 
					   if(dut.hart.ieu.InstrValidW && PCW != 0) begin
 | 
				
			||||||
      if($feof(data_file_PCW)) begin
 | 
					      if($feof(data_file_PCW)) begin
 | 
				
			||||||
@ -345,15 +625,20 @@ module testbench();
 | 
				
			|||||||
        `ERROR
 | 
					        `ERROR
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
					      `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
				
			||||||
      `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
					      `SCAN_PC(data_file_PCW, scan_file_PCW, PCtextW, PCtextW2, InstrWExpected, PCWexpected);
 | 
				
			||||||
      // If repeated or instruction, we want to skip over it (indicates an interrupt)
 | 
					      // If repeated or instruction, we want to skip over it (indicates an interrupt)
 | 
				
			||||||
      if (PCMexpected == PCWexpected) begin
 | 
					      if (PCMexpected == PCWexpected) begin
 | 
				
			||||||
        `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
					        `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
				
			||||||
        `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
					        `SCAN_PC(data_file_PCW, scan_file_PCW, trashString, trashString, InstrWExpected, PCWexpected);
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      if(~(PCW === PCWexpected)) begin
 | 
					      if(~(PCW === PCWexpected)) begin
 | 
				
			||||||
 | 
						if(PCtextW.substr(0,4) != "ecall") begin
 | 
				
			||||||
          $display("%0t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, PCW, PCWexpected);
 | 
					          $display("%0t ps, instr %0d: PCW does not equal PCW expected: %x, %x", $time, instrs, PCW, PCWexpected);
 | 
				
			||||||
          `ERROR
 | 
					          `ERROR
 | 
				
			||||||
 | 
					        end else begin
 | 
				
			||||||
 | 
					         `SCAN_PC(data_file_PCM, scan_file_PCM, trashString, trashString, InstrMExpected, PCMexpected);
 | 
				
			||||||
 | 
					         `SCAN_PC(data_file_PCW, scan_file_PCW, PCtextW, PCtextW2, InstrWExpected, PCWexpected);
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    // Skip over faulting instructions because they do not make it to the W stage.
 | 
					    // Skip over faulting instructions because they do not make it to the W stage.
 | 
				
			||||||
@ -364,12 +649,14 @@ module testbench();
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
  ///////////////////////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
  /////////////////////////// RegFile Write Checking ////////////////////////////
 | 
					  /////////////////////////// RegFile Write Checking ////////////////////////////
 | 
				
			||||||
  ///////////////////////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
  // Initialization
 | 
					  // Initialization
 | 
				
			||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  initial begin
 | 
					  initial begin
 | 
				
			||||||
    data_file_rf = $fopen({`LINUX_TEST_VECTORS,"parsedRegs.txt"}, "r");
 | 
					    data_file_rf = $fopen({`LINUX_TEST_VECTORS,"parsedRegs.txt"}, "r");
 | 
				
			||||||
    if (data_file_rf == 0) begin
 | 
					    if (data_file_rf == 0) begin
 | 
				
			||||||
@ -412,6 +699,7 @@ module testbench();
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  endgenerate
 | 
					  endgenerate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
  /////////////////////////////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
  //////////////////////// Memory Read/Write Checking /////////////////////////
 | 
					  //////////////////////// Memory Read/Write Checking /////////////////////////
 | 
				
			||||||
  /////////////////////////////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@ -442,6 +730,7 @@ module testbench();
 | 
				
			|||||||
  // ------------
 | 
					  // ------------
 | 
				
			||||||
  // Read Checker
 | 
					  // Read Checker
 | 
				
			||||||
  // ------------
 | 
					  // ------------
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  always @(negedge clk) begin
 | 
					  always @(negedge clk) begin
 | 
				
			||||||
    if (dut.hart.MemRWM[1] && ~dut.hart.StallM && ~dut.hart.FlushM && dut.hart.ieu.InstrValidM) begin
 | 
					    if (dut.hart.MemRWM[1] && ~dut.hart.StallM && ~dut.hart.FlushM && dut.hart.ieu.InstrValidM) begin
 | 
				
			||||||
      if($feof(data_file_memR)) begin
 | 
					      if($feof(data_file_memR)) begin
 | 
				
			||||||
@ -500,6 +789,7 @@ module testbench();
 | 
				
			|||||||
      //end
 | 
					      //end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
  //////////////////////////////// CSR Checking /////////////////////////////////
 | 
					  //////////////////////////////// CSR Checking /////////////////////////////////
 | 
				
			||||||
@ -507,6 +797,7 @@ module testbench();
 | 
				
			|||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
  // Initialization
 | 
					  // Initialization
 | 
				
			||||||
  // --------------
 | 
					  // --------------
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
  initial begin
 | 
					  initial begin
 | 
				
			||||||
    data_file_csr = $fopen({`LINUX_TEST_VECTORS,"parsedCSRs.txt"}, "r");
 | 
					    data_file_csr = $fopen({`LINUX_TEST_VECTORS,"parsedCSRs.txt"}, "r");
 | 
				
			||||||
    if (data_file_csr == 0) begin
 | 
					    if (data_file_csr == 0) begin
 | 
				
			||||||
@ -611,8 +902,8 @@ module testbench();
 | 
				
			|||||||
  `CHECK_CSR(SEPC)
 | 
					  `CHECK_CSR(SEPC)
 | 
				
			||||||
  `CHECK_CSR2(MCAUSE, `CSRM)
 | 
					  `CHECK_CSR2(MCAUSE, `CSRM)
 | 
				
			||||||
  `CHECK_CSR2(SCAUSE, `CSRS)
 | 
					  `CHECK_CSR2(SCAUSE, `CSRS)
 | 
				
			||||||
  `CHECK_CSR2(MTVAL, `CSRM)
 | 
					//  `CHECK_CSR2(MTVAL, `CSRM)
 | 
				
			||||||
  `CHECK_CSR2(STVAL, `CSRS)
 | 
					//  `CHECK_CSR2(STVAL, `CSRS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //`CHECK_CSR(FCSR)
 | 
					  //`CHECK_CSR(FCSR)
 | 
				
			||||||
  //`CHECK_CSR(MCOUNTEREN)
 | 
					  //`CHECK_CSR(MCOUNTEREN)
 | 
				
			||||||
@ -626,6 +917,7 @@ module testbench();
 | 
				
			|||||||
  //`CHECK_CSR2(SSCRATCH, `CSRS)
 | 
					  //`CHECK_CSR2(SSCRATCH, `CSRS)
 | 
				
			||||||
  //`CHECK_CSR(SSTATUS)
 | 
					  //`CHECK_CSR(SSTATUS)
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@ -650,11 +942,13 @@ module testbench();
 | 
				
			|||||||
    if (reset) begin
 | 
					    if (reset) begin
 | 
				
			||||||
      PCtextE = "(reset)";
 | 
					      PCtextE = "(reset)";
 | 
				
			||||||
      PCtextM = "(reset)";
 | 
					      PCtextM = "(reset)";
 | 
				
			||||||
      PCtextW = "(reset)";
 | 
					      //PCtextW = "(reset)";
 | 
				
			||||||
    end else begin
 | 
					    end else begin
 | 
				
			||||||
 | 
					/* -----\/----- EXCLUDED -----\/-----
 | 
				
			||||||
      if (~dut.hart.StallW) 
 | 
					      if (~dut.hart.StallW) 
 | 
				
			||||||
        if (dut.hart.FlushW) PCtextW = "(flushed)";
 | 
					        if (dut.hart.FlushW) PCtextW = "(flushed)";
 | 
				
			||||||
        else                 PCtextW = PCtextM;
 | 
					        else                 PCtextW = PCtextM;
 | 
				
			||||||
 | 
					 -----/\----- EXCLUDED -----/\----- */
 | 
				
			||||||
      if (~dut.hart.StallM) 
 | 
					      if (~dut.hart.StallM) 
 | 
				
			||||||
        if (dut.hart.FlushM) PCtextM = "(flushed)";
 | 
					        if (dut.hart.FlushM) PCtextM = "(flushed)";
 | 
				
			||||||
        else                 PCtextM = PCtextE;
 | 
					        else                 PCtextM = PCtextE;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user