数电课程模型机CPU设计:译码器和ALU(Verilog实现)
本文最后更新于 215 天前,其中的信息可能已经有所发展或是发生改变。

译码器

译码器的指令系统表如下图所示。

指令系统表

译码器做起来其实不难,当编码符合要求的时候,把相应的汇编符号输出设为1就行了。

R1、R2代表操作寄存器的地址,可以为A、B或C寄存器中的任何一个,地址分别为00、01和10。

所谓”符合要求“,可以举个例子。比如NOT的编码是0101 R1XX,R1代表寄存器1的地址,XX是通配符,所以可以做匹配IR[7-:4]==4'b0101,而且应为寄存器地址的地方不能是11。(话说也没多少人会在这个位置传进11吧……除了喜欢点一杯炒饭的测试工程师)

特别注意的是,有三种MOV指令。这里定义第一种MOV指令为MOVA,第二种为MOVB,第三种为MOVC。我先使用1100匹配进MOV,然后再区分MOVA、MOVB和MOVC。

module decoder (EN,IR,MOVA,MOVB,MOVC,ADD,SUB,AND,NOT,RSR,RSL,JMP,JZ,JC,IN,OUT,NOP,HALT);
    input EN;
    input[7:0] IR;
    output MOVA,MOVB,MOVC,ADD,SUB,AND,NOT,RSR,RSL,JMP,JZ,JC,IN,OUT,NOP,HALT;
    reg MOVA,MOVB,MOVC,ADD,SUB,AND,NOT,RSR,RSL,JMP,JZ,JC,IN,OUT,NOP,HALT;
always @(IR,EN) begin
    if(EN==1'b1) begin
        if (IR[7-:4]==4'b1100) begin //MOV
            if(IR[3-:2]==2'b11) begin //MOVB 11R2
                MOVA=1'b1;
                MOVB=1'b0;
                MOVC=1'b0;
            end
            else if (IR[1-:2]==2'b11) begin //MOVC R1111
                MOVA=1'b0;
                MOVB=1'b0;
                MOVC=1'b1;
            end
            else begin //MOVA R1R2
                MOVA=1'b1;
                MOVB=1'b0;
                MOVC=1'b0;
            end
        end
        else begin
            MOVA=1'b0;
            MOVB=1'b0;
            MOVC=1'b0;
        end
        if (IR[7-:4]==4'b1001 && IR[3-:2]!=2'b11 && IR[1-:2]!=2'b11) begin //ADD
            ADD=1'b1;
        end
        else ADD=1'b0;
        if (IR[7-:4]==4'b0110 && IR[3-:2]!=2'b11 && IR[1-:2]!=2'b11) begin //SUB
            SUB=1'b1;
        end
        else SUB=1'b0;
        if (IR[7-:4]==4'b1011 && IR[3-:2]!=2'b11 && IR[1-:2]!=2'b11) begin //AND
            AND=1'b1;
        end
        else AND=1'b0;
        if (IR[7-:4]==4'b0101 && IR[3-:2]!=2'b11) begin //NOT
            NOT=1'b1;
        end
        else NOT=1'b0;
        if (IR[7-:4]==4'b1010 && IR[1-:2]==2'b00 && IR[3-:2]!=2'b11) begin //RSR
            RSR=1'b1;
        end
        else RSR=1'b0;
        if (IR[7-:4]==4'b1010 && IR[1-:2]==2'b11 && IR[3-:2]!=2'b11) begin //RSL
            RSL=1'b1;
        end
        else RSL=1'b0;
        if (IR[7:0]==8'b0011_0000) begin //JMP
            JMP=1'b1;
        end
        else JMP=1'b0;
        if (IR[7:0]==8'b0011_0001) begin //JZ
            JZ=1'b1;
        end
        else JZ=1'b0;
        if (IR[7:0]==8'b0011_0010) begin //JC
            JC=1'b1;
        end
        else JC=1'b0;
        if (IR[7-:4]==4'b0010 && IR[3-:2]!=2'b11) begin //IN
            IN=1'b1;
        end
        else IN=1'b0;
        if (IR[7-:4]==4'b0100 && IR[3-:2]!=2'b11) begin //OUT
            OUT=1'b1;
        end
        else OUT=1'b0;
        if (IR[7:0]==8'b0111_0000) begin //NOP
            NOP=1'b1;
        end
        else NOP=1'b0;
        if (IR[7:0]==8'b1000_0000) begin //HALT
            HALT=1'b1;
        end
        else HALT=1'b0;
    end
    else begin
        MOVA=1'b0;
        MOVB=1'b0;
        MOVC=1'b0;
        ADD=1'b0;
        SUB=1'b0;
        AND=1'b0;
        NOT=1'b0;
        RSR=1'b0;
        RSL=1'b0;
        JMP=1'b0;
        JZ=1'b0;
        JC=1'b0;
        IN=1'b0;
        OUT=1'b0;
        NOP=1'b0;
        HALT=1'b0;
    end

end

endmodule //decoder
      

ALU

我之前想复杂了,完全不需要设计RCA,因为Cf指的是最高位的进位或借位(即溢出),而不是逐位取进位或借位,所以可以直接使用拼接解决。怪不得从网上找了一堆资料没发现如何找借位

ALU引脚关系

这样就没有之前那么难了,把ppt里的东西直接翻译出来就行了, 源代码如下。

module ALU2 (M,S,A,B,t,Cf,Zf);
    input M;//算术运算指示
    input [3:0] S;//运算类型
    input [7:0] A,B;//参与运算的数字

    output [7:0] t;//输出结果
    output Cf,Zf;//是否进位,是否为0

    reg [7:0] t;
    reg Cf,Zf;
    reg [7:0] temp1;

    always @(M,S,A,B) begin
        if (M==1'b0) begin //不进行算术运算
            if(S==4'b1100) t[7:0]=A[7:0];
            else t=8'b0;
            Cf=1'b0;
            Zf=1'b0;
        end
        else begin//进行算术运算
            case (S)
                4'b1001: begin //ADD
                    {Cf,t}=A+B;
                    if (t==8'b0) begin
                        Zf=1'b1;
                    end
                    else Zf=1'b0;
                end
                4'b0110: begin //SUB
                    {Cf,t}=B-A;
                    if(t==8'b0) Zf=1'b1;
                    else Zf=1'b0;
                end
                4'b1011: begin //AND
                    // t=A&&B;
                    t[0]=A[0]&&B[0];
                    t[1]=A[1]&&B[1];
                    t[2]=A[2]&&B[2];
                    t[3]=A[3]&&B[3];
                    t[4]=A[4]&&B[4];
                    t[5]=A[5]&&B[5];
                    t[6]=A[6]&&B[6];
                    t[7]=A[7]&&B[7];
                    Cf=0;
                    Zf=0;
                end
                4'b0101: begin
                    t=~B; //NOT
                    Cf=0;
                    Zf=0;
                end
                4'b1010: begin
                    t=B;
                    Cf=0;
                    Zf=0;
                end
                4'b0100: begin
                    t=B;
                    Cf=0;
                    Zf=0;
                end
                4'b1100: begin
                    t=A;
                    Cf=0;
                    Zf=0;
                end
                default: begin
                    Cf=0;
                    Zf=0;
                    t=8'b0;
                end
            endcase
        end
    end
endmodule //ALU2

本文代码仿真所使用的波形文件可从此处获取,使用Quartus II 13.0 SP1生成。2021/12/06已更新本人验收用波形,数据较多。

CC BY-SA

This content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International license. 本文虽使用CC BY-SA 4.0进行授权,但原则上不建议您将代码copy去直接交作业。

评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇