Verilog 16位CPU设计:实现fetch执行周期的问题

Verilog 16位CPU设计:实现fetch执行周期的问题,verilog,cpu-registers,nand2tetris,Verilog,Cpu Registers,Nand2tetris,我正在Coursera上一门叫 NandTotteris和我的16位CPU设计一直在苦苦挣扎。这个 这门课程使用一种叫做HDL的语言,这是一种非常简单的类似Verilog的语言 语言 我花了这么多时间试图迭代基于 下面的图表,我不明白我做错了什么。我 我尽了最大的努力来表示提取和执行机制。做 有人对如何解决这个问题有什么建议吗 以下是设计和控制语法图链接: CPU IO高级图: 门级CPU图: 控制指令语法: 下面是我的代码: // Put your code here:

我正在Coursera上一门叫 NandTotteris和我的16位CPU设计一直在苦苦挣扎。这个 这门课程使用一种叫做HDL的语言,这是一种非常简单的类似Verilog的语言 语言

我花了这么多时间试图迭代基于 下面的图表,我不明白我做错了什么。我 我尽了最大的努力来表示提取和执行机制。做 有人对如何解决这个问题有什么建议吗

以下是设计和控制语法图链接:

CPU IO高级图:

门级CPU图:

控制指令语法:

下面是我的代码:

    // Put your code here:

    // Instruction decoding:from i of “ixxaccccccdddjjj” 
    // Ainstruction: Instruction is 16-bit value of the constant that should be loaded into the A register
    // C-instruction: The a- and c-bits code comp part, d- and j-bits code dest and jump(x-bits are ignored). 
    Mux16(a=outM, b=instruction, sel=instruction[15], out=aMUX); // 0 for A-instruction or 1 for a C-instruction  
    Not(in=instruction[15], out=aInst); // assert A instruction with op-code as true 
    And(a=instruction[15], b=instruction[5], out=cInst); // assert wite-to-A-C-instruction with op code AND d1-bit
    Or(a=aInst, b=cInst, out=aMuxload); // assert Ainstruction or wite-to-A-C-instruction is true
    ARegister(in=aMUX, load=cInst, out=addressM); // load Ainstruction or wite-to-A-C-instruction 


    //  For C-instruction, a-bit determines if ALU will operate on A register input (0) vs M input (1)
    And(a=instruction[15], b=instruction[12], out=Aselector); // assert that c instruction AND a-bit 
    Mux16(a=addressM, b=inM, sel=Aselector, out=aluMUX); // select A=0 or A=1           
    ALU(x=DregisterOut, y=aluMUX, zx=instruction[11], nx=instruction[10], zy=instruction[9], ny=instruction[8], f=instruction[7], no=instruction[6], zr=zr, ng=ng,out=outM); 

    // The 3 d-bits of “ixxaccccccdddjjj” ALUout determine registers are destinations for for ALUout
    // Whenever there is a C-Instruction and d2 (bit 4) is a 1 the D register is loaded
    And(a=instruction[15], b=instruction[4], out=writeD); // assert that c instruction AND d2-bit
    DRegister(in=outM, load=writeD, out=DregisterOut); // d2 of d-bits for D register destination 

    // Whenever there is a C-Instruction and d3 (bit 3) is a 1 then writeM (aka RAM[A]) is true
    And(a=instruction[15], b=instruction[3], out=writeM); // assert that c instruction AND d3-bit  

    // Programe counter to fetch next instruction
    // PC logic: if (reset==1), then PC = 0
    //           else:
    //                load  = comparison(instruction jump bits, ALU output zr & ng)
    //                if load == 1, PC = A
    //                else: PC ++   
    And(a=instruction[2], b=ng, out=JLT); // J2 test against ng: out < 0
    And(a=instruction[1], b=zr, out=JEQ); // J1 test against zr: out = 0
    Or(a=ng, b=zr, out=JGToutMnot)); // J0 test if ng and zr are both zero
    Not(in=JGToutMnot, out=JGToutM; // J0 test if ng and zr are both zero
    And(a=instruction[0], b=JGToutM, out=JGT);
    Or(a=JLT, b=JEQ, out=JLE); // out <= 0  
    Or(a=JGT, b=JLE, out=JMP); // final jump assertion
    And(a=instruction[15], b=JMP, out=PCload); // C instruction AND JMP assert to get the PC load bit
    // load in all values into the programme counter if load and reset, otherwise continue increasing
    PC(in=addressM, load=PCload, inc=true, reset=reset, out=pc);     

回答这类问题而不为你做工作是很棘手的,从长远来看,这对你没有帮助

一些一般性的想法

孤立地考虑每个元素,包括信号汇集的圆圈

用名称标记元素之间的每一行。这些将成为内部控制线。这有助于减少混乱的机会

对垃圾输出要非常小心。如果不希望将有效数据放在outM上,请使用Mux输出false

潜在问题:我似乎记得,使用outM这样的设计输出作为其他东西的输入是个坏主意。输出应仅为输出。现在,您正在将ALU的输出发送到outM,并使用outM作为其他元素的输入。我建议您尝试将ALU输出到一个新的信号ALOUT,并将其用作其他元素的输入,并通过一个由writeM outM控制的带false的mux。但请记住,writeM是一个输出!因此,生成writeM的块需要生成自身的副本,以用作mux的控件。幸运的是,一个块可以有多个out语句

例如,现在您正在生成这样的outM我不会评论它是否错误,我只是用它作为一个例子:

And(a=instruction[15], b=instruction[3], out=writeM); 
您可以创建第二个输出,如下所示:

And(a=instruction[15], b=instruction[3], out=writeM, out=writeM2)
Mux16(a=false,b=ALUout,sel=writeM2,out=outM);
然后像这样清洁你的身体:

And(a=instruction[15], b=instruction[3], out=writeM, out=writeM2)
Mux16(a=false,b=ALUout,sel=writeM2,out=outM);

祝你好运

非常感谢你。我应该为CPU设计指定输入、输出API,这会使您更容易理解芯片中的所有输出。事实证明,最大的问题是A寄存器最终输出应该是15位而不是16位,而馈送到第二个Mux的A寄存器输出在16位是正确的。A寄存器输出的总线大小基本不匹配,程序计数器PC的总线大小也不匹配:。