博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

自定义外设(转)

Posted on 2010-09-04 07:49  阿明的园子  阅读(535)  评论(1)    收藏  举报

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 

默认分类 2010-03-24 16:58:06 阅读61 评论0    字号: 订阅

[quote].COM 缺氧:看到一个always的状态机,难受死了。[/quote] 对状态机还不是很熟悉 ,呵呵 --路漫漫... [quote]lly88:楼主的这个状态机写太好了!好像77,79行有一点问题!我觉得应该这样写: if(row[3:0]!=4'b1111)begin state&l... --路漫漫... [quote]kk007:key_value 和 col 都输入到fpga中吗?[/quote] 不清楚你说的是什么意思 --路漫漫... 看到一个always的状态机,难受死了。 --.COM 缺氧 irq的用法值得关注和研究。 --.COM 缺氧 mark --.COM 缺氧 mark --.COM 缺氧 您好,请问可以成为朋友吗,我刚买了这个板子,希望可以交个朋友,大家 一起学习。 --ningning [quote]lc_ECJTU: 刚采用楼主的建议 测试成功了 不过 逻辑分析仪好像不能用了 不知道是片子烧了还是USB下载线坏了 NO DEVICESE IS SELECTED 谢谢 ... --路漫漫... 楼主你能不能用一个具体实例讲一讲Avalon接口实现!这样我们好更好的理解! --liliaoyuan
 

开发环境:Quartus II 8.1 + Nios II IDE 8.1

外设功能:4*4键盘

自定义外设是SOPC系统灵活性的重要体现,是SOPC系统中极其重要的一种设计方法。在大量的数据需要处理时,利用自定义外设由具体的硬件来实现,可以极大程度的提高系统运行的速度,同时便于系统的模块化与集成,是SOPC系统设计的重中之重!!!

在设计自定义外设之前,一定要知道外围电路的工作原理,也就是自定义的外设的时序、逻辑一定要根据具体的硬件电路来设计。其原图在前一篇Verilog HDL 4*4矩阵 键盘扫描程序中。

键盘是嵌入式系统中应用最广的输入设备,这里要设计的就是4*4键盘的硬件扫描电路,可以通过读相关的寄存器获取键值,值得一提的是该自定义外设支持中断的方式获取键值!!!

自定义外设可以为Master和Slave两种,这里设计的是一个只含有Slave的外设,Verilog HDL源程序如下,主要是在上一篇文章的基础上修改而来。主要添加了Avalon Slave Port的接口部分:也就是和Avalon交换架构进行交互的一些信号的集合(这只是最基本的传输,不包含任何高级传输属性)。

  1//Write by Nick 2009.5.9
  2module key
  3(
  4//Avalon MM slave port interface "s1" with irq
  5 clk,  //50MHZ
  6 reset_n,
  7
  8 chipselect,
  9 address,
 10 write,
 11 writedata,
 12 readdata,
 13 irq,
 14 row,
 15 col
 16 );
 17input clk;
 18input reset_n;
 19
 20input chipselect;
 21input [1:0] address;
 22input write;
 23input [7:0] writedata;
 24output [7:0] readdata;
 25input [3:0] row;
 26output irq;
 27output [3:0] col;
 28
 29reg [7:0] readdata;
 30reg irq;
 31reg irq_reg;
 32reg [3:0] col;
 33reg [4:0] key_value;
 34
 35reg [12:0] count;//delay
 36reg [2:0] state;
 37reg [2:0] pre_state;
 38reg key_flag;
 39reg [3:0] col_reg;
 40reg [3:0] row_reg;
 41wire [7:0] irq_capture;
 42wire [7:0] readdata_reg;
 43
 44assign readdata_reg={8{(address==0)}}&{4'b0000,key_value}|
 45                     ({8 {(address ==1)}} & irq_capture);
 46
 47assign irq_capture=key_value;
 48
 49always @(posedge clk)
 50if(!reset_n) begin readdata<=8'h00;irq<=1'b0;end
 51else
 52begin
 53     readdata<=readdata_reg;
 54if(chipselect&write&&(address==2)) irq<=1'b0;//clear irq signal
 55elseif(key_flag==1'b1) irq<=1;
 56end
 57
 58
 59always @(posedge clk ornegedge reset_n)
 60if(!reset_n) begin col<=4'b0000;state<=0;pre_state<=0;count<=0;end
 61else
 62begin
 63case (state)
 640: 
 65begin
 66         col[3:0]<=4'b0000;
 67         key_flag<=1'b0;
 68         pre_state<=0;
 69if(row[3:0]!=4'b1111) state<=2;
 70elsebegin state<=0;end
 71end
 721:
 73begin
 74if(count<5000) begin count<=count+1;state<=1;end
 75else
 76begin
 77           count<=0;
 78if(row[3:0]!=4'b1111) state<=6;
 79else state<=pre_state+1;
 80end
 81end
 82
 832:  
 84begin
 85         col[3:0]<=4'b1110;
 86         state<=1;
 87         pre_state<=2;
 88end
 893:
 90begin
 91         col[3:0]<=4'b1101;
 92         state<=1;
 93         pre_state<=3;
 94end
 954:
 96begin
 97         col[3:0]<=4'b1011;
 98         state<=1;
 99         pre_state<=4;
100end
1015:
102begin
103         col[3:0]<=4'b0111;
104         state<=1;
105         pre_state<=5;
106end
107
1086:
109begin
110if(row[3:0]!=4'b1111) 
111begin
112              col_reg<=col;
113              row_reg<=row;
114              state<=7;
115              key_flag<=1'b1;
116end
117else
118begin state<=0;end
119end
1207:   
121begin
122         key_flag<=1'b0;
123if(row[3:0]!=4'b1111) state<=7;
124else state<=0;
125end
126endcase
127end
128
129
130always @(clk or col_reg or row_reg)
131begin
132if(!reset_n) key_value<=0;
133else
134if(key_flag==1'b1) 
135begin
136case ({col_reg,row_reg})
1378'b1110_1110:key_value<=1;
1388'b1110_1101:key_value<=2;
1398'b1110_1011:key_value<=3;
1408'b1110_0111:key_value<=4;
141
1428'b1101_1110:key_value<=5;
1438'b1101_1101:key_value<=6;
1448'b1101_1011:key_value<=7;
1458'b1101_0111:key_value<=8;
146
1478'b1011_1110:key_value<=9;
1488'b1011_1101:key_value<=10;
1498'b1011_1011:key_value<=11;
1508'b1011_0111:key_value<=12;
151
1528'b0111_1110:key_value<=13;
1538'b0111_1101:key_value<=14;
1548'b0111_1011:key_value<=15;
1558'b0111_0111:key_value<=16;    
156endcase
157end
158end
159endmodule
160

下面介绍如何将自定义外设添加到SOPC系统。

打开SOPC Builder,添加Verilog HDL文件。如下图:

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

设置信号类型如下:

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

 

设置Avalon接口如下:

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

添加自定义组件的一些基本信息:

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

 

这样就完成了自定义组件的添加,保存后退出即可在SOPC Builder 组件栏看到刚添加的组件。

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

 

这样就完成了自定义组件的添加,保存后退出即可在SOPC Builder 组件栏看到刚添加的组件。

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

 

点“Add”即可像添加其它IP一样添加到SOPC系统中来。

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

     可以清楚的看到键盘中断优先级为“2”,Nios II系统中断号越低,中断优先级越高。点击“Generate”生成Nios II系统如下,可以看到组件已经成功添加到顶层文件.

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

绑定管脚后编译,即完成了自定义外设的整个硬件设计,接下来就是软件设计与验证。

 

点“Add”即可像添加其它IP一样添加到SOPC系统中来。

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

     可以清楚的看到键盘中断优先级为“2”,Nios II系统中断号越低,中断优先级越高。点击“Generate”生成Nios II系统如下,可以看到组件已经成功添加到顶层文件.

(原创)SOPC系统自定义外设之:硬件设计 - 路漫漫... - 博客园 - 快乐丢丢 - 轮回的七彩年华

绑定管脚后编译,即完成了自定义外设的整个硬件设计,接下来就是软件设计与验证。

Feedback

Powered by:
博客园
Copyright © 路漫漫...