桶式移位器

前言

本篇文章介绍CPU的核心部件之一:桶式移位器,简称BS,英文全称为Barrel Shifter
桶式移位器最大的特点就是能在单周期内完成多种方式,各种位数的移位操作

常见的移位操作

常见的移位操作种类如下:

  • 算术右移
    是指数据向右移位,左侧用符号位补齐
  • 逻辑右移
    是指数据向右移位,左侧用0补齐
  • 算术左移和逻辑左移
    是指数据向左移动,右侧用0补齐
  • 循环右移
    是指数据向右移动,左侧用用测移出的位补齐
    比如1011 0101,循环右移两位就会变成 0110 1101
    注意:循环左移可以通过循环右移来实现,对于n位数据,循环左移m位就相当于循环右移n-m位

桶形移位器的实现方式

下面这张图是我从网上找的,链接地址在这里
在这里插入图片描述

这张图可以非常形象的说明桶形移位器的电路逻辑,先对里面的各种值进行一下说明:

  • S C i SCi SCi:表示移位的位数,对于支持n位移位的移位器来说,有n个 S C i SCi SCi,如果想要移动m位,只需要 S C m SCm SCm设置为1,别的 S C i SCi SCi为0即可。
  • a i ai ai:输入的待移位的数的二进制位,对于64位的移位器,需要64个输入
  • a ′ i a'i ai:输出的移位的数的二进制位,对于64位的移位器,需要64个输出
  • S i n 1 Sin1 Sin1:输入的移位标志,右移为1,左移为0
  • i n 1 in1 in1:一个逻辑与门,输入端为 a i ai ai S i n 1 Sin1 Sin1,表示的意思是右移时输出为 a i ai ai,左移时输出为0
  • D 0 / 1 D0/1 D0/1:右移时左侧填补的位,如果是算术右移就连接的是 a i ai ai的最高位,逻辑右移就是0
  • S i n 2 Sin2 Sin2:左移或者循环右移的时候为1,否则为0
  • S i n 2 ‾ \overline {Sin2} Sin2: S i n 2 Sin2 Sin2的非
  • i n 2 in2 in2:由两个与门一个或门组成的逻辑电路,如下图所示:
    在这里插入图片描述

用公式表示输出$$KaTeX parse error: Can't use function '$' in math mode at position 5: in2i$̲为: in2i = Sin2 \cdot ai+\overline {Sin2}\cdot D0/1$$

i n 2 in2 in2的作用可以描述如下:

  • 右移时为0或者符号位,去填补左侧移出的空位
  • 左移时为输入值,用于实现左移,在到达 i n 2 in2 in2之前没有左移的逻辑

案例分析: 循环右移两位

我们按照上图的标记进行分析,以 a 7 a7 a7位为例,因为是循环右移,所以我们先把对应的值确定一下:

  • 循环右移, S i n 1 Sin1 Sin1=1,所以 i n 1 in1 in1 a 7 a7 a7的输出为1
  • 循环右移, S i n 2 Sin2 Sin2=1, S i n 2 ‾ \overline {Sin2} Sin2=0, D 0 / 1 D0/1 D0/1不重要了,因为 S i n 2 ‾ \overline {Sin2} Sin2=0,所以 S i n 2 ‾ ⋅ D 0 / 1 \overline {Sin2}\cdot D0/1 Sin2D0/1=0,也就是 i n 2 in2 in2的值完全取决于 a i ai ai
  • 右移两位,所以 S C 2 SC2 SC2==1,其余都为0

接下来看流程,为了方便,我们再次拷贝一下上面的图:
在这里插入图片描述

  • i n 1 in1 in1 a 7 a7 a7的输出 i n 1 in1 in1的值
  • 跟着电路走,直到到 S C 2 SC2 SC2接触点的时候,因为 S C 2 SC2 SC2=1,所以开关接通
  • a 7 a7 a7的值从 a ′ 5 a'5 a5输出
  • 同理
    a 7 a7 a7的值从 a ′ 5 a'5 a5输出
    a 6 a6 a6的值从 a ′ 4 a'4 a4输出
    a 5 a5 a5的值从 a ′ 3 a'3 a3输出
    a 4 a4 a4的值从 a ′ 2 a'2 a2输出
    a 3 a3 a3的值从 a ′ 1 a'1 a1输出
    a 2 a2 a2的值从 a ′ 0 a'0 a0输出
  • 然后看 a 1 a1 a1,虽然在 i n 1 in1 in1也输出了 a 1 a1 a1的值,但是没有到 S C 2 SC2 SC2就已经跑出电路了,另一条输出到了上面的 a 1 a1 a1,进入 i n 2 in2 in2电路,此时根据上面的数值我们知道 i n 2 in2 in2电路输出 a 1 a1 a1的值,然后该值沿着电路往左下方走,直到到 S C 2 SC2 SC2,因为 S C 2 SC2 SC2=1,所以开关接通, a 1 a1 a1的值从 a ′ 7 a'7 a7输出
  • 同理,我们可以分析 a 0 a0 a0的值从 a ′ 6 a'6 a6输出
  • 这样,循环右移便完成了。

C语言描述

下面给出桶式移位器的C语言描述,git地址

extern long bs(long in_1,long type,long num);
extern void bs_test(void);
#include "alu.h"
long bs(long in_1,long type,long num)
{
    long sin1=0;// 右移才会为1
    long sin2=0;// 左移/循环右移才会为1
    long sin3=0;// 右移才会为1
    long d0=0;  // 右移才有意义,逻辑右移为0,算术右移为最高位
    num%=(sizeof(long)*8);
    switch (type) {
        case 0:// 逻辑左移
            sin1=0;
            sin2=1;
            sin3=0;
            d0=0;
            num =(sizeof(long)*8-num);
            break;
        case 1:// 逻辑右移
            sin1=1;
            sin2=0;
            sin3=1;
            d0=0;
            break;
        case 2:// 算术右移
            sin1=1;
            sin2=0;
            sin3=1;
            d0=in_1>>(sizeof(long)*8-1);
            break;
        case 3:// 循环右移
            sin1=1;
            sin2=1;
            sin3=1;
            d0=0;
            break;
        default:
            break;
    }
    // 每个位都会输出,为了左移或者循环右移
    long a = in_1;
    // 默认输出为0,只有发生移动才会有值
    long in1 = 0;
    // 计算in1的输出,如果不是右移,原样输出
    // 使用-1来表示位都是1的情况
    if(sin1!=0)
    {
        unsigned long temp = in_1;
        in1 = (temp>>num);
    }
    // 下面的三步走的in2的电路
    long in2_1 = alu_and(a, sin2==0?0:-1, sizeof(long)*8);
    long in2_2 = alu_and(sin3, d0, sizeof(long)*8);
    long in2 = alu_or(in2_1, in2_2==0?0:-1, sizeof(long)*8);
    in2 <<=(sizeof(long)*8-num);
    
    return in2|in1;
}

下面是一个测试例子:

void bs_test(void)
{
    printf("bs test start:\n");
    for(int i = 0;i<sizeof(long)*8;i++)
    {
        long r1 = bs(1, 0, i);
        printf("\t1 move left %d:%ld\n",i,r1);
    }
    for(int i = 0;i<sizeof(long)*8+1;i++)
    {
        long r1 = bs(-1, 1, i);
        printf("\t1 move right logic %d:%ld\n",i,r1);
    }
    for(int i = 0;i<sizeof(long)*8+1;i++)
    {
        long r1 = bs(-1, 2, i);
        printf("\t1 move right arithmetic %d:%ld\n",i,r1);
    }
    long a = 0xAAAAAAAAAAAAAAAA;
    for(int i = 0;i<sizeof(long)*8+1;i++)
    {
        long r1 = bs(a, 3, i);
        printf("\t1 move right loop %d:%ld\n",i,r1);
    }
    printf("bs test end\n");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/288354.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

google-java-format 配置及应用

以google 的java 风格为基准&#xff0c;以后面的开发中&#xff0c;都需要满足这个&#xff0c;主要用到的是google的两个插件&#xff1a;google-java-format, google_checks.xml代码格式检测&#xff0c;这两个堪称双剑合并&#xff0c;代码成诗。google-java-format替换ide…

RS485数据采集模块,如何一次采集多个modbus设备数据?

在工业数据采集中&#xff0c;RS485是一种常见的数据通信协议&#xff0c;而Modbus则是其上的常用设备协议。那么&#xff0c;如何用一个模块高效采集多个Modbus设备的数据呢&#xff1f;这就是我们今天要探讨的话题&#xff01; 什么是RS485数据采集模块&#xff1f; 首先&a…

算法28:力扣64题,最小路径和------------样本模型

题目&#xff1a; 给定一个二维数组matrix&#xff0c;一个人必须从左上角出发&#xff0c;最后到达右下角 。沿途只可以向下或者向右走&#xff0c;沿途的数字都累加就是距离累加和 * 返回累加和最小值 思路&#xff1a; 1. 既然是给定二维数组matrix&#xff0c;那么二维数…

FreeRTOS——队列及其实战

1.队列概念 1&#xff09;队列是任务到任务、任务到中断、中断到任务数据交流的一种机制&#xff08;消息传递&#xff09; 2&#xff09;队列类似数组&#xff0c;只能存储有限数量、相同类型的数据&#xff0c;在创建时需指定队列长度与队列项大小 3&#xff09;出队入队阻塞…

xshell登录不上虚拟机了

电脑重启后连不上本地虚机了 1、关闭防火墙 2 虚拟机ping得到主机&#xff0c;而主机ping不到虚拟机的解决办法 原因&#xff1a;可能是主机的网络适配器没有调好 首先&#xff0c;找到虚拟机的网络配置器 根据虚拟机的IP信息修改主机虚拟适配器VMnet8 修改ip使得和虚拟机连…

Element-ui自定义input框非空校验

1、vue自定义非空指令&#xff1a; main.js中自定义非空指令 当input框或下拉框中数据更新时&#xff0c;触发校验 Vue.directive(isEmpty,{update:function(el,binding,vnode){if(vnode.componentInstance.value""){el.classList.add("is-required");}e…

[Unity]实时阴影技术方案总结

一&#xff0c;Planar Shadow 原理就是将模型压扁之后绘制在需要接受阴影的物体上&#xff0c;这种方式十分高效&#xff0c;消耗很低。具体实现过程参考Unity Shader - Planar Shadow - 平面阴影。具按照自己的理解&#xff0c;其实就是根据光照方向计算片元在接受阴影的平面…

详解卡尔曼滤波(Kalman Filter)

1. 从维纳滤波到卡尔曼滤波 黑盒&#xff08;Black Box&#xff09;思想最早由维纳&#xff08;Wiener&#xff09;在1939年提出&#xff0c;即假定我们对从数据到估计中间的映射过程一无所知&#xff0c;仅仅用线性估计&#xff08;我们知道在高斯背景下&#xff0c;线性估计…

计算机创新协会冬令营——暴力枚举题目01

首先是欢迎大家参加此次的冬令营&#xff0c;我们协会欢迎所有志同道合的同学们。话不多说&#xff0c;先来看看今天的题目吧。 题目 力扣题号&#xff1a;2351. 第一个出现两次的字母 注&#xff1a;下述题目和示例均来自力扣 题目 给你一个由小写英文字母组成的字符串 s &…

RocketMQ5.0Pop消费模式

前言 RocketMQ 5.0 消费者引入了一种新的消费模式&#xff1a;Pop 消费模式&#xff0c;目的是解决 Push 消费模式的一些痛点。 RocketMQ 4.x 之前&#xff0c;消费模式分为两种&#xff1a; Pull&#xff1a;拉模式&#xff0c;消费者自行拉取消息、上报消费结果Push&#x…

探索Allure Report:提升自动化测试效率的秘密武器

亲爱的小伙伴们&#xff0c;由于微信公众号改版&#xff0c;打乱了发布时间&#xff0c;为了保证大家可以及时收到文章的推送&#xff0c;可以点击上方蓝字关注测试工程师成长之路&#xff0c;并设为星标就可以第一时间收到推送哦&#xff01; 一.使用 Allure2 运行方式-Python…

【操作系统xv6】学习记录4 -CPU上下文:进程上下文、线程上下文、中断上下文

什么是cpu上下文 CPU 寄存器和程序计数器就是 CPU 上下文&#xff0c;因为它们都是 CPU 在运行任何任务前&#xff0c;必须的依赖环境。 什么是 CPU 上下文切换 先把前一个任务的 CPU 上下文&#xff08;也就是 CPU 寄存器和程序计数器&#xff09;保存起来&#xff0c;然后…

equals()比较字符串和MySQL中=比较结果不一致

问题&#xff1a; 普通车辆入园统计结果数量和普通车辆统计列表数量不一致&#xff1f; 列子&#xff1a;数量:967&#xff0c;列表:974 解决问题步骤 对比统计数量和统计列表的统计方法 统计数量代码实现 一&#xff1a;查询出车辆滞留表数据List 二&#xff1a;查询出…

112. 雷达设备(贪心/逆向思考)

题目&#xff1a; 112. 雷达设备 - AcWing题库 输入样例&#xff1a; 3 2 1 2 -3 1 2 1输出样例&#xff1a; 2 思路&#xff1a; 代码&#xff1a; #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include<…

海外住宅IP代理的工作原理和应用场景分析,新手必看

海外住宅IP代理作为一种技术解决方案&#xff0c;为用户提供了访问全球网络资源和维护隐私安全的方法。本文将介绍海外住宅IP代理的工作原理和应用场景&#xff0c;帮助读者更好地理解和利用这一技术。 一、工作原理 海外住宅IP代理的工作原理基于代理服务器和IP地址的转发。它…

【springboot配置文件加载源码分析】

在Spring Boot的源码中&#xff0c;配置文件的加载是在应用程序启动的早期阶段进行的。具体来说&#xff0c;配置文件加载的主要步骤发生在SpringApplication类的run()方法中的prepareEnvironment方法中&#xff0c;真正读取我们的配置文件还是PropertySourceLoader。 本篇博客…

Docker安装Flarum(开源论坛)

Flarum介绍安装命令 #---------------------------------------------------------- mkdir -p /opt/flarum && cd /opt/flarum #---------------------------------------------------------- docker run -p 8888:8888 --name flarum \ --restartalways \ -v /opt/flar…

靠着这份年终总结,我涨薪8K,成为领导眼中最闪亮的星~

2023 年即将接近尾声&#xff0c;各大公司的“测试媛/猿”们又到了提交年终总结报告的时候了。 每年到这个时候都是抓耳挠腮、冥思苦想的时候&#xff0c;猛然一想&#xff0c;今年跟去年做的事情好像差不多&#xff0c;那么年终总结可以敷衍了事么&#xff1f; 当然是不可以…

chatGPT带你学习设计模式 (二)抽象工厂模式(创建型模式) GURU

深入理解抽象工厂模式 引言 在面向对象编程中&#xff0c;对象的创建是一个常见且关键的挑战。尤其在需要管理一系列相关对象的创建时&#xff0c;传统的对象创建方法&#xff08;如直接使用 new 关键字&#xff09;可能导致代码的高耦合和低灵活性。这时&#xff0c;抽象工厂…

rime中州韵小狼毫 中英互绎 滤镜

英文在日常生活中已经随处可见&#xff0c;我们一般中英互译需要使用专业的翻译软件来实现。但如果我们在输入法中&#xff0c;在输入中文的时候&#xff0c;可以顺便瞟一眼对应的英文词汇&#xff0c;或者在输入英文的时候可以顺便了解对应的中文词汇&#xff0c;那将为我们的…