赞
踩
目录
三八译码器的输入信号有三个,相当于有八个二进制编码可以输入,每个输入都对应着一个输出信号,其真值表如下图所示:
根据真值表使用logsim设计三八译码器的仿真电路图,该图如下:
- 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
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
在Quartus里面创建工程,编写代码后生成的RTL电路如下图所示:
仿真结果如下:
相较于原始设计电路来说Quartus生成的电路更为简洁,它将中间逻辑门实现的电路使用了一个模块封装起来,直观上来说只能看见输入与输出的形式,对其实现过程不甚了解,它的仿真测试结果与真值表一致。
Verilog 最常用的 2 种数据类型就是线型(wire)与寄存器型(reg),其余类型可以理解为这两种数据类型的扩展或辅助。
wire相当于一根导线,无数据储存功能,无驱动能力,通常用于以assign关键字指定的组合逻辑信号,模块的输入输出类型通常默认的是此类型。
always模块内被赋值的信号,必须定义为reg型,默认初始值是x。
reg表示一定要有触发,输出才会反映输入,可以用于组合逻辑或者时序逻辑,能存储数据,有驱动能力,在always @模块表达式左侧被赋值。
寄存器(reg)用来表示存储单元,它会保持数据原有的值,直到被改写。
因此不能将上面代码中的reg类型改为wire类型,否则会出现语法错误。
首先在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
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
相较于门级电路描述方法而言 ,行为级描述更为简洁,但对于逻辑的要求性更高
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
八位全加器是在一位全加器的基础上实现的,根据先前的一位全加器的原理将输入的八位信号依次相加。
- //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
-
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
使用verilog编写代码可以用门级电路描述,也可以用行为描述。前者需要先画出电路图然后再写代码,过程比较繁琐且后期修改不易;后者需要弄清楚输入输出量的逻辑关系,然后再用赋值语句写对于编写者的逻辑要求较高,不过描述更加简洁,后期修改也更加容易。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。