Open square verilog code

Keywords: Verilog

Catalog

1. Description of successive approximation algorithm

2.Verilog implementation

3. Written by testbench

1. Description of successive approximation algorithm

The flow of successive approximation algorithm is shown in Figure 1. First, input data[7:0], then set the experimental value d [3:0] and the determined value d [3:0], and then set each position 1 (e.g. d [3] to 1) in order from high to low, and then compare the experimental value with the input data. If the square of the experimental value is greater than the input value (d [Z ^ 2 > data), then this bit is 0 (d [Q [3] is 0). , otherwise ((D ﹐ Z ^ 2 ≤ data)), this bit is 1 (D ﹐ Q [3] is 1); this bit is iterated to the last bit.

It can be seen that n/2 iterations are required for n-bit data, and n/2 cycles are required for each calculation period.

 

The Figure1 block diagram of successive approximation algorithm

2.Verilog implementation

  1. //////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // successive approximation algorithm
  4. //
  5. module sqrt_1
  6. #(
  7. parameter d_width = 8,
  8. parameter q_width = d_width/2 - 1,
  9. parameter r_width = q_width + 1 )
  10. (
  11. input wire clk,
  12. input wire rst,
  13. input wire i_vaild,
  14. input wire [d_width:0] data_i, //input
  15. output reg o_vaild,
  16. output reg [q_width:0] data_o, //output
  17. output reg [r_width:0] data_r //Remainder
  18. );
  19. //--------------------------------------------------------------------------------
  20. reg [d_width:0] D [r_width:1]; //Number of squares
  21. reg [q_width:0] Q_z [r_width:1]; //temporary
  22. reg [q_width:0] Q_q [r_width:1]; //confirm
  23. reg ivalid_t [r_width:1];
  24. //--------------------------------------------------------------------------------
  25. always@(posedge clk or posedge rst)
  26. begin
  27. if(rst)
  28. begin
  29. D[r_width] <= 0;
  30. Q_z[r_width] <= 0;
  31. Q_q[r_width] <= 0;
  32. ivalid_t[r_width] <= 0;
  33. end
  34. else if(i_vaild)
  35. begin
  36. D[r_width] <= data_i; //Data of the party under Exploitation
  37. Q_z[r_width] <= {1'b1,{q_width{1'b0}}}; //Experiment value setting
  38. Q_q[r_width] <= 0; //Actual calculation results
  39. ivalid_t[r_width] <= 1;
  40. end
  41. else
  42. begin
  43. D[r_width] <= 0;
  44. Q_z[r_width] <= 0;
  45. Q_q[r_width] <= 0;
  46. ivalid_t[r_width] <= 0;
  47. end
  48. end
  49. //-------------------------------------------------------------------------------
  50. // Iterative calculation process
  51. //-------------------------------------------------------------------------------
  52. generate
  53. genvar i;
  54. for(i=r_width-1;i>=1;i=i-1)
  55. begin:U
  56. always@(posedge clk or posedge rst)
  57. begin
  58. if(rst)
  59. begin
  60. D[i] <= 0;
  61. Q_z[i] <= 0;
  62. Q_q[i] <= 0;
  63. ivalid_t[i] <= 0;
  64. end
  65. else if(ivalid_t[i+1])
  66. begin
  67. if(Q_z[i+1]*Q_z[i+1] > D[i+1])
  68. begin
  69. Q_z[i] <= {Q_q[i+1][q_width:i],1'b1,{{i-1}{1'b0}}};
  70. Q_q[i] <= Q_q[i+1];
  71. end
  72. else
  73. begin
  74. Q_z[i] <= {Q_z[i+1][q_width:i],1'b1,{{i-1}{1'b0}}};
  75. Q_q[i] <= Q_z[i+1];
  76. end
  77. D[i] <= D[i+1];
  78. ivalid_t[i] <= 1;
  79. end
  80. else
  81. begin
  82. ivalid_t[i] <= 0;
  83. D[i] <= 0;
  84. Q_q[i] <= 0;
  85. Q_z[i] <= 0;
  86. end
  87. end
  88. end
  89. endgenerate
  90. //--------------------------------------------------------------------------------
  91. // Calculate remainder and final square root
  92. //--------------------------------------------------------------------------------
  93. always@(posedge clk or posedge rst)
  94. begin
  95. if(rst)
  96. begin
  97. data_o <= 0;
  98. data_r <= 0;
  99. o_vaild <= 0;
  100. end
  101. else if(ivalid_t[1])
  102. begin
  103. if(Q_z[1]*Q_z[1] > D[1])
  104. begin
  105. data_o <= Q_q[1];
  106. data_r <= D[1] - Q_q[1]*Q_q[1];
  107. o_vaild <= 1;
  108. end
  109. else
  110. begin
  111. data_o <= {Q_q[1][q_width:1],Q_z[1][0]};
  112. data_r <= D[1] - {Q_q[1][q_width:1],Q_z[1][0]}*{Q_q[1][q_width:1],Q_z[1][0]};
  113. o_vaild <= 1;
  114. end
  115. end
  116. else
  117. begin
  118. data_o <= 0;
  119. data_r <= 0;
  120. o_vaild <= 0;
  121. end
  122. end
  123. //--------------------------------------------------------------------------------

 3.Testbench To write

 
//--------------------------------------------------------------------------------
	`define  		 						d_w 		 8
	`define        						q_w		 `d_w / 2
	`define        						r_w 		 `q_w + 1
//--------------------------------------------------------------------------------
module tb_sqrt;
//--------------------------------------------------------------------------------
	// Inputs
	reg 										clk;
	reg 										rst;
	reg					 					i_vaild;
	reg 			[`d_w-1:0] 				data_i;

	// Outputs
	wire 										o_vaild;
	wire 			[`q_w-1:0]				data_o;
	wire 			[`r_w-1:0]				data_r;

//--------------------------------------------------------------------------------
	// Instantiate the Unit Under Test (UUT)
	sqrt_1 
	#(
		.d_width		( 	`d_w-1		),
		.q_width 	(	`q_w-1		),
		.r_width 	(  `r_w-1		)	
	)
		uut 
	(
		.clk			(	clk			), 
		.rst			(	rst			), 
		.i_vaild		(	i_vaild		), 
		.data_i		(	data_i		), 
		.o_vaild		(	o_vaild		), 
		.data_o		(	data_o		), 
		.data_r		(	data_r		)
	);
//--------------------------------------------------------------------------------
	initial begin
		// Initialize Inputs
		clk = 0;
		rst = 1;
		// Wait 100 ns for global reset to finish
		#100;
      rst = 0; 
		// Add stimulus here

	end
    
	always #5 clk  = ~ clk ;
	
	reg	[`d_w:0]		cnt ;
	
	reg	[31:0]		a ;
//--------------------------------------------------------------------------------
	always@(posedge	clk or posedge	rst)
		begin
			if(rst)
				begin
					i_vaild <= 0;
					data_i <= 0;
					cnt <= 0;
				end
			else	if(cnt < 10)
				begin
					i_vaild <= 1;
					data_i <= {$random} % 255;
					cnt <= cnt + 1;
				end
			else
				begin
					i_vaild <= 0;
					data_i <= 0;
					cnt <= cnt;
				end
		end
//--------------------------------------------------------------------------------
endmodule

 

 

The statement data I < = {$random}% 255; generates a random number from 0 to 255 for testing.

 

 

The simulation results are shown in Figure 2. The calculation period is four clock periods, with input data, root result, data and remainder data.

The Fig. 2 simulation results

Posted by doox00 on Fri, 25 Oct 2019 07:37:15 -0700