找回密码
 注册
关于网站域名变更的通知
查看: 337|回复: 1
打印 上一主题 下一主题

#技术风云榜#添加VGA和I2C模块到ORPSoC并测试验证

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-11-13 14:30 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 qsoiuwisjiuw 于 2020-11-13 14:31 编辑
, Z; o& f# ^# Y( a/ t  ]* l% B8 L* h1 r5 E1 O" O2 t  Y/ @
1,实验步骤
( ]# U/ R+ H% E. S; I本小节,我们将vga_enh模块添加到ORPSoC,进行RTL仿真,并在ML501开发板上进行验证。大体过程如下:% R8 h8 ]/ d$ {& x* A7 ?) k
2 U/ ~6 U  g) P+ T4 ?: a
1>修改RTL代码,将vga_enh模块挂到ORPSoC的wishbone总线上。
: _0 T0 F: j9 E, ?# Q
6 Q1 h4 \) \% r5 L0 c$ v& x2>编写裸机测试程序
: h- {+ u" T0 |. h1 e7 |+ N1 ?
  p2 ~+ W' @/ r* v* m3>仿真
" g# M3 C8 D2 n- ]' T% n7 z' P3 [2 I$ E4 z" f+ l$ a5 A6 E
4>下板子测试
" y" b& }# E4 q
; R2 I% u: H% w) {! Z! Q* A
& s# ?4 r5 j8 l1 d/ K8 V  Y
$ r5 V* ^2 U# s: R2,修改RTL代码
& N2 R2 |8 ]) X+ s; h' ?在修改代码之前,一定要先把ORPSoC的结构弄明白。8 }2 D3 }* `- S% X
( X) B* O5 U' r8 @8 M. b$ `
如何将vga_enh挂到总线上呢,主要有两种方式:其中一种方式是将其master接口挂到dbus_arbiter上,另外一种方式是挂在ddr2的控制器上。两种不同的挂法,示意如下:
$ C4 f+ O7 P; E/ w( e
  m# o/ N  ], e- G. t3 x7 }* ]挂在dbus_arbiter上:
  S* o; l6 ^, c$ B
; h% F0 b/ R& N+ r: ]" ^$ D; ` $ {+ Y5 a% |; `5 Q

* N( G  h6 w. o8 {, y3 F5 N  v, B2 m0 j( e
4 p( K0 l- }) N4 y" v
直接挂在ddr2控制器上:
6 m- p5 u& i" ~$ I: ^) u
$ h9 h" d; Q9 R4 X  E7 u! ~ / d5 U% F3 _) Q$ [$ y9 K

6 K1 T5 _# w: o
% u9 F$ W( g8 r! e" y. W
8 K9 S  Y, Y" `  t这两种方式都算是DMA,我们这里两种方式都支持,两种方式通过define语句决定。暂时选择第二种方式。0 K% P8 h1 V# Q0 c: l( o7 O/ d

4 j" l+ G: u0 D2 a7 g: M当然,无论采用哪种方式,其总线地址都是唯一的,我们这里分配为0x97000000.9 M1 d/ X- Y3 `. R' S7 H' R8 m
; g( R$ i. @& {# D7 l

- s0 W. g) m2 C4 ^% I5 w
4 C4 N3 k2 G7 ?. [. |其实,对于ML501开发板而言,其本身并没有VGA接口,而是DVI接口,由于vga_enh这个模块不仅支持VGA输出,也支持DVI输出,但是需要注意的是,如果想利用ML501的DVI接口输出,就需要配置ML501板子上的CH7301这个芯片,由于配置CH7301需要I2C总线,所以我们除了想ORPSoC中增加vga_enh模块之外,还要增加i2c控制器模块。
- [3 K% [# p7 _& O* w3 _
5 x7 U" B: ~6 p' j* [ORPSoC本身包含两个i2c_master_slave,为了简单起见,我们将其中一个替换成i2c_master。/ V: W. y1 ~! H& r8 ?7 Y

. d1 U% P8 @& w9 H5 \, U- C! ?2 L# F* |+ V: p6 m! R. |
2 L! S3 u: Y! R
; _* W% z! z% I$ @# r! J
3,编写测试程序/ x0 ~- {' j& T, T
无论是进行RTL仿真,还是下板验证,我们都要先编写相应的测试程序。* s' `: g6 R) S. f3 |
) @: Q$ a) O: `: Y5 I2 f
vga.c:5 ^% ^' N; ?5 `0 s, w: p7 }
, B  k" f7 T# z- d# I

4 U4 S- r: `; j5 G/ `/ Q& @$ \! {3 [4 m: H* _$ O
/*9 B$ E& }) ~  C1 J, X. E
* file name : vga.c
0 A& p. @* M+ @$ B+ S* function  : vga controller test+ c! J2 r/ g1 @1 j  B8 J6 o. T
* date      : 2014-01-10$ h  \+ Q6 a' V
* author    : Rill! _% b: F/ Y5 M( H( F
*/
6 g# H8 o7 |/ W # p$ `3 ?  h2 n8 Y5 _* W+ ?5 g
#include "cpu-utils.h"* j1 k$ ^. @" m8 J% N
#include "board.h"
3 z- \! p7 K* D1 ?+ {#include "int.h"
" d4 L& K7 ?( h8 o8 k" a! C#include "uart.h"
1 G0 h& L1 {; v% M#include "printf.h"
6 z& v) n/ D3 r. N/ D  x8 x0 S
: h: _+ Z' k) R1 W  B- d//---VGA defines
, H$ Q0 _6 w* ?1 h#define RILL_VGA_BASE 0x97000000/ \! \4 B4 x6 j+ m# D) e$ s* r1 R4 b
#define VGA_IRQ 22: {. }$ i7 x' u! ]
#define FRAME_BUF_BASE 0x0  //30MB
2 J" c8 Q& l6 }2 P3 V9 p1 X#define FRAME_BUF_SIZE 0x1000
* A, _, ^! M+ s3 _  t
  G, H* a2 l5 R+ O5 @8 [) H, w
+ [' P2 T* y+ X( U//---I2C core defines6 M% C2 x$ [" O6 A
#define RILL_IIC_BASE 0xa0000000: M7 u+ a5 U' _- k0 i$ M  p
#define IIC_REG_ADR_PRER_LO 0x08 v. V9 M( x- O9 ~3 m/ F
#define IIC_REG_ADR_PRER_HI 0x12 z9 @) \! s& x: m
#define IIC_REG_ADR_CTR            0x2
, h8 S, t5 l" E+ [! V5 g , P, y9 o1 I/ G6 J* v7 V2 w
#define IIC_REG_ADR_RXR_W     0x3
- K8 n) v- j6 A8 |6 E/ Y#define IIC_REG_ADR_SR_W      0x4
( F9 j( F' d+ ^1 \/ s#define IIC_REG_ADR_TXR_W     0x3+ L* Y$ y+ [3 a
#define IIC_REG_ADR_CR_W      0x4
- y% V6 `. t2 A5 w* | ! o) j& }- U9 f
#define IIC_REG_ADR_RXR_R     0x3
. L$ v1 f1 v4 \: f#define IIC_REG_ADR_SR_R      0x4
, d+ r5 I& d1 o) W# }7 x#define IIC_REG_ADR_TXR_R     0x56 m" R2 l* Q, S4 d6 L
#define IIC_REG_ADR_CR_R      0x6% ]7 w! G, R% p. c
$ V- h0 z: W& [( B3 B" u
//-----CH7301 defines% X7 \/ i, k' _7 t1 R
#define CH7301_ADR 0x76  y$ M+ ]* \& O* L5 r  V9 e# V

* J( Y; J, D  T" S4 ]# l#define CH7301_REG_ADR0         0x49
, A! U' c  Q6 k# n: h0 C  t" h#define CH7301_REG_ADR1         0x1f9 A, N6 r9 S8 o" s4 [4 f0 c$ s; k9 R9 [
#define CH7301_REG_ADR2         0x21. ^. _1 c5 O5 T9 V7 F0 h" Z) ]
#define CH7301_REG_ADR3         0x33
) ~6 W% [0 C6 W4 J8 y#define CH7301_REG_ADR4                0x343 h' w; H' m' |: Q
#define CH7301_REG_ADR5                0x367 J; n; J  L7 B0 K, `8 }
#define CH7301_REG_ADR6                0x1c# h4 b: Q- H  u( Q- N$ s8 A4 L
#define CH7301_REG_ADR7                0x48+ [1 k4 _) L; Z8 W5 b1 j
+ u7 W" B5 x" ?: I; P) ~
#define CH7301_REG_DATA0         0xc0
6 I% y4 L9 F* l" _+ F#define CH7301_REG_DATA1         0x98. z; x( X( B9 [$ f1 D1 L2 ~4 g
#define CH7301_REG_DATA2        0x09
7 ?8 h1 y: c; H5 k#define CH7301_REG_DATA3        0x082 V2 b0 a' [! g( y; ?
#define CH7301_REG_DATA4        0x165 }+ ^; {3 c' p
#define CH7301_REG_DATA5        0x60
& }# Z- U4 @  @7 s! N#define CH7301_REG_DATA6        0x00
& a. ^: F$ S1 g( C5 d' |#define CH7301_REG_DATA7        0x19
  S9 g7 I3 {( Z2 D+ a& R1 x+ `$ x* V7 M / n/ Z# Z/ J$ H2 [
//---VGA data structure0 O; z& Q5 L7 M- y- f4 Q
typedef struct vga_regs
, I& e4 f3 F& E/ M& t8 p{
1 A6 H1 U$ n+ B! T4 [        unsigned int ctrl; //0x0
+ C. P8 S9 |# D2 o$ ?# U  U" k  T        unsigned int stat; //0x43 i+ h& i3 M0 _! I" Z7 }
        unsigned int htim; //0x8
) Q, b! @# q$ `3 W% Y, C3 D: H0 i2 b        unsigned int vtim; //0xc( i  l3 L, a& n  X3 M3 t3 r
        unsigned int hvlen; //0x10
* U  y% r' P% c        unsigned int vbara; //0x14
9 S5 g' |) e: [        unsigned int vbarb; //0x182 F9 c2 ?7 p+ O+ j$ H
& ?; n" ?% \) ~. A& f% {
}rill_vga_regs_s;* U+ f4 u$ F! V% e: n

. G3 v7 t* g5 _& F: z; `& A * a) l: R& }/ f" H. c) L$ Q, |
//----I2C core data structure 5 n$ h/ u2 r: Z, f5 B; t
#if 0
5 L  m9 _5 X; y) H0 Otypedef struct i2c_regs/ r* v4 R( ^+ Q; t! b6 x2 h) k
{
, x4 ^6 x1 c! G* j1 a! L% L        unsigned char prer_lo;//3'b000
5 a# b2 l- Z/ T& h        unsigned char prer_hi;//3'b001
% N- E' l8 N2 O' H        unsigned char ctr;//3'b010( `7 a8 m0 B; W6 o1 L
        unsigned char rxr;//3'b011( }1 l: o( `& U' d- A
        unsigned char sr;//3'b100
9 a5 M5 Z6 e4 a- V        unsigned char txr;//3'b101
- Z, c5 @5 p0 k5 O* F        unsigned char cr;//3'b110, m2 t" B7 m/ @% u, P
}rill_i2c_regs_s;* }/ R$ M" M$ {& q! O  m
& N1 I9 I0 M6 C9 X
#endif
, e, w3 ^( ~* ~6 p) ~$ ?//===== funcs2 r* P! V" m3 o. M- n- g9 H
7 {7 [# i+ R8 O$ W, z# i. ?
/* The vga interrupt handler. */( W) A& \3 d7 M6 \$ E- F9 c- o$ H% W3 Y
void vga_interrupt(void)$ G1 r: L) K. `8 o: Q
{
- L, C% G) n& _3 u( d        int i = 0;
/ R! ^- W, r4 S" h        i = 1;6 J0 v9 f" U2 i: z& K5 ?; ]
        return;; D( l( m8 s# [: P+ S  ?- n2 z
}
+ y1 z8 K1 \" f2 j3 h" H" W" @% f : h( u. ~. k& l/ @! `& j

& D2 n6 n" [8 {" `. dvoid my_vga_setup(void)* l. g6 u$ ?$ Q* F6 q; g
{
2 j; {& I; `( z8 y6 s1 D- i2 X        volatile rill_vga_regs_s * vga_regs;
! Z. f6 W3 d0 e8 D: C; t        unsigned int thsync = 127;
* ]9 s3 \. ^, e3 [8 o        unsigned int thgdel = 87;
6 Q$ A4 W# m( x' y1 _: u        unsigned int thgate = 799;) X8 E- {, B4 ?: t& N: S
        unsigned int thlen = 1056;
& X+ G6 V: a: Y5 J, R        unsigned int tvsync = 3;+ l: I0 [  c) k7 e2 w! f
        unsigned int tvgdel = 22;% e; g$ L5 r. s0 a: I
        unsigned int tvgate = 599;- ~2 X. K$ [0 O0 Y& E
        unsigned int tvlen = 628;/ }$ |* a! f- T. U5 d7 Z/ r

' S$ j+ R% ?5 X        vga_regs = (rill_vga_regs_s*)(RILL_VGA_BASE);
& A* k2 S2 M2 ^+ O6 x- S          I; p( b  r9 q" ?4 P1 n
        /* config vga regs*/* P' ?7 K0 I# @1 S
        //==1==-> stop vga core
! [" @6 o, j  O4 a6 u& G$ O        vga_regs->ctrl = 0x0;3 h/ D$ Z! ]6 w6 n7 N
, u; ~/ R4 J2 M
        //==2==-> set vbara reg:0x
; \2 u( n) h! R9 j        vga_regs->vbara = FRAME_BUF_BASE;6 V/ O3 n2 P: P# f# F" j
9 Z6 a2 R4 V9 `
        //==3==-> set vbarb reg5 w% {& P% {' @; V$ V: n- k5 w
        vga_regs->vbarb = FRAME_BUF_BASE + FRAME_BUF_SIZE;6 T" c, ~8 t. d1 J1 ^6 s

. |1 `- y0 V7 Y( w        //==4==-> set htim reg
* S" V0 J+ G$ p0 v7 w7 C        vga_regs->htim = (thsync << 24) | (thgdel << 16) | thgate;) G8 d: Y# e. C) o
        //==5==-> set vtim reg
  T* Y6 s2 f) |# e* R        vga_regs->vtim = (tvsync << 24) | (tvgdel << 16) | tvgate;
- o, G8 |7 U* _/ P% M        //==6==-> set hvlen reg
4 D# H7 W  X% t" K. w+ N3 [, p        vga_regs->hvlen = (thlen << 16) | tvlen;
8 B! P8 S$ H3 D        //==7==-> start vga core:0000_0000_0000_0000_0000_0110_0000_00012 Q  K: |" b6 e
        vga_regs->ctrl = 0x621;
4 S& b9 t% c1 |+ v' [) o: H0 } + A! v+ T" e+ \4 I# f9 P
. G' _( N6 @: A2 H
         return;
0 C9 }, p! G+ `/ w) C. y}
7 |0 P. f* h3 Y! g5 o: l; C
* r9 [! X" G0 e% l  R: T5 m( {- ^ 8 O) @4 U- W% F+ e
+ I& F- v# D& _
0 B* m: u, i; R+ _' x
: O0 O& k- y3 ~3 m2 a

2 @! v, F: h& e& B: @! R5 i0 k3 Ivoid i2c_reg_write(unsigned int reg_wb_adr,unsigned char value)6 Q& t* C* ?1 k3 `
{9 D$ o6 ?9 t2 N5 e% |
        //volatile unsigned int * i2c_reg;# q* m! I9 c9 F1 w( r
        //i2c_reg = (unsigned int *)(RILL_IIC_BASE + reg_wb_adr);; @$ E4 [$ _! K8 y
        //i2c_reg = value;
1 M% D' K, T; m% s        REG8(RILL_IIC_BASE + reg_wb_adr) = value;( d  g" X# \/ p
$ \) |! ~+ I& Q; ]3 D
        return;- y& x1 W4 T5 K7 ~
}
7 u$ R' \) q2 w! m 5 y5 x) S& ]: j" @; D" P
unsigned char i2c_reg_read(unsigned int reg_wb_adr)& R% I+ J" q' d7 J: F. Z  v/ u' u
{
/ T# ^' F! p) }' B( o) {        unsigned char ret = 0;        
$ O" X7 t/ I; G. i+ s0 z1 ^) o        //volatile unsigned int * i2c_reg;
. j9 t& o7 B, _" q; D9 d        //ret = (unsigned int *)(RILL_IIC_BASE + reg_wb_adr);
8 L' \! |1 i5 ?4 p" S6 f * N3 H9 h# O1 I+ }
        ret = REG8(RILL_IIC_BASE + reg_wb_adr);
1 a0 C2 n& J  X  p" J& q        return ret;
: y' l* E: ]( t( m% Q; a}2 H7 L! P: c6 ~' b1 Q4 w+ Q* ~
" Y8 C' j$ u8 a/ ^
8 g; [1 [" a& C* p, n6 F

# v; C1 E$ r% Fvoid i2c_wait_ack(void)( ]& r2 t# s4 M9 e8 o
{& O  ^. j' Y; M0 R* A5 G. e
        volatile unsigned int tip = 0;//SR:[ack_from_wr,busy,sl,0,0,0,tip,irq]! z6 n: [, u( j0 @! `& w
        , ^. J: X# a$ ~8 Y
        do
, E4 P" W# D  b% P        {        
5 D. _4 o0 [8 F" {4 D; P( A                tip = (REG32(RILL_IIC_BASE+IIC_REG_ADR_SR_R) & 0x02000000);2 s5 t( ~2 V  h% w- T( o
        }while(tip);, x0 x+ }9 x! F
}
7 T" B2 y# Z( C$ V, D/ z& @ / i% h  E9 Z/ M+ K0 C$ r% J
void i2c_write(unsigned char i2c_adr,unsigned char data)
, ^0 g/ O7 P1 A' s( F{
/ x) {$ Q4 m# H        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) & 0xfe);//present slave addr(ch7301,0x76),set write bit. J3 h# ?! L4 j* X5 b
        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);//set commond(start,write),CR:[sta,sto,rd,wr,ack2rd,0,0,iack]: C  |7 n/ f  v
        i2c_wait_ack();! w2 U6 i6 `9 @+ y
        i2c_reg_write(IIC_REG_ADR_TXR_W,i2c_adr);
: Z) ]. Z; I8 b7 q% J! }) x        i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)
- s* o/ J9 n* G        i2c_wait_ack();: |( {9 i6 Q7 m9 s( R& i7 u) V' F0 a' ?" y
        i2c_reg_write(IIC_REG_ADR_TXR_W,data);
: o  Q. ]. a, p+ t! t+ k        //i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)
; h; D# ?3 t" I7 k; J) _        //i2c_wait_ack();
$ l, c( C# S/ k% h        i2c_reg_write(IIC_REG_ADR_CR_W,0x50);//set commond (write,stop)' N- x* U  G$ V- [' `* H, E3 k
        i2c_wait_ack();
2 I) |! O- y9 d+ J        return;' i. i" F% ]) A) ~1 r6 E. F
}
5 [; B5 _! X. g5 zvoid i2c_read(unsigned char i2c_adr,unsigned char* data); s+ \6 t1 ?4 \5 o4 ?
{
6 c/ Y. S/ L1 T& R' M( m  ~+ E        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) & 0xfe);//present slave addr(ch7301,0x76),set write bit  h; G" L( P. @- C  j
        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);//set commond(start,write),CR:[sta,sto,rd,wr,ack2rd,0,0,iack]
  @- U+ y6 U6 s8 `' h        i2c_wait_ack();2 d) k" @) i+ w: z
        i2c_reg_write(IIC_REG_ADR_TXR_W,i2c_adr);7 {) o  c  ]: i7 ?" W
        i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)
/ s- w* ^( I* X6 O        i2c_wait_ack();
8 {6 L; ^6 v+ {/ s7 F0 Z% _6 |6 r        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) | 0x01);
+ [: M5 w2 y7 b7 Q& v: `        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);/ b5 J- V+ g7 h9 |2 x$ J
        i2c_wait_ack();
' {$ M$ F# O, ?: z, i2 w        i2c_reg_write(IIC_REG_ADR_CR_W,0x28);//set commond (read,nack_read),read comolete!
! W, D4 f$ \& _, s; W0 v7 s- R        i2c_wait_ack();6 B9 [8 t# \) |% l8 b+ v# z4 r
        * data = i2c_reg_read(IIC_REG_ADR_RXR_R);
! |. d" o  B% f. T! b6 `4 D& E        return;+ A* E1 }% {( |4 A* I3 ~
}( V5 J* g# f* J* L
void my_i2c_init(void)
2 s8 G! l/ ?9 n5 o, ^. B: ]3 e{5 H# h) E* a& w0 {7 M4 I/ w
        i2c_reg_write(IIC_REG_ADR_PRER_LO,0xff);//load prescaler lo-byte0 T) g: W; G4 N% a0 \
        i2c_reg_write(IIC_REG_ADR_PRER_HI,0x00);//load prescaler hi-byte- p9 m# D  o7 B6 Q* T
        i2c_reg_write(IIC_REG_ADR_CTR,0x80);//enable core1 @; Y  R- _4 A' C- {
        return;5 D6 p" f& X, ]1 j, s4 N
}
2 z6 m2 }4 |) h* Cvoid my_ch7301_init(void)2 z6 m) M" A) }# N/ I
{4 U- b: B- F$ c& q+ t* S: X( Z$ l
        unsigned char data = 0;
) }$ `' M3 R2 {1 l: Y5 l) ^        i2c_write(CH7301_REG_ADR0,CH7301_REG_DATA0);& z8 ~" k! |6 ~7 |- Y
        i2c_write(CH7301_REG_ADR1,CH7301_REG_DATA1);2 G( m* c3 g. K! d( j
        i2c_write(CH7301_REG_ADR2,CH7301_REG_DATA2);5 u/ y9 o4 e8 u9 Q& ~' ^
        i2c_write(CH7301_REG_ADR3,CH7301_REG_DATA3);
* t* P1 ~% Q$ F5 G1 t        i2c_write(CH7301_REG_ADR4,CH7301_REG_DATA4);2 `8 {* C( j; h: B
        i2c_write(CH7301_REG_ADR5,CH7301_REG_DATA5);9 X; Z: {3 c$ t9 L$ T
        i2c_write(CH7301_REG_ADR6,CH7301_REG_DATA6);2 {3 u% K6 i/ M$ r% y2 P
        i2c_write(CH7301_REG_ADR7,CH7301_REG_DATA7);
( P7 Q. P6 y3 ]2 f2 i( g$ a- {        //read ch7301 data back
) u; j' A" b: ~& Q8 q* j        //i2c_read(CH7301_REG_ADR0,&data);* [. F: ^# {7 b! t
        return;
# o) E8 D! z/ b9 U}
4 ]2 _: z/ S( Dvoid delay(unsigned int delay)& q9 F3 x% v8 E& J- E& F  Q- \: f" b
{6 R7 g6 z: x5 k
        unsigned int time;5 ~. d' P- b; m2 p4 l. k0 o
        time = delay;
, c% C) J% ^$ z) {" H) J+ F5 Z        while(time--)+ K1 N# W8 [0 x( T0 J% Z+ v* G8 G! \, q
        {
8 I9 L6 L1 r2 _                while(delay--);
* S9 ]( |) H/ k! V        }
: q! E, K6 C, @7 f$ l* P: ?$ `        return;6 [* V# E( d" h: a0 E
}
9 d! n" C& j0 d4 N9 b  ?void my_i2c_setup(void)
% |( r, C4 S& ~0 E0 |( i' Z4 \  {{
6 m; b+ C; T3 t        my_i2c_init();% s6 t+ Z5 d/ U& z0 z
        my_ch7301_init();0 i3 M8 u" B. s& ^9 k: r  L
        
1 Q* i# q* {: x  n: [        return;: F# Y  C! Q1 b& H
}) q" F% Z1 [1 |" E5 v7 w
int main (void)
5 y7 P# k3 N. n{
' s4 F3 b5 s  P4 J          /* Initialise handler vector */! D7 n! b# B, W
          //int_init();2 h9 D6 S8 W1 W
          /* Install ethernet interrupt handler, it is enabled here too */* ]3 D" ]1 F' ^. }1 z* X0 |3 S3 e
          //int_add(VGA_IRQ, vga_interrupt, 0);
! h1 ?, J7 e) \" P          /* Enable interrupts in supervisor register */
* P/ e  A2 r+ b, k! l1 J- M          //cpu_enable_user_interrupts();, [4 }6 G0 C, M& l  S/ w8 }4 g
        uart_init(0);
( W' D. f  b$ C; i        printf("\n\t <1-> uart_init done!\n\0");
% k; l  `0 o- [! P& m# z' L
7 T& m( ^7 C% k) A# h        my_i2c_setup();/* configure IIC & CH7301*/! d! V- M, O+ w( E( \8 t
        printf("\n\t <2-> i2c_setup done!\n\0");+ L( u' O5 Q9 {" Q3 w
0 ]" m! u8 Y9 c! o
  my_vga_setup(); /* Configure VGA */
# X! a7 G. N+ B- w) L1 n$ `) N        printf("\n\t <3-> vga_setup done!\n\0");
& r& g. H) z5 F1 ]$ `' m  \0 ] 4 F% t; I8 R7 q1 C& G& g% L
        return 0;6 M( z4 c2 j- u: C# E% z
//         exit(0x8000000d);& Q, x# G5 b) `% I  Q
  " D& ?( f8 N1 m. E
}
4 p4 ~2 _, `! z! M' O+ U+ ]" B& o
# g6 m5 A9 g) T2 _8 U9 T& Y2 ]# Z1 t

4 D9 ~4 `5 H7 q$ p1 f1 B: [makefile:
, _' K$ z8 s! _& v! `( q4 }$ ?3 r* _# Set the path to our board's root directory
( @# ]  z) M8 q1 F* kBOARD_SW_ROOT=../../..
8 ^6 p4 u& u+ O7 j0 V( Z$ H' X . i, f, Q* |4 _. n8 n4 B
include $(BOARD_SW_ROOT)/Makefile.inc
4 a0 {& h0 M9 F3 t% Y$ _" e: y. t' d
" I$ e9 v' E$ u7 x0 P, u% Q%.dis: %.elf
- u$ B5 v9 g( N9 z6 ^+ L        $(Q)$(OR32_OBJDUMP) -d $< > $@. O; H3 q7 p1 y1 b! ^

+ \' K1 l2 D  o/ E  Z%.bin: %.elf
8 r. g5 G" b$ Z* g0 j: A3 r3 n        $(Q)$(OR32_OBJCOPY) -O binary $< $@! G2 r# I: U8 f( j; u+ N- S

& C" Y$ D; c' k9 ]1 pclean:/ o5 K) y! w  a' t. R
        $(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis4 s  x% ^9 ^, I

) Y  M. M' K5 c$ \
( T% u: U/ J" F/ r( E
) ]+ h  h8 P: s, L  S' u) g2 v" _( Z4 K! D1 A
4,RTL仿真
" U( Z- V3 J: K5 A! Q在下板验证之前,强烈建议先进行RTL仿真。
$ A, E: n" K0 O9 D0 E' G; ~6 F7 I: G- F8 A
在搭建好仿真环境之后,我们就可以进行全系统仿真了,步骤如下:# V1 k/ _: F. @0 c, F5 _' ]
$ d0 B! Y. Y! B
a,创建软件仿真目录和软件程序' y: A; x! b% E

, i8 N8 |# \- a1 y
1 c* ]- X7 v; X) k. Gcd ~/soc-designed/orpsocv2/boards/xilinx/ml501/sw/tests/- N* ~8 `6 }* U5 j
mkdir vga& v7 w6 i; v4 E% K( @
cd vga
- u) J0 u1 \# [8 T7 Wmkdir sim
) m7 H2 R0 k9 Q8 g8 L# ycp /path/to/vga.c /path/to/Makefile ./$ a3 l+ t  s% Z0 Z: [/ h; \1 P
. ^4 e# B7 Q  G$ I' c
效果如下所示:7 H7 @: C' V6 f
其中vga.elf文件使用“make vga.elf”命令产生的,在下板验证时使用。0 k; q, e6 ^  u% a6 S: L; \
# I, g" ]/ I. o! }/ F4 E* h+ F

9 x$ J: L- ~; ]6 c" O/ i
& O" E9 R7 d8 G4 K$ o" m+ A
) X( m: e9 C# d) Tb,开始仿真
; y& v& ]: `1 q6 I2 qcd ~/soc-designed/orpsocv2/boards/xilinx/ml501/sim/run/
% W  S$ F, f4 U- |" Smake rtl-test TEST=vga VCD=1 PRELOAD_RAM=1 VCD_DELAY=xxx_ps END_TIME=yyy_ps
6 f/ g' z' C2 D6 ]gtkwave ../out/vga.tar.gz
) S- j! h& S' d: X3 m6 K+ W9 v9 e" q" L* O) e( k+ `! ?8 R
其中“TEST=vga”是指定本次仿真所使用的软件;“VCD=1”是指本次仿真将保存仿真波形数据到VCD文件;“PRELOAD_RAM=1”是指本次仿真将从RAM开始,具体请参考bootrom的相关代码(board.h中);“VCD_DELAY=xxx_ps”是指定VCD数据保存的开始时间,单位为ps;“END_TIME=yyy_ps”是指定仿真结束时间,当然如果软件指令执行完了,但是仿真时间还没到,也会结束仿真,可通过修改or1200_monitor.v中的相关代码来实现指令执行完之后等待END_TIME。% z2 B" `8 V: Q5 G  h% K+ `
在仿真结束后,在../out/目录下会生成波形文件,通过gtkwave既可以打开,如果vcd文件太大,可利用modelsim的vcd2wlf工具将vcd文件转换成wlf格式,再用modelsim打开查看波形。仿真时间和转换时间都比较长,请耐心等待。( p# y" i$ H- ^! m0 S  G$ e$ i

. h5 ~+ l7 `( o  j& G" a. [5 e) f
( C1 Q3 j  n! t/ o; M2 t% g  E! ?% ]' [: ?
c,查看波形; D6 G. \9 Y; {: ^1 ]
通过gtkwave和modelsim,产看vga和i2c_master模块的相关寄存器和端口输出,确定没有任何问题。( Q& F! j5 e6 w# Z3 K3 ]

2 d/ o( e2 D6 A% P! g5 e& v当然,需要注意的是,如果想仿真,就需要在bench的顶层模块例化i2c的仿真模型。
- W* R: n  ~3 r3 q" D
& }! c/ `6 F# T2 b' @1 i- c' @4 `

* y( ?. ^: U' \& i) J# l$ [: d9 G9 g# k/ b1 td,可以直接使用的工程
+ j0 e. O6 R- O( u- ^. _
8 U( k! }2 c' ^% B4 h  U+ }4 a6 ]5 }
6,下板验证  @9 F; z- v0 M, _! [8 {- l( K
在RTL仿真并确认没有问题之后,我们就可以下板验证了,在用ise综合之前要先给vga和i2c模块分配对应的引脚。
" x! q) M/ j+ ?, y+ H1 I  z; E1 A: \, t5 K5 E. g
并将板子的DVI接口连接到显示器。
/ E! J' n- d$ u
, r& b% [. h0 T# s综合完成之后,用iMPACT将bit文件下载到ML501开发板,运行adv_jtag_bridge,运行or32-elf-gdb,将vga.elf下载到内存,并运行。
2 `6 d; r: A! ~* U0 c% c' l& P! T% a. l9 R- k0 o% s
这时,我们就可以看到显示器的输出了。下图就是我的运行结果:
0 }, V. Y  Z$ y+ W0 e9 ?) Z3 ]1 I6 `& n7 K! x

& n  B8 j+ i0 L/ k" J) N% w2 I- D" d
- `* H1 @8 ~1 X" P

# _  K9 j" F8 z需要注意的是,如果这时你连接了ML501的串口到PC并打开putty的话,你还会看到如下打印信息:0 w. J( C" s" x. Y  x4 m6 T

% B. A, T# M( `
- V  S* G+ T9 z) X: K; D* x; w
# r) ]5 r: C" O' S1 c% L7 f6 n, G0 ~  F4 O( U' }

0 e7 n! }% e$ i* }! |这说明,我们添加的vga_enh模块,和i2c_master模块都work了!!4 C' i6 ]9 I2 W  ]/ \7 {
# ]7 b9 E# W0 P' M8 D
0 l$ T. I6 g8 W/ U" j
+ u4 y+ n4 c5 L; ?
3 ^( b5 |9 r+ e. ?9 s& a' j6 |6 Q
/ |3 v/ c0 K) o1 b* C
7,小结! ]4 t2 p' w4 y6 j
本小节,我们向ORPSoC中添加了vga_enh模块和i2c_master模块,并经过了仿真并最终下板验证。1 |# H& A4 ]2 Y$ N  E
  • TA的每日心情
    慵懒
    2020-6-13 15:46
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2020-11-13 15:23 | 只看该作者
    添加VGA和I2C模块到ORPSoC并测试验证
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-11-24 21:10 , Processed in 0.187500 second(s), 27 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表