2014年6月7日 星期六

Division (除法器)

Division (除法器)
源自於
http://blog.csdn.net/chevroletss/article/details/6308399


Reference:

“Digital design and principles and practices”, John F. Wakerly
“Advanced Digital Design with Verilog HDL”, Michael D.Ciletti




`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


test_bench

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:

沒有留言:

張貼留言