diff --git a/linux/testvector-generation/genTrace.sh b/linux/testvector-generation/genTrace.sh index 82f9e48be..e085251ba 100755 --- a/linux/testvector-generation/genTrace.sh +++ b/linux/testvector-generation/genTrace.sh @@ -4,10 +4,12 @@ imageDir=$RISCV/buildroot/output/images outDir=$RISCV/linux-testvectors recordFile="$outDir/all.qemu" traceFile="$outDir/all.txt" +interruptsFile="$outDir/interrupts.txt" read -p "Warning: running this script will overwrite the contents of: * $recordFile * $traceFile + * $interruptsFile Would you like to proceed? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]] @@ -17,8 +19,10 @@ then sudo chown cad $outDir sudo touch $recordFile sudo touch $traceFile + sudo touch $interruptsFile sudo chmod a+rw $recordFile sudo chmod a+rw $traceFile + sudo chmod a+rw $interruptsFile # Compile Devicetree from Source dtc -I dts -O dtb ../devicetree/virt-trimmed.dts > ../devicetree/virt-trimmed.dtb @@ -29,15 +33,17 @@ then -nographic -serial /dev/null \ -bios $imageDir/fw_jump.elf -kernel $imageDir/Image -append "root=/dev/vda ro" -initrd $imageDir/rootfs.cpio \ -singlestep -rtc clock=vm -icount shift=0,align=off,sleep=on,rr=record,rrfile=$recordFile \ - -d nochain,cpu,in_asm \ + -d nochain,cpu,in_asm,int \ -gdb tcp::$tcpPort -S \ - 2>&1 >/dev/null | ./parseQemuToGDB.py | ./parseGDBtoTrace.py | ./remove_dup.awk > $traceFile) \ + 2>&1 >/dev/null | ./parseQemuToGDB.py | ./parseGDBtoTrace.py $interruptsFile | ./remove_dup.awk > $traceFile) \ & riscv64-unknown-elf-gdb -quiet -x genTrace.gdb -ex "genTrace $tcpPort \"$imageDir/vmlinux\"" # Cleanup sudo chown cad $recordFile sudo chown cad $traceFile + sudo chown cad $interruptsFile sudo chmod o-w $recordFile sudo chmod o-w $traceFile + sudo chmod o-w $interruptsFile fi diff --git a/linux/testvector-generation/parseGDBtoTrace.py b/linux/testvector-generation/parseGDBtoTrace.py index ab63330fd..db444f696 100755 --- a/linux/testvector-generation/parseGDBtoTrace.py +++ b/linux/testvector-generation/parseGDBtoTrace.py @@ -130,6 +130,13 @@ def PrintInstr(instr, fp): fp.write(' CSR {}'.format(CSRStr)) fp.write('\n') +# ========= +# Main Code +# ========= +# Parse argument for interrupt file +if len(sys.argv) != 2: + sys.exit('Error parseGDBtoTrace.py expects 1 arg:\n >') +interruptFname = sys.argv[1] # 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 @@ -144,14 +151,24 @@ numInstrs = 0 #instructions = [] MemAdr = 0 lines = [] -interrupts=open('interrupts.txt','w') +interrupts=open(interruptFname,'w') interrupts.close() for line in fileinput.input('-'): if line.startswith('riscv_cpu_do_interrupt'): - with open('interrupts.txt','a') as interrupts: - interrupts.write(str(numInstrs)+': '+line.strip('riscv_cpu_do_interrupt')) - break + with open(interruptFname,'a') as interrupts: + # Write line + # Example line: hart:0, async:0, cause:0000000000000002, epc:0x0000000080008548, tval:0x0000000000000000, desc=illegal_instruction + interrupts.write(line) + # Write instruction count + interrupts.write(str(numInstrs)+'\n') + # Convert line to rows of info for easier Verilog parsing + vals=line.strip('riscv_cpu_do_interrupt: ').strip('\n').split(',') + vals=[val.split(':')[-1].strip(' ') for val in vals] + vals=[val.split('=')[-1].strip(' ') for val in vals] + for val in vals: + interrupts.write(val+'\n') + continue lines.insert(lineNum, line) if InstrStartDelim in line: lineNum = 0 @@ -204,8 +221,8 @@ for line in fileinput.input('-'): #instructions.append(MoveInstrToRegWriteLst) PrintInstr(MoveInstrToRegWriteLst, sys.stdout) numInstrs +=1 - if (numInstrs % 1e4 == 0): - sys.stderr.write('Trace parser reached '+str(numInstrs/1.0e6)+' million instrs.\n') + if (numInstrs % 1e5 == 0): + sys.stderr.write('GDB trace parser reached '+str(numInstrs/1.0e6)+' million instrs.\n') sys.stderr.flush() lineNum += 1 diff --git a/linux/testvector-generation/parseQemuToGDB.py b/linux/testvector-generation/parseQemuToGDB.py index 932761db7..fa2646abe 100755 --- a/linux/testvector-generation/parseQemuToGDB.py +++ b/linux/testvector-generation/parseQemuToGDB.py @@ -115,7 +115,6 @@ for l in fileinput.input(): if l.startswith('riscv_cpu_do_interrupt'): sys.stderr.write(l) interrupt_line = l.strip('\n') - continue elif l.startswith('qemu-system-riscv64: QEMU: Terminated via GDBstub'): break elif l.startswith('IN:'): diff --git a/pipelined/src/cache/cachefsm.sv b/pipelined/src/cache/cachefsm.sv index 3947309bf..90a4974e0 100644 --- a/pipelined/src/cache/cachefsm.sv +++ b/pipelined/src/cache/cachefsm.sv @@ -105,14 +105,14 @@ module cachefsm (* mark_debug = "true" *) statetype CurrState, NextState; - assign DoFlush = FlushCache & ~IgnoreRequest; - assign DoAMO = Atomic[1] & (&RW) & ~IgnoreRequest; + assign DoFlush = FlushCache & ~IgnoreRequest; // *** have to fix ignorerequest timing path + assign DoAMO = Atomic[1] & (&RW) & ~IgnoreRequest; // *** assign DoAMOHit = DoAMO & CacheHit; - assign DoAMOMiss = DoAMOHit & ~CacheHit; - assign DoRead = RW[1] & ~IgnoreRequest; + assign DoAMOMiss = DoAMO & ~CacheHit; + assign DoRead = RW[1] & ~IgnoreRequest; // *** assign DoReadHit = DoRead & CacheHit; assign DoReadMiss = DoRead & ~CacheHit; - assign DoWrite = RW[0] & ~IgnoreRequest; + assign DoWrite = RW[0] & ~IgnoreRequest; // *** assign DoWriteHit = DoWrite & CacheHit; assign DoWriteMiss = DoWrite & ~CacheHit; @@ -225,15 +225,15 @@ module cachefsm (CurrState == STATE_MISS_WRITE_WORD & DoWrite & CPUBusy)) & ~`REPLAY; // **** can this be simplified? - assign PreSelAdr = ((CurrState == STATE_READY & IgnoreRequest) | - (CurrState == STATE_READY & DoAMOHit) | + assign PreSelAdr = ((CurrState == STATE_READY & IgnoreRequest) | // *** ignorerequest comes from TrapM. Have to fix. why is ignorerequest here anyway? + (CurrState == STATE_READY & DoAMOHit) | // also depends on ignorerequest (CurrState == STATE_READY & DoReadHit & (CPUBusy & `REPLAY)) | (CurrState == STATE_READY & DoWriteHit) | (CurrState == STATE_MISS_FETCH_WDV) | (CurrState == STATE_MISS_FETCH_DONE) | (CurrState == STATE_MISS_WRITE_CACHE_LINE) | (CurrState == STATE_MISS_READ_WORD) | - (CurrState == STATE_MISS_READ_WORD_DELAY & (DoAMO | (CPUBusy & `REPLAY))) | + (CurrState == STATE_MISS_READ_WORD_DELAY & (DoAMO | (CPUBusy & `REPLAY))) | // *** (CurrState == STATE_MISS_WRITE_WORD) | (CurrState == STATE_MISS_EVICT_DIRTY) | (CurrState == STATE_CPU_BUSY & (CPUBusy & `REPLAY)) | diff --git a/pipelined/src/cache/cacheway.sv b/pipelined/src/cache/cacheway.sv index cb53a8160..d9f468a92 100644 --- a/pipelined/src/cache/cacheway.sv +++ b/pipelined/src/cache/cacheway.sv @@ -121,13 +121,12 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, always_ff @(posedge clk) begin // Valid bit array, if (reset | InvalidateAll) ValidBits <= #1 '0; - else if (SetValidD) ValidBits[RAdrD] <= #1 1'b1; - else if (ClearValidD) ValidBits[RAdrD] <= #1 1'b0; + else if (SetValid) ValidBits[RAdr] <= #1 1'b1; + else if (ClearValid) ValidBits[RAdr] <= #1 1'b0; end // *** consider revisiting whether these delays are the best option? flop #($clog2(NUMLINES)) RAdrDelayReg(clk, RAdr, RAdrD); - flop #(2) ValidCtrlDelayReg(clk, {SetValid, ClearValid}, - {SetValidD, ClearValidD}); + //flop #(2) ValidCtrlDelayReg(clk, {SetValid, ClearValid}, {SetValidD, ClearValidD}); assign Valid = ValidBits[RAdrD]; ///////////////////////////////////////////////////////////////////////////////////////////// @@ -138,8 +137,8 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26, if (DIRTY_BITS) begin:dirty always_ff @(posedge clk) begin if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; - else if (SetDirtyD) DirtyBits[RAdrD] <= #1 1'b1; - else if (ClearDirtyD) DirtyBits[RAdrD] <= #1 1'b0; + else if (SetDirty) DirtyBits[RAdr] <= #1 1'b1; + else if (ClearDirty) DirtyBits[RAdr] <= #1 1'b0; end flop #(2) DirtyCtlDelayReg(clk, {SetDirty, ClearDirty}, {SetDirtyD, ClearDirtyD}); assign Dirty = DirtyBits[RAdrD]; diff --git a/pipelined/src/cache/sram1rw.sv b/pipelined/src/cache/sram1rw.sv index 921c0af47..41dcbee04 100644 --- a/pipelined/src/cache/sram1rw.sv +++ b/pipelined/src/cache/sram1rw.sv @@ -41,22 +41,25 @@ module sram1rw #(parameter DEPTH=128, WIDTH=256) ( output logic [WIDTH-1:0] ReadData); logic [WIDTH-1:0] StoredData[DEPTH-1:0]; - logic [$clog2(DEPTH)-1:0] AddrD; + logic [$clog2(DEPTH)-1:0] AdrD; logic [WIDTH-1:0] WriteDataD; logic WriteEnableD; //*** model as single port // *** merge with simpleram always_ff @(posedge clk) begin - AddrD <= Adr; - WriteDataD <= WriteData; /// ****** this is not right. there should not need to be a delay. Implement alternative cache stall to avoid this. Eliminates a bunch of delay flops elsewhere - WriteEnableD <= WriteEnable; - if (WriteEnableD) begin - StoredData[AddrD] <= #1 WriteDataD; - end + AdrD <= Adr; + //WriteDataD <= WriteData; /// ****** this is not right. there should not need to be a delay. Implement alternative cache stall to avoid this. Eliminates a bunch of delay flops elsewhere + //WriteEnableD <= WriteEnable; + //if (WriteEnableD) begin + //StoredData[AddrD] <= #1 WriteDataD; + //end + if (WriteEnable) begin + StoredData[Adr] <= #1 WriteData; + end end - assign ReadData = StoredData[AddrD]; + assign ReadData = StoredData[AdrD]; /* always_ff @(posedge clk) begin ReadData <= RAM[Adr]; diff --git a/pipelined/src/lsu/interlockfsm.sv b/pipelined/src/lsu/interlockfsm.sv index bed28563d..5d53bd776 100644 --- a/pipelined/src/lsu/interlockfsm.sv +++ b/pipelined/src/lsu/interlockfsm.sv @@ -112,7 +112,6 @@ module interlockfsm assign SelHPTW = (InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) | (InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS); assign IgnoreRequest = (InterlockCurrState == STATE_T0_READY & (ITLBMissF | DTLBMissM | TrapM)) | - ((InterlockCurrState == STATE_T0_REPLAY) - & (TrapM)); + ((InterlockCurrState == STATE_T0_REPLAY) & (TrapM)); endmodule