博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenRisc-22-添加自己的DMA-like ipcore到ORSoC并测试
阅读量:7208 次
发布时间:2019-06-29

本文共 26233 字,大约阅读时间需要 87 分钟。

引言

之前写了一个wishbone接口的slave,work的很好。
但是要想实现一个功能完成的ipcore,必然要有master接口。
这次就写一个ipcore(mycore),既包含slave,又包含master。
一个具有类似DMA功能的ip core。

 

另:本小节中省略了一些virtualbox下的操作细节,请参考上一篇文章:

 

1,控制流程

1>mycore的linux下的driver写slave
2>slave根据driver发来的指令控制master
3>master进行相应操作,并返回给slave
4>mycore的linux下的driver读slave

2,功能概述

2.1 master写功能
 1》driver向slave的num_1寄存器里写入0x11223344
 2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 写的地址,其实就是num_1)
 3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始写)
 4》打印
 5》driver读slave,验证master写入的值是否正确。

 

2.1.0 模块总连接图

 

2.1.1 代码修改流程说明:跟单独包含slave的ipcore差不多
 1》编写符合wishbone master接口和相应内部逻辑的ip core:mycore
 2》d_bus的arbiter增加master接口:master2
 3》修改master的仲裁优先级
 4》例化本ipcore
 5》编写linux下的driver并测试验证
 
2.1.2 code list:mycore.v,mkg_master.v,mkg_slave.v
 1》mycore.v

 

/*** mycore.v** rill create 2013-04-02**/`include "orpsoc-defines.v"module mycore(   	//===slave interface signals	wb_clk,	wb_rst,			wb_dat_i,	wb_adr_i,	wb_sel_i,	wb_cti_i,	wb_bte_i,	wb_we_i,	wb_cyc_i,	wb_stb_i,			wb_dat_o,	wb_ack_o,	wb_err_o,	wb_rty_o,				//===master interface signals	m_adr,	m_din,	m_dout,	m_cyc,	m_stb,	m_sel,	m_we,	m_ack,	m_err,	m_rty,	m_cti,	m_bte);//===slave interfaceinput [31:0]      				wb_adr_i;input 			    			wb_stb_i;input 			    			wb_cyc_i;input [2:0] 				    wb_cti_i;input [1:0] 				    wb_bte_i;input 			      		    wb_clk;input 			          		wb_rst;input [31:0] 					wb_dat_i;input [3:0] 					wb_sel_i;input 							wb_we_i;	output  [31:0] 		 			wb_dat_o;output  			      	 	wb_ack_o;output                			wb_err_o;output  					 	wb_rty_o;//===master interfaceinput				m_ack; input				m_err; input				m_rty;input	[31:0]		m_din;output	[31:0]		m_adr;output	[31:0]		m_dout;output				m_cyc; output				m_stb;output	[3:0]		m_sel;output				m_we;output	[2:0]		m_cti;output	[1:0]		m_bte;wire [31:0] address;wire [2:0] flag;wire [2:0] test;wire [1:0] done;//===slave external parametersparameter addr_width = 32;parameter mycore_adr = 32'h97;mkg_slave mkg_slave0(	.address (address),	.flag (flag),	.test_status (test),	.test_done (done),		.wb_clk (wb_clk),	.wb_rst (wb_rst),				.wb_dat_i (wb_dat_i),	.wb_adr_i (wb_adr_i),	.wb_sel_i (wb_sel_i),	.wb_cti_i (wb_cti_i),	.wb_bte_i (wb_bte_i),	.wb_we_i (wb_we_i),	.wb_cyc_i (wb_cyc_i),	.wb_stb_i (wb_stb_i),			.wb_dat_o (wb_dat_o),	.wb_ack_o (wb_ack_o),	.wb_err_o (wb_err_o),	.wb_rty_o (wb_rty_o));mkg_master mkg_master(   	.address (address),	.flag (flag),	.test_status (test),	.test_done (done),		.wb_clk (wb_clk),	.wb_rst (wb_rst),	.wb_adr_o (m_adr),	.wb_dat_o (m_dout),	.wb_sel_o (m_sel),	.wb_we_o (m_we),	.wb_cyc_o (m_cyc),	.wb_stb_o (m_stb),	.wb_cti_o (m_cti),	.wb_bte_o (m_bte),  	.wb_dat_i (m_din),	.wb_ack_i (m_ack),	.wb_err_i (m_err),	.wb_rty_i (m_rty));endmodule/************** EOF ****************/

 

 

 

 

 
 2》mkg_master.v

 

 

/*** mkg_master.v** rill create 2013-04-02**/module mkg_master(   	address,	flag,	test_status,	test_done,		//wishbone interface	wb_clk,				wb_rst,			wb_adr_o,	wb_dat_o,	wb_sel_o,	wb_we_o,	wb_cyc_o,	wb_stb_o,	wb_cti_o,	wb_bte_o,  	wb_dat_i,	wb_ack_i,	wb_err_i,	wb_rty_i);input [31:0]		address;input [2:0] 		flag;output reg [2:0] test_status;output reg [1:0] test_done;//wishbone interfaceinput				wb_clk;			input				wb_rst;input				wb_ack_i; input				wb_err_i; input				wb_rty_i;input	[31:0]		wb_dat_i;output	reg [31:0]		wb_adr_o;output	reg [31:0]		wb_dat_o;output	reg 		wb_cyc_o; output	reg			wb_stb_o;output	reg [3:0]		wb_sel_o;output	reg 			wb_we_o;output	reg [2:0]		wb_cti_o;output	reg [1:0]		wb_bte_o;//====master status defineparameter m_idle = 3'b000;parameter m_wait_ack_read = 3'b001;parameter m_wait_ack_write = 3'b010;reg [2:0] status = m_idle;reg [31:0] ram_data;always @(posedge wb_clk)begin	test_status <= status;endalways @(posedge wb_clk)begin	if(wb_rst)		begin			wb_cyc_o <= 1'b0;			wb_stb_o <= 1'b0;			wb_we_o <= 1'b0;			wb_adr_o <= 32'h0;			wb_dat_o <= 32'h0;			test_done <= 2'b00;						status <= m_idle;		end	else		begin			case (status)			m_idle:				begin					if(3'd1 == flag)//read						begin							wb_cyc_o <= 1'b1;							wb_stb_o <= 1'b1;							wb_adr_o <= address;							wb_we_o <= 1'b0;														status <= m_wait_ack_read;						end					else if(3'd2 == flag)//write						begin							wb_adr_o <= address;							wb_dat_o <= 32'h4444_4444;							wb_cyc_o <= 1'b1;							wb_stb_o <= 1'b1;							wb_we_o <= 1'b1;														status <= m_wait_ack_write;						end					else						begin							wb_cyc_o <= 1'b0;							wb_stb_o <= 1'b0;							wb_we_o <= 1'b0;							wb_adr_o <= 32'h0;							wb_dat_o <= 32'h0;														status <= m_idle;						end				end							m_wait_ack_read:				begin					if(1'b1 != wb_ack_i)						begin							test_done <= 2'b10;							status <= m_wait_ack_read;						end					else						begin							ram_data <= wb_dat_i;														wb_cyc_o <= 1'b0;							wb_stb_o <= 1'b0;							wb_we_o <= 1'b0;							wb_adr_o <= 32'h0;							wb_dat_o <= 32'h0;														test_done <= 2'b01;							status <= m_idle;						end				end							m_wait_ack_write:				begin					if(1'b1 != wb_ack_i)						begin							test_done <= 2'b10;							status <= m_wait_ack_write;						end					else						begin							wb_cyc_o <= 1'b0;							wb_stb_o <= 1'b0;							wb_we_o <= 1'b0;							wb_adr_o <= 32'h0;							wb_dat_o <= 32'h0;														test_done <= 2'b01;							status <= m_idle;						end				end						default:				begin					status <= m_idle;				end						endcase		endendendmodule/************** EOF ****************/

 

 

 
 3》mkg_slave.v

 

/*** mkg_slave.v** rill create 2013-04-02**/`include "orpsoc-defines.v"module mkg_slave(   	address,	flag,	test_status,	test_done,	//===slave interface signals	wb_clk,				wb_rst,					wb_dat_i,				wb_adr_i,				wb_sel_i,			wb_cti_i,		wb_bte_i,			wb_we_i,			wb_cyc_i,			wb_stb_i,				wb_dat_o,			wb_ack_o,			wb_err_o,                    	wb_rty_o	);output reg [31:0] address;output reg [2:0] flag;input [2:0] test_status;input [1:0] test_done;//===slave interfaceinput [addr_width-1:0]      	wb_adr_i;input 			    			wb_stb_i;input 			    			wb_cyc_i;input [2:0] 				    wb_cti_i;input [1:0] 				    wb_bte_i;input 			      		    wb_clk;input 			          		wb_rst;input [31:0] 					wb_dat_i;input [3:0] 					wb_sel_i;input 							wb_we_i;	output reg [31:0] 		 		wb_dat_o;output reg 			      	 	wb_ack_o;output                			wb_err_o;output  					 	wb_rty_o;//===slave external parametersparameter addr_width = 32;parameter mycore_adr = 8'h97;	//===slave local regsreg [addr_width-1:0] num_1;//addr index:0x0reg [addr_width-1:0] num_2;//addr index:0x4reg [addr_width-1:0] sum;//addr index:0x8reg [31:0] master_status;//test reg 0xcreg [31:0] write_address;//0x10//====slave status defineparameter s_idle = 3'b000;parameter s_read = 3'b001;parameter s_write = 3'b010;reg [2:0] state = s_idle;reg [1:0] done_flag = 2'b0;reg [2:0] m_status;reg [1:0] m_done;//===mycore process start--->assign wb_err_o=0;assign wb_rty_o=0;//===slave process================always @(posedge wb_clk)begin	m_status <=  test_status;	m_done <= test_done;endalways @(posedge wb_clk)begin	master_status <= {27'b1001_1010_1011_1100_1101_1110_1111_0000,m_status,m_done};endalways @(*)begin	sum = num_1 + num_2;endalways @(posedge wb_clk)begin	if(wb_rst)		begin			address <= 32'h0;			flag <= 3'b0;			done_flag <= 2'b0;		end	else		begin			if(2'b10 == done_flag)				begin					address <= 32'h0;					flag <= 3'b0;				end			else if(2'b01 == done_flag)				begin					address <= write_address;					flag <= 3'b010;					done_flag <= 2'b10;				end			else				begin					if(3 == num_2)						begin							address <= write_address;							flag <= 3'b010;							done_flag <= 2'b01;						end					else						begin							address <= 32'h0;							flag <= 3'b0;							done_flag <= 2'b00;						end									end		endendalways @(posedge wb_clk)begin	if(wb_rst)		begin			state <= s_idle;		end	else		begin			case(state)			s_idle:				begin					wb_dat_o <= 1'b0;					wb_ack_o <= 1'b0;								if(wb_stb_i && wb_cyc_i && wb_we_i)						begin							state <= s_write;						end					else if(wb_stb_i && wb_cyc_i && !wb_we_i)						begin							state <= s_read;						end					else						begin							state <= s_idle;						end				end				s_write:				begin					if(wb_adr_i == {mycore_adr,24'h000000})						begin							num_1 <= wb_dat_i;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i == {mycore_adr,24'h000004})						begin							num_2 <= wb_dat_i;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i == {mycore_adr,24'h000010})						begin							write_address <= wb_dat_i;							wb_ack_o <= 1'b1;						end					else 						begin							//wb_ack_o=1'b0;						end									state <= s_idle;				end  			s_read:				begin					if(wb_adr_i=={mycore_adr,24'h000000})						begin							wb_dat_o <= num_1;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h000004})						begin							wb_dat_o <= num_2;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h000008})						begin							wb_dat_o <= sum;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h00000c})						begin							wb_dat_o <= master_status;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h000010})						begin							wb_dat_o <= write_address;							wb_ack_o <= 1'b1;						end					else 						begin							wb_dat_o = 0;							wb_ack_o <= 1'b1;						end									state <= s_idle;				end							default:				begin					state <= s_idle;				end					endcase		endendendmodule/************** EOF ****************/

 

 

 
 4》d_bus 优先级代码

 

 
 5》linux driver

ip_mkg.c:

 

/*** rill mkg driver**/#include 
#include
#include
#include
#include
#include
/* get_user and put_user *///#include
//#include
#include
/*ioremap*/#include
/*cleanup_module*/#include
#include "ip_mkg.h"void __iomem *g_mkg_mem_base = NULL;static int device_open(struct inode *inode, struct file *file){ g_mkg_mem_base = ioremap(MKG_MEM_BASE,MKG_MEM_LEN); if(NULL == g_mkg_mem_base) { printk(KERN_ERR "mkg open ioremap error!\n"); return -1; } else { printk("mkg ioremap addr:%d!\n",(int)g_mkg_mem_base); } return 0;}static int device_release(struct inode *inode, struct file *file){ return 0;}static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t *offset){ /*int ret_val = 0; char * data = NULL; data = (char*)kmalloc(4, GFP_KERNEL); if((ret_val = copy_from_user(new_regs, (struct reg_data*)ioctl_param, sizeof(struct reg_data))) != 0) ioread32(g_mkg_mem_base+length); printk("============read:%d\n",);*/ return 1;}static ssize_t device_write(struct file *filp, const char *buffer, size_t count, loff_t *offset){ //iowrite32(2,g_mkg_mem_base); return 1;}long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param){#if 0 int ret_val = 0; unsigned int ret = 0; struct reg_data *new_regs; printk("ioctl======\n"); switch(ioctl_num) { case IOCTL_REG_SET: { new_regs = (struct reg_data*)kmalloc(sizeof(struct reg_data), GFP_KERNEL); if((ret_val = copy_from_user(new_regs, (struct reg_data*)ioctl_param, sizeof(struct reg_data))) != 0) { kfree(new_regs); printk(KERN_ERR " error copy line_datafrom user.\n"); return -1; } //iowrite16(new_regs->value,g_mkg_mem_base+new_regs->addr); kfree(new_regs); } break; case IOCTL_REG_GET: { new_regs = (struct reg_data*)kmalloc(sizeof(struct reg_data), GFP_KERNEL); if((ret_val = copy_from_user(new_regs, (struct reg_data*)ioctl_param, sizeof(struct reg_data))) != 0) { kfree(new_regs); printk(KERN_ERR " error copy line_datafrom user.\n"); return -1; } //ret = ioread16(g_mkg_mem_base+new_regs->addr); kfree(new_regs); return ret; } break; }#endif return -1;}struct file_operations our_file_ops = { .unlocked_ioctl = device_ioctl, .read = device_read, .write = device_write, .open = device_open, .release = device_release, .owner = THIS_MODULE,};void test(void){ int loop = 0; unsigned int phy_addr1 = 0; unsigned int phy_addr2 = 0; int * virtual_addr1 = NULL; int * virtual_addr2 = NULL; printk("<----ip_mkg test start---->\n"); //=====ip_mkg reg test======================================================== #if 1 printk("reg test start==\n"); iowrite32(0x11223344,g_mkg_mem_base); iowrite32(0x00000097,g_mkg_mem_base+0x10); iowrite32(0x03000000,g_mkg_mem_base+4); printk("reg test start1==\n"); printk("reg test start2==\n"); printk("reg test start3==\n"); for(loop=0;loop<7;loop++) printk("====reg addr==0x%x==reg value:0x%x==\n",loop*4,ioread32(g_mkg_mem_base+4*loop)); #endif //========================================================================= //============mem write test #if 0 printk("mem write test start==\n"); iowrite32(0x97000004,g_mkg_mem_base); iowrite32(0x2,g_mkg_mem_base+0xc); printk("======reg:c value:0x%x==\n",ioread32(g_mkg_mem_base+0xc)); printk("======reg:14 value:0x%x==\n",ioread32(g_mkg_mem_base+0x14)); printk("======reg:18 value:0x%x==\n",ioread32(g_mkg_mem_base+0x18)); printk("======reg:1c value:0x%x==\n",ioread32(g_mkg_mem_base+0x1c)); printk("======reg:20 value:0x%x==\n",ioread32(g_mkg_mem_base+0x20)); printk("======reg:24 value:0x%x==\n",ioread32(g_mkg_mem_base+0x24)); for(loop = 0;loop<10;loop++) printk("wait=write=\n"); printk("wait=write=\n"); iowrite32(0x1,g_mkg_mem_base+0xc); printk("======reg:c value:0x%x==\n",ioread32(g_mkg_mem_base+0xc)); for(loop = 0;loop<10;loop++) printk("wait=read=\n"); printk("wait=read=\n"); printk("======reg:10 value:0x%x==\n",ioread32(g_mkg_mem_base+0x10)); printk("======reg:c value:0x%x==\n\n",ioread32(g_mkg_mem_base+0xc)); #endif //============mem read test #if 0 printk("mem read test start==\n"); virtual_addr1 = (int *)kmalloc(sizeof(int), GFP_KERNEL); virtual_addr2 = (int *)kmalloc(sizeof(int), GFP_KERNEL); *virtual_addr1 = 0x55; *virtual_addr2 = 0x66; phy_addr1 = virt_to_phys(virtual_addr1); phy_addr2 = virt_to_phys(virtual_addr2); printk("virtual addr1:0x%x==phy addr1:0x%x==\n",(int)virtual_addr1,phy_addr1); printk("virtual addr2:0x%x==phy addr2:0x%x==\n",(int)virtual_addr2,phy_addr2); iowrite32(phy_addr1,g_mkg_mem_base); iowrite32(0x1,g_mkg_mem_base+0xc); printk("wait=read=\n"); printk("======reg:0 value:0x%x==\n",ioread32(g_mkg_mem_base)); printk("======reg:c value:0x%x==\n",ioread32(g_mkg_mem_base+0xc)); printk("====phy addr1==0x%x==ram value:0x%x==\n",phy_addr1,ioread32(g_mkg_mem_base+0x10)); printk("======reg:c value:0x%x==\n\n",ioread32(g_mkg_mem_base+0xc)); iowrite32(phy_addr2,g_mkg_mem_base); iowrite32(0x1,g_mkg_mem_base+0xc); printk("wait=2=\n"); printk("======reg:0 value:0x%x==\n",ioread32(g_mkg_mem_base)); printk("======reg:c value:0x%x==\n",ioread32(g_mkg_mem_base+0xc)); printk("====phy addr2==0x%x==ram value:0x%x==\n",phy_addr2,ioread32(g_mkg_mem_base+0x10)); printk("======reg:c value:0x%x==\n\n",ioread32(g_mkg_mem_base+0xc)); kfree(virtual_addr1); kfree(virtual_addr2); #endif printk("<----ip_mkg test end---->\n"); }int init_module(){ int ret_val; int ret; void __iomem *ret_from_request; //=== Allocate character device ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &our_file_ops); if (ret_val < 0) { printk(KERN_ALERT " device %s failed(%d)\n", DEVICE_NAME, ret_val); return ret_val; } ret = check_mem_region(MKG_MEM_BASE, MKG_MEM_LEN); if (ret < 0) { printk(KERN_ERR "mkg check_mem_region bussy error!\n"); return -1; } ret_from_request = request_mem_region(MKG_MEM_BASE, MKG_MEM_LEN, "ip_mkg"); //===ioremap mkg registers g_mkg_mem_base = ioremap(MKG_MEM_BASE,MKG_MEM_LEN); if(NULL == g_mkg_mem_base) { printk(KERN_ERR "mkg ioremap error!\n"); return -1; } else { ;//printk("mkg ioremap addr:%d!\n",(unsigned int)g_mkg_mem_base); } printk("mkg module init done!\n"); test(); return 0;}void cleanup_module(){ release_mem_region(MKG_MEM_BASE, MKG_MEM_LEN); unregister_chrdev(MAJOR_NUM, DEVICE_NAME);}MODULE_LICENSE("GPL");MODULE_AUTHOR("Rill zhen:rill_zhen@126.com");

 

 

 

ip_mkg.h:

 

#ifndef __IP_MKG_H__#define __IP_MKG_H__#define MAJOR_NUM	102#define DEVICE_NAME	"ip_mkg"#define MKG_MEM_BASE 0x97000000#define MKG_MEM_LEN	32#define IOCTL_REG_SET 0#define IOCTL_REG_GET 1struct reg_data {	unsigned short addr;	int value;};#endif

 

 

 

 
 6》makefile

 

# To build modules outside of the kernel tree, we run "make"# in the kernel source tree; the Makefile these then includes this# Makefile once again.# This conditional selects whether we are being included from the# kernel Makefile or not.ifeq ($(KERNELRELEASE),)    # Assume the source tree is where the running kernel was built    # You should set KERNELDIR in the environment if it's elsewhere    KERNELDIR ?= /home/openrisc/soc-design/linux    # The current directory is passed to sub-makes as argument    PWD := $(shell pwd)modules:	make -C $(KERNELDIR) M=$(PWD) modules ARCH=openrisc CROSS_COMPILE=or32-linux-modules_install:	make -C $(KERNELDIR) M=$(PWD) modules_install ARCH=openrisc CROSS_COMPILE=or32-linux-clean:	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers.PHONY: modules modules_install cleanelse    # called from kernel build system: just declare what our modules are    obj-m := ip_mkg.oendif

 

 

 
2.1.3 模块连接图:

 

 

2.1.4 验证结果:

 

2.2 master读功能
 1》driver向slave的num_1寄存器里写入0x11223344
 2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 读的地址,其实就是num_1)
 3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始读)
 4》打印
 5》driver读slave,验证master读入的值是否正确。

2.2.1 code list:mycore.v,mkg_master.v,mkg_slave.v

 1》mycore.v

 

/*** mycore.v** rill create 2013-04-02**/`include "orpsoc-defines.v"module mycore(   	//===slave interface signals	wb_clk,	wb_rst,			wb_dat_i,	wb_adr_i,	wb_sel_i,	wb_cti_i,	wb_bte_i,	wb_we_i,	wb_cyc_i,	wb_stb_i,			wb_dat_o,	wb_ack_o,	wb_err_o,	wb_rty_o,				//===master interface signals	m_adr,	m_din,	m_dout,	m_cyc,	m_stb,	m_sel,	m_we,	m_ack,	m_err,	m_rty,	m_cti,	m_bte);//===slave interfaceinput [31:0]      				wb_adr_i;input 			    			wb_stb_i;input 			    			wb_cyc_i;input [2:0] 				    wb_cti_i;input [1:0] 				    wb_bte_i;input 			      		    wb_clk;input 			          		wb_rst;input [31:0] 					wb_dat_i;input [3:0] 					wb_sel_i;input 							wb_we_i;	output  [31:0] 		 			wb_dat_o;output  			      	 	wb_ack_o;output                			wb_err_o;output  					 	wb_rty_o;//===master interfaceinput				m_ack; input				m_err; input				m_rty;input	[31:0]		m_din;output	[31:0]		m_adr;output	[31:0]		m_dout;output				m_cyc; output				m_stb;output	[3:0]		m_sel;output				m_we;output	[2:0]		m_cti;output	[1:0]		m_bte;wire [31:0] address;wire [2:0] flag;wire [2:0] test;wire [1:0] done;wire [31:0] value;//===slave external parametersparameter addr_width = 32;parameter mycore_adr = 32'h97;mkg_slave mkg_slave0(	.address (address),	.flag (flag),	.test_status (test),	.test_done (done),	.ram_data (value),		.wb_clk (wb_clk),	.wb_rst (wb_rst),				.wb_dat_i (wb_dat_i),	.wb_adr_i (wb_adr_i),	.wb_sel_i (wb_sel_i),	.wb_cti_i (wb_cti_i),	.wb_bte_i (wb_bte_i),	.wb_we_i (wb_we_i),	.wb_cyc_i (wb_cyc_i),	.wb_stb_i (wb_stb_i),			.wb_dat_o (wb_dat_o),	.wb_ack_o (wb_ack_o),	.wb_err_o (wb_err_o),	.wb_rty_o (wb_rty_o));mkg_master mkg_master(   	.address (address),	.flag (flag),	.test_status (test),	.test_done (done),	.ram_data (value),		.wb_clk (wb_clk),	.wb_rst (wb_rst),	.wb_adr_o (m_adr),	.wb_dat_o (m_dout),	.wb_sel_o (m_sel),	.wb_we_o (m_we),	.wb_cyc_o (m_cyc),	.wb_stb_o (m_stb),	.wb_cti_o (m_cti),	.wb_bte_o (m_bte),  	.wb_dat_i (m_din),	.wb_ack_i (m_ack),	.wb_err_i (m_err),	.wb_rty_i (m_rty));endmodule/************** EOF ****************/

 

 
 2》mkg_master.v

 

/*** mkg_master.v** rill create 2013-04-02**/module mkg_master(   	address,	flag,	test_status,	test_done,	ram_data,	//wishbone interface	wb_clk,				wb_rst,			wb_adr_o,	wb_dat_o,	wb_sel_o,	wb_we_o,	wb_cyc_o,	wb_stb_o,	wb_cti_o,	wb_bte_o,  	wb_dat_i,	wb_ack_i,	wb_err_i,	wb_rty_i);input [31:0]		address;input [2:0] 		flag;output reg [2:0] test_status;output reg [1:0] test_done;output reg [31:0] ram_data;//wishbone interfaceinput				wb_clk;			input				wb_rst;input				wb_ack_i; input				wb_err_i; input				wb_rty_i;input	[31:0]		wb_dat_i;output	reg [31:0]		wb_adr_o;output	reg [31:0]		wb_dat_o;output	reg 		wb_cyc_o; output	reg			wb_stb_o;output	reg [3:0]		wb_sel_o;output	reg 			wb_we_o;output	reg [2:0]		wb_cti_o;output	reg [1:0]		wb_bte_o;//====master status defineparameter m_idle = 3'b000;parameter m_wait_ack_read = 3'b001;parameter m_wait_ack_write = 3'b010;reg [2:0] status = m_idle;always @(posedge wb_clk)begin	test_status <= status;endalways @(posedge wb_clk)begin	if(wb_rst)		begin			wb_cyc_o <= 1'b0;			wb_stb_o <= 1'b0;			wb_we_o <= 1'b0;			wb_adr_o <= 32'h0;			wb_dat_o <= 32'h0;			test_done <= 2'b00;						status <= m_idle;		end	else		begin			case (status)			m_idle:				begin					if(3'd1 == flag)//read						begin							wb_cyc_o <= 1'b1;							wb_stb_o <= 1'b1;							wb_adr_o <= address;							wb_we_o <= 1'b0;														status <= m_wait_ack_read;						end					else if(3'd2 == flag)//write						begin							wb_adr_o <= address;							wb_dat_o <= 32'h4444_4444;							wb_cyc_o <= 1'b1;							wb_stb_o <= 1'b1;							wb_we_o <= 1'b1;														status <= m_wait_ack_write;						end					else						begin							wb_cyc_o <= 1'b0;							wb_stb_o <= 1'b0;							wb_we_o <= 1'b0;							wb_adr_o <= 32'h0;							wb_dat_o <= 32'h0;														status <= m_idle;						end				end							m_wait_ack_read:				begin					if(1'b1 != wb_ack_i)						begin							test_done <= 2'b10;							status <= m_wait_ack_read;						end					else						begin							ram_data <= wb_dat_i;														wb_cyc_o <= 1'b0;							wb_stb_o <= 1'b0;							wb_we_o <= 1'b0;							wb_adr_o <= 32'h0;							wb_dat_o <= 32'h0;														test_done <= 2'b01;							status <= m_idle;						end				end							m_wait_ack_write:				begin					if(1'b1 != wb_ack_i)						begin							test_done <= 2'b10;							status <= m_wait_ack_write;						end					else						begin							wb_cyc_o <= 1'b0;							wb_stb_o <= 1'b0;							wb_we_o <= 1'b0;							wb_adr_o <= 32'h0;							wb_dat_o <= 32'h0;														test_done <= 2'b01;							status <= m_idle;						end				end						default:				begin					status <= m_idle;				end						endcase		endendendmodule/************** EOF ****************/

 

 
 3》mkg_slave.v

 

/*** mkg_slave.v** rill create 2013-04-02**/`include "orpsoc-defines.v"module mkg_slave(   	address,	flag,	test_status,	test_done,	ram_data,	//===slave interface signals	wb_clk,				wb_rst,					wb_dat_i,				wb_adr_i,				wb_sel_i,			wb_cti_i,		wb_bte_i,			wb_we_i,			wb_cyc_i,			wb_stb_i,				wb_dat_o,			wb_ack_o,			wb_err_o,                    	wb_rty_o	);output reg [31:0] address;output reg [2:0] flag;input [2:0] test_status;input [1:0] test_done;input [31:0] ram_data;//===slave interfaceinput [addr_width-1:0]      	wb_adr_i;input 			    			wb_stb_i;input 			    			wb_cyc_i;input [2:0] 				    wb_cti_i;input [1:0] 				    wb_bte_i;input 			      		    wb_clk;input 			          		wb_rst;input [31:0] 					wb_dat_i;input [3:0] 					wb_sel_i;input 							wb_we_i;	output reg [31:0] 		 		wb_dat_o;output reg 			      	 	wb_ack_o;output                			wb_err_o;output  					 	wb_rty_o;//===slave external parametersparameter addr_width = 32;parameter mycore_adr = 8'h97;	//===slave local regsreg [addr_width-1:0] num_1;//addr index:0x0reg [addr_width-1:0] num_2;//addr index:0x4reg [addr_width-1:0] sum;//addr index:0x8reg [31:0] master_status;//test reg 0xcreg [31:0] write_address;//0x10reg [31:0] read_value;//0x14//====slave status defineparameter s_idle = 3'b000;parameter s_read = 3'b001;parameter s_write = 3'b010;reg [2:0] state = s_idle;reg [1:0] done_flag = 2'b0;reg [2:0] m_status;reg [1:0] m_done;//===mycore process start--->assign wb_err_o=0;assign wb_rty_o=0;//===slave process================always @(posedge wb_clk)begin	m_status <=  test_status;	m_done <= test_done;	read_value <= ram_data;endalways @(posedge wb_clk)begin	master_status <= {27'b1001_1010_1011_1100_1101_1110_1111_0000,m_status,m_done};endalways @(*)begin	sum = num_1 + num_2;endalways @(posedge wb_clk)begin	if(wb_rst)		begin			address <= 32'h0;			flag <= 3'b0;			done_flag <= 2'b0;		end	else		begin			if(2'b10 == done_flag)				begin					address <= 32'h0;					flag <= 3'b0;				end			else if(2'b01 == done_flag)				begin					address <= write_address;					flag <= 3'b001;					done_flag <= 2'b10;				end			else				begin					if(3 == num_2)						begin							address <= write_address;							flag <= 3'b001;							done_flag <= 2'b01;						end					else						begin							address <= 32'h0;							flag <= 3'b0;							done_flag <= 2'b00;						end									end		endendalways @(posedge wb_clk)begin	if(wb_rst)		begin			state <= s_idle;		end	else		begin			case(state)			s_idle:				begin					wb_dat_o <= 1'b0;					wb_ack_o <= 1'b0;								if(wb_stb_i && wb_cyc_i && wb_we_i)						begin							state <= s_write;						end					else if(wb_stb_i && wb_cyc_i && !wb_we_i)						begin							state <= s_read;						end					else						begin							state <= s_idle;						end				end				s_write:				begin					if(wb_adr_i == {mycore_adr,24'h000000})						begin							num_1 <= wb_dat_i;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i == {mycore_adr,24'h000004})						begin							num_2 <= wb_dat_i;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i == {mycore_adr,24'h000010})						begin							write_address <= wb_dat_i;							wb_ack_o <= 1'b1;						end					else 						begin							//wb_ack_o=1'b0;						end									state <= s_idle;				end  			s_read:				begin					if(wb_adr_i=={mycore_adr,24'h000000})						begin							wb_dat_o <= num_1;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h000004})						begin							wb_dat_o <= num_2;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h000008})						begin							wb_dat_o <= sum;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h00000c})						begin							wb_dat_o <= master_status;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h000010})						begin							wb_dat_o <= write_address;							wb_ack_o <= 1'b1;						end					else if(wb_adr_i=={mycore_adr,24'h000014})						begin							wb_dat_o <= read_value;							wb_ack_o <= 1'b1;						end					else 						begin							wb_dat_o = 0;							wb_ack_o <= 1'b1;						end									state <= s_idle;				end							default:				begin					state <= s_idle;				end					endcase		endendendmodule/************** EOF ****************/

 

 
 4》d_bus 优先级代码:arbiter_dbus.v(与写相同)
 
 5》linux driver(与写相同)
 
 6》makefile(与写相同)
 
2.2.3 模块连接图:

 

 

2.2.4 验证结果:

 

 

2.3 小结

写driver时要注意大小端的问题。
比如想写0x97000000(master要访问的地址),在driver里面要写0x00000097。

 

转载地址:http://gkoum.baihongyu.com/

你可能感兴趣的文章
SQL-mysql设置utf8编码方法
查看>>
5.4 异步TCP编程(三)
查看>>
采访Hadley Wickham
查看>>
iframe中的各种跳转方法
查看>>
oracle编程、操作不良习惯总结
查看>>
每天一个linux命令(26):用SecureCRT来上传和下载
查看>>
Oracle 表空间状态
查看>>
为redis分配一个新的端口
查看>>
利用Python做绝地科学家(外挂篇)
查看>>
费下载最新版万能视频格式转换器是一款功能强大的全能视频格式转换软件
查看>>
算法实战——多叉树全路径遍历
查看>>
MySQL数据类型和常用字段属性总结
查看>>
斑点检测(LoG,DoG)(下)
查看>>
《CLR Via C# 第3版》笔记之(二十二) - APM和EAP
查看>>
洛谷P5111 zhtobu3232的线段树
查看>>
Angular Cli 创建的Angular项目应用本地css文件和js文件
查看>>
java代码getHostAddress .getHostName()的练习
查看>>
【转】一个孩子关于MaD的思考概述
查看>>
C 再识数组指针 指针数组的概念
查看>>
第5次作业
查看>>