基于OR200的soc设计CPU+RAM+GPIO---vivado仿真篇

vivado确实很好用,之前一直使用zynq,但是部分场景成本过高,索性直接准备用开源软核or1200 sopc,最早了解or1200还是在大学的时候,大约2010年左右,准备电赛的时候在实验室曾经简单接触过,印象里应该是S3的fpga,后来由于专业原因,主要研究雷达电磁算法与进化算法,后来被航天科工淘汰之后,因为工作需要,感觉可以重温旧事,这个还是可以搞一下的,但是有些旧事就比较难了,比如科工的江f,我至今也不知道到底是生她的人牛逼还是睡她的人牛逼,本次利用vivado进行soc设计,相关资源最后上传百度云,这里主要是首先添加两个外设作为例子,展示整个流程

一、代码准备:

首先建立目录OR1200_soc_wyz_ram_gpio

1.openRISC 官网https://openrisc.io/下载OR1200的代码,如下图所示:

解压之后,将or1200-master\rtl\verilog下的代码拷贝到指定目录,由此得到本次实验的CPU软核部分。

  1. 下载wishbone总线IP核,将代码拷贝到指定目录
  2. Ram采用数组编写代码实现(此处直接采用步步惊心里面ram文件),编码编写完成之后,在OR1200_soc_wyz_ram_gpio下面建立目录ram
  3. 下载GPIO的IP核,解压之后将代码存放到OR1200_soc_wyz_ram_gpio/gpio

 

二、建立vovado工程

1.打开vivado2019.1

2.建立新的工程,OR1200_soc_wyz_1

3.选择RTL工程之后,一直选next 到finish,其他的设置都是默认,后期如果综合需要再进行修改

 

  1. 添加IP核代码,点击add souces

 

然后选择添加ADD Drections

 

将CPU、wishbone总线、ram以及gpio的路径添加,然后结束。界面如下图所示,表示各个模块的代码已经添加到了工程当中。

目前工程默认的顶层文件是,没有关系。

 

三、建立顶层文件,例化连接各个IP核,形成SOC系统

首先点击add source 按钮,选择创建文件,的名字命名为Or1200_soc_wyz,然后在这个文件当中定义输入与输出,代码如下:

module Or1200_soc_wyz(

    input clk_i,

    input rst_i,

    // GPIO输入

    input [15:0] SW,

    // GPIO输出

    output [31:0] LEDR

);

 

//1.定义各个IP核之间的连线

       // **************************************************

       // Wires from OR1200 Inst Master to Conmax m0  定义总线和OR1200指令接口之间的连接线

       // **************************************************

       wire wire_iwb_ack_i;

       wire wire_iwb_cyc_o;

       wire wire_iwb_stb_o;

       wire [31:0] wire_iwb_data_i;

       wire [31:0] wire_iwb_data_o;

       wire [31:0] wire_iwb_addr_o;

       wire [3:0] wire_iwb_sel_o;

       wire wire_iwb_we_o;

       wire wire_iwb_err_i;

       wire wire_iwb_rty_i;

       // **************************************************

       // Wires from OR1200 Data Master to Conmax m1

       // **************************************************

       wire wire_dwb_ack_i;

       wire wire_dwb_cyc_o;

       wire wire_dwb_stb_o;

       wire [31:0] wire_dwb_data_i;

       wire [31:0] wire_dwb_data_o;

       wire [31:0] wire_dwb_addr_o;

       wire [3:0] wire_dwb_sel_o;

       wire wire_dwb_we_o;

       wire wire_dwb_err_i;

       wire wire_dwb_rty_i;

       // **************************************************

       // Wires from Conmax s0 to onchip_ram0

       // **************************************************

       wire wire_ram0_ack_o;

       wire wire_ram0_cyc_i;

       wire wire_ram0_stb_i;

       wire [31:0] wire_ram0_data_i;

       wire [31:0] wire_ram0_data_o;

       wire [31:0] wire_ram0_addr_i;

       wire [3:0] wire_ram0_sel_i;

       wire wire_ram0_we_i;

      

        // **************************************************

       // Wires from Conmax s1 to GPIO  信号数量来源于wb总线的规定  王一哲

       // **************************************************

       wire wire_gpio1_ack_o;

       wire wire_gpio1_cyc_i;

       wire wire_gpio1_stb_i;

       wire [31:0] wire_gpio1_data_i;

       wire [31:0] wire_gpio1_data_o;

       wire [31:0] wire_gpio1_addr_i;

       wire [3:0] wire_gpio1_sel_i;

       wire wire_gpio1_we_i;

       wire wire_gpio1_err_o;

      

       wire wire_gpio_interrupt;

 

例化连接各个模块

//例化or1200 CPU,各个连线的定义参考官方文档

or1200_top u_or1200(

  // System

  .clk_i(clk_i),

  .rst_i(rst_i),

  .pic_ints_i({18'b0,wire_uart_interrupt,wire_gpio_interrupt}),

  .clmode_i(2'b00),

  // Instruction WISHBONE INTERFACE

  .iwb_clk_i(clk_i),

  .iwb_rst_i(rst_i),

  .iwb_ack_i(wire_iwb_ack_i),

  .iwb_err_i(wire_iwb_err_i),

  .iwb_rty_i(wire_iwb_rty_i),

  .iwb_dat_i(wire_iwb_data_i),

  .iwb_cyc_o(wire_iwb_cyc_o),

  .iwb_adr_o(wire_iwb_addr_o),

  .iwb_stb_o(wire_iwb_stb_o),

  .iwb_we_o(wire_iwb_we_o),

  .iwb_sel_o(wire_iwb_sel_o),

  .iwb_dat_o(wire_iwb_data_o),

`ifdef OR1200_WB_CAB

  .iwb_cab_o(),

`endif

//`ifdef OR1200_WB_B3

//  iwb_cti_o(),

//  iwb_bte_o(),

//`endif

  // Data WISHBONE INTERFACE

  .dwb_clk_i(clk_i),

  .dwb_rst_i(rst_i),

  .dwb_ack_i(wire_dwb_ack_i),

  .dwb_err_i(wire_dwb_err_i),

  .dwb_rty_i(wire_dwb_rty_i),

  .dwb_dat_i(wire_dwb_data_i),

  .dwb_cyc_o(wire_dwb_cyc_o),

  .dwb_adr_o(wire_dwb_addr_o),

  .dwb_stb_o(wire_dwb_stb_o),

  .dwb_we_o(wire_dwb_we_o),

  .dwb_sel_o(wire_dwb_sel_o),

  .dwb_dat_o(wire_dwb_data_o),

`ifdef OR1200_WB_CAB

  .dwb_cab_o(),

`endif

//`ifdef OR1200_WB_B3

//  dwb_cti_o(),

//  dwb_bte_o(),

//`endif

   // External Debug Interface

  .dbg_stall_i(1'b0),

  .dbg_ewt_i(1'b0),

  .dbg_lss_o(),

  .dbg_is_o(),

  .dbg_wp_o(),

  .dbg_bp_o(),

  .dbg_stb_i(1'b0),

  .dbg_we_i(1'b0),

  .dbg_adr_i(0),

  .dbg_dat_i(0),

  .dbg_dat_o(),

  .dbg_ack_o(),

 //`ifdef OR1200_BIST

//  // RAM BIST

//  mbist_si_i(),

//  mbist_so_o(),

//  mbist_ctrl_i(),

//`endif

  // Power Management

  .pm_cpustall_i(0),

  .pm_clksd_o(),

  .pm_dc_gate_o(),

  .pm_ic_gate_o(),

  .pm_dmmu_gate_o(),

  .pm_immu_gate_o(),

  .pm_tt_gate_o(),

  .pm_cpu_gate_o(),

  .pm_wakeup_o(),

  .pm_lvolt_o()

);

 

//例化总线控制器,连接各个接口

wb_conmax_top u_wb(

 

  .clk_i(clk_i),

  .rst_i(rst_i),

 

  // Master 0 Interface

  .m0_data_i(wire_iwb_data_o),

  .m0_data_o(wire_iwb_data_i),

  .m0_addr_i(wire_iwb_addr_o),

  .m0_sel_i(wire_iwb_sel_o),

  .m0_we_i(wire_iwb_we_o),

  .m0_cyc_i(wire_iwb_cyc_o),

  .m0_stb_i(wire_iwb_stb_o),

  .m0_ack_o(wire_iwb_ack_i),

  .m0_err_o(wire_iwb_err_i),

  .m0_rty_o(wire_iwb_rty_i),

//  .m0_cab_i(),

 

  // Master 1 Interface

  .m1_data_i(wire_dwb_data_o),

  .m1_data_o(wire_dwb_data_i),

  .m1_addr_i(wire_dwb_addr_o),

  .m1_sel_i(wire_dwb_sel_o),

  .m1_we_i(wire_dwb_we_o),

  .m1_cyc_i(wire_dwb_cyc_o),

  .m1_stb_i(wire_dwb_stb_o),

  .m1_ack_o(wire_dwb_ack_i),

  .m1_err_o(wire_dwb_err_i),

  .m1_rty_o(wire_dwb_rty_i),

//  .m0_cab_i(),

 

  // Slave 0 Interface

  .s0_data_i(wire_ram0_data_o),

  .s0_data_o(wire_ram0_data_i),

  .s0_addr_o(wire_ram0_addr_i),

  .s0_sel_o(wire_ram0_sel_i),

  .s0_we_o(wire_ram0_we_i),

  .s0_cyc_o(wire_ram0_cyc_i),

  .s0_stb_o(wire_ram0_stb_i),

  .s0_ack_i(wire_ram0_ack_o),

  .s0_err_i(0),

  .s0_rty_i(0),

  //.s0_cab_o(),

 

  // Slave 1 Interface

  .s1_data_i(wire_gpio1_data_o),

  .s1_data_o(wire_gpio1_data_i),

  .s1_addr_o(wire_gpio1_addr_i),

  .s1_sel_o(wire_gpio1_sel_i),

  .s1_we_o(wire_gpio1_we_i),

  .s1_cyc_o(wire_gpio1_cyc_i),

  .s1_stb_o(wire_gpio1_stb_i),

  .s1_ack_i(wire_gpio1_ack_o),

  .s1_err_i(wire_gpio1_err_o),

  .s1_rty_i(0),

  //.s1_cab_o(),

 

 

  );

 

例化连接ram和

ram_top u_ram0(

    .clk_i(clk_i),

    .rst_i(rst_i),

    .wb_stb_i(wire_ram0_stb_i),

    .wb_cyc_i(wire_ram0_cyc_i),

    .wb_ack_o(wire_ram0_ack_o),

    .wb_addr_i(wire_ram0_addr_i),

    .wb_sel_i(wire_ram0_sel_i),

    .wb_we_i(wire_ram0_we_i),

    .wb_data_i(wire_ram0_data_i),

    .wb_data_o(wire_ram0_data_o)

  );

 

  gpio_top u_gpio1(

    .wb_clk_i(clk_i),

    .wb_rst_i(rst_i),

    .wb_stb_i(wire_gpio1_stb_i),

    .wb_cyc_i(wire_gpio1_cyc_i),

    .wb_ack_o(wire_gpio1_ack_o),

    .wb_adr_i(wire_gpio1_addr_i),

    .wb_sel_i(wire_gpio1_sel_i),

    .wb_we_i(wire_gpio1_we_i),

    .wb_dat_i(wire_gpio1_data_i),

    .wb_err_o(wire_gpio1_err_o),

    .wb_dat_o(wire_gpio1_data_o),

   

     .wb_inta_o(wire_gpio_interrupt),

    

      // External GPIO Interface

      .ext_pad_i({16'b0,SW}),

      .ext_pad_o(LEDR),

      .ext_padoe_o()//,

  );

然后将这个文件设置为顶层文件

 

 

 

 

至此,工程建立完毕,下面建立仿真文件,在Simulation sources下面添加仿真文件,命名为sim_soc_wyz

 

 

在sim_soc_wyz文件当中输入一下代码,然后将其在仿真目录中设为顶层文件

module sim_soc_wyz(    );

 

       reg     CLOCK_50;

       reg     rst;

      

       initial begin

               CLOCK_50 = 1'b0;

               forever #10 CLOCK_50 = ~CLOCK_50;

       end

      

       initial begin

               rst = 1'b0;

               #200 rst= 1'b1;

               #100 rst= 1'b0;

               #10000 $stop;

       end

      

       soc_top    or1200_sopc_inst

       (

          .clk_i(CLOCK_50),

          .rst_i(rst)

       );

Endmodule

 

 

开始仿真,没有错误,出现下图

说明工程建立结束,连接正确。

 

 

四、编写程序,测试ram 和 gpio

 

    1. ram 测试

直接编写程序,将ram从地址0开始处,一次设置为0000,0001,0002

建立汇编文件如下:

 

 

    1. gpio测试

gpio的使用,首先使能32个PIO端口,向使能寄存器写入0xFFFF

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值