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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
本帖最后由 qsoiuwisjiuw 于 2020-11-13 14:31 编辑
7 y3 l/ ?3 t. e; ]$ k4 `
/ d, f: j  E2 ~1,实验步骤
7 m9 k2 _& M5 P% F" K本小节,我们将vga_enh模块添加到ORPSoC,进行RTL仿真,并在ML501开发板上进行验证。大体过程如下:8 ^0 G4 h/ u8 {" V7 z5 b' T7 ~
& o, m8 S% c- L3 t( ~( e
1>修改RTL代码,将vga_enh模块挂到ORPSoC的wishbone总线上。( I! h- O" E% z2 l$ k

+ M- J. _4 ^: }4 Z2>编写裸机测试程序/ M: W: l! }7 M8 W

, H2 j( Q' F# z5 {+ P9 h3>仿真
+ _" O) I5 [) l1 t- O6 ]- s1 Z& B+ c0 _# c
4>下板子测试
4 q! \( I* @- r4 g
) ^2 b# T9 f; ^# {3 B9 p
: ^' A" U! l) Q$ `3 `9 r$ @! p$ @; I
2,修改RTL代码
$ h( L( s9 P2 A+ }/ J5 f- A在修改代码之前,一定要先把ORPSoC的结构弄明白。
$ B; B$ q6 k1 O6 ~; s
5 e- S& ?* M8 v6 F( j: X% Q如何将vga_enh挂到总线上呢,主要有两种方式:其中一种方式是将其master接口挂到dbus_arbiter上,另外一种方式是挂在ddr2的控制器上。两种不同的挂法,示意如下:# {- @; z6 A3 z- `% G
9 \9 G+ Z2 ]" {
挂在dbus_arbiter上:9 ?: {0 ?. E" E% p
) J" O' S9 R. q) n' z) C1 _

. a7 H2 L. x, ?0 V6 O& X$ U$ U5 L3 ?  q5 \. Z
+ ~0 l2 m( H3 A+ h; o  ^

, \, a: J: O; v: G3 @2 i3 @9 E( u! f直接挂在ddr2控制器上:: q1 n; w3 F' Y) ^0 M  H7 }8 U

& o5 y6 a. K7 b: e6 m: R8 T, B" p
' y. `# L3 f  e& B5 S& r
, r7 @* `5 ^, k' `, O/ p1 Z& h7 t& u# p9 i' h; F0 h  [

- o. [3 i* _: M) F# C7 ^: {这两种方式都算是DMA,我们这里两种方式都支持,两种方式通过define语句决定。暂时选择第二种方式。
3 C' t' _  l* h" \9 v, j
0 @. S: Z0 r2 B当然,无论采用哪种方式,其总线地址都是唯一的,我们这里分配为0x97000000.6 i6 o; R  W$ V9 \9 }8 U) q
0 D) G( q- b3 W- T0 D% ?
, z1 I+ x* W& Y' {
/ F4 ^7 d' e; v+ c0 t
其实,对于ML501开发板而言,其本身并没有VGA接口,而是DVI接口,由于vga_enh这个模块不仅支持VGA输出,也支持DVI输出,但是需要注意的是,如果想利用ML501的DVI接口输出,就需要配置ML501板子上的CH7301这个芯片,由于配置CH7301需要I2C总线,所以我们除了想ORPSoC中增加vga_enh模块之外,还要增加i2c控制器模块。
/ _9 r# p' g/ S3 m3 r) c: ~' y: e
ORPSoC本身包含两个i2c_master_slave,为了简单起见,我们将其中一个替换成i2c_master。
! h) [/ v& a) y4 h' Z+ y) z3 r( Z( f: i* R1 E, E) {, K) J. ~

1 |- V1 _1 g& X7 S$ N
3 [; I, L# F% q0 @! t1 j
' k. h1 Y" u# M+ M1 |, t0 K. z+ O3,编写测试程序, ~3 a( ~8 `3 N
无论是进行RTL仿真,还是下板验证,我们都要先编写相应的测试程序。, a% p% T. n! W

1 y3 x4 {* p; Nvga.c:- t9 o+ P9 O( Y: e. h& W
5 M& p7 m( i. I
: l. t$ N4 s  ^% N; D5 g

3 K$ A: l+ D. t# C/*
" z7 J8 ^; e/ |5 c' q* file name : vga.c
# H: j6 S) e4 f* function  : vga controller test
8 K, o5 i( W& R# u* date      : 2014-01-10  Y% h! T8 j6 S- g8 A0 q
* author    : Rill
% L6 F/ H% J- ]( T- O/ z*/+ e% ^$ L+ R9 ^3 ]( G; k
/ o% D  q+ D, x
#include "cpu-utils.h"
  K) _! X8 z# @* Z: m" u% W#include "board.h"1 v9 t4 H# |$ E
#include "int.h"+ i  l8 Z( T( S
#include "uart.h"
. F% e5 B, L3 @/ n9 A1 z0 |#include "printf.h"
) d- }6 p. q0 a& v" t, J% ?$ S/ R / X/ ?: E4 p( P7 \, m' v: ?
//---VGA defines
0 I3 J( ~0 U2 W" Y+ z#define RILL_VGA_BASE 0x97000000
: F6 Y' }- A2 s! h+ G8 a# @% ?: L8 x9 b#define VGA_IRQ 22
" \: V  }" e( }8 y4 F( F" e1 y+ C0 c#define FRAME_BUF_BASE 0x0  //30MB
4 {7 z2 U; V+ x6 M#define FRAME_BUF_SIZE 0x1000
" N: e% a9 ]: ~& {- s* ?- c, P  Z
. b; ^9 t2 k5 t3 Y- d; }& k6 y
. G- F& n- B0 T* K' ]9 I1 }( w//---I2C core defines
1 a$ z; g( q- `' l#define RILL_IIC_BASE 0xa0000000
# r' \& h! S; U#define IIC_REG_ADR_PRER_LO 0x0. [4 \3 S  ]# j
#define IIC_REG_ADR_PRER_HI 0x1$ G- N# @2 Z: N, I/ m% w) _
#define IIC_REG_ADR_CTR            0x2) O# h3 C$ O% q) w! K# a0 {
" ^4 O/ l& M* J
#define IIC_REG_ADR_RXR_W     0x3  E# u! O: ?% m& H) d) J
#define IIC_REG_ADR_SR_W      0x4
1 E* z2 n8 R  y4 E#define IIC_REG_ADR_TXR_W     0x3
+ G& R: K' G- q9 V4 W" k#define IIC_REG_ADR_CR_W      0x4
& c; u7 f1 E2 I% H! W 0 l4 k% J; E; ]- C  ]
#define IIC_REG_ADR_RXR_R     0x3
, x$ b, Z6 B3 J- m; c#define IIC_REG_ADR_SR_R      0x4
1 S% k5 W9 b: j6 P  r#define IIC_REG_ADR_TXR_R     0x5
6 U& p; L. M9 e* z( j4 z#define IIC_REG_ADR_CR_R      0x6
& @8 X& C' l5 u 0 v0 g* x6 I( p4 `2 p" g  ^2 @! p
//-----CH7301 defines
# b1 Y$ \9 O0 _3 ~#define CH7301_ADR 0x76" V# q  f# X  ^) D
$ @; ?( R5 C+ z: o
#define CH7301_REG_ADR0         0x49
  r! g( Q% N7 O2 y% l  p#define CH7301_REG_ADR1         0x1f: o+ k( F: B( X# g+ @( r
#define CH7301_REG_ADR2         0x21
. K7 I. F" p5 d' y5 w#define CH7301_REG_ADR3         0x33
. O9 ?9 T% z: A& z7 i* W( Y6 O#define CH7301_REG_ADR4                0x34/ H9 }" l7 X' x+ N3 g
#define CH7301_REG_ADR5                0x36* W& _$ u# a1 u3 m$ v. m2 y
#define CH7301_REG_ADR6                0x1c9 e* T- Z. x& y' H1 W- R
#define CH7301_REG_ADR7                0x48
, ?# a. u' Q3 \4 ?  E4 T % c, a" W9 n9 y2 H/ P
#define CH7301_REG_DATA0         0xc0/ F" x' s8 E( ?2 _4 q. [5 N' O
#define CH7301_REG_DATA1         0x98
( I( a  F# v. M5 S  y8 A7 Z' g  n1 R" n; G2 [#define CH7301_REG_DATA2        0x09
) i3 V7 M( u' i8 o- Z1 e#define CH7301_REG_DATA3        0x08
1 r9 \1 i  M$ ^#define CH7301_REG_DATA4        0x16
9 D$ X6 l: }+ m#define CH7301_REG_DATA5        0x60* [* N% S4 u' d8 S3 }5 C1 u6 n
#define CH7301_REG_DATA6        0x00
$ z$ T  X# H! N5 @#define CH7301_REG_DATA7        0x192 H1 Z6 W* M( z# e' n3 {

4 m$ v& R" s" D, B8 I3 u//---VGA data structure
* y$ f( O: W( N. V& O( ltypedef struct vga_regs
% @$ m& Q% B* A. C{
% g' h' \, r9 Y3 B        unsigned int ctrl; //0x0* y6 i7 o3 v2 a7 Q# S6 T2 G: M
        unsigned int stat; //0x4
& R$ N4 z/ H8 h3 o  x        unsigned int htim; //0x8# m3 n& q5 a8 Y8 b2 I
        unsigned int vtim; //0xc/ J; K# v# r$ c; s7 {/ U
        unsigned int hvlen; //0x10
1 `5 ]: z4 h8 n# K; q  p        unsigned int vbara; //0x145 T: w3 q+ t: _
        unsigned int vbarb; //0x18
2 N1 m5 ^3 L* F" |, j; l* z; R 3 o! B2 y& Q) F7 d$ u
}rill_vga_regs_s;5 g5 \$ I( N# v1 k: l0 j
+ \! c- o  Z6 Q: J

5 S2 A4 Z# T: Q5 o' R. a//----I2C core data structure ) T9 E  a, U' ?% g
#if 0
/ D- \( Z( D  @typedef struct i2c_regs! k9 R7 x% [2 z& A0 x- Q% ^1 W% Z1 a
{2 f3 \2 z2 t0 B$ b( l
        unsigned char prer_lo;//3'b000
. q2 U' ]! S) G) `" ^2 S4 k( v. g        unsigned char prer_hi;//3'b001) F) }: i0 U( e$ f% S5 i  N) S
        unsigned char ctr;//3'b0109 V4 W8 t+ t8 {% \1 G
        unsigned char rxr;//3'b0115 {- @- i8 ?5 {. F" [0 p+ U: A% x
        unsigned char sr;//3'b1009 j% Z; ?6 H" ^1 S7 M
        unsigned char txr;//3'b1011 [3 d3 N9 l" z
        unsigned char cr;//3'b110) w! b$ ~3 t- J% Y
}rill_i2c_regs_s;
7 q! ?* d& Q1 \7 d: D/ w 9 U2 u) }2 D! D' d( W' y
#endif6 T: X- r; u& E- u) l1 @" {
//===== funcs5 }0 P3 [, x/ [

. \* O8 o2 s2 V: _' `7 X/* The vga interrupt handler. */' i  W; g0 P' @0 B
void vga_interrupt(void)7 c- l+ ^! |& i  H+ p
{0 ~7 V8 G4 d& X& @3 @: x# U+ S
        int i = 0;. C; x2 J  c: F$ ?% I: M! K
        i = 1;
  f' g1 C! |* ^0 Z% u+ H" ?        return;; X" P& f6 t9 W  ~" o5 w
}
" G( L7 {! z# W6 K
1 ?* ^: `* @$ ?" |1 r& h % M, q, Y9 U$ U% J* L+ M# F) [) D# U
void my_vga_setup(void)' C- N- o( M0 O- C; [0 Y
{8 o7 k& w; N3 y
        volatile rill_vga_regs_s * vga_regs;
" L: n$ C. y7 L, R        unsigned int thsync = 127;7 Q8 `. n4 p8 `# W  |4 }
        unsigned int thgdel = 87;3 p3 y' Y9 `$ G8 a
        unsigned int thgate = 799;0 Z) F! a' U! G- O) l: R# X2 O+ Y
        unsigned int thlen = 1056;
. L9 l) g, k9 `9 o2 U- Z) D- ~; m        unsigned int tvsync = 3;4 f7 z; h. A8 l) \9 T. V( R) u3 l
        unsigned int tvgdel = 22;
" ~3 f! u6 U" K        unsigned int tvgate = 599;
$ O+ a* O" k3 ]7 G        unsigned int tvlen = 628;
/ G# [4 [2 O+ a% H- _; s- p/ L, M
0 G- B9 l0 ]1 ]        vga_regs = (rill_vga_regs_s*)(RILL_VGA_BASE);
6 S( T4 G5 Q$ k        6 }) i4 o$ M) V: y
        /* config vga regs*/) A. @9 i. G+ l  n. F4 a# d
        //==1==-> stop vga core
+ ?' p7 O7 H4 m( B        vga_regs->ctrl = 0x0;
/ a# ^( I" C, o# [! v8 _5 s 8 r( ?( l2 z6 N9 F3 d% ^
        //==2==-> set vbara reg:0x
) n/ Q1 O% `7 N; C8 E* X+ y        vga_regs->vbara = FRAME_BUF_BASE;
$ x6 V" C& x+ [8 B# n. X 5 Z2 M; ^1 l  F$ v1 O
        //==3==-> set vbarb reg
+ X( y- h* h# U* B        vga_regs->vbarb = FRAME_BUF_BASE + FRAME_BUF_SIZE;1 K! U" Y/ P( f" u  H! [

: F, Q7 u; y0 R/ [  x        //==4==-> set htim reg
$ H; _! `0 N( @6 _        vga_regs->htim = (thsync << 24) | (thgdel << 16) | thgate;
% W. z* g% I0 y9 N! s5 m! X6 z        //==5==-> set vtim reg$ U. i9 g, a* [  p
        vga_regs->vtim = (tvsync << 24) | (tvgdel << 16) | tvgate;
2 z( W+ o4 j  H6 G$ @* C        //==6==-> set hvlen reg
4 M8 q9 q5 \. i3 d( U        vga_regs->hvlen = (thlen << 16) | tvlen;( p3 E! U$ z; o! G; _: u8 ]1 g
        //==7==-> start vga core:0000_0000_0000_0000_0000_0110_0000_0001
" t9 n! V- @2 k) Z$ b        vga_regs->ctrl = 0x621;! ?0 S& A  C6 F7 Z5 Q
# _  m$ G+ d5 {% k

9 G4 r" s* b8 A8 l: W8 ?         return;5 Z. P3 ^6 ]( m6 U! C: f
}
7 v4 w" \" {6 Y9 n$ t8 D 2 ~; C7 ^6 G8 F" f) h3 A

* G/ j6 B2 N, a' I5 ] 6 m' H6 @+ G0 J$ D* ]

: H" C0 \1 d7 p; e; H- i
2 S7 S* _& ]% q. u- ^1 _/ ?2 b1 a $ p6 y* T/ i% ^: M: g( \
void i2c_reg_write(unsigned int reg_wb_adr,unsigned char value)- k- T& J9 b' z+ G4 E
{
5 h0 L7 f+ U: ]: _        //volatile unsigned int * i2c_reg;8 K9 f: t$ s2 J1 N$ o
        //i2c_reg = (unsigned int *)(RILL_IIC_BASE + reg_wb_adr);
& G6 `8 ^4 G) J! s) t7 |! q        //i2c_reg = value;3 y# }0 ~$ V+ S+ a! i: |4 ~* z
        REG8(RILL_IIC_BASE + reg_wb_adr) = value;3 ~" c3 W# ]% d

. l' V$ Z- x+ N2 ?' Q        return;
+ o9 ?- |% R$ @! o! d}" f5 [4 ?3 [  B' N+ X4 X) O" U7 |% X# A3 f

4 z9 z- {0 J* \, lunsigned char i2c_reg_read(unsigned int reg_wb_adr)
" b; j/ i7 ]0 N8 B% }! e2 f6 D* I  M# ^{# E9 r7 X( o4 \. J  w( S: J
        unsigned char ret = 0;        
$ A; w+ p5 t) m( ?4 t        //volatile unsigned int * i2c_reg;3 |3 l/ d. P  [3 ^# R) H: X
        //ret = (unsigned int *)(RILL_IIC_BASE + reg_wb_adr);5 |0 B3 U* k+ K9 j* i8 X7 ^
4 L' @9 g" E( o8 m1 I+ s
        ret = REG8(RILL_IIC_BASE + reg_wb_adr);
$ {& I9 B; _4 @6 a9 c: s! k" [" u        return ret;, @: F2 R: h  w* S" V
}5 g8 m' {1 ^6 W5 h  d  R! `
7 M  Y$ N$ w8 U( b9 i
+ `1 K$ ^% N' R# Z% W5 ?

% K+ V& ]5 u6 W& U- Gvoid i2c_wait_ack(void)
% B) h# D3 |" t{
& y- \9 B6 U/ ]( F/ G- v. t        volatile unsigned int tip = 0;//SR:[ack_from_wr,busy,sl,0,0,0,tip,irq]5 J" o1 v! \! O9 l0 L, Z
        
5 c$ R4 N7 W9 i$ \        do6 H' C4 O' e' w
        {        
$ n3 P+ B- y4 P7 y* p+ e; x, U                tip = (REG32(RILL_IIC_BASE+IIC_REG_ADR_SR_R) & 0x02000000);/ X1 w( }  G. p( P% Z% F
        }while(tip);
6 ?! U) D$ D4 I) z) v' V  N}
( F, m: c$ h& G% ]% L) p/ P
* N4 x$ l& L( u" K7 Y; ]4 o+ R, Yvoid i2c_write(unsigned char i2c_adr,unsigned char data)- n2 q3 ^/ L; C8 I- ]. q5 F
{
: o  l3 z8 B4 k! p+ Z$ d) X        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) & 0xfe);//present slave addr(ch7301,0x76),set write bit. e; d  D, [# `, C4 K2 g
        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);//set commond(start,write),CR:[sta,sto,rd,wr,ack2rd,0,0,iack]% |& {- l: Z( I( D( r9 M. N; s! T: f
        i2c_wait_ack();
# U8 m; Y0 X3 V. N' O, O- }: {        i2c_reg_write(IIC_REG_ADR_TXR_W,i2c_adr);& F) R; {; p4 |$ b. \& I$ d
        i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)( A* r( O5 `4 v6 v/ t& ^+ W* H
        i2c_wait_ack();' \/ _: b% ^+ Z
        i2c_reg_write(IIC_REG_ADR_TXR_W,data);
+ y3 Z0 ^3 G% k/ X        //i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)0 [8 T4 F9 |0 y: H8 g. c6 r
        //i2c_wait_ack();
) O# r8 a) G0 _1 a8 d# p4 [6 p& a# M        i2c_reg_write(IIC_REG_ADR_CR_W,0x50);//set commond (write,stop)
4 o# E' z6 R8 A4 B, i+ Q; F8 [0 Q        i2c_wait_ack();
7 N5 `3 M: S1 J1 Y        return;4 Z( Y0 b( Q6 X
}
/ T8 a3 k1 D8 \void i2c_read(unsigned char i2c_adr,unsigned char* data)% d. W: M1 \3 F- N
{7 D" j, \5 Z2 `) c9 I; g7 ?' U5 d6 w
        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) & 0xfe);//present slave addr(ch7301,0x76),set write bit
1 g; P3 L6 N9 x- f0 ~& Y. D        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);//set commond(start,write),CR:[sta,sto,rd,wr,ack2rd,0,0,iack]
7 B' t5 x3 A3 z2 J, X        i2c_wait_ack();- B* X( ^0 N% X* Z& X
        i2c_reg_write(IIC_REG_ADR_TXR_W,i2c_adr);, C$ t5 w$ e) q" X8 p
        i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)/ }; C% q4 d/ b0 f
        i2c_wait_ack();
, {7 Y% C+ c" a1 l# X* V" n' p( w        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) | 0x01);
: x9 p) X  ~4 y4 |& C        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);7 H: `) u$ ]( p# ~, Z* l# E& g
        i2c_wait_ack();2 ^: `0 g! ^2 Q0 @( m" f+ L7 N
        i2c_reg_write(IIC_REG_ADR_CR_W,0x28);//set commond (read,nack_read),read comolete!# P1 j; W( o! P
        i2c_wait_ack();1 n' J8 N6 Q! Y1 _7 g
        * data = i2c_reg_read(IIC_REG_ADR_RXR_R);" c5 B3 j# J" c4 p( s
        return;
5 b/ f6 x/ d$ H$ I8 Q# Q7 N4 {}
, l$ i7 b9 x/ [5 Hvoid my_i2c_init(void). U' d) u& ?, {5 y
{+ d: m8 C7 d: L; H4 D' S
        i2c_reg_write(IIC_REG_ADR_PRER_LO,0xff);//load prescaler lo-byte; U3 t: X, g6 @  C$ Z
        i2c_reg_write(IIC_REG_ADR_PRER_HI,0x00);//load prescaler hi-byte# v: o0 d5 V$ ^$ m8 Z( X
        i2c_reg_write(IIC_REG_ADR_CTR,0x80);//enable core
  W# T. E5 t% l, u( i& W: ]        return;
0 t7 v( L& E1 W* K! ~. b}- l6 c: N* y, X- f
void my_ch7301_init(void); S7 r  P9 W1 h/ M1 N" k6 D/ U
{8 r2 L5 G6 F" c' v
        unsigned char data = 0;4 L! w& C3 Z: y$ o7 T9 K# R- f
        i2c_write(CH7301_REG_ADR0,CH7301_REG_DATA0);1 `1 C' K9 c% |! I% b! V4 h9 t
        i2c_write(CH7301_REG_ADR1,CH7301_REG_DATA1);
- {) q3 x- ~8 p. {& Q( s7 k        i2c_write(CH7301_REG_ADR2,CH7301_REG_DATA2);" x1 N3 ^7 l/ P" k! q/ h
        i2c_write(CH7301_REG_ADR3,CH7301_REG_DATA3);
' y! z* X0 P  P4 C        i2c_write(CH7301_REG_ADR4,CH7301_REG_DATA4);
9 l( w: i( c- U. b* E% R* X        i2c_write(CH7301_REG_ADR5,CH7301_REG_DATA5);
- ]- b: f# k' z0 Z+ d3 A8 E        i2c_write(CH7301_REG_ADR6,CH7301_REG_DATA6);
1 J' g. b7 {4 f6 h# v: c        i2c_write(CH7301_REG_ADR7,CH7301_REG_DATA7);0 O6 `0 q( f. @$ c. @+ a! Y
        //read ch7301 data back
; z& d$ E7 ~2 @: ?1 S# T- ^# w        //i2c_read(CH7301_REG_ADR0,&data);
$ N3 o7 B6 q9 J3 C) Z& _4 P" x        return;
4 x; l6 |3 h: K& T8 ]5 E# S}
* K0 W. \9 [" ?void delay(unsigned int delay)
* I) v# z4 Y8 Z$ x# w: l# C! `/ i{, p0 V6 \6 G- |" ]' ]+ M7 |( J) N: S
        unsigned int time;
5 l/ m0 r+ Z3 i5 i  b0 b        time = delay;
: M2 i# f' Y7 x0 u: Y3 [6 K        while(time--)' B2 p) o* ~+ h8 {7 g
        {
) w7 X9 x/ h! B3 x                while(delay--);# b! t+ z7 l; q
        }5 F- c# \  J7 j, i
        return;
0 g" {, K& Z& U# X0 D/ ^}
4 `+ g- G2 }8 g' c$ Wvoid my_i2c_setup(void)
9 C* W. X1 I& D9 `$ v{
/ e! |6 z& ~1 Z: b( F: a# Q- f        my_i2c_init();
+ s& \5 T1 q; G. o8 B- P        my_ch7301_init();$ c$ A  S7 ?" B& G
        * m) u- Z" \: t" m( ?2 q+ A* G
        return;
7 s1 ^% q; |7 n0 @6 O( N' _2 \- V}
6 L; _0 V) }: A$ a$ N2 Xint main (void)
2 V; w4 t5 g8 X$ ^& M{/ A4 J( c1 D9 Y5 A! A
          /* Initialise handler vector */* Q: X# _6 q: L$ `  F) \
          //int_init();7 E# C' [/ [6 Z% E
          /* Install ethernet interrupt handler, it is enabled here too */2 E' L# J$ r) k. t* N/ y1 Z. i
          //int_add(VGA_IRQ, vga_interrupt, 0);
$ d% W5 P8 i0 M; I- \2 R6 V          /* Enable interrupts in supervisor register */+ t5 q% d& ^9 y0 ^4 I
          //cpu_enable_user_interrupts();) p. |9 O- Z, E" e, c5 @* U9 D
        uart_init(0);- P' N" [& S" T, x& y5 x
        printf("\n\t <1-> uart_init done!\n\0");
& e6 `% r9 J/ m 7 b* o! K  h) G" L* \' K) j4 f
        my_i2c_setup();/* configure IIC & CH7301*/+ b( _. {0 p8 U7 n
        printf("\n\t <2-> i2c_setup done!\n\0");, X. f* B5 C6 {- u# S
0 N! Y" d! i2 k
  my_vga_setup(); /* Configure VGA */
8 N2 b* k( A! Y. a  X8 g        printf("\n\t <3-> vga_setup done!\n\0");
: l* q9 @; S  r4 |1 q) w . b% _- U& {$ _0 D( e' c
        return 0;& L5 ]. C% S4 ]- C9 \* Q8 G% K
//         exit(0x8000000d);8 `# I' U8 U; T$ f& u! j
  
8 z( a/ w3 z  [9 u}
) V2 F( P9 M4 u9 t" {  i- E" B. W1 Y- r4 \. P/ t7 t9 b" f' H

( q' Z* s0 H2 _* E+ ?( i5 z+ N5 V+ T9 t
makefile:
, R) e' ~$ w' v5 ]) {  `/ {' @( c# Set the path to our board's root directory+ T1 s/ T4 m, d- P8 D' I
BOARD_SW_ROOT=../../..
& \" E) J& B9 b
0 n: E6 ^+ i5 N) m/ yinclude $(BOARD_SW_ROOT)/Makefile.inc
$ `$ y" K0 A$ Z; w9 g4 m" H & b/ W2 m7 F4 L  z" O
%.dis: %.elf
  z+ B7 R3 W# e. _8 U        $(Q)$(OR32_OBJDUMP) -d $< > $@
: r2 ]7 i6 f8 G; l  v9 m
4 l+ Q; \( u" d0 ?%.bin: %.elf
$ Y6 Q6 ]& S$ U  H        $(Q)$(OR32_OBJCOPY) -O binary $< $@" W+ b" {* P0 S# H
! H7 ?7 L' S  [* F( q# y6 C8 G
clean:& H" {' P) g8 {8 L0 m
        $(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis
4 B: {* Z- o- i) M: x8 T
- s' ~. }1 ]/ A) w* h/ c9 ~7 w* a6 O/ f* _6 F8 R  p- \) [0 N
, E4 @/ q6 m' }+ b1 w  c

3 V1 v( ^7 z" {  p0 c$ O& M2 R: R4,RTL仿真5 V" a  O' H) M* Q" @
在下板验证之前,强烈建议先进行RTL仿真。
0 [$ @/ j( Z) r) @( O# {2 g' Y) v% W
; N: c; h& w3 t5 [8 w0 I在搭建好仿真环境之后,我们就可以进行全系统仿真了,步骤如下:
7 l+ \2 A9 n3 Q: d% g9 E* e6 O8 q9 c, i0 L$ u2 c# u( c' E& H
a,创建软件仿真目录和软件程序
+ Q6 `# p- P* v! p( B1 |6 v% @
# ~) I$ A# I3 v  n& i+ ~% m2 Q
+ P  r' O# m4 a0 Gcd ~/soc-designed/orpsocv2/boards/xilinx/ml501/sw/tests/- r! R5 }+ G6 @) x: J8 Q4 C
mkdir vga( X& A; t2 n& ]7 e
cd vga) E! F' X& `5 J& G( B
mkdir sim% W; I# w/ R2 v5 M9 j4 T
cp /path/to/vga.c /path/to/Makefile ./' C  F% m" O* ~

! ?* H' x9 I, g效果如下所示:( ]0 n# Z& Q/ k% ~. u
其中vga.elf文件使用“make vga.elf”命令产生的,在下板验证时使用。
* H7 f/ Q4 j. G. v7 r% _( x
/ _* ^0 h- S. H$ f4 N# ? : s' l% ?7 U* t* D2 y+ f+ }# Z# z, F

! W( P/ T  G4 ]0 j  V
3 d% z. ?% }$ Ob,开始仿真0 N$ D' L. g$ g( n6 F: m
cd ~/soc-designed/orpsocv2/boards/xilinx/ml501/sim/run/
/ G9 t2 Z' {) H. b6 W3 u2 ]make rtl-test TEST=vga VCD=1 PRELOAD_RAM=1 VCD_DELAY=xxx_ps END_TIME=yyy_ps# D; Q) [2 X- F; I
gtkwave ../out/vga.tar.gz
8 U; w. E( N( C8 }9 e
4 q& c" J8 T* D  ?! i其中“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。
' B. P' t: t6 n( E: V; }在仿真结束后,在../out/目录下会生成波形文件,通过gtkwave既可以打开,如果vcd文件太大,可利用modelsim的vcd2wlf工具将vcd文件转换成wlf格式,再用modelsim打开查看波形。仿真时间和转换时间都比较长,请耐心等待。
+ L2 M! @& k6 H' f# N( h% D
3 g5 }% c6 J/ T9 C3 S
# m# [  p! f0 R5 i
5 V' Z  p' m, j  I6 x: @/ i+ zc,查看波形
- D' A2 V$ t9 N+ W+ Y( J通过gtkwave和modelsim,产看vga和i2c_master模块的相关寄存器和端口输出,确定没有任何问题。
$ W1 F3 t* J9 ]$ K* K& q
3 i8 f3 Q0 }% D5 u, Z3 s% Y当然,需要注意的是,如果想仿真,就需要在bench的顶层模块例化i2c的仿真模型。7 k0 k, e2 I; o8 \  \* W2 H

7 r2 O4 L8 y# x$ u. u( L& G: B2 {0 s( X' z

5 l+ E: Q# W1 ?3 \d,可以直接使用的工程
- z1 J% Y& U0 _+ c- T0 r0 L- a: I* L" J9 F( A* f+ y0 g# I

: q; j. i7 o8 e# ^6,下板验证
% q2 F. }/ a9 R在RTL仿真并确认没有问题之后,我们就可以下板验证了,在用ise综合之前要先给vga和i2c模块分配对应的引脚。0 C! w$ ^+ K* {8 Z6 a
& _# O$ ^4 {9 u" |6 _( |8 R
并将板子的DVI接口连接到显示器。  m8 ]0 ^/ f( ]6 B  S! S
* n8 s6 }5 U; N* {
综合完成之后,用iMPACT将bit文件下载到ML501开发板,运行adv_jtag_bridge,运行or32-elf-gdb,将vga.elf下载到内存,并运行。
( ^- ?( u5 C, @+ u4 b" a
! ~7 t; L9 A6 |/ r0 g* u这时,我们就可以看到显示器的输出了。下图就是我的运行结果:
+ K8 Z" ~5 z5 c7 H' |2 W  C" G) E. S: z- G- W: S  [+ @
. V* L; |7 K4 B8 L

6 A% F- f) ]  `  B( V/ e4 L1 p* @! T) d5 E
; t, \- P6 \) `2 }' ~$ A
需要注意的是,如果这时你连接了ML501的串口到PC并打开putty的话,你还会看到如下打印信息:0 T1 W  t9 H! d) N
! K% `! t0 [5 A  }1 ]
9 M  C$ r; b" a5 i

% l" x" W( `" x# ]$ w
0 M7 b- r4 h2 m1 B
6 d# L# ], v3 Z9 c5 V+ |这说明,我们添加的vga_enh模块,和i2c_master模块都work了!!+ P! ~' p3 V8 K, Z
* G" ?2 a7 ^, J- Z  E
& v0 b' f* _. F+ a

7 D$ ^& z$ g6 t9 l+ O9 q) v( Q
* k' C/ A6 n% r) j: s( K
* d  L! K# Q1 q" {  Z' X- e8 S7,小结) g8 b# a( b$ n8 v" ?. D& W2 F
本小节,我们向ORPSoC中添加了vga_enh模块和i2c_master模块,并经过了仿真并最终下板验证。; @  o# t/ A" y& |( n
  • 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 20:52 , Processed in 0.187500 second(s), 26 queries , Gzip On.

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

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

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