红石电路吧 关注:32,252贴子:153,435

回复:计算机组成原理及ProjecRed技术实用教程——从零开始构建计算

取消只看楼主收藏回复

程序计数器给定了地址就可以把指令从存储器取过来了
指令从存储器取来放入指令寄存器中,指令寄存器与一般的寄存器完全一样。

(画电路的时候忘记分步截图了


IP属地:广东67楼2014-10-24 20:00
回复
    取得了指令还需要对指令进行译码,由于译码后的控制字与数据通路紧密相关,所以必须先确定好数据通路。
    【数据通路设计】
    数据通路是关于CPU内部多个组件直接数据的流向通道。
    数据通路的类型多种多样,有的程序和数据分开,有的不分开,有的所有数据共用一条总线,也就是CPU的内部总线,也有的数据总线分多条。
    在这里我们采用一种类似于MIPS的数据通路,其中程序、数据的数据线和地址线全都有专用的线,数据在寄存器与运算器、存储器都存在直接的通路,这样能够使得控制较为方便,效率比较高,但是连线比较多,寻址不够灵活。
    一个大致的通路如下图所示(存储器就是RAM):


    IP属地:广东68楼2014-10-24 20:16
    回复
      2025-08-21 10:50:22
      广告
      不感兴趣
      开通SVIP免广告
      (上图的通路中,存储器接受的两路信号分别是数据线和地址线)
      仔细观察上图不难发现,这种通路无法在一个周期里面实现寄存器简介寻址并参与运算,因为一个周期要么访问存储器,要么进行运算。
      此外上图无法实现立即数寻址,这是无法忍受的,所以必须要在通路中加入立即数通路。

      那么问题来了,两个或多个数据汇集到一起怎么办?就像上图红圈的地方。
      办法是在每个交叉的地方设置“闸门”,也就是数据选择器,从而选择不同的通路。
      对于存储器,只要提供“是否写入"的信号就能间接确定是否走存储器这条通路。
      类似于这中闸门的还有许多,就像前面寄存器上面的A、B选择线、寄存器选择线、是否写入寄存器等。
      把所有的这些控制通路的信号汇集到一起,组合成一个二进制数,就可以通过一个二进制数来控制通路了,这就是控制字!


      IP属地:广东69楼2014-10-24 20:30
      收起回复
        通过控制字,可以决定在这个周期里面,用哪些寄存器做为待运算的数、是进行运算还是送入存储器、进行何种运算、是把运算结果还是存储器读出的值送入寄存器、送入哪个寄存器。
        通过确定以上的信号,就能确定CPU要做的事情了!这就是控制字的作用,而指令可以看做是控制字的压缩码!
        对于ADD R3,R2,R1,(即R3=R2+R1)这一条指令,实际CPU做的事情就是:
        在A通道选择R2输出,在B通道选择R1输出
        不选择立即数
        存储器不写入
        运算器选择加法运算
        选择运算器输出的结果
        选择R3作为待写入寄存器
        寄存器组写入信号激活
        时钟信号上升沿到来!
        R3的值成功变为R2+R1!


        IP属地:广东70楼2014-10-24 20:40
        回复
          这里是主要的控制字(其中标志位和跳转后面会讲)


          IP属地:广东71楼2014-10-24 20:50
          回复
            在上图中,可以对W/CI/RM/WM/SF/JP/JW进行编码,编码成000,001,010,011,100,这样只需要三个信号就能确定六个控制信号了,也就是这样:

            加上其他的信号,比如运算选择信号、寄存器选择信号、立即数,就是一个完整的指令格式了!

            至于怎么编码,需要用到组合逻辑分析的知识,如果实在觉得麻烦,也可以借助Logisim等工具自动生成
            这里是我设计的译码器:


            IP属地:广东73楼2014-10-24 21:05
            回复
              从上图可以看出,选择功能需要3bit,选择运算需要5bit,选择目标寄存器2bit,源寄存器A2bit,源寄存器B2bit,已经有14bit了,即使是16bit的指令,剩下的立即数和跳转方式几乎没有容身之地了,而加大指令长度又会造成浪费,这时可以采用复用技术,某些位在不同的情况下行使不同的功能。例如这里当寄存器与立即数运算时,B寄存器占用的资源复用作立即数,当跳转时,运算选择信号其中的S2、S1、S0复用作跳转方式,所有的寄存器选择信号复用为立即数。


              IP属地:广东74楼2014-10-24 21:10
              回复
                此外还有状态寄存器还没弄,状态寄存器本应放在寄存器里,这里为了方便,放入控制器。
                由于状态寄存器只用来做跳转依据,所以只有在JP为1时才能查看状态位确定是否进行跳转,这里需要一个与门和数据选择器,与门用来实现JP的总控制功能,数据选择器用来选择跳转方式。
                综合以上的程序计数器、状态寄存器、指令寄存器、指令译码器
                一个【完整的控制器】就构建完成了!


                IP属地:广东75楼2014-10-24 21:16
                回复
                  2025-08-21 10:44:22
                  广告
                  不感兴趣
                  开通SVIP免广告
                  有了【寄存器】、【运算器】、【控制器】,设计好了数据通路和指令集,就可以构建【CPU】了!
                  但是如果一大堆电路全部弄到一起的话,很容易弄乱的,所以需要把几个模块封装一下。
                  Logisim里封装还是很容易的。
                  运算器:

                  寄存器组:

                  控制器:


                  IP属地:广东79楼2014-10-25 16:57
                  回复
                    综合以上,就可以连接CPU的模块间线路了!
                    首先连接三个模块的通路(依照体系结构和数据通路):


                    IP属地:广东81楼2014-10-25 17:12
                    回复
                      然后添加时钟信号(需要注意时钟的顺序):


                      IP属地:广东82楼2014-10-25 17:14
                      回复
                        好啦,一个完整的【CPU】就构建完成了!


                        IP属地:广东83楼2014-10-25 17:15
                        回复
                          但是有了CPU还是不够的,还要有存储器才行,ROM和RAM的连接方式前面已经讲过,这里就不再赘述。
                          最终连出的就是这样子:

                          重启启动时钟,机器就能够根据ROM中的指令(初始地址为0)运行了!


                          IP属地:广东84楼2014-10-25 17:21
                          回复
                            【编译器开发】
                            虽然我们设计的CPU能够跑起来了,但是要让它运行指定的程序还是很困难的,因为程序都是二进制的机器码,这样编程效率太低了,也容易出错,所以我们需要一个能够直观、高效编程方法,那就是汇编。
                            编译器的开发需要有编译原理的知识,由于编译原理较为复杂,这里不再阐述。
                            这里我用Java写了个简单的汇编编译器,能够将汇编源代码转化成机器码。
                            这是一个求斐波那契数列并存入RAM的程序:

                            用编译器编译成的机器码(十六进制表示):


                            IP属地:广东85楼2014-10-25 17:34
                            收起回复
                              2025-08-21 10:38:22
                              广告
                              不感兴趣
                              开通SVIP免广告
                              把编译出来的机器码导入ROM中,运行计算机,在RAM中成功得到了斐波那契数列!


                              IP属地:广东86楼2014-10-25 17:38
                              回复