原文出处http://www.cnblogs.com/carl_yy/archive/2010/09/10/1823522.html
计算器
module calculator(
num,
num_decp,
num_dec,
num_sig,
cal,
enter,
result_int,
result_dec,
result_sig,
result_decp,
clk,
rst
);
input clk;
input rst;
input [9:0] num;
input num_decp;
input num_sig;
input [9:0] num_dec;
input [3:0] cal;
input enter;
output [19:0] result_int;
output [9:0] result_dec;
output result_sig;
output result_decp;
reg [9:0] num1;
reg num1_decp;
reg num1_sig;
reg [9:0] num1_dec;
reg [9:0] num2;
reg num2_decp;
reg num2_sig;
reg [9:0] num2_dec;
reg [9:0] num1cal;
reg num1cal_decp;
reg num1cal_sig;
reg [9:0] num1cal_dec;
reg [9:0] num2cal;
reg num2cal_decp;
reg num2cal_sig;
reg [9:0] num2cal_dec;
reg [3:0] cal_tmp;
reg [19:0] result_int;
reg [9:0] result_dec;
reg result_sig;
reg result_decp;
reg [3:0] cal_st;
always@(posedge clk or negedge rst)
begin
if(~rst)
begin
cal_tmp<=4'b0000;
num1<=0;
num2<=0;
num1_decp<=0;
num2_decp<=0;
num1_dec<=0;
num2_dec<=0;
num1_sig<=0;
num2_sig<=0;
num1cal<=0;
num2cal<=0;
num1cal_decp<=0;
num2cal_decp<=0;
num1cal_dec<=0;
num2cal_dec<=0;
num1cal_sig<=0;
num2cal_sig<=0;
result_int<=0;
result_dec<=0;
result_decp<=0;
result_sig<=0;
cal_st<=0;
end
else
begin
if(|cal)
begin
num1_sig<=num_sig;
num1<=num;
num1_decp<=num_decp;
num1_dec<=num_dec;
cal_tmp<=cal;
end
else
begin
if(enter)
begin
num2_sig<=num_sig;
num2<=num;
num2_decp<=num_decp;
num2_dec<=num_dec;
case({num1_sig,num2_sig,cal_tmp})
6'b000001://num1+num2
begin
cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b010001://num1+(-num2)=num1-num2
begin
cal_st<=2;//num1-num2,num1_sig=num2_sig=0
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=0;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b100001://-num1+num2
begin
cal_st<=2;
//alternate num1 and num2, then it's still num1-num2
num1cal_sig<=0;
num1cal<=num2;
num1cal_decp<=num2_decp;
num1cal_dec<=num2_dec;
num2cal_sig<=0;
num2cal<=num1;
num2cal_decp<=num1_decp;
num2cal_dec<=num1_dec;
end
6'b110001://-num1+(-num2)
begin
cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b000010://num1-num2
begin
cal_st<=2;//num1-num2,num1_sig=num2_sig=0
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b010010://num1-(-num2)
begin
cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
num1cal_sig<=0;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=0;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b100010://-num1-num2
begin
cal_st<=1;//num1+num2,result_sig=num1_sig&num2_sig
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=1;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b110010://-num1-(-num2)=num2-num1
begin
cal_st<=2;//num1-num2,num1_sig=num2_sig=0
num1cal_sig<=0;
num1cal<=num2;
num1cal_decp<=num2_decp;
num1cal_dec<=num2_dec;
num2cal_sig<=0;
num2cal<=num1;
num2cal_decp<=num1_decp;
num2cal_dec<=num1_dec;
end
6'b000100://num1*num2,result_sig=num1_sig^num2_sig
begin
cal_st<=3;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b010100://num1*(-num2)
begin
cal_st<=3;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b100100://(-num1)*num2
begin
cal_st<=3;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b110100://(-num1)*(-num2)
begin
cal_st<=3;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b001000://num1/num2
begin
cal_st<=4;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b011000://num1/(-num2)
begin
cal_st<=4;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b101000://(-num1)/num2
begin
cal_st<=4;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
6'b111000://(-num1)/(-num2)
begin
cal_st<=4;
num1cal_sig<=num1_sig;
num1cal<=num1;
num1cal_decp<=num1_decp;
num1cal_dec<=num1_dec;
num2cal_sig<=num2_sig;
num2cal<=num2;
num2cal_decp<=num2_decp;
num2cal_dec<=num2_dec;
end
endcase
case(cal_st)
4'd1://num1cal+num2cal,result_sig=num1cal_sig&num2cal_sig,where num1cal_sig=num2cal_sig
begin
result_sig<=num1cal_sig&num2cal_sig;
result_int<=num1cal+num2cal+(num1cal_dec+num2cal_dec)/1000;
result_decp<=num1cal_decp|num2cal_decp;
result_dec<=(num1cal_dec+num2cal_dec)%1000;
end
4'd2://num1cal-num2cal,num1cal_sig=num2cal_sig=0
begin
if(num1cal<num2cal)//-(num2cal-num1cal)
begin
result_sig<=1;
if(num2cal_dec<num1cal_dec)
begin
result_int<=num2cal-num1cal-1;
result_decp<=1;
result_dec<=1000+num2cal_dec-num1cal_dec;
end
else
begin
result_int<=num2cal-num1cal;
result_decp<=num1cal_decp|num2cal_decp;
result_dec<=num2cal_dec-num1cal_dec;
end
end
else//num1cal>=num2cal
begin
if(num1cal>num2cal)
begin
result_sig<=0;
if(num1cal_dec<num2cal_dec)
begin
result_int<=num1cal-num2cal-1;
result_decp<=1;
result_dec<=1000+num1cal_dec-num2cal_dec;
end
else//num1cal_dec>=num2cal_dec
begin
result_int<=num1cal-num2cal;
result_decp<=num1cal_decp|num2cal_decp;
result_dec<=num1cal_dec-num2cal_dec;
end
end
else//num1cal==num2cal
begin
if(num1cal_dec<num2cal_dec)//num1cal.dec1-num2cal.dec2=-(num2cal.dec2-num1cal.dec1)
begin
result_sig<=1;
result_int<=num2cal-num1cal;
result_decp<=1;
result_dec<=num2cal_dec-num1cal_dec;
end
else//num1cal.dec>=num2cal.dec
begin
result_sig<=0;
result_int<=num1cal-num2cal;
result_decp<=num1cal_decp|num2cal_decp;
result_dec<=num1cal_dec-num2cal_dec;
end
end
end
end
4'd3:
begin
result_sig<=num1cal_sig^num2cal_sig;
result_int<=num1cal*num2cal+(num1cal*num2cal_dec)/1000+(num2cal*num1cal_dec)/1000+(num1cal_dec*num2cal_dec)/1000000;
result_decp<=num1cal_decp|num2cal_decp;
result_dec<=((num1cal_dec*num2cal_dec)%1000000)/1000+(num1cal*num2cal_dec)%1000+(num2cal*num1cal_dec)%1000;
end
4'd4://num1cal/num2cal
begin
result_sig<=num1cal_sig^num2cal_sig;
result_int<=(num1cal*1000+num1cal_dec)/(num2cal*1000+num2cal_dec);
result_dec<= (((num1cal*1000+num1cal_dec)%(num2cal*1000+num2cal_dec))*1000/(num2cal*1000+num2cal_dec));
if(result_dec==0)
begin
result_decp<=0;
end
else
begin
result_decp<=1;
end
end
endcase
end
end
end
end
endmodule