首先关于Cyclone IV系列的配置和远程系统更新需要阅读《Configuration and Remote System Upgrades in Cyclone IV Devices》这个手册,该手册在官网上可以找到。阅读这个手册可以了解到有关Cyclone IV的配置方式,如并行方式PS方式,串行方式AS这两种,以及主被动配置。还有就是配置的整个流程。这里笔者研究的是AS方式的主动配置,即通PC把配置文件通过串口发送到FPGA上然后FPGA通过一段小逻辑将接收到的文件写入到EPCS存储器里头,这里笔者用的是EPCS16的Flash存储器。烧写的文件格式是rpd(Raw Programming Data File)。
rpd文件的生成
首先在Quartus软件下,笔者用的是Quartus16.1版本,点击Assignments->Device->Device and Pin Optins->Configuration,勾选Use configuration device,然后选择使用的存储器件,这里笔者使用的是EPCS16所以选择EPCS16,如下图所示,然后点击ok,关闭对话框。
再次点击全编译,会自动生成.pof,这个.pof就是要生成.rpd文件的中间文件。当编译生成.pof文件后点击File->Convert Programming Files...,出现如下对话框,并按照如下对话框设置。
需要注意的是这里生成的.rpd文件是小端模式的,而FPGA里头需要的是大端的形式,解决的办法有两种,第1种:点击上述对话框中的Options/Boot info...按钮选择Big endian。第2种:在往Flash芯片里头写入的时候将高低位互换,笔者在这里用的就是第2中方法。
rpd文件的传输
这里笔者用的是matlab编写的一段串口发送小程序,仿照ymodem协议进行稳定可靠的传输。代码如下:
clc;
clear all;
close all;
%%
file_name = 'E:\JIYI_Work_Space\Projects\FPGA_Remote_Update\JIYI_FPGA_RSU_20200921\output_files\JIYI_FPGA_RSU_Little.rpd';
file_id=fopen(file_name,'r'); %以读的方式打开串口原始数据
fseek(file_id,0,'eof'); %将位置索引号指向文件最后
read_total_bytes = double(ftell(file_id)); %获取将要读取的总字节数 127302624
fprintf('读取总字节数:%dBytes,%fKB,%fMB\n',read_total_bytes,read_total_bytes/1024,read_total_bytes/1024/1024);
fseek(file_id,0,'bof'); %将位置索引号指向文件开始
binary_data = uint8(fread(file_id,read_total_bytes,'uint8'));
figure;
plot(binary_data);
%%
scom1 = serial('com3');%%%%%%%%%%%%%%%%open com5
scom1.Terminator = 'CR';
scom1.BaudRate = 115200;
scom1.InputBufferSize = 1024*1024;
scom1.OutputBufferSize = 1024*1024;
scom1.Timeout = 60; %等待时延 单位:秒
scom1.RequestToSend ='on';
fopen(scom1); %打开串口
%%
start_str = [36 70 80 71 65 66]; % $FPGAB 24 46 50 47 41 42
while 1
fwrite(scom1, start_str, 'uint8'); %发送开始传输字符
fprintf('Flash整片擦除开始...\n');
ack = fread(scom1,1,'uint8'); %0x55 85
if(ack(1) == 85) %收到正确回复
fprintf('收到正确开始回复,Flash整片擦除完毕:ack = %s\n',ack(1));
break;
else
fprintf('收到错误开始回复:ack = %s\n',ack(1));
end
end
%%
head =