bug是第十章,写协处理器访问指令时出来的。当然每一章都会产生bugs 汇编测试代码如下:
.org 0x0
.set noat
.set noreorder
.set nomacro
.global _start
_start:
ori $1,$0,0xf
mtc0 $1,$11,0x0 #写compare寄存器,开始计时 $11=0xf
lui $1,0x1000 # $1高16位填0x1000
ori $1,$1,0x401
mtc0 $1,$12,0x0 #将0x401写入status寄存器
mfc0 $2,$12,0x0 #读status寄存器,$2=0x401
_loop:
j _loop
nop
$1寄存器的值0xf->0x10000000->0x10000401
第一次仿真
只有reg1即$1是正确的 Status是错的 Count也是正确的 Comapre是错误的 timer_int_o也是错误的 Status、Compare是错的 可能直接原因就是cp0_reg.v错了
`CP0_REG_COMPARE:begin
compare_o <= data_i;
timer_int_o <= `InterruputNotAssert;
end
写Compare寄存器时少加了中断 修改后结果还是错的 说明错的不止这一个地方
加入reg2
reg2也是错的 ,说明mtc0是错的 接下来查找mct0错在哪里
mem.v模块增加的操作
cp0_reg_we_o <= cp0_reg_we_i;
cp0_reg_write_addr_o <= cp0_reg_write_addr_i;
cp0_reg_data_o <= cp0_reg_data_i;
case(aluop_i)
对mem模块进行仿真,mem模块值是错的 现在是5.22号,pass掉了stupid的5.20 5.21真好,之前发现是mem模块里面定义某个信号的位宽时错了,当时晚了,就很快改了一下,也没有记录下来,不过就是MEM模块的错误,ex模块是没有问题的。
ex.v模块
`define EXE_MFC0_OP 8'b01011101
`define EXE_MTC0_OP 8'b01100000
inst_rom.data
3401000f
40815800
3c011000
34210401
40816000
40026000
08000006
00000000
id.v
if(inst_i[31:21]==11'b010_0000_0000&&inst_i[10:0]==11'b000_0000_0000)
begin
aluop_o <= `EXE_MFC0_OP;
alusel_o <= `EXE_RES_MOVE;
wd_o <= inst_i[20:16];
wreg_o <= `WriteEnable;
instvalid <= `InstValid;
reg1_read_o <= 1'b0;
reg2_read_o <= 1'b0;
end else if(inst_i[31:21]==11'b010_0000_0100&&inst_i[10:0]==11'b00000000000)
begin
aluop_o <= `EXE_MTHI_OP;
alusel_o <= `EXE_RES_MOVE;
wreg_o <= `WriteDisable;
instvalid <= `InstValid;
reg1_read_o <= 1'b1;
reg1_addr_o <= inst_i[20:16];
reg2_read_o <= 1'b0;
end
end
改: aluop_o <= `EXE_MTC0_OP
5.22的突然发现很幼稚的致命Bug…
摆烂还是有好处的,隔了几天没改bug,玩了很久,脑子就清醒了,发现改了一大部分之后,只有中断部分是错的,而中断只有cp0模块才有,当Compare寄存器的值和Count寄存器的值相等时,就等于1了,就开启中断了。后来发现果然是中断的宏定义少了个Not。下图就是改了之后的。就是把Not去掉了。
最终结果
|