算术逻辑单元ALU实验
- 一. 实验目的
- 二. 实验设备
- 三. 实验任务
- 四. 实验步骤
- 五、结果记录和分析
一. 实验目的
1.理解算术逻辑单元ALU的工作原理。 2.掌握算术逻辑单元ALU设计方法。 3.验证32位算术逻辑单元ALU加、减、和、移位等基本功能。 4.选择几组数据,完成几个算术/逻辑操作。
二. 实验设备
1、 装有Xilinx Vivado一台计算机。 2、LS-CPU-EXB-一套002教学系统实验箱。
三. 实验任务
1、学习MIPS指令集,熟悉指令类型,了解指令功能和编码,总结基础ALU运算指令。 2.总结并确定本实验准备实现的目标ALU至少需要5种操作要求ALU操作,包括加减操作,其中减法在内部转换为加法,见表1-1。 表1-1 ALU的控制信号 选择端aluc ALU功能 3 2 1 0
-
0 0 0
-
0 0 1
-
0 1 0
-
0 1 1
-
1 0 0
-
1 0 1
-
1 1 0
0 1 1 1
1 1 1 1
3.根据图1-1所示的结构框图设计实验方案Verilog编写相应的代码。 4、 模拟编写的代码,得到正确的波形图。 5.以上设计为单独模块,设计外围模块调用模块,如图1-2所示。包装好的外围模块需要调用LCD显示触摸屏模块ALU两个源的操作数、操作码和操作结果,以及触摸功能输入源的操作数。可以考虑操作代码LCD也可以用拨码开关输入触摸屏输入。 6.综合布局编写的代码,下载到试验箱中FPGA演示板上。
四. 实验步骤
- 这里给出实验代码。请阅读具体的实验步骤
alu.v module alu(a,b,aluc,r,z); input [31:0] a,b; input [3:0] aluc; output [31:0] r; output z; assign r = cal (a,b,aluc); assign z = ~|r; function [31:0] cal; input [31:0] a,b; input [3:0] aluc; casex(aluc) 4'b0000: cal = a b;//加 4'b0001: cal = a&b;
4'b0010: cal = a^b;
4'b0011: cal = b<<a[4:0];
4'b0100: cal = a-b;
4'b0101: cal = a|b;
4'b0110: cal = {
b[15:0],16'h0};
4'b0111: cal = b>>a[4:0];
4'b1111: cal = $signed(b) >>> a[4:0];//算术右移
endcase
endfunction
endmodule
alu-display.v //************************************************************************* // > 文件名: alu_display.v // > 描述 :ALU
显示模块,调用FPGA板上的IO接口和触摸屏 // > 作者 : LOONGSON // > 日期 : 2016-04-14 //************************************************************************* module alu_display( //时钟与复位信号 input clk, input resetn, //后缀"n"代表低电平有效 //拨码开关,用于选择输入数 input [1:0] input_sel, //00:输入为控制信号(alu_control) //10:输入为源操作数1(alu_src1) //11:输入为源操作数2(alu_src2) //触摸屏相关接口,不需要更改 output lcd_rst, output lcd_cs, output lcd_rs, output lcd_wr, output lcd_rd, inout[15:0] lcd_data_io, output lcd_bl_ctr, inout ct_int, inout ct_sda, output ct_scl, output ct_rstn ); //-----{调用ALU模块}begin reg [3:0] alu_control; // ALU控制信号 reg [31:0] alu_src1; // ALU操作数1 reg [31:0] alu_src2; // ALU操作数2 wire [31:0] alu_result; // ALU结果 wire alu_z; alu alu_module( .aluc(alu_control), .a (alu_src1 ), .b (alu_src2 ), .r (alu_result ), .z (alu_z) ); //-----{调用ALU模块}end //---------------------{调用触摸屏模块}begin--------------------// //-----{实例化触摸屏}begin //此小节不需要更改 reg display_valid; reg [39:0] display_name; reg [31:0] display_value; wire [5 :0] display_number; wire input_valid; wire [31:0] input_value; lcd_module lcd_module( .clk (clk ), //10Mhz .resetn (resetn ), //调用触摸屏的接口 .display_valid (display_valid ), .display_name (display_name ), .display_value (display_value ), .display_number (display_number), .input_valid (input_valid ), .input_value (input_value ), //lcd触摸屏相关接口,不需要更改 .lcd_rst (lcd_rst ), .lcd_cs (lcd_cs ), .lcd_rs (lcd_rs ), .lcd_wr (lcd_wr ), .lcd_rd (lcd_rd ), .lcd_data_io (lcd_data_io ), .lcd_bl_ctr (lcd_bl_ctr ), .ct_int (ct_int ), .ct_sda (ct_sda ), .ct_scl (ct_scl ), .ct_rstn (ct_rstn ) ); //-----{实例化触摸屏}end //-----{从触摸屏获取输入}begin //根据实际需要输入的数修改此小节, //建议对每一个数的输入,编写单独一个always块 //当input_sel为00时,表示输入数控制信号,即alu_control always @(posedge clk) begin if (!resetn) begin alu_control <= 12'd0; end else if (input_valid && input_sel==2'b00) begin alu_control <= input_value[11:0]; end end //当input_sel为10时,表示输入数为源操作数1,即alu_src1 always @(posedge clk) begin if (!resetn) begin alu_src1 <= 32'd0; end else if (input_valid && input_sel==2'b10) begin alu_src1 <= input_value; end end //当input_sel为11时,表示输入数为源操作数2,即alu_src2 always @(posedge clk) begin if (!resetn) begin alu_src2 <= 32'd0; end else if (input_valid && input_sel==2'b11) begin alu_src2 <= input_value; end end //-----{从触摸屏获取输入}end //-----{输出到触摸屏显示}begin //根据需要显示的数修改此小节, //触摸屏上共有44块显示区域,可显示44组32位数据 //44块显示区域从1开始编号,编号为1~44, always @(posedge clk) begin case(display_number) 6'd1 : begin display_valid <= 1'b1; display_name <= "SRC_1"; display_value <= alu_src1; end 6'd2 : begin display_valid <= 1'b1; display_name <= "SRC_2"; display_value <= alu_src2; end 6'd3 : begin display_valid <= 1'b1; display_name <= "CONTR"; display_value <={ 20'd0, alu_control}; end 6'd4 : begin display_valid <= 1'b1; display_name <= "RESUL"; display_value <= alu_result; end 6'd5 : begin display_valid <= 1'b1; display_name <= "ZF"; display_value <= alu_z; end default : begin display_valid <= 1'b0; display_name <= 40'd0; display_value <= 32'd0; end endcase end //-----{输出到触摸屏显示}end //----------------------{调用触摸屏模块}end---------------------// endmodule
alu_tb.v代码如下:
module testbench;
// Inputs
reg [31:0] a;
reg [31:0] b;
reg [3:0] aluc;
//output
wire [31:0] r;
wire z;
//Instantiate the Unit Under Test(UUT)
alu uut(
.a(a),
.b(b),
.r(r),
.aluc(aluc),
.z(z)
);
initial begin
// Initialize Inputs
a=0;
b=0;
aluc=0;
//Wait 100ns for global reset to finish
#100;
//Add stimulus here
end
always #10 a=$random;//$random为系统任务,产生一个随机的32位数
always #10 b=$random; //#10表示等待10个单位时间(10ns),即每过10ns,赋值一个随机的32位数
always #10 aluc= {
$random}%2; //加了拼接符,{$random}产生一个非负数,除2取余得到0或1
endmodule
alu.xdc文件如下:
set_property PACKAGE_PIN AC19 [get_ports clk]
set_property PACKAGE_PIN Y3 [get_ports resetn]
set_property PACKAGE_PIN AC22 [get_ports input_sel[0]]
set_property PACKAGE_PIN AD24 [get_ports input_sel[1]]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports resetn]
set_property IOSTANDARD LVCMOS33 [get_ports input_sel[1]]
set_property IOSTANDARD LVCMOS33 [get_ports input_sel[0]]
set_property PACKAGE_PIN J25 [get_ports lcd_rst]
set_property PACKAGE_PIN H18 [get_ports lcd_cs]
set_property PACKAGE_PIN K16 [get_ports lcd_rs]
set_property PACKAGE_PIN L8 [get_ports lcd_wr]
set_property PACKAGE_PIN K8 [get_ports lcd_rd]
set_property PACKAGE_PIN J15 [get_ports lcd_bl_ctr]
set_property PACKAGE_PIN H9 [get_ports {
lcd_data_io[0]}]
set_property PACKAGE_PIN K17 [get_ports {
lcd_data_io[1]}]
set_property PACKAGE_PIN J20 [get_ports {
lcd_data_io[2]}]
set_property PACKAGE_PIN M17 [get_ports {
lcd_data_io[3]}]
set_property PACKAGE_PIN L17 [get_ports {
lcd_data_io[4]}]
set_property PACKAGE_PIN L18 [get_ports {
lcd_data_io[5]}]
set_property PACKAGE_PIN L15 [get_ports {
lcd_data_io[6]}]
set_property PACKAGE_PIN M15 [get_ports {
lcd_data_io[7]}]
set_property PACKAGE_PIN M16 [get_ports {
lcd_data_io[8]}]
set_property PACKAGE_PIN L14 [get_ports {
lcd_data_io[9]}]
set_property PACKAGE_PIN M14 [get_ports {
lcd_data_io[10]}]
set_property PACKAGE_PIN F22 [get_ports {
lcd_data_io[11]}]
set_property PACKAGE_PIN G22 [get_ports {
lcd_data_io[12]}]
set_property PACKAGE_PIN G21 [get_ports {
lcd_data_io[13]}]
set_property PACKAGE_PIN H24 [get_ports {
lcd_data_io[14]}]
set_property PACKAGE_PIN J16 [get_ports {
lcd_data_io[15]}]
set_property PACKAGE_PIN L19 [get_ports ct_int]
set_property PACKAGE_PIN J24 [get_ports ct_sda]
set_property PACKAGE_PIN H21 [get_ports ct_scl]
set_property PACKAGE_PIN G24 [get_ports ct_rstn]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rst]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_cs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_wr]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rd]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_bl_ctr]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[11]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[12]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[13]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[14]}]
set_property IOSTANDARD LVCMOS33 [get_ports {
lcd_data_io[15]}]
set_property IOSTANDARD LVCMOS33 [get_ports ct_int]
set_property IOSTANDARD LVCMOS33 [get_ports ct_sda]
set_property IOSTANDARD LVCMOS33 [get_ports ct_scl]
set_property IOSTANDARD LVCMOS33 [get_ports ct_rstn]
拨码开关的连接,通过AC22、AD24拨码开关来控制输入SRC_1,SRC_2,CONTR的值
五.结果记录及分析
(1) 仿真波形