TA的每日心情 | 怒 2019-11-20 15:22 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
4 T8 [5 `( A4 b' N- z; f5 d本小节中省略了一些virtualbox下的操作细节,请参考上一篇文章:linux学习之路_添加自己的slave IP core到ORSoC并测试
8 r7 |) f; w3 A X8 j6 T; H
9 v/ B& u& V( v% T" K: Q% i8 P
& l5 H" [/ d: f. r1,控制流程
' d7 d1 \ L2 U% y* ]4 R2 F7 O r$ M1>mycore的linux下的driver写slave
' S1 h) `4 F, O" Q& R2>slave根据driver发来的指令控制master
6 [$ [2 Y2 k1 h; g G2 ^3>master进行相应操作,并返回给slave
/ o% C2 X9 E* ^1 k0 h) E/ s! {4>mycore的linux下的driver读slave
$ m( ^2 N# s9 b8 v* _8 u- K5 I! }- }7 v
2,功能概述2 {2 m, z7 ?4 f4 h' \/ m
2.1 master写功能' P) Q2 K; f* k% t1 I# X
1》driver向slave的num_1寄存器里写入0x112233441 O o3 f9 p8 O
2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 写的地址,其实就是num_1)
" I" w2 H6 D1 \$ r4 K 3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始写)
+ w9 X0 i; ?; E* t, r, D6 t2 w: N 4》打印
w0 A& o; t( X! b 5》driver读slave,验证master写入的值是否正确。. w/ v S- M1 Q. K# `0 I
9 r9 r" |5 i6 }# g/ B" |9 o7 B
' ^5 Z z2 b5 f' H; g
2.1.0 模块总连接图
& ~4 v5 g/ _' H8 D( d% ?$ Z
+ E; O& V. f& a: ~! w1 H4 E
8 h5 R- @9 r, Y- f6 i: N
. ?" G3 C% W9 d' w# m6 J6 W$ F9 K; Y! p, E, H7 {. B' U( I! W2 z
0 ~ }" l- e0 |/ P
2.1.1 代码修改流程说明:跟单独包含slave的ipcore差不多
, B0 P6 ~1 e4 y) ] 1》编写符合wishbone master接口和相应内部逻辑的ip core:mycore
# |- w) Q4 A Q+ n3 N4 w) B 2》d_bus的arbiter增加master接口:master2* v# d$ A/ e- a/ ?: e% _. P
3》修改master的仲裁优先级
* X, ~! m+ c8 r$ Q 4》例化本ipcore
4 T) w* o9 x5 |+ p4 }" B" j 5》编写linux下的driver并测试验证
7 H, Q' O) @% M- \ 6 `3 \( z7 u* j. n+ z1 ~
2.1.2 code list:mycore.v,mkg_master.v,mkg_slave.v) r& m7 O8 t: m7 x4 p" w
1》mycore.v
& g# E+ r% C1 u
[2 E2 F) L1 ]' S; ?, P' ]9 V
3 @ y/ w9 e, P7 W j8 v4 j- /*
- *
- * 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 ****************/
) P* t/ j# P& i! |# `
4 T* r: T5 V3 g0 U9 Y7 J3 Q8 j5 k: H! g' W; _1 b8 G0 Z
; q4 m. K! B2 [* `2 ], C5 a 2》mkg_master.v
7 U; h( `# W# S' w" h9 q4 A0 t8 @" s% U
* f# E* O2 z) g% 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 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 ****************/
( y9 p# g2 O7 I2 o( d2 f3 F
: w4 A2 q/ |' F f/ ~" p - v4 r7 K! o0 U8 @8 X) p/ }
9 W. W2 E% w$ B# Q
3》mkg_slave.v
8 _* n/ x: R; y8 L6 L0 n( V6 c" f$ a5 f x' R) _: @# ~
! j0 x* V& p" M- e* }- /*
- *
- * 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 ****************/, T$ E& F3 |4 P' s! w3 G" F
8 r2 C6 m( F! \" u( w
0 j/ g/ f7 t% _, U( L) X
: j3 I1 U! G5 p 4》d_bus 优先级代码
. N0 h; ^* F8 j/ e1 V. |; E' m+ M1 ^; J3 r& J8 l
! X) z6 R4 x1 L3 e( n1 k
; Q$ X9 k8 {; _" B# Z
& M% P( ?$ x, }% d4 f; M/ U1 Z7 v 7 Q3 L+ r' Q" k! i+ K3 h
5》linux driver
' y- d; V; U& b+ w5 n; ^: J, |# i
) u% C7 o% O/ l- B6 Pip_mkg.c:% t) I2 G" d1 n
) t0 ~4 H( {8 H9 L8 _4 |4 _9 o8 O1 Z6 ]9 J
- /*
- *
- * 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");
- . P' m: i0 H, P) P1 h
. [1 ?8 y& ?) t K' ` _0 c
K) l1 @* W1 j5 N
9 F8 \$ K2 I4 N, `% t) U' s+ J. E9 B7 ]2 a
ip_mkg.h:
5 K& Q3 Z: f% c; _% |' z! F2 l0 m' s2 Y0 z4 z/ V
3 [* I/ T0 o2 Z0 Y. 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 1
- struct reg_data
- {
- unsigned short addr;
- int value;
- };
- #endif4 O \( R0 H6 H2 d6 C) H% i) k
. Z- C0 I! d5 S, C {/ D
2 ^& r, I3 F3 n2 d# e4 |; i
6》makefile
- q, Y8 o1 F. ?4 T" {! g2 b9 ]4 P7 a: b. w4 c+ M- }! R- `
0 H) ?" I$ d, x) J, p5 b2 l: p4 y0 `
- # 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
+ h# z+ _, d& ]7 a* d
7 s7 l% j+ C Q" p1 [6 F+ A& f6 o7 `0 }4 d2 O
" I% q: u% E* W8 A. _/ g
2.1.3 模块连接图:& x7 y$ L+ z. y4 q8 m- s0 K. s6 g
$ _: M% S! n l! _0 B6 h' S7 r
& U/ |% C; ? O2 U. F) p- X3 }; r1 {% `4 A' V
0 }: t: ` T- w p
2.1.4 验证结果:
' F" r( O! p0 }' i' Q9 g2 r% i% p0 s& {3 E
0 I5 X# `. ?- j9 q9 U
: X; J, C" c9 m* [1 g- N! o5 I5 V( T. Y
+ _ O3 [: N3 Q; O O2.2 master读功能
& F4 @0 W6 n! i. l+ g% B/ i0 I 1》driver向slave的num_1寄存器里写入0x112233447 h; N- A& e$ P/ j: f' r0 \
2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 读的地址,其实就是num_1)+ W r, a3 _/ q9 k; ?% p( [
3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始读)9 L( C+ h% x+ Q6 n7 J1 i
4》打印
8 T6 w/ J& X @1 |* z: W F3 i5 Y 5》driver读slave,验证master读入的值是否正确。
( x4 q# o: q: W* i8 B& u0 g+ i3 ~( V! F. G
# ]$ ^: y* |/ b0 E
2.2.1 code list:mycore.v,mkg_master.v,mkg_slave.v6 ^% l7 k' M6 o
1》mycore.v
! h3 F& \+ [0 T" j
9 T' a: N" Q' Z) ]9 U5 ~) e! R$ k. o. T- D5 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;
- 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 ****************/+ K6 s4 Q+ q* c4 W
* F: X1 ~# }0 p/ [( ? ( O+ f7 T8 i" V
O1 u ]9 `$ D y& I4 g* z9 ~: X" K
2》mkg_master.v! E Q* l; S9 y+ n" c
2 C& }/ e. e- i
, T/ R0 z1 p- v& M- /*
- *
- * 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 ****************/0 V/ [, i, P% u% X1 z3 E4 i
8 Q$ o8 J/ @ T8 M- f& M2 a7 Y
3 Y8 S/ D8 @$ V. t' b0 B7 v6 Z0 Y$ p$ z5 |& G1 R
3》mkg_slave.v* p( D; Y4 x; z4 \
& [7 M4 t# U }+ S; M0 p
2 Y; v7 c( T4 T) M3 \+ j- /*
- *
- * 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 ****************/1 S( X; q7 r' u! `1 x+ P! _
$ s% j* B4 T/ u0 | W& J; s
! ^: P: ^. v% U 9 i6 [4 s' s! z9 \3 u% P& O
4》d_bus 优先级代码:arbiter_dbus.v(与写相同)# O2 H: }( n8 n+ u& _
$ N/ t( v1 t3 f2 h4 }* q. m6 R8 ~
5》linux driver(与写相同)
. ]+ j9 V$ B( g7 }( W* K* H & d8 B% Y/ a) z+ G5 i( l
6》makefile(与写相同)0 U3 Z5 q5 n& v4 H
$ y( {! P) F! D% f" ?% n
2.2.3 模块连接图:2 Y+ g% w0 k) q" g a: Y
2 N' D4 R+ s7 |0 H7 `, k
; R) u! l+ M4 K6 G) V# I* {1 K, o1 e- L) d ~: L2 a- R8 G2 b
% ^6 _9 Q5 F7 d$ C% _4 g
2.2.4 验证结果:3 Z1 y8 y" ^( M7 r0 G: n9 U8 c! Z
; D4 G: y3 t; t! p
/ K/ W A) M: }! M
4 X/ L2 }* r6 y0 i' Y+ ^6 _0 {. p6 k6 k# w: Y, k$ b! j
3 L5 v- S2 {1 A8 M4 m
a m- Z5 f" d( {" ^2.3 小结
7 L* q; T! ~0 M% ~写driver时要注意大小端的问题。7 D; ?! q3 }* f: J3 D, D. ]" V
比如想写0x97000000(master要访问的地址),在driver里面要写0x00000097。
7 s) Y2 b% }' S& y& @ |
|