别看,还没翻译完

本文要介绍的是HP 35中的位串行设计。

(头图是HP35 ROM芯片的部分显微照。更具体的来说是IA缓冲部分以及一些相关的控制电路)

(系列中的显微照pmonta.com,他是第一个实现完整HP35 ROM dump的人:显微读出。)

CPU的位

在计算机历史中,工程师一直都在想办法在重重约束下降低生产成本。70年代,晶体管造价极其昂贵,而位串行的设计就是在那个年代背景下诞生的。现在看来完全不可理喻,然而在当时缺非常流行。

现在,典型的CPU是64位设计,也就表示一次性可以进行64位运算并在内部储存64位的数据。但是其实对于CPU的位数的定义,其实本身比较模糊。大部分的解释是字长,或者说是数据路径和主寄存器的宽度。然而如果考虑下现今的处理器的话,64位的Intel处理器可以进行128位的计算,而4004拥有一个4位的ALU而其它的都是8位的。我们可以把这些架构称为混合架构,然后用最能够代表这个架构的位数作为CPU的位数。

而我们今天的主角,HP35,只拥有一个1位的ALU。它的最小数学运算宽度是4位,最大数学运算宽度是56位,指令长度是10位,地址线宽度是8位,而以上这些,都可以在一个机器周期内完成,然而一个机器周期是56个时钟周期。那么……这个CPU到底是多少位的呢?

HP35的架构每一个时钟周期可以处理1位的数据,所有的数据总线也都只有一条线,应该就是被称为1位架构了吧。不过这个是怎么实现的呢?为什么这样的设计就能节约晶体管数量?这样的实现会不会非常慢?这些也就是本文要解答的问题

串行寄存器传输

实现并行寄存器的传输还是很简单的,如果需要使用HDL来描述的话(HDL,硬件描述语言,如果不熟悉的话没关系,代码本身还是很易懂的),就只要这样就行了:

always @ (posedge clock) reg1 <= reg2;

那么如何实现串行的寄存器传输呢?

如果你用过SPI总线的话,那么你应该已经很熟悉串行寄存器传输那一套的东西了:

//将Reg1的内容传输进Reg2
always @ (posedge clock) begin
    reg1 <= {reg1[0], reg1[7:1]};	// 循环Reg1
    reg2 <= {reg1[0], reg2[7:1]};	// 将reg1的LSB传入reg2的MSB
end
// 交换reg1和reg2的内容
always @ (posedge clock) begin
    reg1 <= {reg2[0], reg1[7:1]}; // 将reg2的LSB传入reg1的MSB
    reg2 <= {reg1[0], reg2[7:1]}; // 将reg1的LSB传入reg2的MSB
end