数电课程模型机设计:多路开关、移位逻辑和控制信号产生逻辑(Verilog实现)
本文最后更新于 209 天前,其中的信息可能已经有所发展或是发生改变。

以下代码虽经本人检查,但仅移位逻辑经过仔细验收,仅供参考

多路开关

多路开关做起来还是很简单的,一个case语句就能搞定。记得加default,防止生成锁存器。

module mux (MADD,A,B,C,OUT);
    input[1:0] MADD;
    input[7:0] A,B,C;
    output[7:0] OUT;

    reg[7:0] OUT;

    always @(MADD,A,B,C) begin
        case (MADD) 
            2'b00: OUT=A;
            2'b01: OUT=B;
            2'b10: OUT=C;
            default: OUT=8'b0;
        endcase
    end
endmodule //mux

移位逻辑

这个应该也不算很难。我将输入的三个FBUS、FLBUS和FRBUS合成一个BUS,这样用case语句一起处理或许优雅一些(?)

可以参考下面这张图进行设计。其他情况直接全输出高阻,不用管别的,以防多路输出冲突。

移位逻辑引脚关系
module Shift_Register (F_BUS,FL_BUS,FR_BUS,a,W,Cf);
    input F_BUS,FL_BUS,FR_BUS;
    input[7:0] a;
    output[7:0] W;
    output Cf;
    
    reg[7:0] W;
    reg Cf;

    wire[2:0] BUS;
    
    assign BUS = {F_BUS,FL_BUS,FR_BUS};
    
    always @(BUS) begin
        case (BUS)
            3'b100: begin
                W = a;
                Cf = 0;
            end
            3'b010: begin
                W  = {a[6:0],a[7]};
                Cf = a[7];
            end
            3'b001: begin
                W  = {a[0],a[7:1]};
                Cf = a[0];
            end
            default: begin
                W = 8'bZZZZZZZZ;
                Cf = 0;
            end
        endcase
    end
endmodule //Shift_Register

控制信号产生逻辑

正常来说,如果希望用直接assign这种比较优雅的写法,你需要逐个摸清控制命令的运行模式,即每种IR对应的各个控制信号的值,列个表,然后找每个控制信号在什么命令输入的时候值为1。

要不然,就用一堆条件语句,只是省掉了反查的过程,还是得分析,也不优雅。

但是,老师把这个表已经列出来了,省下了大把的时间:

控制信号产生逻辑引脚关系

我们只需查找每一列输出信号对应的输入信号就行了。规定的信号针脚和表中的控制信号可能有所不同,可以参阅下面的源代码,我在注释中写了一些对应关系。

但是请注意,这里并没有包含所有的指令,比如INPUT。

空白的区域不清楚怎么搞,但我是在这部分输出了0。JZ/JC(T)指的是JZ&&Z或JC&&C,这两种输出是等效的,虽然判断条件看起来不同;相对的,JZ/JC(F)就是JZ&&(~Z)或JC&&(~C)。

源代码如下,部分难以使用几个输入或表示的,我才会使用always语句。

后面整合的时候会知道,MOVB和MOVC的时候,要指定内存地址,需要将C寄存器中的数值输出,所以REG_RA(RAA)的always块中,不能因为MOVB中有一个固定的11就不作为条件;相反,为了将C忠实地输出,需要将三个MOV全都加进去;REG_WA(RWBA)也一样。

此外,上表没有包含NOP的指令输出,经测试只需要REG_WE=1即禁止读写即可,防止总线上数据污染寄存器。

module control_signal (MOVA,MOVB,MOVC,ADD,SUB,AND1,NOT1,RSR,RSL,JMP,JZ,Z,JC,C,IN1,OUT1,NOP,HALT,IR,SM,REG_RA,REG_WA,MADD,ALU_S,PC_LD,PC_INC,REG_WE,RAM_XL,RAM_DL,ALU_M,SHI_FBUS,SHI_FLBUS,SHI_FRBUS,IR_LD,CF_EN,ZF_EN,SM_EN,IN_EN,OUT_EN);
    input MOVA,MOVB,MOVC,ADD,SUB,AND1,NOT1,RSR,RSL,JMP,JZ,Z,JC,C,IN1,OUT1,NOP,HALT,SM;
    //    MOVA,MOVB,MOVC,ADD,SUB,AND, NOT, RSR,RSL,JMP,JZ-T,JC-T,IN, OUT, NOP,HALT,SM
    input[7:0] IR;
    output[1:0] REG_RA,REG_WA,MADD;
    //          RAA,   RWBA,  MADD
    output[3:0] ALU_S;
    //          S
    output PC_LD,PC_INC,REG_WE,RAM_XL,RAM_DL,ALU_M,SHI_FBUS,SHI_FLBUS,SHI_FRBUS,IR_LD,CF_EN,ZF_EN,SM_EN,IN_EN,OUT_EN;
    //     LD PC,IN PC, /WE,   XL,    DL,    M,    F-BUS,   FL-BUS,   FR-BUS,   LD IR,            SM,

    reg[1:0] MADD,REG_RA,REG_WA;
    reg[3:0] ALU_S;
    
    assign RAM_DL = (~SM)||MOVC||JMP||(JZ&&Z)||(JC&&C); //取指,MOVC,JMP,JZT,JCT
    assign RAM_XL = MOVB&&(~SM); //MOVB
    assign PC_LD = JMP||(JZ&&Z)||(JC&&C); //JMP,JZT,JCT
    assign PC_INC = (~SM)||(JZ&&~Z)||(JC&&~C); //取指,JZF,JCF
    assign IR_LD = (~SM); //取指
    assign SHI_FBUS = ADD||SUB||AND1||NOT1||OUT1||MOVA||MOVB; //ADD,SUB,AND,NOT,OUT,MOVA,MOVB
    assign SHI_FLBUS = RSL; //RSL
    assign SHI_FRBUS = RSR; //RSR
    assign ALU_M = ADD||SUB||AND1||NOT1||RSR||RSL||OUT1;
    assign REG_WE = (~SM)||OUT1||MOVB||JMP||JZ||JC||HALT||NOP;
    assign CF_EN = ADD||SUB||RSR||RSL;
    assign ZF_EN = ADD||SUB;
    assign SM_EN = ~HALT;
    assign IN_EN = IN1;
    assign OUT_EN = OUT1;
    
    always @(SM,MOVB,MOVC) begin //MADD
        if(~SM) MADD=2'b0;
        else if(MOVB) MADD=2'b10;
        else if(MOVC) MADD=2'b01;
        else MADD=2'b0; //不锁存只能这样了吧?
    end

    always @(ADD,SUB,AND1,NOT1,RSR,RSL,OUT1,MOVA,MOVB) begin //ALU_S
        if(ADD||SUB||AND1||NOT1||RSR||RSL||OUT1||MOVA||MOVB) ALU_S[3:0]=IR[7-:4];
        else ALU_S=4'b0;
    end

    always @(ADD,SUB,AND1,MOVA,MOVB,MOVC) begin //RAA
        if(ADD||SUB||AND1||MOVA||MOVB||MOVC) REG_RA=IR[1-:2];
        else REG_RA=2'b0;
    end

    always @(ADD,SUB,AND1,NOT1,RSR,RSL,IN1,OUT1,MOVA,MOVB,MOVC) begin//RWBA
        if(ADD||SUB||AND1||NOT1||RSR||RSL||IN1||OUT1||MOVA||MOVB||MOVC) REG_WA=IR[3-:2];
        else REG_WA=2'b0;
    end
    
endmodule

照例,下面提供三个部件仿真时使用的波形文件,使用Quartus Prime 21.1生成:下载链接

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
小恐龙
花!
上一篇
下一篇