(原创)构建基于aemb的sopc系统(五)--系统仿真与fpga验证(DE2-70平台)

构建aemb的sopc系统(不带串口)

下面开始构建aemb的sopc系统并对整个系统做仿真。系统仍先采用aemb+wishbone+onchip memory+gpio的形式

参考(原创)基于or1200最小sopc系统搭建(一)--搭建及仿真(DE2DE2-70

opencores网站上下载aemb_latest.tar.gzwb_conmax_latest.tar.gz gpio_latest.tar.gz解压出源码到 aemb , wb_conmax , gpio 目录下。

Onchip-memoryalteraMegaWizard Plug-In Manager工具生成,并为之编写符合wishbone slave接口规范的接口,参考(原创)Altera 1-port ram wishbone slave接口写法和wishbone master BFM验证,用ram0.mif文件初始化。

Pll的配置如下

Inclk0 50M

Clk c0: output clock frequency: 25MHz, Clock phase shift 0.00 ns, Clock duty cycle %:50

or1200提供时钟

Clk c1: output clock frequency: 10MHz, Clock phase shift 0.00 ns, Clock duty cycle %:50

生成的目录结构

/aemb_sopc_gpio

              /aemb

              /wb_conmax

              /gpio

              /ram

              /pll

构建一个sopc系统

编写aemb_sys.v文件,把各个模块连接起来。

构建顶层模块aemb_sopc.v,把aemb_sys包装起来,便于在DE2上验证

C:\altera\90\quartus\eda\sim_lib目录(参考)下拷贝altera_mf.v220model.v文件到顶层aemb_sopc_gpio目录下,用于仿真

添加Reset_Delay文件用于产生复位信号。

编写aemb_sopc_tb.v测试文件,把开关SW信号附一个任意值。

 

最终的目录结构

/aemb_sopc_gpio

  /aemb

  /wb_conmax

  /gpio

  /ram

  /pll

  aemb_sopc.v

  aemb_sys.v

  aemb_sopc_tb.v

  Reset_Delay.v

  altera_mf.v

  220model.v

编写vlog参数文件vlog.args文件

编写.do脚本文件

调试至硬件平台没有错误

or1200工程中的board.h文件,修改里面的各个模块的地址和配置寄存器的信息与自己的工程相符。

使用orsocdef.h文件,以REG32()的方式访问外部地址空间

编写主程序gpio_aemb.c

#include "orsocdef.h"

#include "board.h"

int main(){

   uint32 gpio_in;

 

   REG32 (RGPIO_OE) = 0xffffffff;

 

   while(1){

     gpio_in = REG32 (RGPIO_IN);

     gpio_in = gpio_in & 0x0000ffff;

     REG32 (RGPIO_OUT) = gpio_in;

   }

}

 

修改gccrom文件,在生成可执行的.elf文件后,加上以下语句。

先用mb-objcopy把生成的.elf文件转换成.ihex文件。

# Convert the ELF file to an IHEX file

mb-objcopy -O ihex $ELFFILE $ELFFILE.ihex && \

echo "copy2ihex=$?" && \

再用ihex2mif工具,把.ihex文件转换成altera ram支持.mif初始化文件。(也可以在生成.srec文件后,用srec2mif工具转换)

# Generate a MIF file from the IHEX file

./my_c/ihex2mif -f $ELFFILE.ihex -o ram0.mif && \

echo "ihex2mif=$?" && \

把生成的ram0.mif文件拷贝到,配置altera ram时指定的目录。

 

Sopc系统进行仿真(不带串口)

以下进行系统级的仿真。

所遇到的问题:

aemb2_edk63.v中为什么把地址设成

output [AEMB_IWB-1:2] iwb_adr_o;

修改aemb_sys.v文件应该把29位的iwb_adr_odwb_adr_o放到wishbone 总线的高29,低两位取零。

但是仿真结果是,只取了第一条指令便停止运行了。通过仿真结果发现aemb模块中的dena信号和iena信号都是无效的,这是因为以下这条语句的原因:

   assign                             iena = ich_fb &

                                                 xwb_fb &

                                                 dwb_fb &

                                                 sys_ena_i;

由于xwb的接口没接,所以iena无效,看来还是把xwb接口的必要的输入信号接上吧。

vlog.args中使用//注释,在sim.do中用#注释

edk63的模拟仿真时,分设了一个rom和一个ramRom只与指令总线相连,ram只与数据总线相连,这样,即使同时取指和取数据都不会发生错误,但是在aemb+wishbone+onchip memory的仿真过程中,只设了一块onchip-memory,这样当指令总线和数据总线同时对onchip memory进行操作时,就发生了错误。在仿真波形上显示的是,当数据总线有一个写操作时,系统便挂起啦了,因为数据总线写的数据,正好被指令总线取走。为什么会这样呢,还应该是ramwishbone slave接口写得有错误。为什么ram0_top.v会不正常呢,在or1200的那个系统中是正常的?

改了一下ram0_top.v,仿真正确了。Wb_conmax是不会同时对同一地址进行操作的ram0_topwb_ack_o的信号有错误,wb_ack_o的有效条件是在系统的总线循环信号和选通信号 wb_stb_i & wb_cyc_i (记为request信号)同时有效并且是在它们同时有效的上升沿处才有效。这就假定了一个情况,就是如果aemb系统的主端口在接收到wb_ack_o信号有效后就必须把request信号置低,表示一次总线操作的完成。

如若不然呢。如若不然,aemb处理器等到wb_ack_o有效后并没有把request置低,而是等着下一次或者更长时间的wb_ack_o有效信号,便不会把request置低,也就不会有这个信号的上升沿产生ram0_top中见不到有request信号的上升沿,便不会把wb_ack_o信号置高,从而就僵持了起来。

怎样解决这个问题呢

ram0_top.v中的这句代码

              assign request_rising_edge = (request_delay ^ request) & request;

改成

              assign request_rising_edge = ~wb_ack_o & request;

就可以了gpio程序的仿真结果。

LEDR输出等于SW的输入。

关于ram0_top中的这个问题,在那个or1200中没有错误。不知道aemb为什么会不一样。

 

FPGA上验证(不带串口)

参照(原创)基于or1200最小sopc系统搭建(二)--QuartuII工程及DE2平台下载构建QuartusII工程。

不过这一次试一下不用图形化页面,只修改.qsf文件的方法

修改or1200_sopc.qsf文件,主要修改的地方有:

文件名改一下改成aemb_sopc.qsf吧

引脚配置全不用改

改一下TOP_LEVEL_ENTITYaemb_sopc

set_global_assignment -name VERILOG_FILE命令加入工程的Verilog文件带路径

执行

>quartus_sh --flow compile aemb_sopc.qsf

编译成功之后,执行以下命令把.sof文件配置到DE2

>quartus_pgm --no_banner --mode=jtag -o p;aemb_sopc.sof

显示效果与(原创)基于or1200最小sopc系统搭建(二)--QuartuII工程及DE2平台下载是相同的看来如果要维护一个可移植的QuartusII工程,除了HDL代码外,只需要一个.qsf文件,或者.tcl文件就可以了。

 

添加串口

下面添加串口,重复以上步骤。

参考(原创)基于or1200最小sopc系统搭建(三)--串口添加串口

uart16550_latest.tar.gz源码文件解压到工程目录aemb_sopc_gpio_uart

修改sopc顶层文件aemb_sys.v添加上串口相关信号

修改工程的顶层文件aemb_sopc.v添加上串口相关信号。

UART的接收器核uart_rx.v拷贝到工程目录aemb_sopc_gpio_uart

修改testbench文件aemb_sopc_tb.v,把串口仿真模块加入

修改vlog.args文件,加入串口相关文件。

修改sim.do文件,增长仿真时间

 

软件工程的建立,加入demo_or32_sw.zip中的uart.huart.c文件。修改主程序:

#include "orsocdef.h"

#include "board.h"

#include "uart.h"

int main(){

   uint32 gpio_in;

 

   REG32 (RGPIO_OE) = 0xffffffff;

   //iprintf("iwillsuc!\n");

 

   uart_init();

   uart_print_str("Hello World From aeMB!\n");

 

   while(1){

     gpio_in = REG32 (RGPIO_IN);

     gpio_in = gpio_in & 0x0000ffff;

     REG32 (RGPIO_OUT) = gpio_in;

   }

}

执行

$ ./gccrom my_c/uart.c my_c/aemb_gpio_uart.c

生成ram0.mif文件

串口程序仿真结果

# H

# e

# l

# l

# o

# W

# o

# r

# l

# d

# F

# r

# o

# m

# a

# e

# M

# B

# !

重新配置QuartusII工程,修改aemb_sopc.qsf文件即可。

加入uart相关的文件

执行

>quartus_sh --flow compile aemb_sopc.qsf

编译成功之后,执行以下命令把.sof文件配置到DE2

>quartus_pgm --no_banner --mode=jtag -o p;aemb_sopc.sof

配置串口115200 8N1

但在下载之后发现,串口并不能正常工作,打印出一些莫名奇妙的东西。在仿真正确的情况下,出现这种情况更令人郁闷。最后,还是张老师发现,问题仍出现在onchip memory上,便没再做修改,把onchip memory直接换掉了。

可以打印出来了,但是复位仍有些问题,便又修改了C代码,把core.hh头文件进去了。

#include "orsocdef.h"

#include "board.h"

#include "uart.h"

#include "aemb/core.hh"

int main(){

   uint32 gpio_in;

 

   REG32 (RGPIO_OE) = 0xffffffff;

 

   uart_init();

   uart_print_str("Hello From aeMB!\n");

 

   while(1){

     gpio_in = REG32 (RGPIO_IN);

     gpio_in = gpio_in & 0x0000ffff;

     REG32 (RGPIO_OUT) = gpio_in;

   }

}

 

再在FPGA上验证,便没有错误了。

实例代码

aemb_sopc_gpio.7z 

aemb_sopc_gpio_uart.7z 

posted @ 2010-06-04 10:35  任怀鲁  阅读(2082)  评论(5编辑  收藏  举报