采用逻辑电路的行为级建模,参考CD4532的功能表,运用always,casex,else if语句实现CD4532的功能。
//filename:CD4532.v
module CD4532(EI,I,Y,GS,EO);
input EI;
input [7:0] I;
output reg [2:0] Y;
output reg GS,EO;
/*输入输出端口说明:
输入端口:EI使能信号,I为输入的数。
输出端口:Y为对应的二进制数。
GS,EO用于多片的级联:当输入信号存在有效信号,GS=1,EO=0;当输入信号全部无效时,GS=0,EO=1;
*/
always @(*) begin
if(EI==0)begin
Y[2:0]=3'b000;
GS=0;
EO=0;
end
else begin
GS=1;
EO=0;
//含有无关项的casex选择来实现优先编码。
casex(I[7:0])
8'b1xxxxxxx:Y[2:0]=3'b111;
8'b01xxxxxx:Y[2:0]=3'b110;
8'b001xxxxx:Y[2:0]=3'b101;
8'b0001xxxx:Y[2:0]=3'b100;
8'b00001xxx:Y[2:0]=3'b011;
8'b000001xx:Y[2:0]=3'b010;
8'b0000001x:Y[2:0]=3'b001;
8'b00000001:Y[2:0]=3'b000;
default begin
GS=0;
EO=1;
Y[2:0]=3'b000;
end
endcase
end
end
endmodule
//filename test_CD4532.v
`timescale 10ns/1ns
module test_CD4532;
reg [7:0] I;
reg EI;
wire [2:0]Y;
wire GS,EO;
CD4532 U0(EI,I,Y,GS,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
采用自顶向下的方式,综合行为级建模,门级描述和数据流建模编写verilog程序。
//filename:_2CD4532.v
//filename:CD4532.v
module CD4532(EI,I,Y,GS,EO);
input EI;
input [7:0] I;
output reg [2:0] Y;
output reg GS,EO;
/*输入输出端口说明:
输入端口:EI使能信号,I为输入的数。
输出端口:Y为对应的二进制数。
GS,EO用于多片的级联:当输入信号存在有效信号,GS=1,EO=0;当输入信号全部无效时,GS=0,EO=1;
*/
always @(*) begin
if(EI==0)begin
Y[2:0]=3'b000;
GS=0;
EO=0;
end
else begin
GS=1;
EO=0;
//含有无关项的casex选择来实现优先编码。
casex(I[7:0])
8'b1xxxxxxx:Y[2:0]=3'b111;
8'b01xxxxxx:Y[2:0]=3'b110;
8'b001xxxxx:Y[2:0]=3'b101;
8'b0001xxxx:Y[2:0]=3'b100;
8'b00001xxx:Y[2:0]=3'b011;
8'b000001xx:Y[2:0]=3'b010;
8'b0000001x:Y[2:0]=3'b001;
8'b00000001:Y[2:0]=3'b000;
default begin
GS=0;
EO=1;
Y[2:0]=3'b000;
end
endcase
end
end
endmodule
module _2CD4532(EI,IN,L,GS,EO);
input EI;
input [15:0] IN;
output [3:0] L;
output GS,EO;
/*输入输出端口定义
输入端口:EI使能信号,IN为输入的数。
输出端口:L译码后对应的四位二进制数。
GS,EO用于多片的级联:当输入信号存在有效信号,GS=1,EO=0;当输入信号全部无效时,GS=0,EO=1;
*/
wire EO1,GS1,GS0;
wire [2:0] Y1,Y0;
wire [7:0] I1;
wire [7:0] I0;
//中间变量定义
genvar k; //循环变量k
for(k=7;k>=0;k=k-1) assign I0[k]=IN[k];
for(k=15;k>=8;k=k-1) assign I1[k-8]=IN[k];
CD4532 U1(EI,I1,Y1,GS1,EO1);
CD4532 U2(EO1,I0,Y0,GS0,EO);
assign L[3]=GS1;
or G3(GS,GS1,GS0);
or G2(L[2],Y1[2],Y0[2]);
or G1(L[1],Y1[1],Y0[1]);
or G0(L[0],Y1[0],Y0[0]);
endmodule
//filename:test_2CD4532
`timescale 10ns/1ns
module test_2CD4532();
reg EI;
reg [15:0] IN;
wire [3:0] L;
wire GS;
wire EO;
_2CD4532 U0(EI,IN,L,GS,EO);//实例化元件。
initial
$monitor($time,":\tEI=%b,I=%b,L=%b,GS=%b,EO=%b\n",EI,IN,L,GS,EO);//监视器监视。
initial begin
//使能信号无效。
EI=0;IN=16'b1000_0000_0000_0000;
#5
//使能信号有效。
EI=1;IN=16'b1000_0000_0000_0000;
#5
EI=1;IN=16'b0001_0000_0000_0000;
#5
EI=1;IN=16'b0000_0000_0001_0000;
#5
EI=1;IN=16'b0000_0000_0000_0000;
#5
$stop;
end
endmodule
1.循环语句定义循环变量时刚开始使用的是integer,出现错误,查询后发现循坏变量需要定义为genvar型。其次是在verilog中不能使用k++,k–,只能写k=k加减1表达式。
2.采用数据流描述方式时,注意连续赋值语句需要加上assign。
3.变量类型需求:
1)always@程序块中赋值语句左边必须为reg型变量
2)测试平台搭建中,输入必须为reg型,输出必须为wire型。