计算逻辑单元(ALU)和存储单元

计算逻辑单元(ALU)和存储单元
本节参考算术逻辑单元 ALU

一 ALU单元

arithmetic and logic unit 算术逻辑单元,简称ALU,是计算机的数学大脑,也就是计算机里负责运算的组件,比如把两个数相加。基本其他的组件都用到了ALU,它有两个 单元 一个算术单元,一个逻辑单元

1 算术单元

算术单元指完成加减基础运算的单元,例如简单的二进制加法运算电路即半加器,器电路原理图 如下所示。

在这里插入图片描述

其中 S U M SUM SUM为加法本位值 C H E R R Y CHERRY CHERRY为进位。
同时可以用两个半加器组合成全加器如下图。
在这里插入图片描述

然后进行封装可以为。
在这里插入图片描述

当很多个全加器叠加起来就可以实现多位的加法,如常见的计算机8位加法运算。
在这里插入图片描述

其他操作,可以使得输入

  • 加法(ADD)
  • 减法(SUBTRACT)
  • 增量+1(INCREMENT)
  • 减量-1(DECREMENT)
    在这里插入图片描述
2 逻辑单元

顾名思义,逻辑单元在计算机内负责执行逻辑操作。比如之前说的“与”,“或”,“非”,“异或”。另外,它还能做简单的数值测试,比如利用许多个“或门”,来检测一个8位数字是否为“0”:

在这里插入图片描述

它接受两个操作数输入( I n A , I n B InA,InB InAInB),以及1个表示要进行的是哪个运算的操作代码(Opcode),然后输出一个结果 ( O u t ) (Out) Out
另外 ALU 还会有各种标志位 ( f l a g ) (flag) flag,来表示计算的状态。例如: 进位标志( C a r r y f l a g Carry flag Carryflag)表示这次计算有没有进位,0标志( Z e r o f l a g Zero flag Zeroflag)表示这次计算的结果是不是为0,这样就可以方便地判断计算是否溢出,或者两个输入的数是否相等。高级的$ ALU$ 中,会有更多的标志位,可以帮助处理器更快更方便地运算。

软件部分(verilog)

加法
减法
有符号比较,小于置位
无符号比较,小于置位
按位与
按位或非
按位或
按位异或
逻辑左移
逻辑右移
算术右移
高位加载

`timescale 1ns / 1ps
//*************************************************************************
//   > 文件名: alu.v
//   > 描述  :ALU模块,可做12种操作
//   > 作者  : LOONGSON
//   > 日期  : 2016-04-14
//*************************************************************************
module alu(
    input  [11:0] alu_control, 
    input  [31:0] alu_src1, 
    input  [31:0] alu_src2,
    output   [31:0] alu_result 
    );
    reg [31:0] alu_result;
    wire alu_add;   //加法
    wire alu_sub;   //减法
    wire alu_slt;   //有符号比较,小于置位
    wire alu_sltu;  //无符号比较,小于置位
    wire alu_and;   //按位与
    wire alu_nor;   //按位或非
    wire alu_or;    //按位或 
    wire alu_xor;   //按位异或
    wire alu_sll;   //逻辑左移
    wire alu_srl;   //逻辑右移
    wire alu_sra;   //算数右移
    wire alu_lui;   //高位加载

    assign alu_add  = alu_control[11];
    assign alu_sub  = alu_control[10];
    assign alu_slt  = alu_control[ 9];
    assign alu_sltu = alu_control[ 8];
    assign alu_and  = alu_control[ 7];
    assign alu_nor  = alu_control[ 6];
    assign alu_or   = alu_control[ 5];
    assign alu_xor  = alu_control[ 4];
    assign alu_sll  = alu_control[ 3];
    assign alu_srl  = alu_control[ 2];
    assign alu_sra  = alu_control[ 1];
    assign alu_lui  = alu_control[ 0];

    wire [31:0] add_sub_result; //加减结果,减法用加法来实现
    wire [31:0] slt_result;     //
    wire [31:0] sltu_result;    //
    wire [31:0] and_result;
    wire [31:0] nor_result;
    wire [31:0] or_result;
    wire [31:0] xor_result;
    wire [31:0] sll_result;
    wire [31:0] srl_result;
    wire [31:0] sra_result;     //
    wire [31:0] lui_result;

    wire signed [31:0] temp_src1;   //带符号数的临时变量
    assign temp_src1 = alu_src1;    //方便后面对alu_src1进行算数右移
    
    assign and_result = alu_src1 & alu_src2;        //按位与
    assign or_result  = alu_src1 | alu_src2;        //按位或
    assign nor_result = ~or_result;                 //或非
    assign xor_result = alu_src1 ^ alu_src2;        //异或
    assign lui_result = {alu_src2[15:0], 16'd0};    //高位加载,第二个操作数的低十六位加载到高十六位上
    assign sll_result = alu_src1 << alu_src2;       //逻辑左移
    assign srl_result = alu_src1 >> alu_src2;       //逻辑右移
    assign slt_result = adder_result[31] ? 1'b1 : 1'b0;   // 带符号数小于置位
    assign sltu_result = adder_cout ? 1'b0 : 1'b1;     //无符号数小于置位
    assign sra_result = temp_src1 >>> alu_src2;     //算数右移

    wire [31:0] adder_operand1;
    wire [31:0] adder_operand2;
    wire        adder_cin     ;
    wire [31:0] adder_result  ;
    wire        adder_cout    ;
    assign adder_operand1 = alu_src1; 
    assign adder_operand2 = alu_add ? alu_src2 : ~alu_src2;     //默认进行减法,为slt和sltu服务
    assign adder_cin      = ~alu_add;  //巧妙到我都以为代码有bug
    adder adder_module(     //调用加法模块
    .operand1(adder_operand1),
    .operand2(adder_operand2),
    .cin     (adder_cin     ),
    .result  (adder_result  ),
    .cout    (adder_cout    )
    );
assign add_sub_result = adder_result;

	always@(*)
	begin

        if(alu_add | alu_sub)
            alu_result <= add_sub_result;
            else if(alu_slt)
            alu_result <= slt_result;
            else if(alu_sltu)
            alu_result <= sltu_result;
            else if(alu_and)
            alu_result <= and_result;
            else if(alu_nor)
            alu_result <= nor_result;
            else if(alu_or)
            alu_result <= or_result;
            else if(alu_xor)
            alu_result <= xor_result;
            else if(alu_sll)
            alu_result <= sll_result;
            else if(alu_srl)
            alu_result <= srl_result;
            else if(alu_sra)
            alu_result <= sra_result;
            else if(alu_lui)
            alu_result <= lui_result;
         
	end
endmodule

二 存储单元

1 静态存储器SRAM(Static Radom Access Memory)

SRAM主要用于主要用于二级快速缓存(Level2 C ache)。它利用晶体管来存储数据。与DRAM相比,SRAM的速度快,但在同样面积中SRAM的容量要比其它类型的内存小。

大部分FPGA器件採用了查找表(Look Up Table,LUT)结构。查找表的原理类似于ROM,其物理结构是静态存储器(SRAM),N个输入项的逻辑函数能够由一个2^N位容量的SRAM实现,函数值存放在SRAM中,SRAM的地址线起输入线的作用,地址即输入变量值,SRAM的输出为逻辑函数值。由连线开关实现与其它功能块的连接。
在这里插入图片描述

  • corecells array:存储单元阵列
  • decode:行列地址译码器
  • Sense Amplifier:灵敏放大器
  • conntrol circuit:控制电路
  • FFIO:缓冲/驱动电路

在图中, A 0 − A m − 1 A_{0}-A_{m-1} A0Am1为地址输入端, C S B CSB CSB W E B WEB WEB O E B OEB OEB为控制端,控制读写操作,为低电平有效, I / O 0 − I / O N − 1 I/O_{0}-I/O_{N-1} I/O0I/ON1为数据输入输出端。存储阵列中的每个存储单元都与其他单元在行和列上共享电学连接,当中水平方向的连线称为“字线”,而垂直方向的数据流入和流出存储单元的连线称为“位线”。通过输入的地址可选择特定的字线和位线。字线和位线的交叉处就是被选中的存储单元。每个存储单元都是按这个方案被唯一选中,然后再对其进行读写操作。有的存储器设计成多位数据如4位或8位等同一时候输入和输出,这种话,就会同一时候有4个或8个存储单元按上述方法被选中进行读写操作。

SRAM六管电路结构

在这里插入图片描述

假设准备往图的6T存储单元写入“1”,先将某一组地址值输入到行、列译码器中,选中特定的单元,然后使写使能信号WE有效,将要写入的数据“1”通过写入电路变成“1”和“0”后分别加到选中单元的两条位线BL,BLB上,此时选中单元的WL=1,晶体管N0,N5打开,把BL,BLB上的信号分别送到Q,QB点,从而使Q=1,QB=0,这样数据“1”就被锁存在晶体管P2,P3,N3,N4构成的锁存器中。写入数据“0”的过程类似。
SRAM的读过程以读“1”为例,通过译码器选中某列位线对BL,BLB进行预充电到电源电压VDD,预充电结束后,再通过行译码器选中某行,则某一存储单元被选中,由于其中存放的是“1”,则WL=1、Q=1、QB=0。晶体管N4、N5导通,有电流经N4、N5到地,从而使BLB电位下降,BL、BLB间电位产生电压差,当电压差达到一定值后打开灵敏度放大器,对电压进行放大,再送到输出电路,读出数据。

### 算术逻辑单元 (ALU) 的 Proteus 仿真实验 #### 实验目标 熟悉 Proteus 虚拟仿真软件的工作环境,掌握其基本工具的使用方法。理解简单运算器的组成以及数据传送通路,验证算术逻辑运算器(74LS181)的算术运算逻辑运算功能[^2]。 #### 所需材料与设备 - 计算机一台,已安装Proteus仿真软件。 - 数字电路基础知识。 - 了解74LS181芯片及其工作原理。 #### 实验准备 在开始之前,确保已经掌握了Proteus的基本操作技能,包括但不限于元件库管理、布线连接、属性设置等功能。同时准备好所需的电子元器件模型文件,特别是用于构建ALU的核心组件——74LS181 TTL系列四位二进制全加/减法器兼多模式比较器集成电路。 #### 构建 ALU 模型 按照实际硬件电路的设计思路,在Proteus环境中搭建起由多个74LS181组成的多位数ALU结构。注意合理安排各个子模块之间的信号传输路径,并正确配置输入输出端口参数以满足特定应用场景下的需求。 #### 进行功能测试 完成上述步骤之后就可以着手编写相应的控制程序来驱动整个系统正常运转了。此时可以利用Proteus内置的支持多种编程语言编译链接机制的优势来进行在线调试;也可以直接加载预先写好的HEX/BIN格式的目标代码文件到单片机内部Flash存储空间当中去执行。最后通过观察示波器显示出来的实时变化曲线或者借助其他辅助手段进一步确认最终成果的有效性准确性[^3]。 ```python # Python伪代码模拟部分测试过程 def test_alu_operations(): operations = ['ADD', 'SUBTRACT', 'AND', 'OR'] for op in operations: result = perform_operation(op) print(f"Testing {op}: Result is {result}") def perform_operation(operation_type): # 假设这是调用Proteus API的地方 pass test_alu_operations() ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值