1.加减法
module addsub ( input [7:0] dataa, input [7:0] datab, input add_sub, // if this is 1, add; else subtract input clk, output reg [8:0] result ); always @ (posedge clk) begin if (add_sub) result <= dataa + datab; //or "assign {cout,sum}=dataa+datab;" else result <= dataa - datab; end endmodule
补码不仅可以执行正值和负值转换,其实补码存在的意义,就是避免计算机去做减法的操作。
1101 -3 补
+ 1000 8
01015
假设 -3 + 8,只要将 -3 转为补码形式,亦即 0011 => 1101,然后和 8,亦即 1000 相加
就会得到 5,亦即 0101。至于溢出的最高位可以无视掉
2.乘法
module mult(outcome,a,b); parameter SIZE=8; input[SIZE:1] a,b; output reg[2*SIZE:1] outcome; integer i; always @(a or b) begin outcome<=0; for(i=0,i<=SIZE;i=i+1) if(b[i]) outcome<=outcome+(a<<(i-1)); end endmodule
乘法-带符号位,在初始化之际,取乘数和被乘数的正负关系,然后取被乘数和乘数的正值。输出结果根据正负关系取得。
else if( Start_Sig ) case( i ) 0: begin isNeg <= Multiplicand[7] ^ Multiplier[7]; Mcand <= Multiplicand[7] ? ( ~Multiplicand + 1'b1 ) : Multiplicand; Mer <= Multiplier[7] ? ( ~Multiplier + 1'b1 ) : Multiplier; Temp <= 16'd0; i <= i + 1'b1; end 1: // Multipling if( Mer == 0 ) i <= i + 1'b1; else begin Temp <= Temp + Mcand; Mer <= Mer - 1'b1; end //浪费时钟 2: begin isDone <= 1'b1; i <= i + 1'b1; end 3: begin isDone <= 1'b0; i <= 2'd0; end endcase /*************************/ assign Done_Sig = isDone; assign Product = isNeg ? ( ~Temp + 1'b1 ) : Temp; /*************************/ endmodule
乘法器.vt示例
`timescale 1 ps/ 1 ps module multiplier_module_simulation(); reg CLK; reg RSTn; reg Start_Sig; reg [7:0] Multiplicand; reg [7:0] Multiplier; wire Done_Sig; wire [15:0]Product; /***********************************/ initial begin RSTn = 0; #10; RSTn = 1; CLK = 1; forever #10 CLK = ~CLK; end /***********************************/ multiplier_module U1 ( .CLK(CLK), .RSTn(RSTn), .Start_Sig(Start_Sig), .Multiplicand(Multiplicand), .Multiplier(Multiplier), .Done_Sig(Done_Sig), .Product(Product) ); /***********************************/ reg [3:0]i; always @ ( posedge CLK or negedge RSTn ) if( !RSTn ) begin i <= 4'd0; Start_Sig <= 1'b0; Multiplicand <= 8'd0; Multiplier <= 8'd0; end else case( i ) 0: // Multiplicand = 10 , Multiplier = 2 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin Multiplicand <= 8'd10; Multiplier <= 8'd2; Start_Sig <= 1'b1; end 1: // Multiplicand = 2 , Multiplier = 10 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin Multiplicand <= 8'd2; Multiplier <= 8'd10; Start_Sig <= 1'b1; end 2: // Multiplicand = 11 , Multiplier = -5 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin Multiplicand <= 8'd11; Multiplier <= 8'b11111011; Start_Sig <= 1'b1; end 3: // Multiplicand = -5 , Multiplier = -11 if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end else begin Multiplicand <= 8'b11111011; Multiplier <= 8'b11110101; Start_Sig <= 1'b1; end 4: begin i <= 4'd4; end endcase /***********************************/ endmodule
循环除法器
module streamlined_divider_module ( input CLK, input RSTn, input Start_Sig, input [7:0]Dividend, input [7:0]Divisor, output Done_Sig, output [7:0]Quotient, output [7:0]Reminder, /**************************/ output [15:0]SQ_Diff, output [15:0]SQ_Temp ); /******************************/ reg [3:0]i; reg [8:0]s; reg [15:0]Temp; reg [15:0]Diff; reg isNeg; reg isDone; always @ ( posedge CLK or negedge RSTn ) if( !RSTn ) begin i <= 4'd0; s <= 9'd0; Temp <= 16'd0; Diff <= 16'd0; isNeg <= 1'b0; isDone <= 1'b0; end else if( Start_Sig ) case( i ) 0: begin isNeg <= Dividend[7] ^ Divisor[7]; s <= Divisor[7] ? { 1'b1, Divisor } : { 1'b1 , ~Divisor + 1'b1 }; Temp <= Dividend[7] ? { 8'd0 , ~Dividend + 1'b1 } : { 8'd0 , Dividend }; Diff <= 16'd0; i <= i + 1'b1; end 1,2,3,4,5,6,7,8: begin Diff = Temp + { s , 7'd0 }; if( Diff[15] ) Temp <= { Temp[14:0] , 1'b0 }; else Temp <= { Diff[14:0] , 1'b1 }; i <= i + 1'b1; end 9: begin isDone <= 1'b1; i <= i + 1'b1; end 10: begin isDone <= 1'b0; i <= 2'd0; end endcase /*********************************/ assign Done_Sig = isDone; assign Quotient = isNeg ? ( ~Temp[7:0] + 1'b1 ) : Temp[7:0]; assign Reminder = Temp[15:8]; /**********************************/ assign SQ_Diff = Diff; assign SQ_Temp = Temp; /**********************************/ endmodule