⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 divider_stg_0.v

📁 VerilogHDL_advanced_digital_design_code_Ch10 VerilogHDL高级数字设计源码Ch10
💻 V
字号:
module Divider_STG_0 (quotient, remainder, Ready, Error, word1, word2, Start, clock, reset);
/* This version checks for a divide by zero, subtracts the divisor from the dividend until the dividend is less than the divisor, and counts the number of subtractions performed. The length of divisor must not exceed the length of dividend .*/ 

  parameter 				L_divn = 8;
  parameter 				L_divr = 4;		 
  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;
  output 		[L_divr -1: 0]	remainder;
  output 					Ready, Error;
  input 		[L_divn -1: 0] 	word1;			// Datapath for dividend
  input 		[L_divr -1: 0] 	word2;			// Datapath for divisor
  input 					Start, 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;
  wire 					GTE = (dividend >= divisor);	// Comparator
  wire 					Ready = ((state == S_idle) && !reset) || (state == S_3);
  wire 					Error = (state == S_Err);
  assign 	 			remainder = dividend[L_divr -1: 0];

  always @ (posedge clock or posedge reset) 
    if (reset) state <= S_idle; else state <= next_state; 		// State transitions

  always @ (state or word1 or word2 or Start or GTE ) begin 	// Next state and control logic
    Load_words = 0; Subtract = 0; 
    case (state)
      S_idle: 	case (Start) 		  
  		  0:   	next_state = S_idle; 
			  
      		  1:	if (word2 == 0) next_state = S_Err; 
			else if (word1) 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) 		  
  		  0:   	next_state = S_3; 
			  
      		  1:	if (word2 == 0) next_state = S_Err; 
			else if (word1 == 0) next_state = S_3;
else begin next_state = S_1; Load_words = 1; end
		endcase
      S_Err:		next_state = S_Err;
      default:	next_state = S_Err;
    endcase
  end

// Register/Datapath Operations

  always @ (posedge clock or posedge reset) begin
    if (reset) begin divisor <= 0; dividend <= 0; quotient <= 0; end
    else if (Load_words == 1)  begin 
      dividend <= word1; 
      divisor <= word2; 
      quotient <= 0; end
    else if (Subtract)  begin 
      dividend <= dividend[L_divn -1: 0] + 1'b1 + {{(L_divn -L_divr){1'b1}}, ~divisor[L_divr -1: 0]};
      quotient <= quotient + 1; end
   end
endmodule

module test_Divider_STG_0 ();
  parameter L_divn = 8;
  parameter L_divr = 4;
  wire [L_divn -1: 0] quotient;
  wire [L_divr-1:0] remainder;
  wire Ready, Div_zero;
  integer word1;		// dividend
  integer word2;		// divisor
  reg Start, clock, reset;
  reg [L_divn-1: 0] expected_value;
  reg [L_divr-1:0] expected_remainder;		 
  reg code_error;

  Divider_STG_0 M1 (quotient, remainder, Ready, Error, word1, word2, Start, clock, reset);
 
  integer k, m;

  initial #1800000 $finish;
  initial begin clock = 0; forever #10 clock = ~clock; end

// Exhaustive Test
always @ (negedge Ready) begin 
//always @ (posedge clock) 
//begin if (!reset && Start && (M1.state == M1.S_idle) || (M1.state == M1.S_3)) 
	begin  
	 #2 if (word2 != 0) begin expected_value = 0; expected_remainder = 0; code_error = 0;  end
	if (word2 != 0) begin expected_value = word1 / word2; expected_remainder = word1 % word2; end
 	end
code_error = (!reset && Ready && !Start) ? | {|(expected_value ^ quotient), |(expected_remainder ^ remainder)}: 0;
#10 code_error = 0;
end


initial begin	
// Test for divide by zero detection
#2 reset = 1;
#15 reset = 0; Start = 0;
#10 Start = 1; #5 Start = 0;		
end

initial begin 
// Test for recovery from error state on reset
#50 reset = 1; #5 Start = 1; #5 reset = 0;
word1 = 0; 
word2 = 1; 
while (word2 <= 15) #20 word2 = word2 +1;
 #20 Start = 0; 

end		// Test for recovery from running reset state

initial begin #500  // Exhaustive patterns

  	word1 = 1 /*127*/; while (word1 <= 127 /*255*/) begin			
	word2 = 1; while (word2 <= 15) begin
  		#0 Start = 0; 
		#30 Start = 1;
      	#20 Start = 0; 
      	@ (posedge Ready) #0;
		word2 = word2 + 1; end  	// word2
	word1 = word1 + 1; end 	 		//word1
end 		// initial
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -