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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
本帖最后由 qsoiuwisjiuw 于 2020-11-13 14:31 编辑 ! i$ p2 S; K& Y
, X3 \& T" Y2 M6 e  m
1,实验步骤
7 o" J$ N# }# s1 w# _4 ?本小节,我们将vga_enh模块添加到ORPSoC,进行RTL仿真,并在ML501开发板上进行验证。大体过程如下:
% ^% r2 @2 M. \# m. q7 Q% D9 `  @; H$ P! e
1>修改RTL代码,将vga_enh模块挂到ORPSoC的wishbone总线上。
/ i% x, ]* C- V3 a0 ?. h; R1 Q4 y0 ?0 s; ?/ M$ ~- S$ ?
2>编写裸机测试程序
  y, w7 H- M0 z" w( F2 J1 F, A" J. [* U. m! s8 i
3>仿真8 z( M$ B) B, N; z8 ^0 ]# l
  z$ T8 l- q$ N# h! z/ U( K* m
4>下板子测试
$ T& ^8 Y" H- I4 ]) I! E* B2 T' n  o8 [( y3 ^+ K* q/ `/ S

# c8 ~. r: w1 @' b9 p% K8 Y, L) c% w3 Z
2,修改RTL代码' y# Z$ H7 k/ @, d
在修改代码之前,一定要先把ORPSoC的结构弄明白。: U# e; p6 e9 E+ x2 U' I
8 g8 I% J2 x3 w$ ]& [( L
如何将vga_enh挂到总线上呢,主要有两种方式:其中一种方式是将其master接口挂到dbus_arbiter上,另外一种方式是挂在ddr2的控制器上。两种不同的挂法,示意如下:
4 l% P/ m, Z+ Q8 B* c; Y5 k. A. s# @. O- X, z% s8 L. R- |: p5 A; k
挂在dbus_arbiter上:; U* N1 w) b, m) A3 t6 B9 _

2 F1 _' ]9 q9 c3 {& G
; F* j- |( u8 Z  `8 R" K/ f, P1 ]* y0 r9 N, D

! Z7 p$ k$ l1 o: @6 p+ }
+ P  a. J( d3 @5 T$ M( \直接挂在ddr2控制器上:
! |& N+ D# a) A0 |$ k, ?+ D4 A6 g8 T" r3 n2 A3 t

& ~3 z+ @  f/ t! u5 ~" V% m  _0 Z) T. P) u4 w2 s
- Z) ~5 ?& N& T1 Y6 k2 S: f- F

9 d7 v4 c' X8 w  b* Y: z这两种方式都算是DMA,我们这里两种方式都支持,两种方式通过define语句决定。暂时选择第二种方式。* B! a! C( \1 }7 `. d& |! i
+ q  R! W' J8 x
当然,无论采用哪种方式,其总线地址都是唯一的,我们这里分配为0x97000000.
+ _* I% n& P/ D8 H1 ^
: z- W0 b- X6 o9 {( S
8 K, y% V1 B5 [( o
% S: }% I8 F/ C$ l* w其实,对于ML501开发板而言,其本身并没有VGA接口,而是DVI接口,由于vga_enh这个模块不仅支持VGA输出,也支持DVI输出,但是需要注意的是,如果想利用ML501的DVI接口输出,就需要配置ML501板子上的CH7301这个芯片,由于配置CH7301需要I2C总线,所以我们除了想ORPSoC中增加vga_enh模块之外,还要增加i2c控制器模块。* F" l6 \/ d$ j1 L8 B

/ g- G& Z/ G- C' {$ GORPSoC本身包含两个i2c_master_slave,为了简单起见,我们将其中一个替换成i2c_master。
/ I; Y1 `) X+ s1 m" {' F0 J3 a8 P8 O. N; B0 t. F! y
- h- F' P" M. U3 B9 }" C

4 r+ ?3 Y, y& @1 A) K
# v' R- S& _* D3,编写测试程序
/ |; H( n& p, e, n! @' ]无论是进行RTL仿真,还是下板验证,我们都要先编写相应的测试程序。% R* M$ o2 m& L: S* }' ^4 H

. I6 B6 n; d" h* E: c) Dvga.c:
) a1 Y5 {5 ]  [0 w, _5 i+ f# D% [- q, X

& c" V( m5 Q0 ^' J" J8 d  s' U$ T; p. Z1 d% t+ A
/*1 y1 ?0 Y7 q  u* F. `+ j. S6 T
* file name : vga.c; X) _! k' a- e" k/ b6 y
* function  : vga controller test% F) z- k2 b0 u/ M$ J$ |
* date      : 2014-01-10# z8 P+ i. z  c
* author    : Rill
9 T" K$ N0 \# O* ?9 Z1 n/ h; Q*/
  n2 k2 [% o; L. \! k! u- q
! t6 _; V: k$ U0 I! D#include "cpu-utils.h"
' ?2 _' l7 z3 Q& w#include "board.h"
6 m9 R. S- d) h+ J1 l" e* q% Q9 }$ C6 J#include "int.h". D" s  A" Q/ X; O
#include "uart.h"0 p! t: {" h/ _' d* Y1 _
#include "printf.h"
! H0 H- f( z5 h' L3 A/ i% R
# A  N) ]# T7 m9 w# }//---VGA defines
: c/ @; W( h3 h#define RILL_VGA_BASE 0x97000000. R. P) P, c4 [
#define VGA_IRQ 22$ o/ I7 m& N- I0 h7 X
#define FRAME_BUF_BASE 0x0  //30MB1 F0 N+ B3 J7 \9 Q6 ~
#define FRAME_BUF_SIZE 0x1000* `, Z0 a  ?  T+ N0 u# e

$ R& k& N9 X# F& q8 b: E + R* D1 w& U+ t
//---I2C core defines3 u) V+ S; t4 ]- [5 ^2 ^7 E
#define RILL_IIC_BASE 0xa0000000
/ L8 m# R4 H: v$ l' t: Q#define IIC_REG_ADR_PRER_LO 0x0
! t* {) o2 @& W5 x' d0 ^" O3 k#define IIC_REG_ADR_PRER_HI 0x1! M2 v5 p5 ]* ^, ?/ W9 C) b6 U
#define IIC_REG_ADR_CTR            0x2
+ g, t7 j0 A) h
6 g" G( p$ K2 Q9 x! i9 v4 O#define IIC_REG_ADR_RXR_W     0x3
8 @2 ]0 T! T1 N4 q#define IIC_REG_ADR_SR_W      0x4  E* d+ f; c5 Y  _
#define IIC_REG_ADR_TXR_W     0x38 l+ M" c: s, f; b4 t/ ?4 x
#define IIC_REG_ADR_CR_W      0x4
; L5 I5 Q7 m9 O; H7 y: a: T
" B; {! s, j; O& e2 V4 O9 r#define IIC_REG_ADR_RXR_R     0x3
: V1 `7 _% H% c; n2 G1 n. y, L#define IIC_REG_ADR_SR_R      0x40 }$ E  _! p* Q7 W$ J6 A( {
#define IIC_REG_ADR_TXR_R     0x5
4 `) k( L& ]. j/ P$ N* j7 v#define IIC_REG_ADR_CR_R      0x6: `2 |( j0 G+ q' p# \
8 f! @! r3 K7 g6 J8 c
//-----CH7301 defines
  M6 d4 T4 [& B#define CH7301_ADR 0x76' B! Z2 p3 E$ F0 f9 F
1 g/ I5 x1 r" f0 ]
#define CH7301_REG_ADR0         0x491 |, }1 ?8 u6 y* M' D* k6 t
#define CH7301_REG_ADR1         0x1f; p, |4 G! [$ B0 V- s  w* Z# W( |
#define CH7301_REG_ADR2         0x21; k' t0 t  |# V" |4 a1 I" ~
#define CH7301_REG_ADR3         0x33
% C6 y; c1 g( Q( A8 i" N#define CH7301_REG_ADR4                0x34
4 c8 A. ?/ \; ^) d* \8 F2 N) r#define CH7301_REG_ADR5                0x36
: x- D& H7 q" P5 |#define CH7301_REG_ADR6                0x1c
! ]- D$ G; [& t$ P+ F+ t4 E: P9 _, L#define CH7301_REG_ADR7                0x488 y, w# L9 }4 P: ], l5 Y; l

- r4 \5 u4 W, g' E$ R% B#define CH7301_REG_DATA0         0xc0: d  C& [( a9 }3 Z4 _: U
#define CH7301_REG_DATA1         0x98+ ?  W. l. D4 x) k1 s: S
#define CH7301_REG_DATA2        0x09/ w& g! b: G$ D% U
#define CH7301_REG_DATA3        0x08
" l- K' M0 L4 N" `  Z#define CH7301_REG_DATA4        0x16* ]4 J1 t- h8 U; @
#define CH7301_REG_DATA5        0x60- E4 r  W3 ?& X( i
#define CH7301_REG_DATA6        0x00! G" ~7 I$ T6 [5 j) G
#define CH7301_REG_DATA7        0x19$ e5 c1 I* t5 h' k

0 u' o, t9 a1 d( z5 O6 W: s//---VGA data structure
# P2 H# }: I5 e8 q* I: Qtypedef struct vga_regs
  Q! K& K/ z2 v# G{
- H0 F& N2 S2 m- x' |" m        unsigned int ctrl; //0x0# S2 H$ C& n8 f  d/ v; _. i
        unsigned int stat; //0x4
& Y6 ?2 S% d" c) R3 H8 h1 v9 b; S1 G        unsigned int htim; //0x8
! [# o2 z  b* u# _        unsigned int vtim; //0xc
2 u7 v: B) h) Y, A. P! H        unsigned int hvlen; //0x10
3 Q7 k6 o9 C6 C' U0 f) x        unsigned int vbara; //0x14
; ^" j; c: d2 a- S        unsigned int vbarb; //0x18
, i; e+ c" a4 V6 P4 e ' J( ~7 v0 {! ?
}rill_vga_regs_s;# A7 P( O4 ~* H' X$ h

- W% B/ H7 E; Z) T, J
6 y* A4 P! Z3 Q) M% I2 ^' K5 V//----I2C core data structure
9 c0 \. z' q3 R! s; q7 v7 O#if 0$ ^* |" ~0 g5 `  z6 j) G' t0 I
typedef struct i2c_regs
; i# S% ~( Q* M5 a{0 R- S$ Y' G: _% J9 ~% i. C. Q
        unsigned char prer_lo;//3'b0006 N4 k% I8 z% q1 ~) {
        unsigned char prer_hi;//3'b001( A8 ^% U3 S6 ^$ A5 o/ \! R
        unsigned char ctr;//3'b0107 O" ?7 @- {% V# `4 M) s6 f
        unsigned char rxr;//3'b0110 i6 @6 p6 N8 M$ \& v- G5 U
        unsigned char sr;//3'b100: D8 i5 o, y0 V1 m2 U( h
        unsigned char txr;//3'b1013 t( A9 i1 y% ]6 B/ v
        unsigned char cr;//3'b110
/ y" ^  v! Z2 N5 U; y' \; }}rill_i2c_regs_s;7 e) r# h& \; d7 a

) }  j7 |' R$ t& u#endif
4 \! z6 s  ?- J//===== funcs) i7 k/ i( `( v- P) L2 z' l! g

6 q* o8 _& ?9 X. R/* The vga interrupt handler. */
8 q' U8 M6 B# H9 Z! E( Fvoid vga_interrupt(void)( c0 M' W6 N1 M7 b7 b
{
/ a( a( ]* A% M0 o/ a        int i = 0;
! Y/ ^& w  ]! V$ l        i = 1;. {. m' x6 X5 B9 L$ P  U' ^
        return;
, O/ r+ Z( a; ]5 N: w}) F) G% }2 \  C$ M) l1 g0 u- F" F
: |$ e# Z  H# [9 r

; @# y- {" Z0 _7 U. W( }void my_vga_setup(void)
( Z9 h+ |' e& m3 X{
' Z. l* z/ m5 e5 M" o$ c6 H        volatile rill_vga_regs_s * vga_regs;
, O1 z4 a: W: [! W" D2 z        unsigned int thsync = 127;/ [2 t6 X3 x9 C; |" U: e- Q
        unsigned int thgdel = 87;
+ x  r+ Z8 C1 u: j+ h# U. p        unsigned int thgate = 799;' ]  {- G6 q2 i0 K% o1 H/ G
        unsigned int thlen = 1056;4 m$ P, N4 }) w7 Z7 D* N
        unsigned int tvsync = 3;+ V4 @7 S$ w# H5 T4 |$ E# u9 H
        unsigned int tvgdel = 22;
9 V5 D3 Y+ d1 n+ F        unsigned int tvgate = 599;) ?& L5 Z2 j/ U0 d5 G1 z
        unsigned int tvlen = 628;
# o* \4 |9 f" w+ c/ X, u
/ m- F- N0 _/ w/ I0 X) l        vga_regs = (rill_vga_regs_s*)(RILL_VGA_BASE);
( B+ _3 G: R6 e/ Z* L        # s% `$ ]# _8 M% U
        /* config vga regs*/  {0 ?7 O# B  R
        //==1==-> stop vga core
* A1 t4 z3 q  W& y7 E7 j        vga_regs->ctrl = 0x0;( v9 g; ~8 u$ c* u9 B( y
2 G5 s  M1 J8 m, @
        //==2==-> set vbara reg:0x 0 T7 G! y7 [9 ^9 M
        vga_regs->vbara = FRAME_BUF_BASE;
7 E1 X/ Q) h* {  F) R: Y 5 z0 j$ e1 G" K7 M3 k% A; u8 F
        //==3==-> set vbarb reg' e' |# w1 ^; x
        vga_regs->vbarb = FRAME_BUF_BASE + FRAME_BUF_SIZE;+ `! r: Q& w0 _0 V- P, m  T: }; R
& I( S- h  y# p& q6 i
        //==4==-> set htim reg( p; C4 ?3 T! Q4 B* m4 s
        vga_regs->htim = (thsync << 24) | (thgdel << 16) | thgate;
, d% M; C+ m3 i% s) N        //==5==-> set vtim reg
! v- s" M# k; x7 h/ l        vga_regs->vtim = (tvsync << 24) | (tvgdel << 16) | tvgate;- c. |3 Z+ j+ z$ d
        //==6==-> set hvlen reg
& E* y6 `" [+ p# `- ]& o        vga_regs->hvlen = (thlen << 16) | tvlen;
+ y) _$ K; f9 K  O: |5 f- _7 \        //==7==-> start vga core:0000_0000_0000_0000_0000_0110_0000_0001
, [0 y# h. h- u9 X# V8 u        vga_regs->ctrl = 0x621;& q3 v1 H4 H3 `6 u# H, i5 X0 v
6 d* @7 N4 _$ S' l( ~# N' j- }7 F

; U: [2 l- g* f, ~. T, j         return;
4 a1 ]6 S; k' p2 U% K) L}5 m. K3 D3 v5 q7 i& T

6 P7 w6 c/ w9 A5 _ " t/ E# w6 x5 Z( H* x" E" C- z

$ ^3 x" y1 J* C8 v9 w0 r
2 i! k1 Y* X& S9 E
! P% {# z( g2 r8 C6 \ 0 [, H3 G) O; m/ r
void i2c_reg_write(unsigned int reg_wb_adr,unsigned char value)
1 V! q9 J3 q8 Z: D8 |3 T{# j, z' j* W! h0 u7 M8 O' f
        //volatile unsigned int * i2c_reg;
3 m0 D5 c& A. ~3 H" i/ s! b        //i2c_reg = (unsigned int *)(RILL_IIC_BASE + reg_wb_adr);9 L  ~8 O+ q! D2 [* V  q5 t
        //i2c_reg = value;
! J2 o* i# k' y4 c. {        REG8(RILL_IIC_BASE + reg_wb_adr) = value;- d( s7 `! t0 V  H: B8 G

; i0 Q6 l  k9 Z" Z        return;
% `3 z% \# J  D; ^5 Q, @1 j% J6 P}* E' b' k, F' }" p7 J7 R+ Z1 c0 _
! Y: m; E6 R& I2 g4 r4 m4 r
unsigned char i2c_reg_read(unsigned int reg_wb_adr)/ B/ t( s! P' s6 }4 J, p
{
9 B/ z# V3 b! V% R! ~        unsigned char ret = 0;        3 W. h4 R. o9 G4 K; x8 I: y
        //volatile unsigned int * i2c_reg;; T3 F# V5 \9 G# Z. V
        //ret = (unsigned int *)(RILL_IIC_BASE + reg_wb_adr);
& Y. W% o) I+ ?" f3 j
5 g3 N2 s. A* ]/ N2 o        ret = REG8(RILL_IIC_BASE + reg_wb_adr);- [' R  H! `6 U6 B5 M  [8 @
        return ret;3 \1 q$ t, {' @7 e2 H2 d. C
}
  k3 [( U2 l4 e 5 {9 F/ S" E1 ?0 G0 M5 X
/ n( f& a) r, m1 i/ R, |2 W
& Z' @: {3 [- A1 d$ P, c  p
void i2c_wait_ack(void)
8 s3 h) S3 G* A0 g" L{
0 C# E# P' {) ?6 R2 z( F& g/ T: ?, ^" E$ T        volatile unsigned int tip = 0;//SR:[ack_from_wr,busy,sl,0,0,0,tip,irq]
$ W( @/ J+ c. P! B( ]8 ~        
; O) D0 S, A' n3 I  S        do: C/ Z( o* }9 Z% l2 Z3 x, G( i) s2 k
        {        . Q. s% z. e7 V7 b3 ?( Y. R
                tip = (REG32(RILL_IIC_BASE+IIC_REG_ADR_SR_R) & 0x02000000);0 M. ~% R  e8 ]4 \
        }while(tip);
: H% P7 P) H8 a' Z( V& v- N7 v}
& G: f; t5 C$ g7 o
9 O& L7 X! B* ?/ C+ zvoid i2c_write(unsigned char i2c_adr,unsigned char data)
9 m" x& E" g$ J, f5 }{
0 w: N0 _: ?  w( V0 R; `( Y  L  |3 O        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) & 0xfe);//present slave addr(ch7301,0x76),set write bit# }& \" S* g: e+ T
        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);//set commond(start,write),CR:[sta,sto,rd,wr,ack2rd,0,0,iack]+ X0 Y" h* v. h9 Z* P: ]
        i2c_wait_ack();
9 D9 C" J% H) _$ f        i2c_reg_write(IIC_REG_ADR_TXR_W,i2c_adr);% ]+ h, e0 d  Z3 y/ Y! ]) ]
        i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)
. s. J; T2 B/ ^& G! o1 |        i2c_wait_ack();! d% t' \) K. \) N8 {3 |# b, u
        i2c_reg_write(IIC_REG_ADR_TXR_W,data);( t/ {0 |5 U7 I: J2 V
        //i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)
- m  ~3 n& P- U* j1 w# o        //i2c_wait_ack();
' Y( q# @5 W9 b; s: z. s        i2c_reg_write(IIC_REG_ADR_CR_W,0x50);//set commond (write,stop)
8 e; @% ^: N5 P" b        i2c_wait_ack();
1 U; l  ^- o& f9 p: E        return;& L* `/ d: p. u! E& F3 d
}) \; q2 y$ f. y( {/ }% S
void i2c_read(unsigned char i2c_adr,unsigned char* data)
8 l2 T  E% G# G{2 ]/ _% _& t" j5 i
        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) & 0xfe);//present slave addr(ch7301,0x76),set write bit% {; S9 w8 l/ {! ?3 y2 z
        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);//set commond(start,write),CR:[sta,sto,rd,wr,ack2rd,0,0,iack]
! K% v; p& n3 E: ?1 Y9 q' ?        i2c_wait_ack();  i- T+ u/ y+ I0 x$ ]
        i2c_reg_write(IIC_REG_ADR_TXR_W,i2c_adr);" |$ p' y# b7 U5 A1 H
        i2c_reg_write(IIC_REG_ADR_CR_W,0x10);//set commond(write)
' [8 a2 ~+ W$ ?6 C, l        i2c_wait_ack();
/ R+ k6 I' u. r3 U        i2c_reg_write(IIC_REG_ADR_TXR_W,(CH7301_ADR<<1) | 0x01);
. D2 t$ H$ q; F: p/ |* C/ I2 K        i2c_reg_write(IIC_REG_ADR_CR_W,0x90);
( V+ T0 G2 j- @: ^1 l, A        i2c_wait_ack();
5 o; ~. @  u7 Y        i2c_reg_write(IIC_REG_ADR_CR_W,0x28);//set commond (read,nack_read),read comolete!- F. [7 p& c$ a' A# L- @
        i2c_wait_ack();
1 N$ d9 p% r- J( P# i        * data = i2c_reg_read(IIC_REG_ADR_RXR_R);$ \7 J- s& I* _. A% a7 {
        return;. T5 N" ^( j1 d  S/ K/ J1 t
}; A% Y( s4 C' t5 d# g4 k0 a* m: \
void my_i2c_init(void)2 \2 {# W# K7 j
{% b; G' y) V! o$ i4 M
        i2c_reg_write(IIC_REG_ADR_PRER_LO,0xff);//load prescaler lo-byte9 J: m! _4 [0 |: O4 R
        i2c_reg_write(IIC_REG_ADR_PRER_HI,0x00);//load prescaler hi-byte
. p- C0 F% H# Q        i2c_reg_write(IIC_REG_ADR_CTR,0x80);//enable core
8 N' ]# {  B' v/ y- u! }) p        return;
8 N+ T1 _$ _# p4 f}2 \- D" u' _7 O3 g) z
void my_ch7301_init(void)$ U3 \. W' z& `# e: c4 {
{+ D: w5 R% F+ ]( x4 w5 ?
        unsigned char data = 0;( k; h* Q5 |, S1 P
        i2c_write(CH7301_REG_ADR0,CH7301_REG_DATA0);
3 s' o1 F  v+ c& |7 [: b        i2c_write(CH7301_REG_ADR1,CH7301_REG_DATA1);/ L* W: M) ]* _4 b
        i2c_write(CH7301_REG_ADR2,CH7301_REG_DATA2);
$ T) d- c$ a: D5 s" o        i2c_write(CH7301_REG_ADR3,CH7301_REG_DATA3);% |6 G# n/ S1 X8 B
        i2c_write(CH7301_REG_ADR4,CH7301_REG_DATA4);
' y. U, V; q0 B        i2c_write(CH7301_REG_ADR5,CH7301_REG_DATA5);
5 S# t- V. \: M9 t+ L4 Q        i2c_write(CH7301_REG_ADR6,CH7301_REG_DATA6);8 ^. M  B5 W5 F+ ]3 F
        i2c_write(CH7301_REG_ADR7,CH7301_REG_DATA7);6 S" W6 i2 j3 }9 a9 a, {9 f* m
        //read ch7301 data back
4 i( a7 X8 _2 F8 |8 y        //i2c_read(CH7301_REG_ADR0,&data);
6 v. h9 D0 W) _) J& R        return;8 N2 |4 N3 c, @
}! Q$ F1 q9 G9 e* ~0 G7 R" O( X  R
void delay(unsigned int delay)! ~. c9 `* y8 w4 T, J
{+ z; ?4 ]0 k& `, x/ u" m9 p( X5 P
        unsigned int time;7 r  M- p; Z& D' @: A* J; O( C9 A$ R/ O( U
        time = delay;
+ G/ }8 X+ n, G2 J; H        while(time--)
) }, @. w1 h# t5 h! c        {% e* z8 `5 k% D$ U; A0 ^- y9 v
                while(delay--);# j9 X/ o5 P0 D( {
        }% E: S* T! N" v: k/ I+ d
        return;
4 w6 h7 n8 D/ S# B# Q6 c! r( ]5 k}# n" ]1 a: x' `- _
void my_i2c_setup(void), a' f2 }' r" |" J' h# h" G$ u% u
{
! P7 F+ V% \: }7 Z        my_i2c_init();+ D& v; b9 Z% F3 q& f
        my_ch7301_init();
2 ~  V( s( z3 I  j* G% d% s) r        
* J5 F6 X8 K9 D4 `        return;
; B2 j# _% X, o}
5 _6 L1 H% A2 I0 b! e2 X2 hint main (void)& d/ A& h% [. Y  o9 Z! P' n
{
1 U  `- N8 E4 l5 K( R          /* Initialise handler vector */2 c2 |( p" h! M( r7 q0 U6 K
          //int_init();* M/ N5 P$ d6 `5 G( Q) _: M
          /* Install ethernet interrupt handler, it is enabled here too */  b- @0 e/ i! c. R
          //int_add(VGA_IRQ, vga_interrupt, 0);
! ~+ X; \! I- A) v  I/ U9 x          /* Enable interrupts in supervisor register */- A* a6 s. l) ?. t- V0 K5 d
          //cpu_enable_user_interrupts();+ |* u( Y& `, F* d2 M9 M
        uart_init(0);/ J/ t4 {3 M) r1 z: ]; Z5 D) ^5 `
        printf("\n\t <1-> uart_init done!\n\0");! h" @$ ]% |) S. ^6 A
1 ^  O/ k- u3 N
        my_i2c_setup();/* configure IIC & CH7301*/+ `  e  c% U, i4 s2 O7 C7 j
        printf("\n\t <2-> i2c_setup done!\n\0");  f0 o: T8 e& E9 P! q# x
" C# T  u& l, g0 s: K3 P& {
  my_vga_setup(); /* Configure VGA */
- a- T; M, C* P        printf("\n\t <3-> vga_setup done!\n\0");; ^. O" I& X; m1 L* m$ F1 e9 e

3 }; v9 g9 `3 M        return 0;
7 T4 X; n  z+ x3 ^& v/ z //         exit(0x8000000d);
, Q- H7 z* ~4 F/ ^  $ @: S$ \  D) x2 w" F+ b1 @1 X
}
- b/ ^, s/ [$ A; V9 |( G1 j  Z& e$ X/ M

5 ]; r$ ]* |+ q6 d; t; i8 X8 G7 ^5 j6 R( I
makefile:% Z# o% r8 P5 r4 O5 z4 L% ]
# Set the path to our board's root directory# B. Q  r- O# @2 X2 J
BOARD_SW_ROOT=../../..' p; w6 |0 Q) N2 |: U& p( [/ ^' D
; N( _( T+ p' w5 |/ I! Y( A  t; f
include $(BOARD_SW_ROOT)/Makefile.inc' X2 @0 G- N7 {& Y) p

' G  r, D9 F  _8 ^; d: y. \%.dis: %.elf
2 d6 Q3 y( u; i5 W: X) F# q        $(Q)$(OR32_OBJDUMP) -d $< > $@) i2 b+ R0 B. P$ F% e9 j* D) R

% m: V+ A# K) l%.bin: %.elf5 X" O/ J8 K4 P6 J
        $(Q)$(OR32_OBJCOPY) -O binary $< $@4 A  `% e& m  C5 Z- K" \
# Y2 {! g; Y6 H# R% @
clean:
! d2 ^" [. U4 l/ F4 \        $(Q)rm -f *.elf *.bin *.vmem *.flashin *.dis
, i: [  ^# e: z) r$ b7 F; V, Q. i- l! T
0 @4 ], Y5 c4 c" v2 X$ X2 v

$ W6 B- W! x8 v+ `& V. m" x& n) o/ e8 b5 k3 O" o6 J4 _! ~( }* V
4,RTL仿真4 F  h/ S: r, J2 v2 z5 G" r2 o
在下板验证之前,强烈建议先进行RTL仿真。
5 {6 K6 m6 [1 K
; T. o/ a2 O. G  k# @4 M  G2 |在搭建好仿真环境之后,我们就可以进行全系统仿真了,步骤如下:
" c( h5 i% w/ q+ y0 y. D. R* P) M6 |$ E6 A! C% \- O8 M& n
a,创建软件仿真目录和软件程序
# U  p. t+ k3 `' l# m; P8 I
9 i( F" v! ^5 B% P
5 r3 Y4 c) Y% P3 q  Pcd ~/soc-designed/orpsocv2/boards/xilinx/ml501/sw/tests/" B/ R4 P; }- z' v* P* C
mkdir vga
8 \) ]2 o/ f8 Qcd vga) p' H3 G9 C" r7 M
mkdir sim
" w. f5 Z% ^, P: m& K) {, wcp /path/to/vga.c /path/to/Makefile ./
$ D* C; H$ A& l9 @" {+ ]% W( S
2 V4 R- o& a7 H/ U! a效果如下所示:/ Q1 o: I; V7 {. g
其中vga.elf文件使用“make vga.elf”命令产生的,在下板验证时使用。
* u  n: @0 ~$ O; s3 M1 o
8 k! e) m" C; s7 ]/ E. E
2 ~" t$ `" u/ v: E( Q& U9 U4 r7 b5 |0 @
6 {: b/ [: I  K9 K3 O! \0 P- R7 P
b,开始仿真
7 z3 k5 @/ O' X; Ncd ~/soc-designed/orpsocv2/boards/xilinx/ml501/sim/run/
* B5 T, T# Y4 ]4 ]# c& \' y0 B' Rmake rtl-test TEST=vga VCD=1 PRELOAD_RAM=1 VCD_DELAY=xxx_ps END_TIME=yyy_ps
8 e) w4 Z3 T# @, [gtkwave ../out/vga.tar.gz. l1 X) I. M* v2 Z
+ K9 v( o/ {: f0 ~
其中“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。
7 F  ^8 n9 R( B6 s2 b在仿真结束后,在../out/目录下会生成波形文件,通过gtkwave既可以打开,如果vcd文件太大,可利用modelsim的vcd2wlf工具将vcd文件转换成wlf格式,再用modelsim打开查看波形。仿真时间和转换时间都比较长,请耐心等待。
2 g+ e) A, u4 @) y: s% A0 ~% O* i1 W' C5 c& ^: E

3 W6 ~) U6 V, u2 |
) I- {1 L5 ?0 z/ L  I2 ]  m) P3 ~! ic,查看波形
6 }2 w: U2 X% c6 R( K1 E  [通过gtkwave和modelsim,产看vga和i2c_master模块的相关寄存器和端口输出,确定没有任何问题。
* ^6 f% A3 @8 w: X8 ]. A8 r; l3 m
当然,需要注意的是,如果想仿真,就需要在bench的顶层模块例化i2c的仿真模型。) @) J3 O* |7 p; _3 C# f, z; s
6 u" X: _$ ?/ @* }' e& p- A0 I( w

5 f, }0 C3 n2 n8 ]8 m% p
4 B$ v( Q/ X% [3 H0 t' y" ad,可以直接使用的工程
3 z" m5 q1 R1 R8 `! `% f/ J* e! ]  l( o
6 J; Q+ ?3 A5 M; d% B( q
5 F  p7 o0 d) r) ^6,下板验证/ w& w) t% X; u( E
在RTL仿真并确认没有问题之后,我们就可以下板验证了,在用ise综合之前要先给vga和i2c模块分配对应的引脚。) i& R7 o( e& H5 M2 w; C

8 [3 G4 Y6 Z3 H: f- d* V并将板子的DVI接口连接到显示器。+ [+ ]1 k1 ^. W5 Y/ Z
9 d3 L' u4 ], _& l
综合完成之后,用iMPACT将bit文件下载到ML501开发板,运行adv_jtag_bridge,运行or32-elf-gdb,将vga.elf下载到内存,并运行。
+ n6 x2 ~) p# {0 B+ S: V$ F: v
" X. C: r; N; e0 {" |/ n: q/ n这时,我们就可以看到显示器的输出了。下图就是我的运行结果:
9 ~1 L) T; o2 I
7 B4 J! q# O( x : Y8 `$ W( t) o  c1 y- P, r$ F

# b1 e' j2 `3 d( m) ^3 T* \+ U! c, h0 }# Z% I% F+ S
+ ?% f, h6 x3 Z# B, W5 D0 z
需要注意的是,如果这时你连接了ML501的串口到PC并打开putty的话,你还会看到如下打印信息:
/ I8 P5 g2 v9 C5 Z: X- D: {6 O- f$ J0 u5 r" _" D* J' |3 r4 Z

$ p. Q, O7 ]5 J! r1 N
4 r# Y  ^, l; S2 N, W4 e1 D* @, ?4 ?& H; P

* l; u8 B: f/ t这说明,我们添加的vga_enh模块,和i2c_master模块都work了!!
% @6 O% a3 @$ \3 e5 n8 Z
9 Z: W! v9 I2 n& e4 d; i/ m! C* q# b+ ]$ Q
% g0 L: Y3 j$ t6 z; W) E

! v/ f: y' r" Q6 V4 l) c
: t$ G1 e% K- \  e! N7,小结
/ W) ?! ]' }& ~  ?3 u  A- M- }本小节,我们向ORPSoC中添加了vga_enh模块和i2c_master模块,并经过了仿真并最终下板验证。
" L# e) |! W% E: q9 [9 O* \+ k
  • 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 22:12 , Processed in 0.187500 second(s), 26 queries , Gzip On.

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

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

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