3751
最简单的就是直接遍历,不断取出每个数,然后和旁边的两个数去比较,如果都大于或都小于,那就是可以的
优化的话感觉可以归并
对于归并的话,就是拆成左右两半后,看mid和mid+1,
对于mid,就是看mid-1和mid+1上的数是否都大于或都小于
对于mid+1,就是看mid和mid+2上的数是否都大于或都小于
然后由于第一个和最后一个都不能是,所以当区间长度为1,2时,就直接返回0
这样判断一个数的波动值的复杂度就是logn,整体的复杂度是mlogn
又或者可以直接构造?
构想枚举每个数位上的每个数,对于三位数,在不限制的情况下,如果中间位数上的数是x,那么左边共9个,右边共10个,选比x都小的设有a个,??感觉能构造,但是逻辑暂时没想明白
寄存器
冒险冲突
ROB
寄存器重命名
什么叫通过寄存器重命名消除?什么是重命名?解决机制是什么?
寄存器
CSR
异常
debug2
debug1
为什么说ESTAT很有信息量?”bit1 软件中断 pending 已经在了,但 Ecode 还残留着之前 n50 非法指令异常的 0xd“什么意思?什么叫bit1软件中断pending已经在了?”中断 pending 置上了,但 CPU 没有及时把它作为中断异常接走“又是什么意思?我知道ERA是异常指令处理完后pc的返回指令,但CRMD = 00000008和PRMD = 00000004是什么意思?int_ex是什么意思?什么叫只看CSR文件当前值?”但 csrwr ESTAT 到 WB/负沿才真正更新 CSR。等 int_ex 变高时,后面的 b 0 已经进了后级甚至提交了“什么叫b 0已经提交了?
什么是自旋分支b 0?什么是软件中断pending位?bit1是什么东西?
如果发现了异常指令,在ID阶段,它产生了异常label信号,不是到下一拍,即EX阶段才会由label信号产生出ERA等各种信号吗?那ERA是如何知道取出异常指令时的pc的呢?以及是如何知道要跳到异常入口1c008000?
bitx意思就是第几个x上的二进制是吧,那是指谁的第几位?以及DA,IE等名词都是什么意思?为什么进入异常后DA要保留而IE要被清除掉?以及PRMD是什么,要保存进入异常前的IE?
为什么说ESTAT[1]被置上,软件中断请求就来了?
意思是int_ex才是那个是否触发中断异常的信号,但中断异常不是指令吗?即由指令来触发的中断与异常,这个内部信号到底是干嘛的?即内部还说要是否触发中断与异常,异常指令前面在写CSR寄存器,写ESTAT等各种寄存器时不就是在触发中断异常吗?以及int前缀是什么意思?vet是什么意思?
这里当有异常指令时,不是会产生flush信号来洗掉新指令吗?为什么说还有b 0进入流水线?甚至还能到写回阶段?即异常指令肯定是比b 0要先执行完的,怎么还会有这个问题?
-------------
-----------
当int_ex为1时,但是要明白什么时候Int_ex为1?即int_ex在哪个阶段可能被置为1?比如来了一条可能引发中断,或者说想要触发中断的指令,那它是到写回阶段才可能使int_ex为1吗?那说当作ID_int_ex,是说相当于又向此时的流水线注入了一条直接触发中断的指令是吧?
fix
CRMD/ECFG/ESTAT/TCFG/TICLR当中分别都有哪些信息?int_ex生效是如何生效的?生效后的过程是怎样的?
对于解决方式1,暂停流水线F/D,即stall信号是如何发挥作用的,以及flush?给E插bubble,就是说“assign stallE = old_stallE; // 不停 E,让 CSR 指令继续往后走”是什么机制?这怎么就不停E了?以及FlushE,后面的判断说是E不暂停,而且是要写csr,那为什么就要flush了?
stallE不是说ID2EX不更新吗?当判断出是要写CSR,那不已经到了E阶段,那不停E不应该是不去stallM,即EX2ME阶段吗?那如果这样理解的话,E阶段上写CSR的指令进入到MEM阶段,然后ID2EX的行动被stall了,那下一拍的EX指令是什么?即从ID来的指令已经被stall了,那应该直接是空的了吗?“如果只 stallD=1,但不 FlushE,下一拍 D 里的 b 0 仍可能被送进 E。这样 b 0 就跑掉了。”都stall了,为什么E取值还能取到?
对于解决方法2,这个是否就是和解决RAW等冒险冲突一样,能提前旁路?
那如果是t0阶段csrwr要呼唤一次中断,t1阶段是其它的指令a;如果真能旁路,即方式二,那么t1时刻,csrwr走到ID,也没产生出相关的中断异常信号,a完成了IF阶段;等t2阶段,csrwr被旁路,又或者ID时,即t1时刻,csrwr就可以被旁路?然后触发了Int_ex,那就相当于要把ID阶段,即此时的指令a当成异常指令来执行;但一方面,a毕竟是普通指令,怎么能被当成异常指令来执行?这样真的没问题吗?
那对于非法指令异常,比如syscall,break等直接触发中断的指令,其ERA也是自己的pc吗?那这样ERA的语义不就乱了吗?难道这类直接触发中断的指令在执行完中断后,也要再回到自己继续执行?
意思就是说ERA只是负责保存当时的pc地址,如果是正常的指令,那就不+4,如果是主动触发异常的指令,那是由编译器负责产生的额外指令,即要求再csrrd t0 csr_era后面固定跟一条pc+4的指令,来越过当前的异常指令;但如果万一真的没有那个pc+4指令呢?
那如果syscall真的因为没有add i 4陷入了死循环,那怎么打破呢?
以及对于精确异常的概念,如果是由Int_ex执行的中断,是否也会清理掉新指令,即IF阶段的指令?
但是b怎么能被清除呢?是最初的csrwr指令呼唤的中断,那怎么能保留a而清掉b呢?因为看上去a和b的地位是一样;如果清掉b,那b还执不执行?因为a和b都是正常指令啊;
意思就是说a虽然是正常指令,但被Int_ex打上异常标签后,实际上也不会被继续执行了,可以认为只承载异常信息的bubble了,相当于也被flush掉了,b也要flush掉,只是此时的流水线不再处理a和b了,而是要处理异常中断程序里的指令ABCDE了,等他们都处理完后,再csrrd,回来继续流水线处理ab
change
这个写值计算函数是什么意思?addr_w_hcode是什么?hcode是什么?以及这个写csr的掩码计算,addr==14'h5的这些值是怎么来的?csr_next_value是怎么计算出来的?
原来的rf[14'h5],[14'h4]等都是什么意思?以及rf[14'h0]
reg [31:0]rf[387:0]是什么意思?是说有32个388位的寄存器吗,这个388是什么特殊的含义?
example
测试
- 配置要跑的测试:
./configure.sh --run func/func_lab3 --output-uart-info
- 第一次完整编译运行:
make -j8
- 改了 RTL 后,通常不用重新编译软件,可以跑:
make verilator testbench simulation_run_prog -j8
- 只想重新跑仿真,不重新编译 RTL/testbench:
make run
- 改了 func 软件或想强制重编软件:
make clean_soft make -j8
nscscc
流水线
“根据 CSR 的 DA/PG/DMW/TLB MAT 判断是否 uncache”什么叫是否Uncache?DMW,PG以及TLB MAT都是什么?
分支预测的完整机制是怎样的?
对load/store/CACOP/PRELD计算虚地址是如何计算的?指令本身不就自带一个地址吗,那个地址不是虚地址吗?