【计算机组成原理】实验1
使用Verilog语言实现定点加法和定点乘法,测试平台:Vivado
1. 代码:
①定点加法:
adder.v:
`timescale 1ns / 1ps
module adder(
input [31:0] operand1,
input [31:0] operand2,
input cin,
output [31:0] result,
output cout
);
assign {cout,result} = operand1 + operand2 + cin;
endmodule
testbench.v:
`timescale 1ns / 1ps
module testbench;
// Inputs
reg [31:0] operand1;
reg [31:0] operand2;
reg cin;
// Outputs
wire [31:0] result;
wire cout;
// Instantiate the Unit Under Test (UUT)
adder uut (
.operand1(operand1),
.operand2(operand2),
.cin(cin),
.result(result),
.cout(cout)
);
initial begin
// Initialize Inputs
operand1 = 0;
operand2 = 0;
cin = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
end
always #10 operand1 = $random;
always #10 operand2 = $random;
always #10 cin = {$random} % 2;
endmodule
文章来源地址https://www.toymoban.com/news/detail-724062.html
②定点乘法:
multiply.v:
`timescale 1ns / 1ps
module multiply( // 乘法器
input clk, // 时钟
input mult_begin, // 乘法开始信号
input [31:0] mult_op1, // 乘法源操作数1
input [31:0] mult_op2, // 乘法源操作数2
output [63:0] product, // 乘积
output mult_end // 乘法结束信号
);
//乘法正在运算信号和结束信号
reg mult_valid;
assign mult_end = mult_valid & ~(|multiplier); //乘法结束信号:乘数全0
always @(posedge clk)
begin
if (!mult_begin || mult_end)
begin
mult_valid <= 1'b0;
end
else
begin
mult_valid <= 1'b1;
end
end
//以下:两个源操作取绝对值,正数的绝对值为其本身,负数的绝对值为取反加1
wire op1_sign; //操作数1的符号位
wire op2_sign; //操作数2的符号位
wire [31:0] op1_absolute; //操作数1的绝对值
wire [31:0] op2_absolute; //操作数2的绝对值
// 这里需要补充 wire变量赋初值
assign op1_sign = mult_op1[31];
assign op2_sign = mult_op2[31];
assign op1_absolute = op1_sign ? (~mult_op1 + 1) : mult_op1;
assign op2_absolute = op2_sign ? (~mult_op2 + 1) : mult_op2;
//以下:加载被乘数,运算时每次左移一位
reg [63:0] multiplicand;
always @ (posedge clk)
begin
if (mult_valid)
begin // 如果正在进行乘法,则被乘数每时钟左移一位
multiplicand <= {multiplicand[62:0],1'b0};
end
else if (mult_begin)
begin // 乘法开始,加载被乘数,为乘数1的绝对值
multiplicand <= {32'd0,op1_absolute};
end
end
//以下:加载乘数,运算时每次右移一位
reg [31:0] multiplier;
//这里需要补充 乘数的赋值
always @ (posedge clk)
begin
if(mult_valid)
begin //如果正在进行乘法,则乘数每时钟右移一位
multiplier <= {1'b0,multiplier[31:1]};
end
else if(mult_begin)
begin //乘法开始,加载乘数,为乘数2的绝对值
multiplier <= op2_absolute;
end
end
// 以下:部分积--乘数末位为1,由被乘数左移得到;乘数末位为0,部分积为0
wire [63:0] partial_product;
// 这里需要补充 部分积的赋初值
assign partial_product = multiplier[0] ? multiplicand : 64'd0;
//以下:累加器
reg [63:0] product_temp;
always @ (posedge clk)
begin
if (mult_valid)
begin
product_temp <= product_temp + partial_product;
end
else if (mult_begin)
begin
product_temp <= 64'd0; // 乘法开始,乘积清零
end
end
//以下:乘法结果的符号位和乘法结果
reg product_sign;
//这里需要补充 reg变量符号位的赋值和乘法结果的赋值
always @ (posedge clk)
begin
if (mult_valid)
begin
product_sign <= op1_sign ^ op2_sign;
end
end
assign product = product_sign ? (~product_temp+1) : product_temp;
endmodule
testbench.v:
`timescale 1ns / 1ps
module tb;
// Inputs
reg clk;
reg mult_begin;
reg [31:0] mult_op1;
reg [31:0] mult_op2;
// Outputs
wire [63:0] product;
wire mult_end;
// Instantiate the Unit Under Test (UUT)
multiply uut (
.clk(clk),
.mult_begin(mult_begin),
.mult_op1(mult_op1),
.mult_op2(mult_op2),
.product(product),
.mult_end(mult_end)
);
initial begin
// Initialize Inputs
clk = 0;
mult_begin = 0;
mult_op1 = 0;
mult_op2 = 0;
#500;
mult_begin = 1;
mult_op1 = 32'H00001111;
mult_op2 = 32'H00003333;
#400;
mult_begin = 0;
end
always #5 clk = ~clk;
endmodule
②仿真图像及其分析:
1、加法器:
operand1 + opreand2 = result
2、乘法器:
当mult_end=1时 ,product的值等于两个操作数(mult_op1、muilt_op2)的乘积。
--------------------------------------------------------------------------------------------------------------------------------
白泠Infinity文章来源:https://www.toymoban.com/news/detail-724062.html
到了这里,关于【计算机组成原理】实验1:定点加法和定点乘法(Verilog)中海大的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!