mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-28 07:02:55 +08:00
255 lines
7.8 KiB
Verilog
255 lines
7.8 KiB
Verilog
// 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
|
|
|