基于Verilog的简单计算器设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
module alu4(
input wire [3:0]alusel,
input wire [3:0]a,
input wire [3:0]b,
output reg nf, //令标志位output reg zf, //负标志位output reg cf, //进位标志output reg ovf, //溢出位标志output reg [7:0]y,
output reg [3:0]rem //余数
);
reg [4:0]temp;
reg [7:0]pv;
reg [7:0]dp;
integer i;
reg [1:0]remL;
reg [1:0]quotL;
always@(*)
begin
y=0;
rem=0;
cf=0;
ovf=0;
nf=0;
temp=5'b00000;
case(alusel)
4'b0001:y=a; //传递
4'b0010: //加法
begin
temp={1'b0,a}+{1'b0,b};
y=temp[3:0];
cf=temp[4];
ovf=y[3]^a[3]^b[3]^cf;
end
4'b0011: //减法1
begin
temp={1'b0,a}-{1'b0,b};
y=temp[3:0];
cf=temp[4];
ovf=y[3]^a[3]^b[3]^cf;
end
4'b0100: //减法二
begin
temp={1'b0,b}-{1'b0,a};
y=temp[3:0];
cf=temp[4];
ovf=y[3]^a[3]^b[3]^cf;
end
4'b0101: //乘法
begin
pv=8'b00000000;
dp={4'b0000,b};
for (i=0;i<=3;i=i+1)
begin
if(a[i]==1)
pv=pv+dp;
dp={dp[6:0],1'b0};
end
y=pv;
end
4'b0110:div({1'b0,b[3:0]},a,y,rem); //除法1
4'b0111:div({1'b0,a[3:0]},b,y,rem); //除法2
4'b1000:y=~a; //非
4'b1001:y=a&b; //与
4'b1010:y=a|b; //或
4'b1011:y=a^b; //异或
4'b1100:y={a[2:0],1'b0}; //左移1位
4'b1101:y={a[2:0],a[3]}; //循环左移1位
4'b1110:y={a[0],a[3:1]}; //循环右移1位
4'b1111:y={a[3],a[3:1]}; //算数右移1位
default:y=a;
endcase
nf=y[3];
if(y==4'b0000)
zf=1;
else
zf=0;
if(y>=10)
cf=1;
else
cf=0;
if(y>99)
ovf=1;
else
ovf=0;
end
task div( //定义除法
input wire[3:0]numerator,
input [3:0]denom,
output [3:0]y,
output [3:0]rem
);
begin
reg [7:0]numer;
reg [4:0]d;
reg [4:0]n1;
reg [3:0]n2;
begin
numer={4'b0000,numerator};
d={1'b0,denom};
n2=b;
n1={1'b0,numer[7:4]};
repeat(4)
begin
n1={n1[3:0],n2[3]};
n2={n2[2:0],1'b0};
if(n1>=d)
begin
n1=n1-d;
n2[0]=1;
end
end
y=n2;
rem=n1[3:0];
end
end
endtask
binbcd B(.a(a), //调用BCD码模块,元件例化.b(b),
.y(y),
.rem(rem),
);
Endmodule
module binbcd( //将二进制转换成BCD码input wire [3:0]a,
input wire [3:0]b,
input wire [3:0]rem,
input wire [3:0]y,
output reg [7:0]p,
output wire [4:0]q,
output wire [4:0]n,
output wire [4:0]m
);
assign n[4]=a[3]&a[2]|a[3]&a[1];
assign n[3]=a[3]&~a[2]&~a[1];
assign n[2]=~a[3]&a[2]|a[2]&a[1];
assign n[1]=a[3]&a[2]&~y[1]|~y[3]&y[1];
assign n[0]=a[0];
assign m[4]=b[3]&b[2]|b[3]&b[1];
assign m[3]=b[3]&~b[2]&~b[1];
assign m[2]=~b[3]&b[2]|b[2]&b[1];
assign m[1]=b[3]&b[2]&~b[1]|~b[3]&b[1];
assign m[0]=b[0];
assign q[4]=rem[3]&rem[2]|rem[3]&rem[1];
assign q[3]=rem[3]&~rem[2]&~rem[1];
assign q[2]=~rem[3]&rem[2]|rem[2]&rem[1]; assign q[1]=rem[3]&rem[2]&~rem[1]|~rem[3]&rem[1]; assign q[0]=rem[0];
reg[17:0]z;
integer j;
always @(*)
begin
for (j=0;j<=17;j=j+1)
z[j]=0;
z[10:3]=y;
repeat(5)
begin
if(z[11:8]>4)
z[11:8]=z[11:8]+3;
if(z[15:12]>4)
z[15:12]=z[15:12]+3;
z[17:1]=z[16:0];
end
p=z[17:0];
end
endmodule