源自於
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:
沒有留言:
張貼留言