verilog仿真——8线-3线优先编码器CD4532

任务

  1. 实现CD4532的设计与仿真
  2. 用2片CD4532构成16线-4线优先编码器

CD4532

实现思路

根据示例基本掌握verilog的语法,可以进行自主设计。

  • 原本想通过逻辑表达式将编码器的内部逻辑表达,但看到示例中有用到case的语法,是人易读的表达方式,因此改为用case语句将输入信号映射至对应的输出编码。
    • 对于优先编码问题,涉及到优先级高位有效,忽略低位输入,则采用casex实现,详见代码
  • 原本直接将所有输入输出端口列写,同样看到示例中利用数组结构,更简单易读

设计

//file name: CD4532
.v
module CD4532(
	input [7:0] I, //input 8bits signal
	input EI,
	output reg [2:0] Y,
	output reg GS,EO
);
/*电路功能描述
 1.(*)表示 always 块中所有输入信号都是敏感信号
 2.输出信号在过程语句中被赋值,定义成 reg 型
*/
//I0,I1,I2,I3,I4,I5,I6,I7为输入信号,优先级依次升高
//EI为编码器使能端
//Y0 Y1 Y2 8-3线编码器输出编码
//GS:当EI为1,只要有输入端信号有效,输出为1
//EO:当EI为1,且所有输入端为0时,输出为1
always @(*)begin
	if(EI)begin
		GS=1;EO=0;
		casex(I[7:0])//ENCODER 8_3
			8'b1xxx_xxxx: Y[2:0]=3'b111;
			8'b01xx_xxxx: Y[2:0]=3'b110;
			8'b001x_xxxx: Y[2:0]=3'b101;
			8'b0001_xxxx: Y[2:0]=3'b100;
			8'b0000_1xxx: Y[2:0]=3'b011;
			8'b0000_01xx: Y[2:0]=3'b010;
			8'b0000_001x: Y[2:0]=3'b001;
			8'b0000_0001: Y[2:0]=3'b000;
			default: begin GS=0;EO=1; end
		endcase
	end
	else begin
		Y[2:0]=3'b000;
		GS=0;EO=0;
	end
end
endmodule

注意问题:

  • 赋值语句用 ; 分隔
  • 多个语句利用 begin 和 end成块
  • 注意end和endmodule不要遗漏

仿真

//file name: tb_CD4532.v
`timescale 1ns/1ns
module tb_CD4532;
reg [7:0] I;
reg EI;
wire [2:0] Y;
wire GS,EO;
//实例化8-3编码器CD4532
CD4532 CD4532_inst(
.I(I),
.EI(EI),
.Y(Y),
.GS(GS),
.EO(EO)
);
initial 
	$monitor($time,":\tI=%b,EI=%b,EO=%b,GS=%b,Y=%b\n",I,EI,EO,GS,Y);
initial begin
//初始化
EI = 0; I=8'b1111_1111;
#1
EI = 0; I=8'b0111_1111;
#1
EI = 1; I=8'b1111_1111;
#1
EI = 1; I=8'b0111_1111;
#1
EI = 1; I=8'b0001_1111;
$stop;
end
endmodule
简单测试了几个输入,应该没有问题

16线-4线优先编码器

实现思路

各用一片接收8线的输入信号,分别用CD1代表高8位,CD0代表低8位,特性是:

  • 只要高8位有效,低8位的输入无效
    • 此时4位编码的高位有效
  • 高8位无效时,读取低8位的输入
  • 高8位与低8位的输入都无效,最终无效

同时,CD4532为我们提供了实现方案:

//GS:当EI为1,只要有输入端信号有效,输出为1
//EO:当EI为1,且所有输入端为0时,输出为1

结合需求和供给的特性,我们这样做:

  • 将CD1的EO1接至CD0的EO0处
    • GS1接到编码最高位
  • CD1与CD0的输出端分别接至编码的低三位

设计

//filename:encoder16to4.v
module encoder16to4(
	input [15:0] I,
	input EI,
	output reg [3:0] Y,
	output reg GS,EO
);
wire GS1,GS0,EO1,EO0;
wire [2:0] Y1,Y0;
//实例化8-3编码器CD4532 CD1
CD4532 CD1(
.I(I[15:8]),//高8位
.EI(EI),
.Y(Y1[2:0]),
.GS(GS1),
.EO(EO1)
);
//实例化8-3编码器CD4532 CD0
CD4532 CD0(
.I(I[7:0]),//低8位
.EI(EO1),
.Y(Y0[2:0]),
.GS(GS0),
.EO(EO0)
);
always @(*)begin
	Y[2:0]=Y1|Y0;
	Y[3]=GS1;
	GS=GS1|GS0;
	EO=EO1&EO0;
end
endmodule

仿真

//filename:tb_encoder16to4.v
`timescale 1ns/1ns
module tb_encoder16to4;
reg [15:0] I;
reg EI;
wire [3:0] Y;
wire GS,EO;
//示例化16-4编码器
encoder16to4 encoder16to4_inst(
.I(I),
.EI(EI),
.Y(Y),
.GS(GS),
.EO(EO)
);
initial begin
//初始化
EI = 0; I=16'h7000;
#1
EI = 1; I=16'h0000;
#1
EI = 1; I=16'h0001;
#1
EI = 1; I=16'h0002;
#1
EI = 1; I=16'h00f0;
#1
EI = 1; I=16'h0f00;
#1
EI = 1; I=16'hf000;
#1
//$finish;
$stop;
end
endmodule

错误

Illegal output or inout port connection for port ‘EO’.

原因&解决方法

用reg型的输出端口对CD4532进行实例化,加载文件报错,修改为wire型的变量进行实例化,initial的过程语句将wire变量值传递至reg输出端口。

1 comment

Leave a comment

Your email address will not be published. Required fields are marked *