编程文件格式的转换 MAX+plusII或QuartusII生成的SOF或POF文件不能直接用于CPU配置FPGA中,需要进行数据转换才能得到软件可用的配置数据。在MaxplusII中的具体步骤如下: 1. 进入数据转换对话框 图1 进入数据转换对话框 2.选择需要转换的SOF文件,对于配置多个FPGA的场合,应选择所有的SOF文件并排好次序。输出文件的格式我们选则二进制的rbf(Sequential)。 (也可以选择其他格式,如HEX等,在CPU软件编写上会与本文例子略有区别,关于不同文件格式的区别,在altera的AN116号文档上有详细解释) 图2 选择相应的输出数据格式 在QuartusII软件的file菜单下,同样可以找到类似菜单进行格式转化。 " l* j& r1 @7 l, V9 z5 w
CPU程序设计
: [7 d( Y) ~) X9 x9 X6 v5 I以MPC860为例,我们可以将转换完成的RBF文件作为二进制文件,直接写到MPC860系统的某一ROM/Flash区域。由于这段数据的起始地址和长度都是已知的,相应的软件编写是很方便的。
本设计的CPU源程序 void InitPORT(void) { // 初始化PB口相应位:& g- q) q" ~$ N& a
// PB24-输出,PB25-输入,PB26-输出,PB27-输入,PB28-输出
- f! N: E9 }8 v: [/ a! B2 o6 d, YIMMR->pip_pbpar=0x00000000;
6 I$ D: D7 D8 g, O; T& C3 `IMMR->pip_pbdir=0xFFFFF5AF;
8 G% n9 M+ G0 `& ?$ y, S! xIMMR->pip_pbodr=0x00000000;
+ [( d' Z& b2 M, B5 s8 }2 bIMMR->pip_pbdat=0xffffff57;2 f; F1 ?! P. N1 l/ F2 ]; L9 r
} UBYTE Fpga_DownLoad(void)
1 N0 C- T f, \" Z# Z! M{ // FPGA配置9 \* A7 t# @' c( x, M. Y
UBYTE *Bootaddr;
% E1 }6 o' E! n- J7 [! ^7 y/ X- aUWORD CountNum=0x0;
7 g3 I. U: R- G5 X+ bUBYTE FpgaBuffer, i; // 获得Boot区首地址" `& V1 j1 K& _# r$ t M3 p7 n) C5 j
Bootaddr=(UBYTE *)(IMMR->memc_or0 & IMMR->memc_br0 & 0xFFFF8000); Set_nCONFIG(0); // nCONFIG="0",使FPGA进入配置状态
4 @ W+ N7 M, sSet_DCLK(0);
/ a! Z' a$ E" K V- fDELAY5us();8 Q, A m9 Q" s& c. p; U W) \- h
if (Read_nSTATUS() == 1); K, t% h2 p, f
{ // 检测nSTATUS,如果为"0",表明FPGA已响应配置要求,可开始进行配置。否则报错
* n% a3 p( M- m- j# y$ l6 tErr_LED(1);! }2 o2 f; |! x0 |
return 0;
5 j$ X1 ]/ C7 ]: E8 r" l, f}
$ ]" z) `' C% N! sSet_nCONFIG(1);9 T4 Y; Z, F1 ?" d, [
DELAY5us();
0 r1 D$ v% X6 ~ X- C: [* h// 开始输出配置数据:. s, P5 i t; r3 s: e P7 Q$ |
while(CountNum <= 0x0e74e)
, _1 z1 d3 Y5 P{
- y1 t' H+ S; d' N& XFpgaBuffer= *(Bootaddr+0x70000+CountNum);, a/ U5 \7 \/ a! k5 _
for (i=0; i<8; i++)
; n3 Y& M: Y. g) z) b# A{ // DCLK="0"时,在Data0上放置数据(LSB first)
6 k4 A0 J8 J: |* ?* W1 [Set_Data0(FpgaBuffer&0x01);
. f/ j% a8 L: Z. k: u8 zSet_DCLK(1); // DCLK->"1",使FPGA读入数据
, q# s+ M! \4 y! k9 d/ T, mFpgaBuffer >>= 1; // 准备下一位数据
9 Z8 [5 w2 [5 c& ]* Pif (Read_nSTATUS() == 0)9 u' T7 g. f0 v3 ~
{ // 检测nSTATUS,如果为"0",表明FPGA配置出错 3 P0 D* ]7 s7 ]# _+ X5 A3 T
Err_LED(1);
# u/ Q3 k1 @$ C0 b- ]return 0;
; l# Y4 ]* K* x9 m0 b: L}
! Y2 E8 c5 c8 a" Y0 K4 hSet_DCLK(0);+ f: g/ _9 S5 t
}
8 y: u) C0 M* `! m7 JCountNum++;. W. l! ~/ w- L9 r' j: \% A
}
9 q$ f) Z2 f( y
// FPGA初始化:: i5 ~# M0 U$ a
// ACEX 1K和FLEX 10KE需要10个周期,APEX 20K需要40个周期
+ z/ m$ T) e) u: r& e) w6 \7 D$ m0 `for(i=0; i<10; i++)
. s+ Q+ B G$ R" O0 r{
+ N9 A [3 M6 I7 y3 I& M) \Set_DCLK(1);" F) d5 S6 l+ n5 l6 [& \ ^+ n( f0 S
DELAY100us();
0 d. W5 g/ O$ w' g8 ZSet_DCLK(0);0 w! \( N- }# ?, Z; p5 U
DELAY100us();9 n0 Y0 l4 Z7 G3 R& V9 t
}0 G8 T/ M; i2 `; P" S" u0 y
Set_Data0(0);* d1 s9 L6 n, K# Y: K0 g
if (Read_nCONF_Done() == 0)& j; `) s7 A- y3 [3 Z4 r7 O
{ // 检测nCONF_Done,如果为"0",表明FPGA配置未成功
! I7 I- y& x: R: eErr_LED(1);) v1 Z. w" P% D/ q- Z, `
return 0;
7 @: P; F% \/ P* I5 z7 L1 K- M}! f4 [, ^( {& p5 D2 j
return 1; // 成功返回
; x0 m. N0 y2 N- C. G) d# n% Y} // Data0输出
6 [% b9 w5 A" j' ^! gvoid Set_Data0(UBYTE setting)
& `& W3 ?5 T+ l9 ?. Y9 ?{ // PB24! e3 ?( J/ F8 N4 N/ c: g! x
if (setting) IMMR->pip_pbdat |= 0x00000080;! l, S/ r1 y: m8 w# m5 t5 B
else IMMR->pio_pbdat &= 0xFFFFFF7F;9 ^8 l. B( g5 B7 r- H- L' b4 x
} // 读nSTATUS状态
# z- k9 l, ~. T" I- wUBYTE Read_nSTATUS(void)0 H' Z' T* ^! {7 _8 h; R7 F
{ // PB25- L" j0 T8 C8 D$ ^# Y7 P
if (IMMR->pio_pbdat & 0x00000040) return 1;" ]0 a5 {8 L6 ~5 u) Z
else return 0;
9 z- ^% [. ]8 v" Z u! z} // 设置nCONFIG电平- ^$ Z4 w8 F+ U! A* ]8 v, b9 ?
void Set_nCONFIG(UBYTE setting)
( _4 C& n( F" i/ r# e{ // PB26' y: n6 m2 S* v" p. Q$ ]/ ~
if (setting) IMMR->pip_pbdat |= 0x00000020;6 g3 i9 {4 V5 {+ S8 n# Y
else IMMR->pio_pbdat &= 0xFFFFFFDF;
, I9 X; I* ?+ N, S0 T. C} // 读nCONF_Done状态9 O- f$ A5 @; N$ a; P2 ^
UBYTE Read_nCONF_Done(void)
' I- g0 g7 g5 L5 E- t% k! X3 z{ // PB27
5 V3 Q r0 g: ?+ qif (IMMR->pio_pbdat & 0x00000010) return 1;. k4 l& V% }$ C8 z
else return 0;
" b2 _/ S5 c3 X3 e, P1 j1 B} // 输出DCLK' C7 K' H% ?( l4 i* X
void Set_DCLK(UBYTE setting)9 s. _& e# D2 J3 ^; F0 l* @
{ // PB28
: m9 ~8 ^( {2 K1 uif (setting) IMMR->pio_pbdat |= 0x00000008;! C! ]$ I0 I% L% `
else IMMR->pio_pbdat &= 0xFFFFFFF7; e; ~& r( T' T: j4 I4 q4 T
}2 D, k* n; z3 O8 w
// 结束 |