天天看点

Division (除法器)

Reference:

“Digital design and principles and practices”, John F. Wakerly

“Advanced Digital Design with Verilog HDL”, Michael D.Ciletti

Division (除法器)

`timescale 1ns / 1ps

//

// Company: SEU.IC

// Engineer: Ray

// Description:

// 1, this verilog code is designed for unsigned integer division;

// 2, subtract_and_shift --> division;

// 3, word1_in/word2_in = quotient + remainder;

// 4, word1_in is the dividend and word2_in is the divisor;

// 5, if word2_in == 'd0, then set the error_out;

// 6, ready_out is utilized to indicate the completion of division

// 7, the width of word2_in is not larger than the width of word1_in;

// 8, the subtraction is realized by 2s complement addition

//

module division_4(

quotient_out,

remainder_out,

ready_out,

error_out,

word1_in,

word2_in,

start_in,

clock,

reset);

parameter l_divn = 8;

parameter l_divr = 8;

parameter s_idle = 0,

s_1 = 1,

s_2 = 2,

s_3 = 3,

s_err = 4;

parameter l_state = 3;

output [l_divn-1 : 0] quotient_out;

output [l_divn-1 : 0] remainder_out;

output ready_out, error_out;

input [l_divn-1 : 0] word1_in;

input [l_divr-1 : 0] word2_in;

input start_in, clock, reset;

reg [l_state-1 : 0] state, next_state;

reg load_words, subtract;

reg [l_divn-1 : 0] dividend;

reg [l_divr-1 : 0] divisor;

reg [l_divn-1 : 0] quotient_out;

wire GTE = (dividend >= divisor);

wire ready_out = ((state == s_idle)&&!reset)||(state == s_3);

wire error_out = (state == s_err);

assign remainder_out = dividend;

always @(posedge clock, posedge reset)

if(reset)

state <= s_idle;

else

state <= next_state;

always@(state, word1_in, word2_in, start_in, GTE)

begin

load_words = 0;

subtract = 0;

case (state)

s_idle: case(start_in)

0: next_state = s_idle;

1: if(word2_in == 0) next_state = s_err;

else if(word1_in)

begin

next_state = s_1;

load_words = 1;

end

else

next_state = s_3;

endcase

s_1: if(GTE)

begin

next_state = s_2;

subtract = 1;

end

else

next_state = s_3;

s_2: if(GTE)

begin

next_state = s_2;

subtract = 1;

end

else

next_state = s_3;

s_3: case(start_in)

0: next_state = s_3;

1: if(word2_in == 0) next_state = s_err;

else if(word1_in == 0) next_state = s_3;

else

begin

next_state = s_1;

load_words = 1;

end

endcase

s_err: next_state = s_idle;

default: next_state = s_idle;

endcase

end

always @(posedge clock, posedge reset)

begin

if(reset)

begin

divisor <= 'd0;

dividend <= 'd0;

quotient_out <= 'd0;

end

else if(load_words == 1)

begin

divisor <= word2_in;

dividend <= word1_in;

quotient_out <= 'd0;

end

else if(subtract)

begin

dividend <= dividend[l_divn-1 : 0] + 1'b1 + {​{(l_divn - l_divr){1'b1}}, ~divisor[l_divr-1 :0]};// 2s complement addition

quotient_out <= quotient_out + 1;

end

end

endmodule

Testbench:

module tb_div_4;

// Inputs

reg [7:0] word1_in;

reg [7:0] word2_in;

reg start_in;

reg clock;

reg reset;

// Outputs

wire [7:0] quotient_out;

wire [7:0] remainder_out;

wire ready_out;

wire error_out;

// Instantiate the Unit Under Test (UUT)

division_4 uut (

.quotient_out(quotient_out),

.remainder_out(remainder_out),

.ready_out(ready_out),

.error_out(error_out),

.word1_in(word1_in),

.word2_in(word2_in),

.start_in(start_in),

.clock(clock),

.reset(reset)

);

always #10 clock = ~clock;

initial begin

// Initialize Inputs

word1_in = 0;

word2_in = 0;

start_in = 0;

clock = 0;

reset = 1;

// Wait 100 ns for global reset to finish

#100;

reset = 0;

// Add stimulus here

word1_in = 'd20;

word2_in = 'd10;

#50;

start_in = 1;

#50;

start_in = 0;

word1_in = 'd241;

word2_in = 'd78;

#100;

start_in = 1;

#50;

start_in = 0;

word1_in = 'd201;

word2_in = 'd55;

#200;

start_in = 1;

#50;

start_in = 0;

word1_in = 'd100;

word2_in = 'd0;

#200;

start_in = 1;

#50;

start_in = 0;

end

endmodule

Simualtion Wave:

Division (除法器)