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

📄 220model.v

📁 《数字信号处理的FPGA实现》代码
💻 V
📖 第 1 页 / 共 5 页
字号:
  reg  tmp_cout ;
  reg  tmp_overflow ;
  reg  [lpm_width-2:0] tmp_a, tmp_b;
  integer i, j, k, n;
  integer dataa_int, datab_int, result_int, compare, borrow; 


  always @(  cin or dataa or datab or add_sub )
	begin

	begin
		borrow = cin?0:1 ;
		// cout is the same for both signed and unsign representation.  
		if (lpm_direction == "ADD" || add_sub == 1) 
				begin
						{tmp_cout,tmp_result} = dataa + datab + cin ;
						tmp_overflow = tmp_cout ;
				end
				else
		if (lpm_direction == "SUB" || add_sub == 0) 
				begin
						// subtraction
						{tmp_overflow, tmp_result} = dataa - datab - borrow ;
						tmp_cout = (dataa >= (datab+borrow))?1:0 ;
				end
	
		if(lpm_representation == "SIGNED")
		begin
			// convert to negative integer
			if(dataa[lpm_width-1] == 1)
			begin
				for(j = 0; j < lpm_width - 1; j = j + 1)
					tmp_a[j] = dataa[j] ^ 1;
				dataa_int = (tmp_a + 1) * (-1) ;
			end
			else dataa_int = dataa;

			// convert to negative integer
			if(datab[lpm_width-1] == 1)
			begin
				for(k = 0; k < lpm_width - 1; k = k + 1)
					tmp_b[k] = datab[k] ^ 1;
				datab_int = (tmp_b + 1) * (-1);
			end
			else datab_int = datab;

			// perform the addtion or subtraction operation
			if(lpm_direction == "ADD" || add_sub == 1)
				result_int = dataa_int + datab_int + cin ;
			else
			if(lpm_direction == "SUB" || add_sub == 0)
				result_int = dataa_int - datab_int - borrow ;
			tmp_result = result_int ;

			// set the overflow
			compare = 1 << (lpm_width -1);
			if((result_int > (compare - 1)) || (result_int < (-1)*(compare)))
				tmp_overflow = 1;
			else
				tmp_overflow = 0;
		end

	end
	end

  always @(posedge clock or posedge aclr )
	begin
		if(aclr)
		begin
		for(i = 0; i <= lpm_pipeline; i = i + 1)
		begin
			tmp_result2[i] = 'b0 ;
			tmp_cout2[i] = 1'b0 ;
			tmp_overflow2[i] = 1'b0 ;
		end
		end
	else if (clken == 1) begin
		tmp_result2[lpm_pipeline] = tmp_result ;
		tmp_cout2[lpm_pipeline] = tmp_cout ;
		tmp_overflow2[lpm_pipeline] = tmp_overflow ;
		for(n = 0; n < lpm_pipeline; n = n +1)
		begin
			tmp_result2[n] = tmp_result2[n+1] ;
			tmp_cout2[n] = tmp_cout2[n+1];
			tmp_overflow2[n] = tmp_overflow2[n+1];
		end
		end
	end


  assign result = (lpm_pipeline >0) ? tmp_result2[0]:tmp_result ;
  assign cout = (lpm_pipeline >0) ? tmp_cout2[0]  : tmp_cout;
  assign overflow = (lpm_pipeline >0) ? tmp_overflow2[0] : tmp_overflow ;

endmodule // lpm_add_sub

//------------------------------------------------------------------------

module lpm_compare (  alb, aeb, agb, aleb, aneb, ageb, dataa, datab, clock, clken, aclr ) ;

  parameter lpm_type = "lpm_compare" ;
  parameter lpm_width = 1 ;
  parameter lpm_representation = "UNSIGNED" ;
  parameter lpm_pipeline = 0 ;
  parameter lpm_hint = "UNUSED" ;

  input  [lpm_width-1:0] dataa, datab ;
  input  clock ;
  input  clken;
  input  aclr ;
  output alb, aeb, agb, aleb, aneb, ageb ;

  reg    tmp_alb, tmp_aeb, tmp_agb ;
  reg    tmp_aleb, tmp_aneb, tmp_ageb ;
  reg    [lpm_pipeline:0] tmp_alb2, tmp_aeb2, tmp_agb2 ;
  reg    [lpm_pipeline:0] tmp_aleb2, tmp_aneb2, tmp_ageb2 ;
  reg    [lpm_width-1:0] a_int;
  integer i, j, k, l, m, n, o, p, u, dataa_int, datab_int;

  always @( dataa or datab)
	begin
		if (lpm_representation == "UNSIGNED") 
				begin
			dataa_int = dataa[lpm_width-1:0];
			datab_int = datab[lpm_width-1:0];
				end
		else
		if (lpm_representation == "SIGNED")
			begin
			if ( dataa[lpm_width-1] == 1)
				begin
				a_int = 0;
				for(i = 0; i < lpm_width - 1; i = i + 1)
							a_int[i] = dataa[i] ^ 1;
				dataa_int = (a_int + 1) * (-1) ;
			end
			else dataa_int = dataa[lpm_width-1:0];

			if ( datab[lpm_width-1] == 1)
				begin
				a_int = 0;
				for(j = 0; j < lpm_width - 1; j = j + 1)
							a_int[j] = datab[j] ^ 1;
				datab_int = (a_int + 1) * (-1) ;
			end
			else datab_int = datab[lpm_width-1:0];
			end

		tmp_alb = (dataa_int < datab_int);
		tmp_aeb = (dataa_int == datab_int);
		tmp_agb = (dataa_int > datab_int);
		tmp_aleb = (dataa_int <= datab_int);
		tmp_aneb = (dataa_int != datab_int);
		tmp_ageb = (dataa_int >= datab_int);
	end

  always @( posedge clock or posedge aclr)
	begin
		if (aclr)
			begin 
			for(u = 0; u <= lpm_pipeline; u = u +1)
		begin
					tmp_aeb2[u] = 'b0 ;
					tmp_agb2[u] = 'b0 ;
					tmp_alb2[u] = 'b0 ;
					tmp_aleb2[u] = 'b0 ;
					tmp_aneb2[u] = 'b0 ;
					tmp_ageb2[u] = 'b0 ;
		end
			end
	else if (clken == 1)
		begin
				// Assign results to registers
				tmp_alb2[lpm_pipeline] = tmp_alb ;
				tmp_aeb2[lpm_pipeline] = tmp_aeb ;
				tmp_agb2[lpm_pipeline] = tmp_agb ;
				tmp_aleb2[lpm_pipeline] = tmp_aleb ;
				tmp_aneb2[lpm_pipeline] = tmp_aneb ;
				tmp_ageb2[lpm_pipeline] = tmp_ageb ;

			for(k = 0; k < lpm_pipeline; k = k +1)
					tmp_alb2[k] = tmp_alb2[k+1] ;
			for(l = 0; l < lpm_pipeline; l = l +1)
					tmp_aeb2[l] = tmp_aeb2[l+1] ;
			for(m = 0; m < lpm_pipeline; m = m +1)
					tmp_agb2[m] = tmp_agb2[m+1] ;
			for(n = 0; n < lpm_pipeline; n = n +1)
					tmp_aleb2[n] = tmp_aleb2[n+1] ;
			for(o = 0; o < lpm_pipeline; o = o +1)
					tmp_aneb2[o] = tmp_aneb2[o+1] ;
			for(p = 0; p < lpm_pipeline; p = p +1)
					tmp_ageb2[p] = tmp_ageb2[p+1] ;
	end
	end

  assign alb = (lpm_pipeline > 0) ? tmp_alb2[0] : tmp_alb;
  assign aeb = (lpm_pipeline > 0) ? tmp_aeb2[0] : tmp_aeb;
  assign agb = (lpm_pipeline > 0) ? tmp_agb2[0] : tmp_agb;
  assign aleb = (lpm_pipeline > 0) ? tmp_aleb2[0] : tmp_aleb;
  assign aneb = (lpm_pipeline > 0) ? tmp_aneb2[0] : tmp_aneb;
  assign ageb = (lpm_pipeline > 0) ? tmp_ageb2[0] : tmp_ageb;

endmodule // lpm_compare

//------------------------------------------------------------------------

module lpm_mult ( result, dataa, datab, sum, clock, clken, aclr ) ;

  parameter lpm_type       = "lpm_mult" ;
  parameter lpm_widtha     = 1 ;
  parameter lpm_widthb     = 1 ;
  parameter lpm_widths     = 1 ;
  parameter lpm_widthp     = 2 ;
  parameter lpm_representation  = "UNSIGNED" ;
  parameter lpm_pipeline   = 0 ;
  parameter lpm_hint = "UNUSED" ;

  input  clock ;
  input  clken ;
  input  aclr ;
  input  [lpm_widtha-1:0] dataa ;
  input  [lpm_widthb-1:0] datab ;
  input  [lpm_widths-1:0] sum ;
  output [lpm_widthp-1:0] result;

  // inernal reg
  reg   [lpm_widthp-1:0] tmp_result ;
  reg   [lpm_widthp-1:0] tmp_result2 [lpm_pipeline:0];
  reg   [lpm_widtha-2:0] a_int ;
  reg   [lpm_widthb-2:0] b_int ;
  reg   [lpm_widths-2:0] s_int ;
  reg   [lpm_widthp-2:0] p_reg ;
  integer p_int;
  integer i, j, k, m, n, p, maxs_mn ;
  integer int_dataa, int_datab, int_sum, int_result ;


  always @( dataa or datab or sum)
	begin
		if (lpm_representation == "UNSIGNED")
			begin
				int_dataa = dataa ;
				int_datab = datab ;
				int_sum = sum ;
			end
		else 
			if (lpm_representation == "SIGNED")
				begin
					// convert signed dataa
					if(dataa[lpm_widtha-1] == 1)
						begin
							int_dataa = 0 ;
							for(i = 0; i < lpm_widtha - 1; i = i + 1)
								a_int[i] = dataa[i] ^ 1;
							int_dataa = (a_int + 1) * (-1) ;
						end
					else int_dataa = dataa ;

					// convert signed datab
					if(datab[lpm_widthb-1] == 1)
						begin
							int_datab = 0 ;
							for(j = 0; j < lpm_widthb - 1; j = j + 1)
								b_int[j] = datab[j] ^ 1;
							int_datab = (b_int + 1) * (-1) ;
						end
					else int_datab = datab ;

					// convert signed sum
					if(sum[lpm_widths-1] == 1)
						begin
							int_sum = 0 ;
							for(k = 0; k < lpm_widths - 1; k = k + 1)
								s_int[k] = sum[k] ^ 1;
							int_sum = (s_int + 1) * (-1) ;
						end
					else int_sum = sum ;
				end
			else 
				begin
					int_dataa = {lpm_widtha{1'bx}} ;
					int_datab = {lpm_widthb{1'bx}} ;
					int_sum   = {lpm_widths{1'bx}} ;
				end

		p_int = int_dataa * int_datab + int_sum ;
		maxs_mn = ((lpm_widtha+lpm_widthb)>lpm_widths)?lpm_widtha+lpm_widthb:lpm_widths ;
		if(lpm_widthp >= maxs_mn)
			tmp_result = p_int ;
		else
			begin
				p_reg = p_int;
				for(m = 0; m < lpm_widthp; m = m +1)
					tmp_result[lpm_widthp-1-m] = p_reg[maxs_mn-1-m] ;
			end 
	end

	always @(posedge clock or posedge aclr)
	begin
	  if(aclr)
		begin
			for(p = 0; p <= lpm_pipeline; p = p + 1)
				tmp_result2[p] = 'b0;
		end
	  else if (clken == 1)
	  begin :syn_block
		tmp_result2[lpm_pipeline] = tmp_result ;
		for(n = 0; n < lpm_pipeline; n = n +1)
			tmp_result2[n] = tmp_result2[n+1] ;
	  end
	end

  assign result = (lpm_pipeline > 0) ? tmp_result2[0] : tmp_result ;

endmodule // lpm_mult

//------------------------------------------------------------------------

module lpm_divide ( quotient,remain, numer, denom, clock, clken, aclr ) ;

  parameter lpm_type       = "lpm_divide" ;
  parameter lpm_widthn     = 1 ;
  parameter lpm_widthd     = 1 ;
  //parameter lpm_widthq     = 1 ;
  //parameter lpm_widthr     = 1 ;
  parameter lpm_nrepresentation    = "UNSIGNED" ;
  parameter lpm_drepresentation    = "UNSIGNED" ;
  parameter lpm_pipeline   = 0 ;

  input  clock ;
  input  clken ;
  input  aclr ;
  input  [lpm_widthn-1:0] numer ;
  input  [lpm_widthd-1:0] denom ;
  output [lpm_widthn-1:0] quotient;
  output [lpm_widthd-1:0] remain;

  // inernal reg
  reg   [lpm_widthn-1:0] tmp_quotient [lpm_pipeline:0];
  reg   [lpm_widthd-1:0] tmp_remain [lpm_pipeline:0];
  reg   [lpm_widthn-1:0] ONES, ZEROS, UNKNOWN, HiZ ;
  reg   [lpm_widthd-1:0] DZEROS, DUNKNOWN ;
  reg   [lpm_widthn-1:0] NUNKNOWN ;
  reg   [lpm_widthd-1:0] RZEROS  ;
  integer i;
  integer int_numer, int_denom, int_quotient, int_remain ;

  initial
  begin


	// check if lpm_widthn > 0
	if(lpm_widthn <= 0)
		$display("%t: Error! LPM_WIDTHN must be greater than 0.\n", $time);
	// check if lpm_widthd > 0
	if(lpm_widthd <= 0)
		$display("%t: Error! LPM_WIDTHD must be greater than 0.\n", $time);
	// check if lpm_widthn > 0
	  //if(lpm_widthq <= 0)
	  //    $display("%t: Error! LPM_WIDTHQ must be greater than 0.\n", $time);
	// check if lpm_widthR > 0
	  //if(lpm_widthr <= 0)
	  //    $display("%t: Error! LPM_WIDTHR must be greater than 0.\n", $time);
	// check for valid lpm_nrep value
	if((lpm_nrepresentation !== "SIGNED") && (lpm_nrepresentation !== "UNSIGNED"))
		$display("%t: Error! LPM_NREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".", $time);

	// check for valid lpm_drep value
	if((lpm_drepresentation !== "SIGNED") && (lpm_drepresentation !== "UNSIGNED"))
		$display("%t: Error! LPM_DREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".", $time);

		// check if lpm_pipeline is > 1 and clock is not used
		if((lpm_pipeline >=1 ) && (clock === 1'bz) )
				$display("%t: Error! The clock pin is requied if lpm_pipeline is used\n", $time) ;
	else if((lpm_pipeline == 0 ) && (clock !== 1'bz) )
		$display("%t: Error! If the clock pin is used, lpm_pipeline must be greater than 0.\n", $time) ;
	
	for(i=0; i < lpm_widthn; i=i+1)
	  begin
			ONES[i] = 1'b1 ;
			ZEROS[i] = 1'b0 ;
			UNKNOWN[i] = 1'bx ;
			HiZ[i] = 1'bz ;
	  end

	for(i=0; i < lpm_widthd; i=i+1)
			DUNKNOWN[i] = 1'bx ;

	for(i=0; i < lpm_widthn; i=i+1)
			NUNKNOWN[i] = 1'bx ;

		for(i=0; i < lpm_widthd; i=i+1)
			RZEROS[i] = 1'b0 ;

  end

  always @(numer or denom)
		begin
			if (lpm_nrepresentation == "UNSIGNED")
					int_numer = numer ;
			else if (lpm_nrepresentation == "SIGNED")
				begin
				// convert signed numer
				if(numer[lpm_widthn-1] == 1)
				begin
					int_numer = 0 ;
					for(i = 0; i < lpm_widthn - 1; i = i + 1)
						int_numer[i] = numer[i] ^ 1;
					int_numer = -(int_numer + 1) ;
				end
				else int_numer = numer ;
			end
				else 
			int_numer = NUNKNOWN ;

		if (lpm_drepresentation == "UNSIGNED")
										int_denom = denom ;
		else if (lpm_drepresentation == "SIGNED")
						begin
				// convert signed denom
				if(denom[lpm_widthd-1] == 1)
				begin
					int_denom = 0 ;
					for(i = 0; i < lpm_widthd - 1; i = i + 1)
						int_denom[i] = denom[i] ^ 1;
					int_denom = -(int_denom + 1) ;
				end
				else int_denom = denom ;
			end
			else 
			int_denom = DUNKNOWN ;

		int_quotient = int_numer / int_denom ;
		int_remain = int_numer % int_denom ;

		tmp_quotient[lpm_pipeline] = int_quotient ;
		tmp_remain[lpm_pipeline] = int_remain ;
	end

	always @(posedge clock or aclr)
	begin :syn_block
			if(aclr)
		begin
			disable syn_block ;
			for(i = 0; i <= lpm_pipeline; i = i + 1)
				tmp_quotient[i] = ZEROS;
				tmp_remain[i] = RZEROS;
		end
		else
				   if (clken)
		   for(i = 0; i < lpm_pipeline; i = i +1)
		   begin
			tmp_quotient[i] = tmp_quotient[i+1] ;
			tmp_remain[i] = tmp_remain[i+1] ;
		   end
	end

  assign quotient = tmp_quotient[0] ;
  assign remain = tmp_remain[0] ;

endmodule // lpm_divide

//------------------------------------------------------------------------

module lpm_abs ( result, overflow, data ) ;

	parameter lpm_type = "lpm_abs" ;
	parameter lpm_width = 1 ;
	parameter lpm_hint = "UNUSED" ;

	input  [lpm_width-1:0] data ;
	output [lpm_width-1:0] result ;
	output overflow ;

	reg    [lpm_width-1:0] a_int ;
	reg    [lpm_width-1:0] result ;
	reg    overflow;
	integer i;

	always @(data)
		begin

			overflow = 0;
			if (data[lpm_width-1] == 1)
				begin
					a_int = 0;
					for(i = 0; i < lpm_width - 1; i = i + 1)
						a_int[i] = data[i] ^ 1;
					result = (a_int + 1);
					overflow = (result == ( 1<<(lpm_width -1)));
				end
			else
				result = data;
		end

endmodule // lpm_abs

//------------------------------------------------------------------------

module lpm_counter ( q, //eq, 
		data, clock, cin, cout,
		clk_en, cnt_en, updown,
		aset, aclr, aload, 
		sset, sclr, sload) ;

  parameter lpm_type = "lpm_counter";
  parameter lpm_width = 1 ;
  parameter lpm_modulus = 0 ;
  parameter lpm_direction = "UNUSED" ;
  parameter lpm_avalue = "UNUSED" ;
  parameter lpm_svalue = "UNUSED" ;
  parameter lpm_pvalue = "UNUSED" ;
  parameter lpm_hint = "UNUSED" ;

  output [lpm_width-1:0] q ;
  //output [lpm_modulus-1:0] eq ;
  output cout ;
  input  cin ;
  input  [lpm_width-1:0] data ;
  input  clock, clk_en, cnt_en, updown ;
  input  aset, aclr, aload ;
  input  sset, sclr, sload ;

  reg  [lpm_width-1:0] tmp_count ;

⌨️ 快捷键说明

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