基于ARM Cortex-M0软核处理器 在FPGA 搭建soc遇到的问题(灯不亮 / 程序进入一次中断程序后无法返回)
一、Modelsim仿真发现所有的指令都不执行,可能是指令读取问题和总线信号的控制问题。
我遇到的:HRESP信号未使用,也没有赋值。查阅后发现HRESP是数据错误响应信号,允许设置为常0即代表不会出错,就不会压制主机了。
二、Modelsim仿真能通过,但是下载到FPGA上后,进行KEIL调试发现没有输出,
我遇到的:灯不能亮,即使Modelsim的输出为8'b0000_0011(绑定FPGA8个led),但是灯没有亮。
可能的原因
1.FPGA管脚绑定的输出驱动电平问题,没有设定IO口的标准 可能导致不能驱动。
2.模块端口例化时的连接信号要仔细检查。我是通过GPIO模块的输出来驱动led,但是GPIO模块没有连接正确的复位信号,这种编译下载不会报错,但是Modelsim仿真发现GPIO模块输出信号在arm cpu复位之后还出现了很多不定态“x”(即使在x之后有值,FPGA上的灯也没亮):
正确连接后(可以正常对模块复位)
仔细检查FPGA的软件报的WARNING,尤其要使用的信号。 体会到了复位的重要性,以及不定态“x”的恐怖。
三、遇到的问题:程序进入一次中断程序后无法返回
起初是在板子上运行的时候想通过按键触发不同的中断程序实现点亮不同的灯,但是每次复位后按下一个按键,点亮一个灯,但是再按下其他按键没有效果。
然后写测试文件,通过Modelsim进行仿真,发现在触发一次中断后,灯的输出确实正常,但是pc寄存器的值会变为x,ISPR的值也是x。百思不得其解,尝试改了KEIL编译器版本,启动文件堆栈大小,都没能够解决问题。
回到启动文件里,观察按键中断服务程序有POP和PUSH指令,然而在仿真中触发中断以后PC的值并没有从R14(LR)寄存器中,进行恢复,突然想到自己的DATARAM是自己简化的,而堆栈就是在RAM中存储的,想到可能是由于PUSH指令并没有将R14(LR)寄存器的值写入DATARAM,也就是DATARAM出现问题。然后发现DATARAM和网上的代码之间的差异。(前几个实验并没有使用到DATARAM,只使用了CODERAM)。
AHBlite总线中写操作使用的写大小,是要经过对(HSIZE[1:0],HADDR[1:0])进行译码,所以将HADDR寄存了一个周期,因此在第二个周期得出(假设第一个周期给出地址),但是HWRITE是在地址阶段拉高的,自己写的模块并没有对HWRITE进行寄存!导致写大小有效时,HWRITE已经无效。修改后运行正常。
需要保证小模块的功能正确后才能接入。