【错误提示】
Downloading ELF Process failed
Using cable "USB-Blaster [USB-0]", device 1, instance 0x00
Pausing target processor: not responding.
Resetting and trying again: FAILED
Leaving target processor paused
【原因】
NIOS II里面Reset Vector的地址设置到了SDRAM里面,而板子刚通电的时候SDRAM的内容是随机的。每次下载sof文件到板子上,NIOS CPU首先就从SDRAM里面开始执行程序,就会出错,CPU立即卡死,下载器就检测不到NIOS CPU的存在了。
除非SDRAM里面事先成功放好了程序,NIOS II去执行的时候不会卡死,这个时候eclipse才能碰巧检测到NIOS CPU,成功下载新写的程序。但是只要SDRAM一断电再开,同样的程序就下不进去了,因为CPU死了。
https://www.intel.com/content/www/us/en/programmable/support/support-resources/knowledge-base/solutions/rd07162014_6.html
【解决办法】
无论是在onchip memory上运行程序,还是在SDRAM里面运行程序,NIOS II的Reset Vector和Exception Vector地址都必须设置在onchip memory上!
这样才能保证NIOS CPU不会因为SDRAM内容随机而卡死。
Reset Vector只是程序的起始地址,起始地址在onchip memory里面,但是后面的部分是可以在SDRAM里面的:
Using cable "USB-Blaster [USB-0]", device 1, instance 0x00
Processor is already paused
Initializing CPU cache (if present)
OK
Downloading 00000000 ( 0%)
Downloading 01000000 ( 0%)
Downloading 0100CD1C (94%)
Downloaded 52KB in 0.6s (86.6KB/s)
Verifying 00000000 ( 0%)
Verifying 01000000 ( 0%)
Verifying 0100CD1C (94%)
Verified OK
Starting processor at address 0x01000194
只要qsys里面配置了SDRAM,并且reset vector是放到onchip memory里面的,那么新建的bsp工程,默认就是reset和exceptions段在onchip memory里面,其他段全部都在SDRAM中。
如果是先前建立的C工程,就得在BSP Editor里面手动改过来。
还有就是,SDRAM的时钟引脚sdram_clk不在SDRAM Controller核里面,要自己单独定义,并且要和主时钟形成-63°的相位差。否则也是下载不进去程序的!
module main(
input clock,
input uart_rx,
output uart_tx,
output sdram_clk,
output [11:0] sdram_addr,
output [1:0] sdram_ba,
output sdram_cas_n,
output sdram_cke,
output sdram_cs_n,
inout [15:0] sdram_dq,
output [1:0] sdram_dqm,
output sdram_ras_n,
output sdram_we_n
);
/* 产生复位信号 */
wire nrst;
Reset reset(clock, nrst);
/* PLL倍频 */
wire altpll_c0;
wire altpll_locked;
altpll_0 altpll_0(
.areset(~nrst),
.inclk0(clock),
.c0(altpll_c0), // 频率等于clock, 但相位相差63度
.locked(altpll_locked)
);
/* NIOS II */
// 注意NIOS和SDRAM的时钟频率相等, 但相位相差63度
assign sdram_clk = altpll_c0;
nios u0(
.clk_clk(clock),
.reset_reset_n(altpll_locked),
.uart_0_external_connection_rxd(uart_rx),
.uart_0_external_connection_txd(uart_tx),
.new_sdram_controller_0_wire_addr(sdram_addr),
.new_sdram_controller_0_wire_ba(sdram_ba),
.new_sdram_controller_0_wire_cas_n(sdram_cas_n),
.new_sdram_controller_0_wire_cke(sdram_cke),
.new_sdram_controller_0_wire_cs_n(sdram_cs_n),
.new_sdram_controller_0_wire_dq(sdram_dq),
.new_sdram_controller_0_wire_dqm(sdram_dqm),
.new_sdram_controller_0_wire_ras_n(sdram_ras_n),
.new_sdram_controller_0_wire_we_n(sdram_we_n)
);
endmodule
module Reset(
input clock,
output nrst
);
reg [3:0] counter = 4'd15;
assign nrst = (counter == 0);
always @(posedge clock) begin
if (!nrst)
counter <= counter - 1'b1;
end
endmodule
SDRAM的时序参数可以保持默认: