用 Verilog 设计一个3-8译码器、一个多位全加器和一个16位算术逻辑单元 (ALU)

用 Verilog 设计一个3-8译码器、一个多位全加器和一个16位算术逻辑单元 (ALU)

1. 3-8译码器

译码器的编辑与生成

3-8译码器的 verilog 代码如下:

module decoder74LS138 (
	output reg [7:0] out,
	input [2:0] in
);
    always@(*)
		case (in)
			0: out = 8'b00000001;
			1: out = 8'b00000010;
			2: out = 8'b00000100;
			3: out = 8'b00001000;
			4: out = 8'b00010000;
			5: out = 8'b00100000;
			6: out = 8'b01000000;
			7: out = 8'b10000000;
		endcase
endmodule

生成的 RTL 电路如下:

在这里插入图片描述

译码器的仿真测试

3-8译码器仿真测试的 verilog 代码如下:

`timescale 1ns/1ns
module tb_decoder74LS138();

reg [2:0] in;
wire [7:0] out;

initial begin
	in = 0;
end

always #10 in <= {$random} % 8;

initial begin
	$timeformat(-9, 0, "ns", 6);
	$monitor("@time %t:in=%b out=%b", $time, in, out);
end

decoder74LS138 decoder74LS138_ins
(
	.in(in),
	.out(out)
);

endmodule

仿真测试波形图如下:

在这里插入图片描述

Transcript 结果如下:

# @time    0ns:in=000 out=00000001
# @time   10ns:in=100 out=00010000
# @time   20ns:in=001 out=00000010
# @time   40ns:in=011 out=00001000
# @time   50ns:in=101 out=00100000
# @time   80ns:in=010 out=00000100
# @time   90ns:in=001 out=00000010
# @time  100ns:in=101 out=00100000
# @time  110ns:in=110 out=01000000
# @time  120ns:in=101 out=00100000
# @time  140ns:in=100 out=00010000
# @time  150ns:in=001 out=00000010
# @time  160ns:in=110 out=01000000
# @time  170ns:in=101 out=00100000
# @time  180ns:in=010 out=00000100
# @time  190ns:in=101 out=00100000
# @time  200ns:in=111 out=10000000
# @time  210ns:in=010 out=00000100
# @time  220ns:in=111 out=10000000
# @time  230ns:in=010 out=00000100
# @time  240ns:in=110 out=01000000
# @time  250ns:in=000 out=00000001
# @time  260ns:in=101 out=00100000
# @time  270ns:in=100 out=00010000
# @time  280ns:in=101 out=00100000
# @time  310ns:in=011 out=00001000
# @time  320ns:in=010 out=00000100
# @time  330ns:in=000 out=00000001
# @time  350ns:in=010 out=00000100
# @time  360ns:in=101 out=00100000
# @time  370ns:in=110 out=01000000
# @time  380ns:in=011 out=00001000
# @time  390ns:in=101 out=00100000
# @time  400ns:in=011 out=00001000
# @time  420ns:in=101 out=00100000
# @time  430ns:in=010 out=00000100
# @time  440ns:in=110 out=01000000
# @time  450ns:in=101 out=00100000
# @time  460ns:in=111 out=10000000
# @time  470ns:in=011 out=00001000
# @time  480ns:in=010 out=00000100
# @time  500ns:in=100 out=00010000
# @time  510ns:in=010 out=00000100
# @time  530ns:in=001 out=00000010
# @time  540ns:in=000 out=00000001
# @time  560ns:in=001 out=00000010
# @time  570ns:in=011 out=00001000
# @time  580ns:in=110 out=01000000
# @time  610ns:in=100 out=00010000
# @time  620ns:in=010 out=00000100
# @time  630ns:in=011 out=00001000
# @time  640ns:in=001 out=00000010
# @time  650ns:in=101 out=00100000
# @time  660ns:in=111 out=10000000
# @time  670ns:in=011 out=00001000
# @time  680ns:in=010 out=00000100
# @time  690ns:in=110 out=01000000
# @time  700ns:in=101 out=00100000
# @time  710ns:in=001 out=00000010
# @time  730ns:in=010 out=00000100
# @time  740ns:in=100 out=00010000
# @time  750ns:in=111 out=10000000
# @time  770ns:in=000 out=00000001
# @time  780ns:in=111 out=10000000
# @time  800ns:in=100 out=00010000
# @time  810ns:in=011 out=00001000
# @time  820ns:in=001 out=00000010
# @time  840ns:in=000 out=00000001
# @time  850ns:in=111 out=10000000
# @time  860ns:in=001 out=00000010
# @time  870ns:in=110 out=01000000
# @time  880ns:in=100 out=00010000
# @time  890ns:in=010 out=00000100
# @time  900ns:in=000 out=00000001
# @time  910ns:in=111 out=10000000
# @time  920ns:in=101 out=00100000
# @time  930ns:in=010 out=00000100
# @time  940ns:in=110 out=01000000
# @time  950ns:in=101 out=00100000
# @time  960ns:in=001 out=00000010
# @time  970ns:in=111 out=10000000
# @time  980ns:in=011 out=00001000
# @time  990ns:in=101 out=00100000

2. 全加器

用门级描述方式生成的全加器

1位全加器

verilog 代码

module full_adder_structural(a, b, cin, sum, cout);
	input a, b, cin;
	output sum, cout;
	wire t1, t2, t3, t4;
	and u1(t1, a, b);
	and u2(t2, a, cin);
	and u3(t3, b, cin);
	or u4(cout, t1, t2, t3);
	xor u5(t4, a, b);
	xor u6(sum, t4, cin);
endmodule

RTL 图

在这里插入图片描述

4个1位全加器级联构成的4位串行全加器

verilog 代码

module serial_carry_adder_4bit_structural (
	input [3:0] a, b,
	input cin,
	output [3:0] sum,
	output cout
);
	wire [4:0] c;
	assign c[0] = cin;
	full_adder_structural fa_0(a[0], b[0], c[0], sum[0], c[1]);
	full_adder_structural fa_1(a[1], b[1], c[1], sum[1], c[2]);
	full_adder_structural fa_2(a[2], b[2], c[2], sum[2], c[3]);
	full_adder_structural fa_3(a[3], b[3], c[3], sum[3], c[4]);
	assign cout = c[4];
endmodule

RTL 图

在这里插入图片描述

用行为级描述方式生成的全加器

1位全加器

verilog 代码

module full_adder (
	input a, b, cin,
	output sum, cout
);
	assign sum = a ^ b ^ cin;
	assign cout = (a & b) | (a & cin) | (b & cin);
endmodule

RTL 图

在这里插入图片描述

4个1位全加器级联构成的4位串行全加器

verilog 代码

module serial_carry_adder_4bit (
	input [3:0] a, b,
	input cin,
	output [3:0] sum,
	output cout
);
	wire [4:0] c;
	assign c[0] = cin;
	full_adder fa_0(a[0], b[0], c[0], sum[0], c[1]);
	full_adder fa_1(a[1], b[1], c[1], sum[1], c[2]);
	full_adder fa_2(a[2], b[2], c[2], sum[2], c[3]);
	full_adder fa_3(a[3], b[3], c[3], sum[3], c[4]);
	assign cout = c[4];
endmodule

RTL 图

在这里插入图片描述

8个1位全加器级联构成的8位串行全加器

verilog 代码

与4位串行全加器类似。

module serial_carry_adder_8bit (
	input [7:0] a, b,
	input cin,
	output [7:0] sum,
	output cout
);
	wire [8:0] c;
	assign c[0] = cin;
	full_adder fa_0(a[0], b[0], c[0], sum[0], c[1]);
	full_adder fa_1(a[1], b[1], c[1], sum[1], c[2]);
	full_adder fa_2(a[2], b[2], c[2], sum[2], c[3]);
	full_adder fa_3(a[3], b[3], c[3], sum[3], c[4]);
	full_adder fa_4(a[4], b[4], c[4], sum[4], c[5]);
	full_adder fa_5(a[5], b[5], c[5], sum[5], c[6]);
	full_adder fa_6(a[6], b[6], c[6], sum[6], c[7]);
	full_adder fa_7(a[7], b[7], c[7], sum[7], c[8]);
	assign cout = c[8];
endmodule

RTL 图(1位全加器内部已省略)

在这里插入图片描述

3. 算术逻辑单元 (ALU)(16位)

verilog 代码

代码中的 n 表示位数,这里 n = 16.

//16bit arithmetic and logic unit(ALU)
module ALU_16bit#(
	parameter n = 16
	)(
	input [n-1:0] opA, //INPUT operand A
	input [n-1:0] opB, //INPUT operand B
	input [3:0] S , //INPUT Signal that selects working mode
	input wire M , //INPUT Signal that controls logical operation
	input wire Cin, //INPUT signal that carry
	output reg[n-1:0]DO,//OUTPUT DATA
	output wire C , //OUTPUT Carry
	output wire V , //Overflow
	output wire N , //DO's sign bit
	output wire Z //if DO is 0
);
	reg [n-1:0] p;
	reg [n-1:0] g;
	reg [n:0] carry;
	//main body
	always@(opA,opB,S,M,Cin)
	//need blocking assignment
		begin
			carry[0] = Cin;
			g = {n{S[3]}}&opA&opB | {n{S[2]}}&opA&(~opB) | {n{(~M)}};
			//Expand bits
			//let every bit is S[3]/S[2]/(~M)
			//by {n{}}
			p = ~({n{S[3]}}&opA&opB | {n{S[2]}}&opA&(~opB) | {n{S[1]}}&(~opA)&opB | {n{S[0]}}&(~opA)&(~opB));
			//Expand bits
			//let every bit is S[3]/S[2]/S[1]/S[0]
			//by {n{}}
			carry[n:1] = g|(p&carry[n-1:0]);
			DO = p^carry[n-1:0];
		end
	//CVNZ analysis
	assign C = carry[n];//carry is the MSD of carry[n,0]
	assign V = (opA[n-1]&opB[n-1]&~DO[n-1]) | (~opA[n-1]&~opB[n-1]&DO[n-1]);//1:overflow;0:not
	assign N = DO[n-1];//sign bit is the MSD
	assign Z = (!(DO))?1:0;//if all bits are 0,then Z=1,else Z=0;
endmodule

RTL 图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值