TA的每日心情 | 怒 2019-11-20 15:22 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
' W5 R6 B9 P( ]( \7 L$ ]! t本小节中省略了一些virtualbox下的操作细节,请参考上一篇文章:linux学习之路_添加自己的slave IP core到ORSoC并测试
( u, U' j0 G9 @4 z4 b9 F* Q
6 n* S9 O$ l5 A7 y% r% R9 l
) v( T8 v( h8 K% t1,控制流程( i6 x- }' x( C8 h" w
1>mycore的linux下的driver写slave& E8 P& D9 Y% `0 M+ ~9 c% b
2>slave根据driver发来的指令控制master6 a1 O$ b7 Q `( _% S
3>master进行相应操作,并返回给slave3 `: R8 R/ |0 W
4>mycore的linux下的driver读slave
8 r4 U. ^5 W% ~" F4 z; _3 {) e. g
5 L2 i5 u& Q3 c. T6 a2,功能概述
- J* V# H J; R1 N( N/ I2.1 master写功能8 G/ q- I4 @0 J8 _
1》driver向slave的num_1寄存器里写入0x11223344$ \) |9 h- j U. u/ ?
2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 写的地址,其实就是num_1)
0 I o; k! ^) u: ~5 ` 3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始写)! i2 u2 p5 t* a M5 ?3 B/ c; n
4》打印
+ m; i, k) f$ [ 5》driver读slave,验证master写入的值是否正确。
( a) [, k! S7 R6 f& u4 X i' w- _8 y' Y% p* J2 F9 L6 \
7 J+ [/ W+ s: ~' a! Z- B2.1.0 模块总连接图- A5 W7 ?0 ^+ N
: M/ h( l. V6 }
: t7 p" \2 Z, ]: Z& p( \& E) u' {- L6 N
4 | N% n! W" u( J
" Z ~/ s0 W/ d5 Z% G5 f2.1.1 代码修改流程说明:跟单独包含slave的ipcore差不多1 Z4 g- ^# o) G8 U% Q5 j
1》编写符合wishbone master接口和相应内部逻辑的ip core:mycore
$ L% b, B" P9 L1 @. n 2》d_bus的arbiter增加master接口:master2
% y9 e7 g. ~+ d( F) \- l7 \' s7 W 3》修改master的仲裁优先级1 s( C& m* P; n& V- Y4 N
4》例化本ipcore$ B# W2 X6 z2 g' a& W" X
5》编写linux下的driver并测试验证% g/ U/ k+ V: G
C$ w* u+ y4 I2 d
2.1.2 code list:mycore.v,mkg_master.v,mkg_slave.v
, p" ^ r I* E$ |# X6 G 1》mycore.v
+ }6 b( a3 B7 u
3 @9 g& j+ l9 K _8 n, e
! g# V8 N! \( C* t1 U- X! A3 u- /*
- *
- * 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 ****************/
$ O; r( p# Z; D7 A' \4 Q2 [ / L9 ` s4 a- R {* A
" D f* i. i! o$ F; D4 @
' y$ z7 t4 V# C8 J" u 2》mkg_master.v
$ T" s% ^* E F; A. N
# J( }$ b- O- `* Y8 b
/ X1 _4 s( M6 r& z# h2 L' D. C$ k- /*
- *
- * 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 ****************/ B# w4 A4 ^3 ]7 |: s3 `
/ T5 s6 M4 G# W% n) Z
! |9 M- Y$ w a' {3 ~3 U u. E! k% {. X+ z& r+ Y8 J
3》mkg_slave.v
! W3 v% ]* N0 R# ]6 b# O4 L& x" e! O9 G2 G
$ {: j2 c% {. F$ [* @2 l& D6 x6 R* s
- /*
- *
- * 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 ****************/
/ M9 W( ~: h. M. f n5 I! V 2 x& v# a+ [6 y
+ V+ {2 w+ h/ C4 A/ o8 M0 G/ m
/ O5 \6 A; J" c' S. V9 w8 Y 4》d_bus 优先级代码
! O/ g! f9 f4 i4 O0 H
- ]9 P! a% j0 K7 ~! G$ e
3 Y+ k: i8 k# x; Z% f/ Q/ O( Z
2 [' b, g& i$ ~5 ] S4 e; [0 j
+ o Y' d! ^, t& ~3 i
8 i0 e9 k- N1 N4 f3 M& w 5》linux driver) m+ j* p) s$ a2 d9 L
) K/ X" S' l$ |: n2 r/ J$ ?ip_mkg.c:
$ f5 r: f8 j, }( w% v) B
' J7 t4 Z7 a% L
+ H' B2 R* V5 Q2 U; 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");
1 w* r' ^) n* [3 m
( O% d8 \0 k+ y% }
% x3 w$ y2 E/ P V+ ~! L z% `% `/ `! h# d- Q8 R" p; l9 q
3 |9 M- ~* I( E
ip_mkg.h:
* B: W% E% @0 ~; k
! z9 x: }1 \: r9 x) X8 [! C4 p
/ v* N/ l0 n3 R- #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 i5 d, {0 d u* @9 s2 e
& E; p) C% n% P4 e' e8 b
& ]& h2 L% Z$ h3 v: m
6》makefile
& C; ?, |' L7 m2 c2 x! `0 x# e' [: C- P9 r, ^8 g" ^# W9 W
3 p2 w0 A2 e7 v/ p, u9 U- # 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
- n1 [% |9 n/ Z3 o& `2 _6 J : u4 Q& L3 h. @
7 o( |3 u( M$ x7 [# i
4 k! M3 B) ^2 y' e5 e
2.1.3 模块连接图:
) {, _* L( N% m* k0 D% |6 D% s5 Z5 `. C/ ^- ]. K: r; V3 S( S; X
; k+ C( K2 S, e% {$ J2 c5 n4 u2 K% {
$ X. V3 V! e' ?: f, a" U2.1.4 验证结果:, ]7 Q+ i S7 h' E6 _
0 J9 y9 ^# |5 {! q7 @
$ b O& Z9 s7 o6 Y% P
4 R/ a% h; k, j
; i, o9 E; r3 E1 t4 y! F
& u# t. Z+ M1 _* H& [2.2 master读功能
{. e) h0 B1 {! E. K+ H, r P 1》driver向slave的num_1寄存器里写入0x11223344
# [3 {6 H3 b! {- [# O9 z( g 2》driver向slave的write_address寄存器里写入0x00000097.(这是让master 读的地址,其实就是num_1)
! |3 ^0 |4 w5 ^4 H- a+ \. a; [4 s 3》driver向slave的num_2寄存器里写入0x03000000.(这是让master开始读)$ N% q/ g0 C- I' _' [& F
4》打印
# o: k8 p, n3 L9 x# h! w 5》driver读slave,验证master读入的值是否正确。
$ z. F5 z% u1 B& f8 J; o
5 N) o% ^* ~+ {2 _8 N; Z: }0 R
% B) J* G5 c- z" w" s2.2.1 code list:mycore.v,mkg_master.v,mkg_slave.v; @1 v4 o) X- Q. d3 o1 P
1》mycore.v
6 C& @+ I. k5 a4 O* I2 O
! ~$ F% U5 e9 W0 n7 R0 a9 b; u+ V+ [( o1 h% r1 s6 o) }; R
- /*
- *
- * 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 ****************/
+ K, Q" _( l |4 H `3 M9 j6 k
& U, U3 Q( U2 {7 P y1 @+ Z5 ~+ z& n# Z
1 r; r( b0 e: Q& |3 b
0 [5 T. k& T. a& @: v1 l% V- W2 i 2》mkg_master.v5 P T' q' F, @1 S* B2 O4 }
: S2 G% ]9 Y7 s- r
/ S; R; r" R. F 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 ****************/
$ D/ M( U, N" r* _, _8 c
1 j9 h- o% O/ c- \* {* b4 h, V ' o- [7 C, N9 n- G( ~
5 L5 l6 A- N X8 ^: O5 |
3》mkg_slave.v1 v/ A6 X1 F- H: \( |
. h- k; P' i4 B
( p% X; {( R0 D6 a4 k" G- /*
- *
- * 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 ****************/# i! t4 `; e' `/ \5 U
/ y) g. n5 i# {2 E
& _. J6 i7 b r9 c
8 `1 y" w2 Q' }- i3 Y
4》d_bus 优先级代码:arbiter_dbus.v(与写相同) c1 i$ j9 T, c# m) ~
1 l1 h5 ]7 m" R. X, h 5》linux driver(与写相同)
0 w) q6 q" x- _; _8 J
5 T8 q9 O ?6 G% ?& L 6》makefile(与写相同)
. [" X9 p: i6 d0 m `& ?, ?! ? % n$ _+ @. ^ ~, f2 D
2.2.3 模块连接图:
, e/ O! d- k( L; Y& K& `
2 I' @( Y8 ?* S' W; ^
8 Y( L4 C. g2 B' q k
# n+ x6 Q: `& B" D+ `& M# f0 V7 |- W1 D. Q ~& h7 ~
2.2.4 验证结果:) u( F. |5 ^: h( v' T
# G( o& Y. V3 F3 M/ j& s
. R5 I. h8 n W6 z6 [
( r. F" ]/ I2 C" T) V
- m, B( M: H8 c$ Y4 F
: G4 r& \. q' W- S5 \
; d w5 c Y# f: [2.3 小结! O9 O: n3 C( N3 y) B% d
写driver时要注意大小端的问题。" s6 v; r9 D5 A: |/ P- o" G1 @# _
比如想写0x97000000(master要访问的地址),在driver里面要写0x00000097。
% W4 w1 W9 e+ c3 E- y |
|