[转]Verilog编写的计算器

原文出处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
原文地址:https://www.cnblogs.com/woshitianma/p/2811800.html