目录
一、三八译码器原理
二、使用verilog编写三八译码器
1.使用verilog代码如下:
2.verilog的数据类型
(1)wire类型
(2)reg类型
三、使用verilog编写全加器
1.一位全加器
2.四位全加器
3.八位全加器
总结
一、三八译码器原理
三八译码器的输入信号有三个,相当于有八个二进制编码可以输入,每个输入都对应着一个输出信号,其真值表如下图所示:
根据真值表使用logsim设计三八译码器的仿真电路图,该图如下:
二、使用verilog编写三八译码器
1.使用verilog代码如下:
module decoder_3_8(a,b,c,out);
input a,b,c;
output [7:0] out;
reg [7:0] out;
always @(a,b,c) begin
case({a,b,c})
3'b000:out=8'b0000_0001;
3'b001:out=8'b0000_0010;
3'b010:out=8'b0000_0100;
3'b011:out=8'b0000_1000;
3'b100:out=8'b0001_0000;
3'b101:out=8'b0010_0000;
3'b110:out=8'b0100_0000;
3'b111:out=8'b1000_0000;
endcase
end
endmodule
在Quartus里面创建工程,编写代码后生成的RTL电路如下图所示:
仿真结果如下:
相较于原始设计电路来说Quartus生成的电路更为简洁,它将中间逻辑门实现的电路使用了一个模块封装起来,直观上来说只能看见输入与输出的形式,对其实现过程不甚了解,它的仿真测试结果与真值表一致。
2.verilog的数据类型
Verilog 最常用的 2 种数据类型就是线型(wire)与寄存器型(reg),其余类型可以理解为这两种数据类型的扩展或辅助。
(1)wire类型
wire相当于一根导线,无数据储存功能,无驱动能力,通常用于以assign关键字指定的组合逻辑信号,模块的输入输出类型通常默认的是此类型。
(2)reg类型
always模块内被赋值的信号,必须定义为reg型,默认初始值是x。
reg表示一定要有触发,输出才会反映输入,可以用于组合逻辑或者时序逻辑,能存储数据,有驱动能力,在always @模块表达式左侧被赋值。
寄存器(reg)用来表示存储单元,它会保持数据原有的值,直到被改写。
因此不能将上面代码中的reg类型改为wire类型,否则会出现语法错误。
三、使用verilog编写全加器
1.一位全加器
首先在logsim中设计仿真电路图,如下所示:
根据仿真电路图就可以用verilog门级描述生成电路,代码和生成的RTL电路如下:
module adder_1bit(a,b,c,sum,cout);
input a,b,c;
output sum,cout;
wire t1,t2,t3;
xor x1(t1,a,b);
and x2(t2,t1,c);
and x3(t3,a,b);
xor x4(sum,t1,c);
or x5(cout,t2,t3);
endmodule
使用过门级电路过后,我们使用verilog的行为级语言进行描述,代码和RTL电路如下所示:
module shiyan1(
//输入信号,ain表示被加数,bin表示加数,cin表示低位向高位的进位
input ain,bin,cin,
//输出信号,cout表示向高位的进位,sum表示本位的相加和
output reg cout,sum
);
reg s1,s2,s3;
always @(ain or bin or cin) begin
sum=(ain^bin)^cin;//本位和输出表达式
s1=ain&cin;
s2=bin&cin;
s3=ain&bin;
cout=(s1|s2)|s3;//高位进位输出表达式
end
endmodule
相较于门级电路描述方法而言 ,行为级描述更为简洁,但对于逻辑的要求性更高
2.四位全加器
verilog使用门级电路,代码和电路图如下:
module full_adder_4(A,B,C,sum,cout);
input A,B,C;
output cout,sum;
wire t1,t2,t3,t4;
and U1(t1,A,B);
and U2(t2,A,C);
and U3(t3,B,C);
or U4(cout,t1,t2,t3);
xor U5(t4,A,B);
xor U6(sum,t4,C);
endmodule
verilog行为级描述如下:
module adder_4bit(A,B,C,cout,sum);
input A,B,C;
output sum,cout;
wire t1,t2,t3;
assign sum=A^B^C;
assign t1=A&B,
t2=A&C,
t3=B&C;
assign cout=t1|t2|t3;
endmodule
3.八位全加器
八位全加器是在一位全加器的基础上实现的,根据先前的一位全加器的原理将输入的八位信号依次相加。
//1位全加器模块
module adder_1bit(s, cout, a, b, cin);
//输入输出端口定义
output s, cout;
input a, b, cin;
//采用行为描述的方式实现1位全加器
assign s = a ^ b ^ cin;
assign cout = a & b | a & cin | b & cin;
endmodule
//8位加法器顶层模块
module adder_8bit(s, cout, a, b, cin);
//输入输出端口及变量定义
output [7 : 0] s;
output cout;
input [7 : 0] a, b;
input cin;
wire [6 : 0] carry;
//采用结构描述的方式实现一个8位加法器
adder_1bit m0(s[0], carry[0], a[0], b[0], cin);
adder_1bit m1(s[1], carry[1], a[1], b[1], carry[0]);
adder_1bit m2(s[2], carry[2], a[2], b[2], carry[1]);
adder_1bit m3(s[3], carry[3], a[3], b[3], carry[2]);
adder_1bit m4(s[4], carry[4], a[4], b[4], carry[3]);
adder_1bit m5(s[5], carry[5], a[5], b[5], carry[4]);
adder_1bit m6(s[6], carry[6], a[6], b[6], carry[5]);
adder_1bit m7(s[7], cout, a[7], b[7], carry[6]);
endmodule
参考资料:
小梅哥——38译码器-CSDN博客文章来源:https://www.toymoban.com/news/detail-765896.html
总结
使用verilog编写代码可以用门级电路描述,也可以用行为描述。前者需要先画出电路图然后再写代码,过程比较繁琐且后期修改不易;后者需要弄清楚输入输出量的逻辑关系,然后再用赋值语句写对于编写者的逻辑要求较高,不过描述更加简洁,后期修改也更加容易。文章来源地址https://www.toymoban.com/news/detail-765896.html
到了这里,关于使用verilog编写三八译码器及四位全加器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!