c语言转为or1200汇编语言,使用iverilog+gtkwave 仿真or1200

为了学习雷思磊的,步步惊心 软核处理器内部设计和分析,又不想在linux下使用庞大的modelsim,只能摸索开源verilog仿真软件。

1.首先准备or1200源码,在opencores.org上下载吧。

2.在你的linux系统上安装iverilog和gtkwave,安装方法很简单,fedora:sudo yum install iverilog gtkwave. ubuntu:sudo apt-get install iverilog gtkwave

3.安装or1200的交叉编译器,编译器下载也在opencores.org,具体怎么安装,在网上搜一把,"交叉编译器安装“,虽然是arm的,但是or1200也一样。

4.接下来编写第一个测试程序test.S,第一个程序是or1200汇编程序,内容如下:

.section .text ,"ax"

.org 0x100

.global _start

_start:

l.andi r0,r0,0

l.extwz r1,r0

l.extwz r2,r0

l.addi r1,r1,0x0a

l.add r2,r2,r1

l.nop 0x0001 5.编写程序链接脚本,ram.ld,注意原书中"Entry(_start)"无法编译通过,我把它改为ENTRY(_start)

MEMORY

{

ram : ORIGIN = 0x00000000, LENGTH = 0x00005000

}

SECTIONS

{

.text :

{

*(.text)

} > ram

.data :

{

*(.data)

} > ram

.bss :

{

*(.bss)

} > ram

}

ENTRY (_start) 6.编译程序

or32-elf-as -o test.o test.S

or32-elf-ld -T ram.ld test.o -o test.or32 7.这个test.or32可以放入or1200模拟器中允许,为了装入qmem我们还需要进行处理,先把test.or32转为bin文件,再把bin转为存储器初始化文件。

or32-elf-objcopy -O binary test.or32 test.bin 8.应为我没有bin转hex的工具,只好自己写一个,代码如下:

#include

#include

#include

int main(int argc,char **argv)

{

FILE *fd_src,*fd_dst;

char buf[64];

int ret,i;

if (argc != 2)

{

printf("usage: %s binfile\n",argv[0]);

return 0;

}

fd_src = fopen(argv[1],"rb");

if(!fd_src)

{

perror("src fopen:");

return 0;

}

memset(buf,0,64);

sprintf(buf,"%s.hex",argv[1]);

fd_dst = fopen(buf,"w+");

if(!fd_dst)

{

perror("dst fopen:");

fclose(fd_src);

return 0;

}

i = 0;

while ((ret=fread(buf,1,4,fd_src))!=0)

{

if(ret != 4)

{

printf("read file error\n");

fclose(fd_src);

fclose(fd_dst);

return 0;

}

ret = htonl(*((int *)buf));

fprintf(fd_dst,"%08x\r\n",ret);

i++;

}

while (i!=2048)

{

fprintf(fd_dst,"00000000\r\n");

i++;

}

fclose(fd_src);

fclose(fd_dst);

} 9.编写testbench文件,注意我在源文件中加了,initial那一节,这很重要。

`timescale 1ns/100ps

module or1200_tb1();

reg CLOCK_50;

reg rst;

initial begin

CLOCK_50 = 1'b0;

forever #10 CLOCK_50 = ~CLOCK_50;

end

initial begin

rst = 1'b1;

#200 rst = 1'b0;

#1000 $stop;

end

or1200_top or1200_top_inst

(

.clk_i(CLOCK_50),

.rst_i(rst),

.pic_ints_i(20'b0),

.clmode_i(2'b00),

//指令总线

.iwb_clk_i(clk_i), .iwb_rst_i(rst), .iwb_dat_i(32'b0), .iwb_ack_i(1'b0), .iwb_err_i(1'b0),

.iwb_rty_i(1'b0), .iwb_cyc_o(), .iwb_adr_o(), .iwb_dat_o(), .iwb_stb_o(), .iwb_we_o(),

.iwb_sel_o(),

`ifdef OR1200_WB_CAB

.iwb_cab_o(),

`endif

//数据总线

.dwb_clk_i(clk_i), .dwb_rst_i(rst), .dwb_dat_i(32'b0), .dwb_ack_i(1'b0), .dwb_err_i(1'b0),

.dwb_rty_i(1'b0), .dwb_cyc_o(), .dwb_adr_o(), .dwb_dat_o(), .dwb_stb_o(), .dwb_we_o(),

.dwb_sel_o(),

`ifdef OR1200_WB_CAB

.dwb_cab_o(),

`endif

//外部调试接口

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

//电源接口

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

);

initial

begin

$dumpfile("or1200_tb1.vcd");

$dumpvars(0,or1200_top_inst);

end

endmodule 10.根据书上要求,更改or1200_qmem.v文件,并在or1200_spram_2048x32.v的611行添加

initial $readmemh("test.in.hex",mem) 11.编译所以verilog文件:

iverilog -o or1200_tb1 or1200_tb1.v $(SRC) //SRC代表所有verilog源文件

vvp -n or1200_tb1 -lxt2

cp or1200_tb1.vcd or1200_tb.lxt2 12.使用gtkwave打开or1200_tb.lxt2,就可以看波形如下图,和modelsim显示的一样

1fae6e38fd7c9be3cc06f1bdc5390817.png

13.注意iverilog好像不能观察形如reg [aa:bb]  cccc[dd:ee];这类的变量,所以寄存器文件or1200_rf/rb_b/mem[1],无法查看,所以你只能修改源码,修改or1200_dpram.v,我在100行添加如下:

wire [dw-1:0] mem_r0;

wire [dw-1:0] mem_r1;

wire [dw-1:0] mem_r2;

wire [dw-1:0] mem_r3;

wire [dw-1:0] mem_r4;

wire [dw-1:0] mem_r5;

wire [dw-1:0] mem_r6;

wire [dw-1:0] mem_r7;

wire [dw-1:0] mem_r8;

wire [dw-1:0] mem_r9;

wire [dw-1:0] mem_r10;

wire [dw-1:0] mem_r11;

wire [dw-1:0] mem_r12;

wire [dw-1:0] mem_r13;

wire [dw-1:0] mem_r14;

wire [dw-1:0] mem_r15;

wire [dw-1:0] mem_r16;

wire [dw-1:0] mem_r17;

wire [dw-1:0] mem_r18;

wire [dw-1:0] mem_r19;

wire [dw-1:0] mem_r20;

wire [dw-1:0] mem_r21;

wire [dw-1:0] mem_r22;

wire [dw-1:0] mem_r23;

wire [dw-1:0] mem_r24;

wire [dw-1:0] mem_r25;

wire [dw-1:0] mem_r26;

wire [dw-1:0] mem_r27;

wire [dw-1:0] mem_r28;

wire [dw-1:0] mem_r29;

wire [dw-1:0] mem_r30;

wire [dw-1:0] mem_r31;

assign mem_r0 = mem[0];

assign mem_r1 = mem[1];

assign mem_r2 = mem[2];

assign mem_r3 = mem[3];

assign mem_r4 = mem[4];

assign mem_r5 = mem[5];

assign mem_r6 = mem[6];

assign mem_r7 = mem[7];

assign mem_r8 = mem[8];

assign mem_r9 = mem[9];

assign mem_r10 = mem[10];

assign mem_r11 = mem[11];

assign mem_r12 = mem[12];

assign mem_r13 = mem[13];

assign mem_r14 = mem[14];

assign mem_r15 = mem[15];

assign mem_r16 = mem[16];

assign mem_r17 = mem[17];

assign mem_r18 = mem[18];

assign mem_r19 = mem[19];

assign mem_r20 = mem[20];

assign mem_r21 = mem[21];

assign mem_r22 = mem[22];

assign mem_r23 = mem[23];

assign mem_r24 = mem[24];

assign mem_r25 = mem[25];

assign mem_r26 = mem[26];

assign mem_r27 = mem[27];

assign mem_r28 = mem[28];

assign mem_r29 = mem[29];

assign mem_r30 = mem[30];

assign mem_r31 = mem[31];

14.想观察mem[1],就直接观察mem_r1,就成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值