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

📄 divider_stg_0_sub.v

📁 VerilogHDL_advanced_digital_design_code_Ch10 VerilogHDL高级数字设计源码Ch10
💻 V
字号:
module Divider_STG_0_sub (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_divn -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 					Ready = ((state == S_idle) && !reset) || (state == S_3);
  wire 					Error = (state == S_Err);
  wire		 [L_divn-1:0]		difference;
  wire					carry;
  assign					{carry, difference} = dividend[L_divn-1: 0] 
					+ {{(L_divn -L_divr){1'b1}}, ~divisor[L_divr -1:  0]} 
+ 1'b1;
  assign 	 			remainder = dividend;

  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 carry ) 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 (!carry) next_state = S_3;
			else begin next_state = S_2; Subtract = 1; end
                    S_2:		if (!carry) next_state = S_3;
else begin next_state = S_2; Subtract = 1; end
      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 <= difference;
      quotient <= quotient + 1; end
   end
endmodule


module test_Divider_STG_0_sub ();
  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;		 
  wire code_error;
  wire carry = M1.carry;
  integer k, m;

  Divider_STG_0_sub M1 (quotient, remainder, Ready, Error, word1, word2, Start, clock, reset);

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

// Exhaustive Test
always @ (negedge Ready)  begin  
	 #2 if (word2 != 0) begin expected_value = 0; expected_remainder = 0;  end
	if (word2 != 0) begin expected_value = word1 / word2; expected_remainder = word1 % word2; end
 end

assign code_error = (!reset && Ready && !Start) ? | {(expected_value ^ quotient), |(expected_remainder ^ remainder)}: 0;

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 + -