用文本输入方式(Verilog HDL)设计一个 8 位算术逻辑单元。
假定暂存器 A、B 中的操作数均为 8 位补码,包含一位符号位。用双符号位补码进行算术加法运算并需要判断运算结果是否溢出,考虑低位进位输入 Cin。如果运算结果溢出,则需将溢出标志位 Overflow 置为 1,不溢出则置为 0。
逻辑运算时 Overflow 均置为 0。算术 右移按照补码的算术右移规则执行
功能表
ALU结构框图
一、实验分析与设计
通过Sel、Wt实现数据的输入,A、B两个8位补码,进位信号Cin。在信号S的控制下实现运算。
由于采用双符号位补码进行运算,所以将运算值拓展一位,即九位 reg [8:0]A,B,F进行相应运算。
将运算结果Overflow和F[7:0]输出。
在F = A + B,F[8]与F[7]异号表示运算溢出,Overflow = 1。SEL = 3’b000 Data = F[7:4]; SEL = 3'b001 Data = F[3:0];
二、程序代码
module sy4(clk,Cin,D,S,Sel,Wt,Overflow,SEL,code);
input clk,Cin;
input[7:0] D;
input[2:0] S;
input Sel,Wt;
output Overflow;
output[2:0] SEL;
output[7:0] code;
reg Overflow = 0;
reg[2:0] SEL = 3'b000;
reg[7:0] code = 8'b00000000;
reg[8:0] A,B,F;
//数据输入
always@(posedge Wt)
begin
if(Sel == 0)
begin
A[7:0] = D;
A[8] = D[7];
end
else
begin
B[7:0] = D;
B[8] = D[7];
end
end
//计算部分
always@(S)
begin
Overflow = 0;
case(S)
3'd0: F = 9'd0;
3'd1: F = A & B;
3'd2: F = A | B;
3'd3: F = A ^ B;
3'd4:
begin
F = A + B + Cin;
if(F[8] ^ F[7]) Overflow = 1;
end
3'd5: F[7:0] = {A[6:0],1'b0};
3'd6: F[7:0] = {1'b0,A[7:1]};
3'd7: F = A >> 1;
default: F = 9'd0;
endcase
end
//显示部分
reg[3:0] Data;
always@(posedge clk)
begin
if(SEL < 3'b001) SEL = SEL + 1;
else SEL = 3'b000;
end
always@(posedge clk)
begin
case(SEL)
3'b000: Data = F[7:4];
3'b001: Data = F[3:0];
endcase
end
//译码
always @(Data)
begin
case(Data)
4'd0 : code = 8'h3f;
4'd1 : code = 8'h06;
4'd2 : code = 8'h5b;
4'd3 : code = 8'h4f;
4'd4 : code = 8'h66;
4'd5 : code = 8'h6d;
4'd6 : code = 8'h7d;
4'd7 : code = 8'h07;
4'd8 : code = 8'h7f;
4'd9 : code = 8'h6f;
4'd10: code = 8'h77;
4'd11: code = 8'h7c;
4'd12: code = 8'h39;
4'd13: code = 8'h5e;
4'd14: code = 8'h79;
4'd15: code = 8'h71;
default : code = 8'bx;
endcase
end
endmodule
三、ModelSim仿真
Test Bench
`timescale 1 ps/ 1 ps
module sy4_vlg_tst();
reg Cin;
reg [7:0] D;
reg [2:0] S;
reg Sel;
reg Wt;
reg clk;
// wires
wire Overflow;
wire [2:0] SEL;
wire [7:0] code;
sy4 i1 (
.Cin(Cin),
.D(D),
.Overflow(Overflow),
.S(S),
.SEL(SEL),
.Sel(Sel),
.Wt(Wt),
.clk(clk),
.code(code)
);
initial
begin
//输入值
clk = 0;
Cin = 1;
S = 3'b000;
D = 8'b01010111;
Wt = 0;
Sel = 0;
#20
Wt = 1;
#10
D = 8'b01110101;
Wt = 0;
Sel = 1;
#20
Wt = 1;
#10
Wt = 0;
//计算
#30
S = 3'b000;
#60
S = 3'b001;
#60
S = 3'b010;
#60
S = 3'b011;
#60
S = 3'b100;
#60
S = 3'b101;
#60
S = 3'b110;
#60
S = 3'b111;
#60
S = 3'b000;
$display("Running testbench");
end
always #10 clk = ~clk;
endmodule
波形图
F = A (001010111) B(001110101)