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

📄 mult_shift_tb.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.
/////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////
// Testbench
///////////////////////////////////////////
// Needs the altmult_add model in quartus/eda/sim_lib/altera_mf.v 
// as well as the stratix II atom models.

module mult_shift_tb ();

reg fail;
reg clk,ena_in,ena_out,rst,a_signed,b_signed;
reg shift_not_mult,direction_right,shift_not_rot;
reg [31:0] data_a,data_b;
wire [63:0] data_o_w, data_o_x, data_o_y, data_o_z;

mult_shift_32_32 w (
	.clk(clk),.ena_in(ena_in),.ena_out(ena_out),.rst(rst),
	.a_signed(a_signed),.b_signed(b_signed),
	.data_a(data_a),.data_b(data_b),
	.data_o(data_o_w),
	.shift_not_mult(shift_not_mult),
	.direction_right(direction_right),
	.shift_not_rot(shift_not_rot)
);	

mult_32_32 x (.clk(clk),.ena_in(ena_in),.ena_out(ena_out),.rst(rst),
	.a_signed(a_signed),.b_signed(b_signed),
	.data_a(data_a),.data_b(data_b),
	.data_o(data_o_x));

cpu_mult_cell y (.A_en(ena_out),
	.E_ctrl_mul_cell_src1_signed(a_signed),
	.E_ctrl_mul_cell_src2_signed(b_signed),
	.E_src1_mul_cell(data_a),
	.E_src2_mul_cell(data_b),
	.M_en(ena_in),
	.clk(clk),
	.reset_n(!rst),
	.A_mul_cell_result(data_o_y)
);


///////////////////////////////////////////
// functional model
///////////////////////////////////////////
reg mult_showing_r, mult_showing_rr;
wire signed [32:0] tmp_a;
wire signed [32:0] tmp_b;
wire signed [71:0] tmp_mult;
assign tmp_a = {a_signed & data_a[31],data_a};
assign tmp_b = {b_signed & data_b[31],data_b};
assign tmp_mult = tmp_a * tmp_b;

wire [31:0] tmp_shr = data_a >> data_b[4:0];
wire [31:0] tmp_shl = data_a << data_b[4:0];
wire [63:0] double_a = {data_a,data_a};
wire [63:0] signext_a = {{32{a_signed & data_a[31]}} ,data_a};
wire [31:0] tmp_ror = (double_a >> data_b[4:0]);
wire [31:0] tmp_rol = (double_a << data_b[4:0]) >> 32;
wire [31:0] tmp_asr = (signext_a >> data_b[4:0]);

wire [63:0] tmp_result = !shift_not_mult ? tmp_mult[63:0] :
			{32'b0,
			(shift_not_rot ? (direction_right ? 
								(a_signed ? tmp_asr : tmp_shr) : tmp_shl) :
							 (direction_right ? tmp_ror : tmp_rol)
			)};
	
reg [63:0] wait_x,wait_y;

always @(posedge clk or posedge rst) begin
	if (rst) begin
		wait_x <= 0;
		wait_y <= 0;
		mult_showing_r <= 1'b0;
		mult_showing_rr <= 1'b0;

	end
	else begin
		if (ena_in) begin
			wait_x <= tmp_result[63:0];
			mult_showing_r <= !shift_not_mult;
		end
		if (ena_out) begin
			wait_y <= wait_x;
			mult_showing_rr <= mult_showing_r;
		end
	end
end
assign data_o_z = wait_y;


///////////////////////////////////////////
// test stim and verify
///////////////////////////////////////////

initial begin
  clk = 1;
  rst = 0;
  ena_in = 1;
  ena_out = 1;
  fail = 0;
  a_signed = 0;
  b_signed = 0;
  #10 rst = 1;
  #10 rst = 0;
  #5000000 if (!fail) $display ("PASS");
  $stop();
end

always @(negedge clk) begin
	ena_in = $random;
	ena_out = $random;
	shift_not_mult = $random;
	direction_right = $random;
	shift_not_rot = $random;
	a_signed = $random;
	b_signed = $random;
	data_a = $random;
	data_b = $random;
end

always begin 
  #500 clk = ~clk;	
end

always @(negedge clk) begin

	// compare pure multiplier against altmult version
	#10 if (data_o_x !== data_o_y) begin
		$display ("Simple MULT Mismatch at time %d",$time);
		fail = 1;
	end

	// compare multshift unit against functional model
	if (data_o_w !== data_o_z) begin
		$display ("Shift MULT unit Mismatch at time %d",$time);
		fail = 1;
	end

	// when in multiply mode compare between mult and multshift
	// units
	if (mult_showing_rr) begin
		if (data_o_x !== data_o_z) begin
			$display ("Mult showing - cross unit mismatch at time %d",$time);
			fail = 1;
		end
	end
end

endmodule

///////////////////////////////////////////////////////
// altmult based multiplier used by NIOS, for
// testing purposes.
//
// The altmult_add model is in the quartus/eda/sim_lib/altera_mf.v 
// library.
///////////////////////////////////////////////////////

module cpu_mult_cell (
                       // inputs:
                        A_en,
                        E_ctrl_mul_cell_src1_signed,
                        E_ctrl_mul_cell_src2_signed,
                        E_src1_mul_cell,
                        E_src2_mul_cell,
                        M_en,
                        clk,
                        reset_n,

                       // outputs:
                        A_mul_cell_result
                     )
;

  output  [ 63: 0] A_mul_cell_result;
  input            A_en;
  input            E_ctrl_mul_cell_src1_signed;
  input            E_ctrl_mul_cell_src2_signed;
  input   [ 31: 0] E_src1_mul_cell;
  input   [ 31: 0] E_src2_mul_cell;
  input            M_en;
  input            clk;
  input            reset_n;

  wire    [ 63: 0] A_mul_cell_result;
  wire             mul_clr;
  assign mul_clr = ~reset_n;
  altmult_add the_altmult_add
    (
      .aclr0 (mul_clr),
      .aclr1 (mul_clr),
      .clock0 (clk),
      .clock1 (clk),
      .dataa (E_src1_mul_cell),
      .datab (E_src2_mul_cell),
      .ena0 (M_en),
      .ena1 (A_en),
      .result (A_mul_cell_result),
      .signa (E_ctrl_mul_cell_src1_signed),
      .signb (E_ctrl_mul_cell_src2_signed)
    );

  defparam the_altmult_add.addnsub_multiplier_aclr1 = "UNUSED",
           the_altmult_add.addnsub_multiplier_pipeline_aclr1 = "UNUSED",
           the_altmult_add.addnsub_multiplier_register1 = "CLOCK0",
           the_altmult_add.dedicated_multiplier_circuitry = "YES",
           the_altmult_add.input_aclr_a0 = "ACLR0",
           the_altmult_add.input_aclr_b0 = "ACLR0",
           the_altmult_add.input_register_a0 = "CLOCK0",
           the_altmult_add.input_register_b0 = "CLOCK0",
           the_altmult_add.input_source_a0 = "DATAA",
           the_altmult_add.input_source_b0 = "DATAB",
           the_altmult_add.lpm_type = "altmult_add",
           the_altmult_add.multiplier1_direction = "ADD",
           the_altmult_add.multiplier_register0 = "UNREGISTERED",
           the_altmult_add.number_of_multipliers = 1,
           the_altmult_add.output_aclr = "ACLR1",
           the_altmult_add.output_register = "CLOCK1",
           the_altmult_add.signed_aclr_a = "ACLR0",
           the_altmult_add.signed_aclr_b = "ACLR0",
           the_altmult_add.signed_pipeline_register_a = "UNREGISTERED",
           the_altmult_add.signed_pipeline_register_b = "UNREGISTERED",
           the_altmult_add.signed_register_a = "CLOCK0",
           the_altmult_add.signed_register_b = "CLOCK0",
           the_altmult_add.width_a = 32,
           the_altmult_add.width_b = 32,
           the_altmult_add.width_result = 64;


endmodule

⌨️ 快捷键说明

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