TA的每日心情 | 怒 2019-11-20 15:22 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
7 I( X! r) p! B# v本小节中省略了一些virtualbox下的操作细节,请参考上一篇文章:linux学习之路_添加自己的slave IP core到ORSoC并测试# |7 Y: ] E _& ?$ G4 k
, q& K- s0 Z/ X
5 c# Z1 I1 t" i1 R% ]
1,控制流程
5 B Z* d7 Y0 R1>mycore的linux下的driver写slave+ V( H8 r; r3 U9 N, M( Z: z
2>slave根据driver发来的指令控制master5 d K" j2 {, z6 o
3>master进行相应操作,并返回给slave0 W; ?. m- S9 ?* W/ G# E
4>mycore的linux下的driver读slave
) }) c6 y' K& C, g+ {# k j8 J
u6 Z; d2 v t2,功能概述. \ Q( Z% C# c2 N5 j
2.1 master写功能4 U0 C8 M3 X2 @% `+ z( U, U z: `
1》driver向slave的num_1寄存器里写入0x11223344
' ]2 ~4 i8 I; a, e6 w1 ~ 2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 写的地址,其实就是num_1)6 |/ K+ Z. H. V% K4 p, o% ~* S
3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始写)$ b$ z8 ?/ x2 g4 _" Z
4》打印; c; p: J6 K3 Y3 T7 X2 A6 r' [+ o
5》driver读slave,验证master写入的值是否正确。
7 ]- T+ T4 {# T; A! a( {1 c
' ]9 y2 ~) Z8 r2 \$ ^% Q" g- P# @& U( |# E h+ J$ b9 }
2.1.0 模块总连接图
( g7 d0 g6 Y( m! B
u" k* v8 R/ ^) E
/ x9 ?( b/ H$ R8 H. O3 q7 Q! b4 G) ?2 g7 k$ l% s4 w" C% T
" w# @" S- v: Z A7 T" X' j
& n8 m. Z/ _0 B }: f% t( r
2.1.1 代码修改流程说明:跟单独包含slave的ipcore差不多& |/ |1 U* b- k: N/ ]% R! a% ?
1》编写符合wishbone master接口和相应内部逻辑的ip core:mycore$ l# S9 [' i. ?, J3 W- }( a* N9 O
2》d_bus的arbiter增加master接口:master2. j, z5 I* O/ R1 H5 ?
3》修改master的仲裁优先级; [( I, l" P3 v. R
4》例化本ipcore$ E1 v( ^0 n: z" L1 A
5》编写linux下的driver并测试验证; Y& S6 X3 g3 w
$ r% H" H5 W0 m2 M$ h
2.1.2 code list:mycore.v,mkg_master.v,mkg_slave.v
! K. [4 ^) `# W- a- B 1》mycore.v
6 v/ H2 r) Z3 M: {- M5 W
" l; o" G% T, j9 k5 q# P U/ }* Y
- /*
- *
- * 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 interface
- input [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 interface
- input 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 parameters
- parameter 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 ****************/" i0 b9 z) d/ ~8 [- z
9 M% L! p" a1 c3 C, d) H4 K
. _6 C) [' g8 }: D! G0 j3 O
+ e1 M. O% H& ~6 O/ y3 n7 V% {* E9 B- d
2》mkg_master.v) [' K! ]( D5 }
. ~$ C' B0 t7 g
$ e& q% \' M7 T5 G- /*
- *
- * 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 interface
- input 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 define
- parameter 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;
- end
- always @(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
- end
- end
- endmodule
- /************** EOF ****************/, x* T. [: L2 M- o% ?! I+ S Y
8 @% m+ Z ~+ z3 Z) c% k! _5 _3 p
1 w1 U' `4 l! f9 J9 m0 |9 [' Y& R% V2 y8 c _7 {; m$ S
3》mkg_slave.v
5 C; u2 K k3 C5 I1 H! \& F
. z7 K" U5 w( \2 \% Q* m
8 P- z% ~# P( W% W9 j& f: c- /*
- *
- * 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 interface
- input [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 parameters
- parameter addr_width = 32;
- parameter mycore_adr = 8'h97;
- //===slave local regs
- reg [addr_width-1:0] num_1;//addr index:0x0
- reg [addr_width-1:0] num_2;//addr index:0x4
- reg [addr_width-1:0] sum;//addr index:0x8
- reg [31:0] master_status;//test reg 0xc
- reg [31:0] write_address;//0x10
- //====slave status define
- parameter 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;
- end
- always @(posedge wb_clk)
- begin
- master_status <= {27'b1001_1010_1011_1100_1101_1110_1111_0000,m_status,m_done};
- end
- always @(*)
- begin
- sum = num_1 + num_2;
- end
- always @(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
- end
- end
- always @(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
- end
- end
- endmodule
- /************** EOF ****************/
( f* o# s& `8 q+ L! p0 F ) q3 r/ J: l. g U/ Q' ~+ j) h6 L
) O' F5 a0 _4 } ?' I1 m
3 U/ d1 L8 ~# z, W/ P5 C
4》d_bus 优先级代码
% [4 c7 n0 D* J' v8 Z
4 E' ?) A& _ x: ~1 H
( T G$ x1 j+ x, u( |$ J9 `9 H
: |% P3 Z1 t' _4 l8 v
0 |- R+ Y7 Z$ [* E; S5 X
}% y4 `8 @9 T3 }, M 5》linux driver) X2 h1 `. q& e6 n+ n3 I
7 i6 q9 c8 U, I( T% f1 V' f) f* ?$ B
ip_mkg.c:
, `' h/ F- o7 P9 p7 E) g$ }! x6 H {
, W! t! h o0 ^( Z2 F
- /*
- *
- * rill mkg driver
- *
- */
- #include <linux/vmalloc.h>
- #include <linux/slab.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <asm/uaccess.h> /* get_user and put_user */
- //#include <linux/clk.h>
- //#include <linux/ioport.h>
- #include <asm/io.h> /*ioremap*/
- #include <linux/platform_device.h> /*cleanup_module*/
- #include <asm-generic/io.h>
- #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");
4 i; V/ V! B# Q: U! M6 f" @: ]8 H 1 W( C+ G4 F( I7 D3 s! x1 z S
2 Q. Y9 |" _* K3 v, `2 R! u
M* f. `( E; o# o) B4 G1 m( _# x7 O9 w: z* a1 d; h" d* A
ip_mkg.h:
4 R% o. }/ S, q+ {" A( S* O$ }. `& t) ^- U
' t8 d/ Y" e2 ?9 T/ V
- #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 1
- struct reg_data
- {
- unsigned short addr;
- int value;
- };
- #endif
3 W# V1 J& U# ^4 [ ) z2 _8 M0 D2 l' u4 i) T
4 m' i% `# j5 c$ o, Z 6》makefile& \$ h0 a; y) @$ ~3 y6 b
$ F9 H3 U& c s1 k
0 S& \- }* ?3 X( D$ Y" |/ b- # 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 clean
- else
- # called from kernel build system: just declare what our modules are
- obj-m := ip_mkg.o
- endif
" E$ U/ A0 y4 D4 P , {6 J" L) w7 C7 X/ Z, ?3 i, d/ r
- I& S- s% p* ?& h
* ~( E1 h, d1 X* W) S2.1.3 模块连接图:7 n9 `# _4 s$ u6 g+ Q
$ J2 x, j- _( \4 h, N( J
' p* o# f/ I3 }4 t8 f
6 B/ g8 q. R0 B; y: ?; z
) d, ~3 }4 p$ M0 G! G F2.1.4 验证结果:1 z. o9 a/ ?1 w: I- Y
5 `! j& S6 ?! j1 k6 j4 H
1 P* W* ?" @3 J |! T% U
: b1 c( I; ]* f* P2 l) l, ?! d5 J, Y9 D
2 S1 _+ W3 T- J& p
3 M% h' T7 [+ P* F0 G- k, U. l! R2.2 master读功能: ]0 d5 Q- i n) A
1》driver向slave的num_1寄存器里写入0x11223344
+ i" ^8 }2 I+ ?3 P9 x0 }3 z 2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 读的地址,其实就是num_1)
/ a; |* n# h% N/ @2 P6 z7 L 3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始读)
; A7 I. B3 X6 X0 z6 u* G5 \ 4》打印, p5 {$ h+ N; V$ S2 F
5》driver读slave,验证master读入的值是否正确。- ?. q0 Q5 D, \( H% L/ x
! _/ n2 |' _+ ~
- N( i: |7 `5 R" z0 d5 D. `$ \8 E
2.2.1 code list:mycore.v,mkg_master.v,mkg_slave.v
: i0 o d* G4 x3 X3 X. p- H 1》mycore.v
/ |3 r4 Y. S* I% b$ }: K) W
# Z9 p: c9 D, n; k9 ^6 D( u( s0 U2 p2 @: S u( X
- /*
- *
- * 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 interface
- input [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 interface
- input 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 parameters
- parameter 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 ****************/! P! z l3 @8 R X' S1 i* z
S( A( ?+ o/ T* O* D# ^
: B, E" X1 l+ x" v. T c2 S7 e! n" M
2》mkg_master.v
4 ]2 p3 Y! z/ K3 W5 _
{9 T/ u7 P4 @: I! A4 v% X1 G" C' d, w" L& F" X
- /*
- *
- * 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 interface
- input 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 define
- parameter 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;
- end
- always @(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
- end
- end
- endmodule
- /************** EOF ****************/
. u0 [' X3 @ {3 ?& s. j 1 L- i/ } K1 O$ H- I' T# n
5 t. D% U+ g; I7 q; r
$ C, H8 ?" o3 d9 Y
3》mkg_slave.v
2 D( r) ]1 {" b5 w
2 K1 ]3 Q1 P# f; ]6 D0 C+ B
A" x( R+ N. L* ]( x. H y- /*
- *
- * 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 interface
- input [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 parameters
- parameter addr_width = 32;
- parameter mycore_adr = 8'h97;
- //===slave local regs
- reg [addr_width-1:0] num_1;//addr index:0x0
- reg [addr_width-1:0] num_2;//addr index:0x4
- reg [addr_width-1:0] sum;//addr index:0x8
- reg [31:0] master_status;//test reg 0xc
- reg [31:0] write_address;//0x10
- reg [31:0] read_value;//0x14
- //====slave status define
- parameter 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;
- end
- always @(posedge wb_clk)
- begin
- master_status <= {27'b1001_1010_1011_1100_1101_1110_1111_0000,m_status,m_done};
- end
- always @(*)
- begin
- sum = num_1 + num_2;
- end
- always @(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
- end
- end
- always @(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
- end
- end
- endmodule
- /************** EOF ****************/
& f1 n$ l( r. J% Q! [$ J* d+ X , ?- J6 Q0 i1 s2 d& Y3 O
9 G% s+ m: k) j3 f$ u! Y% G
0 r& @) d7 z3 f) h {" Z u; a" y 4》d_bus 优先级代码:arbiter_dbus.v(与写相同) _8 e% Y: |: U8 s- l% K$ a! V( K
: `; S$ I3 O& ]! `3 i 5》linux driver(与写相同)
2 z1 V; t6 |0 c5 H7 g' m' C
* u: ~% N. x0 n0 h 6》makefile(与写相同)1 c. d' ]+ r) }% Z4 [+ M" g
- ?. I; c2 A1 P2 w& S# W
2.2.3 模块连接图:
! b* n! P! S9 K6 X8 U3 p. u$ `3 k1 Z8 T
: N5 m2 I# L. l; p9 D8 h3 M
& |% |* W, M5 |) p6 Z. S5 `
/ r4 t; C& I8 z
2.2.4 验证结果:& r! f$ `" r3 M0 z, T
5 V* @" O8 X; s0 p u4 ~- m - r9 X8 d) S8 }1 U9 N9 ~2 ?
9 e9 `0 @3 |0 V- l, C0 e) [; p R9 [$ m1 X4 s3 r
) ]* M# y- x: j1 o3 t. f9 h$ L5 Y5 @' ?) z, L& V9 q/ M: I
2.3 小结8 n* P* L; v% p8 |
写driver时要注意大小端的问题。( N! |* I2 o$ f, |1 l n
比如想写0x97000000(master要访问的地址),在driver里面要写0x00000097。
: [- O7 @& l& s9 b# b/ j |
|