3FPGA编码器徐艺萍.docx
《3FPGA编码器徐艺萍.docx》由会员分享,可在线阅读,更多相关《3FPGA编码器徐艺萍.docx(19页珍藏版)》请在冰豆网上搜索。
3FPGA编码器徐艺萍
2.3编码器
在数字系统里,常常需要将某一个信息(输入)变换为某一特定的代码输出。
把二进制码按一定的规律编排,例如8421码、格雷码等,使每组代码具有一特定的含义(代表某个数或者控制信号)称为编码。
具有编码功能的逻辑电路称为编码器。
编码器有若干个输入,在某一个时刻只有一个输入信号被转换成二进制码。
例如8线–3线编码器和10线–4线编码器分别有8个输入、3位二进制码输出和10个输入、4位二进制码输出。
二进制编码的结构框图如图2.3.1所示。
图2.3.1二进制编码的结构框图
2.2.1普通编码器
1.基本原理
下面以4线–2线普通编码器为例来介绍普通编码器的工作原理。
4线–2线编码器的逻辑图如图2.3.2所示,表2.3.1是4线–2线编码器的真值表。
图2.3.224线—2线编码器逻辑图
表2.3.14线–2线编码器真值表
输入
输出
I0
I1
I2
I3
Y1
Y0
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
0
0
1
1
0
1
0
1
由上表可知,4个输入I0~I3为高电平有效信号,输出是两个二进制代码Y1Y0,任何时刻I0~I3中只能有一个取值为1,并且有一组对应的二进制码输出。
除了表中列出的4个输入变量的4种组合有效外,其余12种组合所对应的输出均为0,因而可由功能表得到如下逻辑表达式:
2.实现方案
通过FPGA来实现普通编码器的功能有以下几种方案:
(1)采用数据流描述方式(逻辑门表示),用assign关键字来实现。
(2)采用if…..else语句来实现。
(想到了)
(3)采用case语句来实现。
(想到了)
(4)采用嵌套条件运算符“?
:
”来实现。
3.FPGA的实现
下面以第一种方案为例来进行FPGA的实现。
(1)创建工程
在创建工程的时候,注意器件族类型、器件型号、综合工具和仿真器的选择,在这里选择的器件族类型(DeviceFamily)是Virtex2P,器件型号(Device)是XC2VP30ff896-7,综合工具(SynthesisTool)是XST(VHDL/Verilog),仿真器(Simulator)是ISESimulator(VHDL/Verilog)。
(2)设计输入
VerilogHDL代码如下:
moduleencoder4_2(I3,I2,I1,I0,Y1,Y0);
inputI3,I2,I1,I0;
outputY1,Y0;
wireY1,Y0;
assignY1=((~I0)&(~I1)&(I2)&(~I3))|((~I0)&(~I1)&(~I2)&(I3));
assignY0=((~I0)&(I1)&(~I2)&(~I3))|((~I0)&(~I1)&(~I2)&(I3));
endmodule
对于第二种方案的VerilogHDL代码如下:
moduleencoder4_2(I3,I2,I1,I0,Y1,Y0);
inputI3,I2,I1,I0;
outputY1,Y0;
regY1,Y0;
always@(I3orI2orI1orI0)
begin
if({I3,I2,I1,I0}==4'b0001){Y1,Y0}=2'b00;
elseif({I3,I2,I1,I0}==4'b0010){Y1,Y0}=2'b01;
elseif({I3,I2,I1,I0}==4'b0100){Y1,Y0}=2'b10;
elseif({I3,I2,I1,I0}==4'b1000){Y1,Y0}=2'b11;
else{Y1,Y0}=2'b00;
end
endmodule
对于第三种方案的VerilogHDL代码如下:
moduleencoder4_2(I3,I2,I1,I0,Y1,Y0);
inputI3,I2,I1,I0;
outputY1,Y0;
regY1,Y0;
always@(I3orI2orI1orI0)
begin
case({I3,I2,I1,I0})
4'b0001:
{Y1,Y0}=2'b00;
4'b0010:
{Y1,Y0}=2'b01;
4'b0100:
{Y1,Y0}=2'b10;
4'b1000:
{Y1,Y0}=2'b11;
default:
{Y1,Y0}=2'b00;
endcase
end
endmodule
对于第四种方案的VerilogHDL代码如下:
moduleencoder4_2(I3,I2,I1,I0,Y1,Y0);
inputI3,I2,I1,I0;
outputY1,Y0;
wireY1,Y0;
assign{Y1,Y0}=({I3,I2,I1,I0}==4'b0001)?
2'b00:
({I3,I2,I1,I0}==4'b0010)?
2'b01:
({I3,I2,I1,I0}==4'b0100)?
2'b10:
({I3,I2,I1,I0}==4'b1000)?
2'b11:
2'b00;
endmodule
(3)功能仿真
①在sources窗口的“sourcesfor”中选择“BehavioralSimulation”。
②由TestBenchWaveForm添加激励源,如图2.3.3所示。
仿真结果如图2.3.4所示。
图2.3.3激励波形
图2.3.4仿真结果
从仿真的结果中我们可以看到:
当输入为0001时,编码输出为00;当输入为0010时,编码输出为01;当输入为0100时,编码输出为10;当输入为1000时,编码输出为11,当输入为其他值的时候,编码输出也为00,这就达到了我们设计的效果。
在进行功能仿真验证之后,再进行综合。
(4)进行ChipScope在线调试
①生成ICON核和VIO核并添加到工程。
这里使用的是核生成法。
因为ICON核只需要控制VIO核,所以控制端口数为1,如图2.3.5所示。
VIO核使用异步输入输出端口,异步输入端口的位宽为2,异步输出端口的位宽为4,如图2.3.6所示。
图2.3.5操作示意图1
图2.3.6操作示意图2
最后得到的代码如下:
moduleencoder4_2(Y1,Y0);
wireI3,I2,I1,I0;
outputY1,Y0;
wireY1,Y0;
wire[35:
0]CONTROL0;
wire[3:
0]ASYNC_OUT;
wire[1:
0]ASYNC_IN;
ICONI_ICON
(
.CONTROL0(CONTROL0)
);
VIOI_VIO
(
.CONTROL(CONTROL0),
.ASYNC_IN(ASYNC_IN),
.ASYNC_OUT(ASYNC_OUT)
);
assignASYNC_IN[0]=Y0;
assignASYNC_IN[1]=Y1;
assignI0=ASYNC_OUT[0];
assignI1=ASYNC_OUT[1];
assignI2=ASYNC_OUT[2];
assignI3=ASYNC_OUT[3];
assignY1=((~I0)&(~I1)&(I2)&(~I3))|((~I0)&(~I1)&(~I2)&(I3));
assignY0=((~I0)&(I1)&(~I2)&(~I3))|((~I0)&(~I1)&(~I2)&(I3));
endmodule
②在ISE里进行综合和实现,然后生成bit文件。
③在ChipScope里观测调试。
在Processes窗口中选择双击“AnalyzeDesignUsingChipscope”进入ChipScopeProAnalyzer窗口,点击
图标检查连接情况,然后下载bit文件进行在线观测。
调试结果如图2.3.7~2.3.11所示。
图2.3.7调试结果1
图2.3.8调试结果2
图2.3.9调试结果3
图2.3.10调试结果4
图2.3.11调试结果5
从上面的调试结果可以看出编码器的设计是正确的。
4.总结
从上面设计的普通编码器我们可以看出,这种编码器存在一个不足,当4个输入中有2个或2个以上的取值同时为1时,就会出现编码错误。
为了解决这个问题,我们可以使用优先编码器。
2.2.2优先编码器
1.基本原理
上一节的普通编码器虽然简单,但当同时出现有两个或两个以上的输入为高电平时,其输出将是混乱的。
在数字系统中,特别是在计算机系统中,常常要控制几个工作对象,例如微型计算机主机要控制打印机、磁盘驱动器、输入键盘等。
当某个部件需要实行操作时,必须先送一个信号给主机(称为服务请求),经主机识别后再发出允许操作信号(服务响应),并按事先编好的程序工作。
这里会有几个部件同时发出服务请求的可能,而在同一时刻只能给其中1个部件发出允许操作信号。
因此,必须根据轻重缓急,规定好这些控制对象允许操作的先后次序,即优先级别。
识别这类请求信号的优先级别并进行编码的逻辑部件称为优先编码器。
下面以8线–3线优先编码器为例来具体说明优先编码器的工作原理。
8线–3线优先编码器的功能表如表2.3.2所示。
表2.3.28线–3线优先编码器功能表
输入
输出
EI
I7
I6
I5
I4
I3
I2
I1
I0
Y2
Y1
Y0
GS
EO
0
1
1
1
1
1
1
1
1
1
x
0
1
0
0
0
0
0
0
0
x
0
x
1
0
0
0
0
0
0
x
0
x
x
1
0
0
0
0
0
x
0
x
x
x
1
0
0
0
0
x
0
x
x
x
x
1
0
0
0
x
0
x
x
x
x
x
1
0
0
x
0
x
x
x
x
x
x
1
0
x
0
x
x
x
x
x
x
x
1
0
0
1
1
1
1
0
0
0
0
0
0
1
1
0
0
1
1
0
0
0
0
1
0
1
0
1
0
1
0
0
0
1
1
1
1
1
1
1
1
0
1
0
0
0
0
0
0
0
0
从功能表我们可以看出,该编码器有8个信号输入端,3个二进制码输出端。
此外,电路还设置了输入使能端EI,输出使能端EO和优先编码工作状态标志GS。
当EI=1时,编码器工作;而当EI=0时,则不论8个输入端为何种状态,3个输出端均为低电平,且优先标志端和输出使能端均为低电平,编码器处于非工作状态。
当EI为1,且至少有一个输入端有编码请求信号(逻辑1)时,优先编码工作状态标志GS为1,表明编码处于工作状态,否则为0。
由功能表可知,在8个输入端均无高电平输入信号和只有输入I0端(优先级别最低位)有高电平输入时,Y2Y1Y0均为000,出现了输入条件不同而输出代码相同的情况,这可由GS的状态加以区别,当GS=0时,表示8个输入端均无高电平输入,此时Y2Y1Y0=000为非编码输出;GS=1时,Y2Y1Y0=000表示响应输入I0的输出代码,Y2Y1Y0=000为编码输出。
EO只有在EI为0,且所有输入端都为0时,输出为1,它可与另一片同样器件的EI连接,以便组成更多输入端的优先编码器。
2.实现方案
通过FPGA来实现8线–3线优先编码器的功能有以下几种方案:
(1)采用if…..else语句来实现。
(2)采用数据流描述方式,不建议采用。
3.FPGA的实现
下面以第一种方案为例来进行FPGA的实现。
(1)创建工程
在创建工程的时候,注意器件族类型、器件型号、综合工具和仿真器的选择,在这里选择的器件族类型(DeviceFamily)是Virtex2P,器件型号(Device)是XC2VP30ff896-7,综合工具(SynthesisTool)是XST(VHDL/Verilog),仿真器(Simulator)是ISESimulator(VHDL/Verilog)。
(2)设计输入
VerilogHDL代码如下:
moduleencoder8_3(I7,I6,I5,I4,I3,I2,I1,I0,EI,GS,EO,Y2,Y1,Y0);
inputI7,I6,I5,I4,I3,I2,I1,I0,EI;
outputGS,EO;
outputY2,Y1,Y0;
regY2,Y1,Y0;
regGS,EO;
always@(I7orI6orI5orI4orI3orI2orI1orI0orEI)
begin
if(~EI){Y2,Y1,Y0,GS,EO}=5'b00000;
elseif(I7){Y2,Y1,Y0,GS,EO}=5'b11110;
elseif(I6){Y2,Y1,Y0,GS,EO}=5'b11010;
elseif(I5){Y2,Y1,Y0,GS,EO}=5'b10110;
elseif(I4){Y2,Y1,Y0,GS,EO}=5'b10010;
elseif(I3){Y2,Y1,Y0,GS,EO}=5'b01110;
elseif(I2){Y2,Y1,Y0,GS,EO}=5'b01010;
elseif(I1){Y2,Y1,Y0,GS,EO}=5'b00110;
elseif(I0){Y2,Y1,Y0,GS,EO}=5'b00010;
else{Y2,Y1,Y0,GS,EO}=5'b00001;
end
endmodule
(3)功能仿真
①在sources窗口的“sourcesfor”中选择“BehavioralSimulation”。
②由TestBenchWaveForm添加激励源,如图2.3.12所示。
仿真结果如图2.3.13所示。
图2.3.12激励波形
图2.3.13仿真结果
从仿真的结果中我们可以看到:
,这就实现了异或门电路的功能。
在进行功能仿真验证之后,再进行综合。
(4)进行ChipScope在线调试
①生成ICON核和VIO核并添加到工程。
这里使用的是核生成法。
因为ICON核只需要控制VIO核,所以控制端口数为1,如图2.3.14所示。
VIO核使用异步输入输出端口,异步输入端口的位宽为1,异步输出端口的位宽为2,如图2.3.15所示。
图2.3.14操作示意图1
图2.3.15操作示意图2
最后得到的代码如下:
moduleencoder8_3(GS,EO,Y2,Y1,Y0);
wireI7,I6,I5,I4,I3,I2,I1,I0,EI;
outputGS,EO;
outputY2,Y1,Y0;
regY2,Y1,Y0;
regGS,EO;
wire[35:
0]CONTROL0;
wire[8:
0]ASYNC_OUT;
wire[4:
0]ASYNC_IN;
ICONI_ICON
(
.CONTROL0(CONTROL0)
);
VIOI_VIO
(
.CONTROL(CONTROL0),
.ASYNC_IN(ASYNC_IN),
.ASYNC_OUT(ASYNC_OUT)
);
assignASYNC_IN[0]=GS;
assignASYNC_IN[1]=EO;
assignASYNC_IN[2]=Y2;
assignASYNC_IN[3]=Y1;
assignASYNC_IN[4]=Y0;
assignI0=ASYNC_OUT[0];
assignI1=ASYNC_OUT[1];
assignI2=ASYNC_OUT[2];
assignI3=ASYNC_OUT[3];
assignI4=ASYNC_OUT[4];
assignI5=ASYNC_OUT[5];
assignI6=ASYNC_OUT[6];
assignI7=ASYNC_OUT[7];
assignEI=ASYNC_OUT[8];
always@(I7orI6orI5orI4orI3orI2orI1orI0orEI)
begin
if(~EI){Y2,Y1,Y0,GS,EO}=5'b00000;
elseif(I7){Y2,Y1,Y0,GS,EO}=5'b11110;
elseif(I6){Y2,Y1,Y0,GS,EO}=5'b11010;
elseif(I5){Y2,Y1,Y0,GS,EO}=5'b10110;
elseif(I4){Y2,Y1,Y0,GS,EO}=5'b10010;
elseif(I3){Y2,Y1,Y0,GS,EO}=5'b01110;
elseif(I2){Y2,Y1,Y0,GS,EO}=5'b01010;
elseif(I1){Y2,Y1,Y0,GS,EO}=5'b00110;
elseif(I0){Y2,Y1,Y0,GS,EO}=5'b00010;
else{Y2,Y1,Y0,GS,EO}=5'b00001;
end
endmodule
②在ISE里进行综合和实现,然后生成bit文件。
③在ChipScope里观测调试。
在Processes窗口中选择双击“AnalyzeDesignUsingChipscope”进入ChipScopeProAnalyzer窗口,点击
图标检查连接情况,然后下载bit文件进行在线观测。
调试结果如图2.3.16~2.3.19所示。
图2.3.16调试结果1
图2.3.17调试结果2
图2.3.18调试结果3
图2.3.19调试结果4
从上面的调试结果可以看出8线–3线优先编码器的设计是正确的。
4.总结
这里设计的是一个8线–3线优先编码器,通过对优先编码器的了解,还可以设计出其他种类的优先编码器,比如4线–2线优先编码器、16线–4线优先编码器等等。
我们具体采用哪一种优先编码器要根据实际情况而定。