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

📄 lc_mult_signed.v

📁 本電子檔為 verilog cookbook,包含了通訊,影像,DSP等重要常用之verilog編碼,可作為工程師與初學者的參考手冊
💻 V
字号:
// Copyright 2007 Altera Corporation. All rights reserved.  
// Altera products are protected under numerous U.S. and foreign patents, 
// maskwork rights, copyrights and other intellectual property laws.  
//
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design 
// License Agreement (either as signed by you or found at www.altera.com).  By
// using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation.  In the event that you do
// not agree with such terms and conditions, you may not use the reference 
// design file and please promptly destroy any copies you have made.
//
// This reference design file is being provided on an "as-is" basis and as an 
// accommodation and therefore all warranties, representations or guarantees of 
// any kind (whether express, implied or statutory) including, without 
// limitation, warranties of merchantability, non-infringement, or fitness for
// a particular purpose, are specifically disclaimed.  By making this reference
// design file available, Altera expressly does not recommend, suggest or 
// require that this reference design file be used in combination with any 
// other product not provided by Altera.
/////////////////////////////////////////////////////////////////////////////

// baeckler -01-02-2007
module lc_mult_signed (clk,a,b,o);

parameter WIDTH_A = 16;
parameter WIDTH_B = 13;
parameter WIDTH_O = WIDTH_A + WIDTH_B;
parameter REGISTER_LAYERS = 1;
parameter REGISTER_MIDPOINTS = 1;

/////////////////////////////////////
// these are just for sanity - to 
// display the actual latency in 
// simulation.
/////////////////////////////////////
function integer layer_latency;
	input integer words;
	begin
		layer_latency = 2;
		while (words > 1) begin
			words = (words/2) + (words - (2*(words/2)));
			layer_latency = layer_latency + 1;
		end
	end
endfunction

function integer midpoint_latency;
	input integer words;
	begin
		midpoint_latency = 0;
		while (words > 1) begin
			words = (words/2) + (words - (2*(words/2)));
			midpoint_latency = midpoint_latency + 1;
		end
	end
endfunction

input clk;
input [WIDTH_A-1:0] a;
input [WIDTH_B-1:0] b;
output [WIDTH_O-1:0] o;

wire b_negative = b[WIDTH_B-1];
wire [WIDTH_O-1:0] o_wire;
reg [WIDTH_O-1:0] o;

genvar i;
wire [WIDTH_B * WIDTH_A - 1:0] partials;

// report the latency in simulation
generate
	if (REGISTER_LAYERS) begin
		initial begin 
			$display ("lc_mult_signed layer latency for WIDTH_B=%d is %d",
				WIDTH_B,layer_latency(WIDTH_B));
		end
	end
	if (REGISTER_MIDPOINTS) begin
		initial begin 
			$display ("lc_mult_signed midpoint latency for WIDTH_B=%d is %d",
				WIDTH_B,midpoint_latency(WIDTH_B));
		end
	end
endgenerate

/////////////////////////////////////
// Construct the partial products
/////////////////////////////////////

// for all but the last word do simple AND gates
generate 
	for (i=0; i<(WIDTH_B-1); i=i+1) 
	begin : ps
		assign partials[i*WIDTH_A+WIDTH_A-1:i*WIDTH_A] = a & {WIDTH_A{b[i]}};
	end	
endgenerate

// for the last word and with !A
// this is analagous to B and (B xor A)
assign partials[WIDTH_B*WIDTH_A-1:WIDTH_B*WIDTH_A-WIDTH_A] = ~a & {WIDTH_A{b[WIDTH_B-1]}};

reg [WIDTH_B * WIDTH_A - 1:0] partials_r;
reg b_negative_r;
generate
	if (REGISTER_LAYERS) begin
		always @(posedge clk) begin
			partials_r <= partials;
			b_negative_r <= b_negative;
		end
	end
	else begin
		always @(*) begin
			partials_r = partials;
			b_negative_r <= b_negative;
		end
	end
endgenerate

/////////////////////////////////////
// Sum the partial products
/////////////////////////////////////
wire [WIDTH_O-1:0] sum;
wire b_negative_final;
adder_tree at (.clk(clk),
		.in_words(partials_r),
		.extra_bit_in(b_negative_r),
		.extra_bit_out(b_negative_final),
		.out(sum));
	defparam at .NUM_IN_WORDS = WIDTH_B;
	defparam at .BITS_PER_IN_WORD = WIDTH_A;
	defparam at .OUT_BITS = WIDTH_O;
	defparam at .SIGN_EXT = 1;
	defparam at .REGISTER_OUTPUT = REGISTER_LAYERS;
	defparam at .REGISTER_MIDDLE = REGISTER_MIDPOINTS;
	defparam at .SHIFT_DIST = 1;
	defparam at .EXTRA_BIT_USED = 1;

/////////////////////////////////////
// final signed correction
/////////////////////////////////////
assign o_wire = sum + (b_negative_final << (WIDTH_B-1));

/////////////////////////////////////
// optional output registers
/////////////////////////////////////
generate
	if (REGISTER_LAYERS) begin
		always @(posedge clk) begin
			o <= o_wire;
		end
	end
	else begin
		always @(*) begin
			o = o_wire;
		end
	end
endgenerate

endmodule

⌨️ 快捷键说明

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