如何在JavaScript中实现乘法器电路

时间:2019-03-03 12:04:35

标签: javascript logic multiplication circuit

TBH我很难理解逻辑门图,因为我还没有完全理解底层电子设备及其所有工作原理。

我有一些有关基本逻辑门的学习经验,在观看了几段视频并进行了很多思考之后,我可以在几分钟内了解它。

但是后来我看到了一些在软件中“实现”的“逻辑门”的例子,这使发生的事情更加有意义。例如,here

然后,我什至可以更深入地了解full adder的工作方式,如here

function fullAdder(a,b,c){
  return {
    c:or(and(xor(a,b),c), and(a,b)), // C is the carry
    s:xor(xor(a,b),c) // S is the sum
  };
}

与逻辑图相比,这是非常基本的。

现在,我想了解multiplicationdivision是如何在逻辑门中实现的,例如x86的MUL运算符。

function MUL(a,b){
  return {
    ...
  };
}

除了花一些严肃的时间来理解乘法器电路,然后尝试使用上述示例将其转化为也许与非门的实现之外,我真的不知道从哪里开始。想知道是否已经知道这一点的人可以演示JavaScript的实现。

1 个答案:

答案 0 :(得分:1)

乘法依赖于数字以二进制编码的方式。 如果A为无符号并由a_n-1,a_n-2,...,a_1,a_0位编码,则其值为
A = a_n-1 * 2 ^ n-1 + a_n-2 * 2 ^ n-2 + ... + a_1 * 2 ^ 1 + a_0

所以要乘以A×B,必须做
A×B = A×(b_n-1 * 2 ^ n-1 + b_n-2 * 2 ^ n-2 + ... + b_1 * 2 ^ 1 + b_0)
= A×b_n-1 * 2 ^ n-1 + A×b_n-2 * 2 ^ n-2 + ... + A×b_1 * 2 ^ 1 + A×b_0
乘法只是一个很大的加法,其中每一项A×b_i * 2 ^ i如果b_i == 1则为A×2 ^ i,如果b_i == 0则为0

这是C语言的实现


int mult(unsigned short A, unsigned short B){
  int res=0;
  int mask=0x1;
  for(int i=0; i<16;i++,mask<<=1){
    if(B&mask)
      res += (A << i);
  }
  return res;
}

b_i上的测试可以用“与”门代替。

int mult(unsigned short A, unsigned short B){
  int res=0;
  int mask=0x1;
  for(int i=0; i<16;i++,mask<<=1){
     res += (A&~(((B&mask)>>i) -1))<<i;
  }
  return res;
}

这个奇特的表达式提取B(B&mask)的第i位,将其放在LSB(>>i)处,减去1,这样我们得到1-1 = 0,它的位是1, -1 = 0xffffffff否则。我们只需要对A进行补码并进行“与”运算就可以得到A或0(取决于第i位)。幸运的是,硬件方面的工作更加轻松。复制B的b_i位并对A的每一位做一个“与”就足够了。

为简化硬件,A<<i的可变移位可以在每一步(A=A<<1)处用A的左移1位代替。对于b_i提取,可以进行类似的修改,使得我们始终考虑B的LSB。

int mult(unsigned short A, unsigned short B){
  int res=0;
  int mask=0x1;
  for(int i=0; i<16;i++){
     res += A&~((B&mask) -1);
     A <<= 1;
     B >>= 1;
  }
  return res;
}

展开循环后,这或多或少是简单乘法器在硬件中的外观。 您可以在js中实现它,并用由Gates完成的加法器替换+,并使用模拟的“ and”门。

实际上,硬件乘法器要复杂一些。

  • 它们使用不带进位传播的特殊加法器来减少加法时间(进位保存加法)。这需要在计算结束时额外添加

  • 他们经常使用基数4来减少添加步骤(修改的Booth算法)。

  • 它们通过管道传输以提高吞吐量

顺便说一句,您可能对此online simulator中的各种计算机算术算法感兴趣。