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

📄 fp_float_to_int.v

📁 nios里面用自定义指令集来实现三角函数
💻 V
字号:
//Legal Notice: (C)2006 Altera Corporation. All rights reserved.  Your
//use of Altera Corporation's design tools, logic functions and other
//software and tools, and its AMPP partner logic functions, and any
//output files any of the foregoing (including device programming or
//simulation files), and any associated documentation or information are
//expressly subject to the terms and conditions of the Altera Program
//License Subscription Agreement or other applicable license agreement,
//including, without limitation, that your use is for the sole purpose
//of programming logic devices manufactured by Altera and sold by Altera
//or its authorized distributors.  Please refer to the applicable
//agreement for further details.

// synthesis translate_off
`timescale 1ns / 1ps
// synthesis translate_on

// turn off superfluous verilog processor warnings 
// altera message_level Level1 
// altera message_off 10034 10035 10036 10037 10230 10240 10030 

module fp_float_to_int (
	reset,
	clk,
	clk_en,
	operandA,
	result
);


	// default to single precision and no pipelining, latency is 0, 1, 2 depending on the number of "true" set below
	parameter ENABLE_INPUT_PIPELINING = "false";
	parameter ENABLE_OUTPUT_PIPELINING = "false";
	parameter ENABLE_INTERNAL_PIPELINING = "false";  // recommend setting to true on Stratix II (smaller and faster)
	parameter MANTISSA_WIDTH = 23;  // 23 for single precision, 52 for double precision
	parameter EXPONENT_WIDTH = 8;  // 8 for single precision, 11 for double precision
	
	localparam DATA_WIDTH_FLOAT = MANTISSA_WIDTH + EXPONENT_WIDTH + 1;  // 32 for single precision, 64 for double precision
	localparam DATA_WIDTH_INT = 32; // fixed since it's an int as an output
	localparam BIAS_FACTOR = {(EXPONENT_WIDTH-1){1'b1}};
	localparam SHIFT_WIDTH = DATA_WIDTH_INT + MANTISSA_WIDTH;


	// inputs A and B will be either registered or non-registered operandA and operandB
	input [DATA_WIDTH_FLOAT-1:0] operandA;
	reg [DATA_WIDTH_FLOAT-1:0] operandA_d1;
	wire [DATA_WIDTH_FLOAT-1:0] A;


	input reset;
	input clk;
	input clk_en;
	
	
	/* float/double to int/unsigned int logic */
 	wire [SHIFT_WIDTH-1:0] stage_A; // prime the inputs into the shifting logic
 	wire [SHIFT_WIDTH-1:0] stage_B;  // holds the value after the first shift
 	wire [SHIFT_WIDTH-1:0] stage_C;  // holds the value after the final shift
	wire [SHIFT_WIDTH-1:0] temp_stage_C;
	reg [SHIFT_WIDTH-1:0] temp_stage_C_d1;
 	wire [SHIFT_WIDTH-1:0] stage_C_twos_compliment;  // holds the two's complement value of stage_C
 	wire [EXPONENT_WIDTH-1:0] biased_exp;  // holds the biased exponential
	reg [EXPONENT_WIDTH-1:0] temp_biased_exp;
	reg [EXPONENT_WIDTH-1:0] biased_exp_d1;
 	wire [EXPONENT_WIDTH-1:0] unbiased_exp;  // holds the exponential minus the bias factor
	reg [EXPONENT_WIDTH-1:0] temp_unbiased_exp;
	reg [EXPONENT_WIDTH-1:0] unbiased_exp_d1;
	
	/* logic to create conditions for special cases
       and the unsigned/signed modes */
 	wire sb;  // sign bit
	reg temp_sb;
	reg sb_d1;
 	wire NaN;  // decodes the input NaN condition
	reg temp_NaN;
	reg NaN_d1;
 	wire Inf;  // decodes the input +/- infinity condition
	reg temp_Inf;
	reg Inf_d1;
 	wire Denormal;  // decodes the input denormal condition (too small)
	reg temp_Denormal;
	reg Denormal_d1;



	// output result will be either registered or non-register temp_result
	output [DATA_WIDTH_INT-1:0] result;
	wire [DATA_WIDTH_INT-1:0] result;
	wire [DATA_WIDTH_INT-1:0] temp_result;
	reg [DATA_WIDTH_INT-1:0] temp_result_d1;



	always @ (posedge clk or posedge reset)
	begin
		if (reset)
		begin
			// this will be synthesized away if input pipelining is not enabled
			operandA_d1 <= 0;
			temp_sb <= 0;
			temp_NaN <= 0;
			temp_Inf <= 0;
			temp_Denormal <= 0;
			temp_biased_exp <= 0;
			temp_unbiased_exp <= 0;
			// this will be synthesized away if internal pipelining is not enabled
			sb_d1 <= 0;
			NaN_d1 <= 0;
			Inf_d1 <= 0;
			Denormal_d1 <= 0;
			biased_exp_d1 <= 0;
			unbiased_exp_d1 <= 0;
			temp_stage_C_d1 <= 0;
		end
		else 
		begin
			if (clk_en)
			begin
				// first register stage
				operandA_d1 <= operandA;
				temp_sb <= operandA[DATA_WIDTH_FLOAT-1];
				temp_NaN <= (operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH] == {EXPONENT_WIDTH{1'b1}}) & (operandA[MANTISSA_WIDTH-1:0] != 0);
				temp_Inf <= (operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH] == {EXPONENT_WIDTH{1'b1}}) & (operandA[MANTISSA_WIDTH-1:0] == 0);
				temp_Denormal <= operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH] == 0;
				temp_biased_exp <= operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH];
				temp_unbiased_exp <= biased_exp - BIAS_FACTOR;
				
				// internal register stage
				sb_d1 <= sb;
				NaN_d1 <= NaN;
				Inf_d1 <= Inf;
				Denormal_d1 <= Denormal;
				biased_exp_d1 <= biased_exp;
				unbiased_exp_d1 <= unbiased_exp;
				temp_stage_C_d1 <= temp_stage_C;
			end
		end
	end


	// this generate statement will optimize away input registers depending on ENABLE_INPUT_PIPELINING
	generate
	if(ENABLE_INPUT_PIPELINING == "true")
	begin
		assign A = operandA_d1;
		assign sb = temp_sb;
		assign NaN = temp_NaN;
		assign Inf = temp_Inf;
		assign Denormal = temp_Denormal;
		assign biased_exp = temp_biased_exp;
		assign unbiased_exp = temp_unbiased_exp;
	end
	else
	begin
		assign A = operandA;
		assign sb = operandA[DATA_WIDTH_FLOAT-1];
		assign NaN = (operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH] == {EXPONENT_WIDTH{1'b1}}) & (operandA[MANTISSA_WIDTH-1:0] != 0);
		assign Inf = (operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH] == {EXPONENT_WIDTH{1'b1}}) & (operandA[MANTISSA_WIDTH-1:0] == 0);
		assign Denormal = operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH] == 0;
		assign biased_exp = operandA[DATA_WIDTH_FLOAT-2:MANTISSA_WIDTH];
		assign unbiased_exp = biased_exp - BIAS_FACTOR;
	end
	endgenerate	


	/*************************************************************************************/
	/* This is where the actual float --> int conversion takes place */
    // 31 zeros, 1 one, mantissa (23 or 52 bits)
	assign stage_A = {{{(DATA_WIDTH_INT-1){1'b0}}, 1'b1}, A[MANTISSA_WIDTH-1:0]};

	// handle the shift distance portion that's a multiple of 8
	assign stage_B = 	(unbiased_exp[4:3] == 2'b00)? stage_A:
						(unbiased_exp[4:3] == 2'b01)? stage_A << 8 :
						(unbiased_exp[4:3] == 2'b10)? stage_A << 16 : stage_A << 24;
						
	// handle the remaining shift distance portion between 0 to 7
	assign temp_stage_C =	(unbiased_exp[2:0] == 3'b000)? stage_B:
						(unbiased_exp[2:0] == 3'b001)? stage_B << 1 :
						(unbiased_exp[2:0] == 3'b010)? stage_B << 2 :
						(unbiased_exp[2:0] == 3'b011)? stage_B << 3 :
						(unbiased_exp[2:0] == 3'b100)? stage_B << 4 :
						(unbiased_exp[2:0] == 3'b101)? stage_B << 5 :
						(unbiased_exp[2:0] == 3'b110)? stage_B << 6 : stage_B << 7;
				
	assign stage_C_twos_compliment = (sb == 0)?  stage_C[SHIFT_WIDTH-1:SHIFT_WIDTH-32] :
												((~stage_C[SHIFT_WIDTH-1:SHIFT_WIDTH-32]) + 1); // convert to 2s compliment 
	/*************************************************************************************/


	// will optimize away the internal registers depending on ENABLE_INTERNAL_PIPELINING		
	generate
	if(ENABLE_INTERNAL_PIPELINING == "true")
	begin
		assign stage_C = temp_stage_C_d1;
		assign temp_result = ((NaN_d1 == 1) | (Denormal_d1 == 1) | (biased_exp_d1 < BIAS_FACTOR))?  0 : // Zero and denormal are caught along with NaN and numbers with negative exponents (-1 < input < 1)
							 ((Inf_d1 == 1) & (sb_d1 == 0))? 32'h7FFFFFFF : // +infinity saturates to maximum value
							 ((Inf_d1 == 1) & (sb_d1 == 1))? 32'h80000000 : // -infinity saturates to minimum value
							 ((biased_exp_d1 > (BIAS_FACTOR + 30)) & (sb_d1 == 0))? 32'h7FFFFFFF : // too large positive input saturates to maximum value
							 ((biased_exp_d1 > (BIAS_FACTOR + 30)) & (sb_d1 == 1))? 32'h80000000 : // too large negative input saturates to maximum negative value
							 stage_C_twos_compliment;  // we already know the answer is in the range [-2^30, 2^30 -1] so a 2's compliment answer is good enough for float-->unsigned int/int
	end
	else
	begin
		assign stage_C = temp_stage_C;
		assign temp_result = ((NaN == 1) | (Denormal == 1) | (biased_exp < BIAS_FACTOR))?  0 : // Zero and denormal are caught along with NaN and numbers with negative exponents (-1 < input < 1)
							 ((Inf == 1) & (sb == 0))? 32'h7FFFFFFF : // +infinity saturates to maximum value
							 ((Inf == 1) & (sb == 1))? 32'h80000000 : // -infinity saturates to minimum value
							 ((biased_exp > (BIAS_FACTOR + 30)) & (sb == 0))? 32'h7FFFFFFF : // too large positive input saturates to maximum value
							 ((biased_exp > (BIAS_FACTOR + 30)) & (sb == 1))? 32'h80000000 : // too large negative input saturates to maximum negative value
							 stage_C_twos_compliment;  // we already know the answer is in the range [-2^30, 2^30 -1] so a 2's compliment answer is good enough for float-->unsigned int/int
	end
	endgenerate	


	always @ (posedge clk or posedge reset)
	begin
		if (reset)
		begin
			temp_result_d1 <= 0;
		end
		else 
		begin
			if (clk_en)
			begin
				temp_result_d1 <= temp_result;
			end
		end
	end
	
	// this will be synthesized away the output registers depending on ENABLE_OUTPUT_PIPELINING
	generate
	if(ENABLE_OUTPUT_PIPELINING == "true")
	begin
		assign result = temp_result_d1;
	end
	else
	begin
		assign result = temp_result;
	end
	endgenerate

	

endmodule

⌨️ 快捷键说明

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