您的位置:首页 > 运维架构

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

2010-04-30 10:07 1166 查看
做一个or1200的最小系统,or1200+wishbone+ram+gpio,在DE2平台上实现读取SW的值然后再LEDR上显示出来的简单程序。我将记录一些主要的步骤。

opencores上下载源码or1200-rel1.tar.bz2wb_conmax_latest.tar.gzgpio_latest.tar.gz解压出源码到 or1200 , wb_conmax , gpio 目录下。

除此之外,还需要一个onchip-memory和为系统提供时钟的PLL,用altera的MegaWizard Plug-In Manager工具生成。

Ram的生成参考(原创)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

生成的目录结构

/or1200_sopc

/or1200

/wb_conmax

/gpio

/ram

/pll

建一个sopc的顶层文件,把上述源码连接起来,相当一SOPC Builder的所作的工作,现在靠自己动手做了。编写or1200_sys.v文件

module or1200_sys(

input clk_i,

input rst_n,

// buttons

input [15:0] SW,

// segments

output [31:0] LEDR

);

wire rst = ~rst_n;

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

// Wires from OR1200 Inst Master to Conmax m0

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

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 s15 to GPIO

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

wire wire_gpio_ack_o;

wire wire_gpio_cyc_i;

wire wire_gpio_stb_i;

wire [31:0] wire_gpio_data_i;

wire [31:0] wire_gpio_data_o;

wire [31:0] wire_gpio_addr_i;

wire [3:0] wire_gpio_sel_i;

wire wire_gpio_we_i;

wire wire_gpio_err_o;

wire wire_gpio_interrupt;

or1200_top u_or1200(

// System

.clk_i(clk_i),

.rst_i(rst),

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

.clmode_i(2'b00),

// Instruction WISHBONE INTERFACE

.iwb_clk_i(clk_i),

.iwb_rst_i(rst),

.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),

.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),

// 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 2 Interface

.s1_data_i(wire_gpio_data_o),

.s1_data_o(wire_gpio_data_i),

.s1_addr_o(wire_gpio_addr_i),

.s1_sel_o(wire_gpio_sel_i),

.s1_we_o(wire_gpio_we_i),

.s1_cyc_o(wire_gpio_cyc_i),

.s1_stb_o(wire_gpio_stb_i),

.s1_ack_i(wire_gpio_ack_o),

.s1_err_i(wire_gpio_err_o),

.s1_rty_i(0)//,

//.s1_cab_o(),

);

ram0_top u_ram0(

.clk_i(clk_i),

.rst_i(rst),

.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_gpio(

// WISHBONE Interface

.wb_clk_i(clk_i),

.wb_rst_i(rst),

.wb_cyc_i(wire_gpio_cyc_i),

.wb_adr_i(wire_gpio_addr_i),

.wb_dat_i(wire_gpio_data_i),

.wb_sel_i(wire_gpio_sel_i),

.wb_we_i(wire_gpio_we_i),

.wb_stb_i(wire_gpio_stb_i),

.wb_dat_o(wire_gpio_data_o),

.wb_ack_o(wire_gpio_ack_o),

.wb_err_o(wire_gpio_err_o),

.wb_inta_o(wire_gpio_interrupt),

//`ifdef GPIO_AUX_IMPLEMENT

// // Auxiliary inputs interface

// .aux_i(),

//`endif // GPIO_AUX_IMPLEMENT

// External GPIO Interface

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

.ext_pad_o(LEDR),

.ext_padoe_o()//,

//`ifdef GPIO_CLKPAD

// .clk_pad_i()

//`endif

);

endmodule

构建顶层模块or1200_sopc.v

//small sopc with openrisc

//`include "or1200_defines.v"

module or1200_sopc

(

//////////////////// Clock Input ////////////////////

CLOCK_27, // On Board 27 MHz

CLOCK_50, // On Board 50 MHz

//////////////////// Push Button ////////////////////

KEY, // Pushbutton[3:0]

//////////////////// DPDT Switch ////////////////////

SW, // Toggle Switch[17:0]

//////////////////////// LED ////////////////////////

LEDR//, // LED Red[17:0]

);

//////////////////////// Clock Input ////////////////////////

input CLOCK_27; // On Board 27 MHz

input CLOCK_50; // On Board 50 MHz

//////////////////////// Push Button ////////////////////////

input [3:0] KEY; // Pushbutton[3:0]

//////////////////////// DPDT Switch ////////////////////////

input [17:0] SW; // Toggle Switch[17:0]

//////////////////////////// LED ////////////////////////////

output [17:0] LEDR; // LED Red[17:0]

wire CPU_RESET;

wire clk_25,clk_10;

Reset_Delay delay1 (.iRST(KEY[0]),.iCLK(CLOCK_50),.oRESET(CPU_RESET));

cpu_pll pll0 (.inclk0(CLOCK_50),.c0(clk_25),.c1(clk_10));

or1200_sys or1200(

.clk_i(clk_25),

.rst_n(CPU_RESET),

// buttons

.SW(SW[15:0]),

// segments

.LEDR(LEDR[17:0])

);

endmodule

其中的Reset_Delay模块如下,产生复位信号。

module Reset_Delay(iRST,iCLK,oRESET);

input iCLK;

input iRST;

output reg oRESET;

reg [23:0] Cont;

always@(posedge iCLK or negedge iRST)

begin

if(!iRST)

begin

oRESET <= 1'b0;

Cont <= 24'h0000000;

end

else

begin

if(Cont!=24'hFFFFFF)

begin

Cont <= Cont+1;

oRESET <= 1'b0;

end

else

oRESET <= 1'b1;

end

end

endmodule

关于or1200_define的配置,参考工程orpXL所写。

or1200_defines.v:

Line 263: Comment out "`define OR1200_ASIC"

Line 326: Enable comment "`define OR1200_ALTERA_LPM"

Line 577: Comment out "`define OR1200_CLKDIV_2_SUPPORTED"

or1200_spram_2048x32.v

Line 591: Comment out "lpm_ram_dq_component.lpm_outdata = "UNREGISTERED","

Other files from opencores.org are remained without change.

下面在modelsim中先做仿真。

从C:\altera\90\quartus\eda\sim_lib目录(参考)下拷贝altera_mf.v和220model.v文件到顶层or1200_sopc目录下

编写or1200_sopc_tb.v测试文件

`timescale 1ns/100ps

module or1200_sopc_tb();

reg CLOCK_50;

reg CLOCK_27;

reg [3:0] KEY;

reg [17:0] SW;

wire [17:0] LEDR;

initial begin

CLOCK_50 = 1'b0;

forever #10 CLOCK_50 = ~CLOCK_50;

end

initial begin

KEY[0] = 1'b0;

#50 KEY[0]= 1'b1;

end

initial begin

SW = 18'h1234;

end

or1200_sopc or1200_sopc_inst

(

//////////////////// Clock Input ////////////////////

.CLOCK_27(CLOCK_27), // On Board 27 MHz

.CLOCK_50(CLOCK_50), // On Board 50 MHz

//////////////////// Push Button ////////////////////

.KEY(KEY), // Pushbutton[3:0]

//////////////////// DPDT Switch ////////////////////

.SW(SW), // Toggle Switch[17:0]

//////////////////////// LED ////////////////////////

.LEDR(LEDR)//, // LED Red[17:0]

);

endmodule

最终的目录结构

/or1200_sopc

  /or1200

  /wb_conmax

  /gpio

  /ram

  /pll

  or1200_sopc.v

  or1200_sys.v

  or1200_sopc_tb.v

  Reset_Delay.v

  altera_mf.v

  220model.v

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

+libext+.v

-vlog01compat

+acc

-y ./pll

-y ./ram

-y ./or1200

-y ./gpio

-y ./wb_conmax

-v altera_mf.v

-v 220model.v

-work ./work

//

// Test bench files

//

or1200_sopc_tb.v

//

// RTL files (gpio)

//

+incdir+./gpio

./gpio/gpio_top.v

./gpio/gpio_defines.v

//

// RTL files (top)

//

+incdir+../rtl

./or1200_sys.v

./or1200_sopc.v

./pll/cpu_pll.v

./Reset_Delay.v

//

// wb_conmax

//

+incdir+./wb_conmax

./wb_conmax/wb_conmax_arb.v

./wb_conmax/wb_conmax_defines.v

./wb_conmax/wb_conmax_master_if.v

./wb_conmax/wb_conmax_msel.v

./wb_conmax/wb_conmax_pri_dec.v

./wb_conmax/wb_conmax_pri_enc.v

./wb_conmax/wb_conmax_rf.v

./wb_conmax/wb_conmax_slave_if.v

./wb_conmax/wb_conmax_top.v

//

// RTL files (or1200)

//

+incdir+./or1200

./or1200/or1200_defines.v

./or1200/or1200_iwb_biu.v

./or1200/or1200_wb_biu.v

./or1200/or1200_ctrl.v

./or1200/or1200_cpu.v

./or1200/or1200_rf.v

./or1200/or1200_rfram_generic.v

./or1200/or1200_alu.v

./or1200/or1200_lsu.v

./or1200/or1200_operandmuxes.v

./or1200/or1200_wbmux.v

./or1200/or1200_genpc.v

./or1200/or1200_if.v

./or1200/or1200_freeze.v

./or1200/or1200_sprs.v

./or1200/or1200_top.v

./or1200/or1200_pic.v

./or1200/or1200_pm.v

./or1200/or1200_tt.v

./or1200/or1200_except.v

./or1200/or1200_dc_top.v

./or1200/or1200_dc_fsm.v

./or1200/or1200_reg2mem.v

./or1200/or1200_mem2reg.v

./or1200/or1200_dc_tag.v

./or1200/or1200_dc_ram.v

./or1200/or1200_ic_top.v

./or1200/or1200_ic_fsm.v

./or1200/or1200_ic_tag.v

./or1200/or1200_ic_ram.v

./or1200/or1200_immu_top.v

./or1200/or1200_immu_tlb.v

./or1200/or1200_dmmu_top.v

./or1200/or1200_dmmu_tlb.v

./or1200/or1200_amultp2_32x32.v

./or1200/or1200_gmultp2_32x32.v

./or1200/or1200_cfgr.v

./or1200/or1200_du.v

./or1200/or1200_sb.v

./or1200/or1200_sb_fifo.v

./or1200/or1200_mult_mac.v

./or1200/or1200_qmem_top.v

./or1200/or1200_dpram_32x32.v

./or1200/or1200_spram_2048x32.v

./or1200/or1200_spram_2048x32_bw.v

./or1200/or1200_spram_2048x8.v

./or1200/or1200_spram_512x20.v

./or1200/or1200_spram_256x21.v

./or1200/or1200_spram_1024x8.v

./or1200/or1200_spram_1024x32.v

./or1200/or1200_spram_1024x32_bw.v

./or1200/or1200_spram_64x14.v

./or1200/or1200_spram_64x22.v

./or1200/or1200_spram_64x24.v

./or1200/or1200_xcv_ram32x8d.v

//

// Library files

//

//altera_mf.v

编写.do脚本文件

vlib ./work

vlog -f ./vlog.args

vsim -novopt work.or1200_sopc_tb -pli

add wave -radix hex /*

add wave -radix hex /or1200_sopc_tb/or1200_sopc_inst/or1200/*

run 20000ns

可先编译硬件vlog直至没有错误。

Model Technology ModelSim ALTERA vlog 6.4a Compiler 2008.08 Oct 22 2008

-- Compiling module or1200_sopc_tb

… …

Top level modules:

or1200_sopc_tb

or1200_immu_tlb

or1200_dmmu_tlb

or1200_sb_fifo

or1200_dpram_32x32

or1200_spram_2048x32_bw

or1200_spram_2048x8

or1200_spram_512x20

or1200_spram_256x21

or1200_spram_1024x8

or1200_spram_1024x32

or1200_spram_1024x32_bw

下面开始配置软件环境了

首先解决工具链问题

参考网页http://opencores.org/openrisc,gnu_toolchain获得,本文中采用预先编译好的工具链OpenRISC toolchain including GCC-4.2.2 with uClibc-0.9.29, GDB-6.8 and or1ksim-0.3.0, compiled under Ubuntu x86/i686 (32-bit)

$ wget ftp://ocuser:oc@195.67.9.12/toolchain/or32-elf-linux-x86.tar.bz2

解压

$ tar jxf or32-elf-linux-x86.tar.bz2

解压会产生一个新的目录,or32-elf/ 导出文件路径,把以下这句命令添加到~/.bashrc文件中

export PATH=$PATH:/opt/or32-elf/bin

测试以下,输入or32-elf-,按两下tab键

$ or32-elf-

or32-elf-addr2line or32-elf-gcov or32-elf-objdump

or32-elf-ar or32-elf-gdb or32-elf-profile

or32-elf-as or32-elf-gdbtui or32-elf-ranlib

or32-elf-c++filt or32-elf-gprof or32-elf-readelf

or32-elf-cpp or32-elf-ld or32-elf-sim

or32-elf-gcc or32-elf-mprofile or32-elf-size

or32-elf-gcc-4.2.2 or32-elf-nm or32-elf-strings

or32-elf-gccbug or32-elf-objcopy or32-elf-strip

现就可以编写程序了

构建软件工程,主要参考代码demo_or32_sw.ziporpXL中的代码,用or1200的汇编工具可最终生成.ihex,.srec等格式的文件,但altera ram初始化时并不支持这种格式。就需要另外的转换工具,ihex2mif或者srec2mif工具来完成最后的格式转换。

用gcc编译ihex2mif.c文件把生成的可执行文件ihex2mif保存到/software文件夹下。

构建的工程目录

/software

reset.S

ram.ld

Makefile

gpio_or1200.c

board.h

orsocdef.h

ihex2mif

board.h与orsocdef.h从参考代码中拷出,并进行裁剪。链接文件ram.ld,初始化文件reset.S没有多大变动。

编写的gpio_or1200.c文件源码

#include "orsocdef.h"

#include "board.h"

int

main (void)

{

long gpio_in;

REG32 (RGPIO_OE) = 0xffffffff;

while(1){

gpio_in = REG32 (RGPIO_IN);

gpio_in = gpio_in & 0x0000ffff;

REG32 (RGPIO_OUT) = gpio_in;

}

return 0;

}

编写自己的Makefile文件

ifndef CROSS_COMPILE

CROSS_COMPILE = or32-elf-

endif

CC = $(CROSS_COMPILE)gcc

LD = $(CROSS_COMPILE)ld

NM = $(CROSS_COMPILE)nm

OBJDUMP = $(CROSS_COMPILE)objdump

OBJCOPY = $(CROSS_COMPILE)objcopy

INCL = board.h orsocdef.h

OBJECTS = reset.o gpio_or1200.o

CFLAGS = -g -c -Wunknown-pragmas -mhard-mul -msoft-div -msoft-float -O2

export CROSS_COMPILE

# *****************

# File Dependencies

# *****************

gpio_or1200.o : $(INCL)

reset.o : board.h

# ********************

# Rules of Compilation

# ********************

all: gpio_or1200.or32 gpio_or1200.ihex gpio_or1200.srec ram0.mif clean

%.o: %.S

@printf "\r\n\t--- Assembling $(<) ---\r\n"

$(CC) $(CFLAGS) $< -o $@

%.o: %.c

@printf "\r\n\t--- Compiling $(<) ---\r\n"

$(CC) $(CFLAGS) $< -o $@

gpio_or1200.or32: ram.ld $(OBJECTS)

$(LD) -T ram.ld $(OBJECTS) -o $@

$(OBJDUMP) -D $@ > gpio_or1200.dis

gpio_or1200.ihex: gpio_or1200.or32

$(OBJCOPY) -O ihex $< $@

gpio_or1200.srec: gpio_or1200.o

$(OBJCOPY) -O ihex $< $@

ram0.mif: gpio_or1200.ihex

./ihex2mif -f gpio_or1200.ihex -o ram0.mif

clean:

rm -f *.o *.or32 *.ihex *.srec *.dis

接下来执行

$ make all

便会生成ram0.mif文件,拷贝到ram的初始化目录。

接下来就可以进行仿真了,在dos环境下。

$ vsim –do sim.do

仿真结果(大致能看清吧)原图放到了这里



接下来,就用quartusII 建立工程吧。

仿真源代码

or1200_sopc

or1200_sopc_sw
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐