数字逻辑课程设计,简单的8位模型计算机verilog设计

0、摘要

       ~~~~~~        本设计将自顶向下地进行模型计算机设计,完成了系统设计、功能模块设计和仿真、系统设计与仿真,实现了功能模块和系统的下载和调试。加深了对“数字逻辑与数字系统”知识的理解,强化了理论知识,掌握了的实践和应用。

       ~~~~~~        在Vivado 2018.3环境下,采用Verilog语言构建算术逻辑运算单元、累加器、控制器、地址寄存器、程序计数器、数据寄存器、存储器、存储器选择器、节拍发生器、时钟信号源、指令寄存器、指令译码器和数码管显示器等功能模块,以及8位模型计算机系统。在ModelSim仿真环境下,完成功能模块,以及模型系统仿真。

        ~~~~~~~        功能模块主要有:节拍产生器、控制器、算术逻辑运算单元ALU、累加器ACC、地址寄存器MAR、程序计数器PC、数据寄存器DR、存储器ROM、时钟信号源、指令寄存器IR、数码管显示译码器等。

        ~~~~~~~        在满足基本要求的前提下,进行了进一步的功能扩充,实现了对累加器中寄存器的拓展,利用存储器ROM实现了对指令的拓展。对指令集做到了与、或操作。

1、绪论

1.1 模型计算机简介

       ~~~~~~       为了更好地理解数字逻辑与数字系统课程的基础知识,进一步学习计算机的基本结构和原理。在本次课程设计中,选择了“模型计算机设计与实现”题目。

       ~~~~~~       模型计算机是以实际的计算机结构为基础,对其进行抽象和简化,使之具备计算机的基本结构和功能,可以对数据或指令进行处理和执行。

       ~~~~~~       模型计算机有以下模块:CPU、存储单元、输入和输出、以及总线。具体有节拍产生器、控制器、算术逻辑运算单元ALU、累加器ACC、地址寄存器MAR、程序计数器PC、数据寄存器DR、存储器ROM、时钟信号源、指令寄存器IR,使模型机系统具有演示性和操作性。

       ~~~~~~       CPU模块的核心器件是控制器,可实现读操作指令、加法操作指令、减法操作指令、与操作指令、或操作指令、停机操作指令,有地址寄存信号IMAR、数据寄存输出信号IDR、数据寄存输出信号EDR、累加器的输入信号IA、累加器的输出信号EA、ALU的加法运算信号ISUM、ALU的减法运算信号ISUB、ALU的与法运算信号IAND、ALU的或法运算信号IOR、ALU的输出信号EALU、指令寄存的寄存信号IIR,由8个时序节拍构成时序发生器。

       ~~~~~~       为了进一步提高自己的能力,增强自己的水平,设计并实现的具有特色功能如下:

(1) 丰富了指令,在5条指令基础上,拓展为2条指令,实现了与、或指令;

(2) 拓展了存储器的容量,从5×8拓展到11X8;

(3) 对算术逻辑单元功能进行了扩展,实现了加、减、与、或;

1.2 设计主要内容

1.2.1 设计指标

       ~~~~~~       本模型计算机具备以下功能模块及参数指标。

(1) 存储器模块、CPU模块、外设输入模块和输出模块;

(2) 地址总线(4条),数据总线(8位),控制总线(12条);

(3) 指令集:读指令、加运算、减运算、与运算、或运算、停机指令,共计6条;

(4) 存储器容量为11×8位;

(5) 芯片主时钟频率为100MHz,节拍器输入时钟4HZ;

(6) 输入方式:modelsim仿真显示、quartus逻辑分析仪;

(7) 输出方式:4位数码管显示总线值,14个LED灯分别显示8个节拍信号以及6个指令信号。

1.2.2 设计思路

  1. 模块化设计

       ~~~~~~       (1) 根据确立的设计指标,对各个模块进行单独设计和仿真,对该模块可能涉及的作用和功能有清晰地认识,同时需要注意各模块协同工作时的时序关系和控制信号;

       ~~~~~~       (2) 模块设计的方式可以更为多样化,以Verilog语言编程为主、电路原理图设计和状态转换图设计等方式为辅,尽可能多地熟悉Vivado 2018.3软件的使用方法和功能;

       ~~~~~~       (3) 自顶向下,逐层设计。对各模块的设计应从顶层的应用/功能入手,分解其在执行指令中选通信号的控制情况和模块工作的先后情况,对可能出现的问题要及早发现及早改正,以免后续综合时,对系统产生不确定性影响。

  1. 顶层设计与描述

       ~~~~~~       当功能模块设计完成后,根据模型机的结构,将各元器件用总线和控制线连接起来,连接的顺序由小及大、由内到外;每连完一个模块就测试一个模块,确保模块内部可以正常工作。

  1. 仿真

       ~~~~~~       在设计过程中,及时对小的模块进行仿真验证,通过才能继续设计。若只在最后进行仿真验证,则对于出现的问题将可能很难发现或解决,从而增大了程序调试的任务量,影响了课程设计的进度。仿真工具使用ModelSim,编写Verilog测试文件。

  1. 下载和调试
      ~  功能模块ModelSim仿真成功后,通过quartus的逻辑分析仪进行功能模块调试。

2、系统设计

2.1模型计算机原理

       ~~~~~~       所谓模型计算机就是以计算机实际结构为基础,将其简化,能对输入的信息进行处理运算,更便于分析设计。

       ~~~~~~       计算机主要由运算器、控制器、存储器、输入设备、输出设备五大部分组成。计算机能按照用户要求、完成提前设计好的指令,指令是计算机执行具体操作的命令。一条指令就是机器语言的一个语句,用来说明机器硬件要完成什么样的基本操作。

       ~~~~~~       在设计整体结构时,依据的是各指令的数据通路。然后采用自顶向下,逐步分解细化的方法进行设计。先整体模块,后局部模块。

       ~~~~~~       在本设计中,把模型计算机划分成十余个基本模块,分别是存储器、时钟信号源、节拍发生器、操作控制器、程序计数器、地址寄存器、累加器、算术逻辑单元、指令寄存器和指令译码器和存储器选择器。

       ~~~~~~       让预设指令在这些部件中按顺序执行达到预期目的。计算机执行一条指令分为三步进行:

       ~~~~~~       第1步是取指令,将要执行的指令从内存取到控制器中;

       ~~~~~~       第2步是分析指令,对所取的指令通过译码器进行分析判断,判断该指令要完成的操作;

       ~~~~~~       第3步是执行指令,根据分析结果向各部件发出操作信息,执行该指令相应的操作功能。

2.2 模型计算机组成

       ~~~~~~       在设计整体结构时,依据的是各指令的数据通路。然后采用自顶向下,逐步分解细化的方法进行设计。先整体模块,后局部模块。

       ~~~~~~       从整体上看,模型计算机主要分为:CPU模块、外设输入模块、外设输出模块、存储模块。模型计算机结构框图如图2.1所示,具体模块有:节拍发生器模块、指令寄存器模块IR、算术逻辑单元模块ALU、数据寄存器模块DR、程序计数器模块PC、地址寄存器模块MAR、操作控制器模块等。

在这里插入图片描述

                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                         图2-2-1 模型计算机结构框图

2.3 模型计算机的指令系统设计

       ~~~~~~       在模型计算机中,指令用于验证模型机能否正常工作。该模型机所实现的指令如表2-2-1所示。

表2-2-1 模型机指令

指令码指令内容
00111110LD AX,1将存储器中的数据送入寄存器AX
11000110ADD AX,6将存储器的数送入AX相加并存储
10000110SUB AX,3将存储器的数送入AX相减并存储
00100110AND AX,0将存储器的数送入AX相与并存储
01111100OR AX,4将存储器的数送入AX相或并存储
01110110HALT停机指令

       ~~~~~~       对于指令系统的设计,为了方便描述,以“LD AX,1” , “ADD AX,6”,“HALT”为例,具体如下:

MOV AX 1;AX←1,把1送入寄存器AX,操作码是00111110;

ADD AX,6;AX←AX+6,把AX中1与6相加,结果送入寄存器AX,操作码是11000110;

HALT;运算完毕,停机,操作码是00001110。

       ~~~~~~       根据模型计算机的结构框图,可设计指令系统中每条指令的执行流程。一条指令从存储器中取出到执行完,需要若干个机器周期,任何指令的第一个机器周期都是“取指令周期”,一条指令一共需要几个机器周期,取决于指令在机内实现的复杂程度。

本模型计算机指令流程如下:

MOV AX,12
T0:(PC)→MAR→ABUS,IMAR=0
T1:DBUS→DR,IDR=1
T2:(PC)+1→PC,IPC=1
(DR)→IR,IIR=0,LD=1
T3:(PC)→MAR→ABUS,IMAR=0
T4:DBUS→DR,IDR=1
T5:(PC)+1→PC,IPC=1
T6:DBUS→A, IA=0
T7:空

ADD AX,6

T0:(PC)→MAR→ABUS,IMAR=0
T1:DBUS→DR,IDR=1
T2:(PC)+1→PC,IPC=1
    (DR)→IR    IIR=0 ADD=1
T3:(PC)→MAR→ABUS,IMAR=0
T4:DBUS→DR,IDR=1
T5:(PC)+1→PC,IPC=1
    A+6->SR   ISUM=0
T6:DBUS→A     IA=0   EDR=1
T7:空

SUB AX,3
T0:(PC)→MAR→ABUS,IMAR=0
T1:DBUS→DR,IDR=1
T2:(PC)+1→PC,IPC=1
    (DR)→IR    IIR=0 SUB=1
T3:(PC)→MAR→ABUS,IMAR=0
T4:DBUS→DR,IDR=1
T5:(PC)+1→PC,IPC=1
    A-3->SR   ISUB=0
T6:DBUS→A     IA=0   EDR=1
T7:空

AND A,0

T0:(PC)→MAR→ABUS,IMAR=0
T1:DBUS→DR,IDR=1
T2:(PC)+1→PC,IPC=1
    (DR)→IR    IIR=0 AND=1
T3:(PC)→MAR→ABUS,IMAR=0
T4:DBUS→DR,IDR=1
T5:(PC)+1→PC,IPC=1
    A&0->SR   IAND=0
T6:DBUS→A     IA=0   EDR=1
T7:空

OR A,4

T0:(PC)→MAR→ABUS,IMAR=0
T1:DBUS→DR,IDR=1
T2:(PC)+1→PC,IPC=1
    (DR)→IR    IIR=0 OR=1
T3:(PC)→MAR→ABUS,IMAR=0
T4:DBUS→DR,IDR=1
T5:(PC)+1→PC,IPC=1
    A|4->SR   IOR=0
T6:DBUS→A     IA=0   EDR=1
T7:空

HALT

T0:(PC)→MAR→ABUS,IMAR=0
T1:DBUS→DR,IDR=1
T2:(PC)+1→PC,IPC=1
    (DR)→IR    IIR=0 AND=1
T3:(PC)→MAR→ABUS,IMAR=0
T4:DBUS→DR,IDR=1
T5:(PC)+1→PC,IPC=1
    DR->SR   HALT=1
T6:空
T7: 空

通过节拍设计可得控制器的指令设计为:

IMAR = T 0 + T 3 ∗ L D + T 3 ∗ A D D + T 3 ∗ S U B + T 3 ∗ A N D + T 3 ∗ O R ‾ \overline{T0+T3*LD+T3*ADD+T3*SUB+T3*AND+T3*OR} T0+T3LD+T3ADD+T3SUB+T3AND+T3OR

IDR = T 1 + T 4 ∗ L D + T 4 ∗ A D D + T 4 ∗ S U B + T 4 ∗ A N D + T 4 ∗ O R {T1+T4*LD+T4*ADD+T4*SUB+T4*AND+T4*OR} T1+T4LD+T4ADD+T4SUB+T4AND+T4OR

IPC = T 2 + T 5 ∗ L D + T 5 ∗ A D D + T 5 ∗ S U B + T 5 ∗ A N D + T 5 ∗ O R {T2+T5*LD+T5*ADD+T5*SUB+T5*AND+T5*OR} T2+T5LD+T5ADD+T5SUB+T5AND+T5OR

IIR = T 2 ‾ \overline{T2} T2

ISUB = T 5 ∗ S U B ‾ \overline{T5*SUB} T5SUB

IADD = T 5 ∗ A D D ‾ \overline{T5*ADD} T5ADD

IAND = T 5 ∗ A N D ‾ \overline{T5*AND} T5AND

IOR = T 5 ∗ O R ‾ \overline{T5*OR} T5OR

IA = T 6 ∗ L D + T 6 ∗ A D D + T 6 ∗ S U B + T 6 ∗ A N D + T 6 ∗ O R ‾ \overline{T6*LD+T6*ADD+T6*SUB+T6*AND+T6*OR} T6LD+T6ADD+T6SUB+T6AND+T6OR

EALU = T 6 ∗ A D D + T 6 ∗ S U B + T 6 ∗ A N D + T 6 ∗ O R ‾ \overline{T6*ADD+T6*SUB+T6*AND+T6*OR} T6ADD+T6SUB+T6AND+T6OR

EA = T 7 ∗ A D D + T 7 ∗ S U B + T 7 ∗ A N D + T 7 ∗ O R ‾ \overline{T7*ADD+T7*SUB+T7*AND+T7*OR} T7ADD+T7SUB+T7AND+T7OR

EDR = T 6 ∗ A D D + T 6 ∗ S U B + T 6 ∗ A N D + T 6 ∗ O R + T 7 ∗ A D D + T 7 ∗ S U B + T 7 ∗ A N D + T 7 ∗ O R {T6*ADD+T6*SUB+T6*AND+T6*OR+T7*ADD+T7*SUB+T7*AND+T7*OR} T6ADD+T6SUB+T6AND+T6OR+T7ADD+T7SUB+T7AND+T7OR

在这里插入图片描述

3、功能模块设计与仿真

3.1节拍发生器

       ~~~~~~       节拍发生器用于产生八个节拍脉冲信号T0~T7,以便控制计算机按固定节拍有序地工作。节拍发生器是一个环形移位寄存器,产生的波形如图3-1-1所示。当CLR=0时,将初始节拍置00000001,检测到时钟信号的上升沿时,变换到下一个节拍,即将节拍循环右移,以实现特定的功能。
在这里插入图片描述

                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                              图3-1-1 节拍发生器脉冲波形图

3.1.1节拍发生器的Verilog设计

       ~~~~~~       节拍发生器可以用8个D触发器组成移位寄存器,初始值为00000001。编译成功后节拍发生器的RTL如图3-1-2所示。

//D触发器的Verilog代码如下:
//8个D触发器构成的节拍器
`timescale 1ns / 10ps
module pulse(
input wire CLK,
input wire start,
output wire [7:0] T
);
//功能定义
reg DF0,DF1,DF2,DF3,DF4,DF5,DF6,DF7;
assign T = {DF7,DF6,DF5,DF4,DF3,DF2,DF1,DF0};
always@(posedge CLK or negedge start)
begin
if (!start) begin
 DF0 <= 1; DF1 <= 0; DF2 <= 0; DF3 <= 0;
 DF4 <= 0; DF5 <= 0; DF6 <= 0; DF7 <= 0;
 end
 else begin
 DF0 <= DF7; DF1 <= DF0; DF2 <= DF1; DF3 <= DF2;
 DF4 <= DF3; DF5 <= DF4; DF6 <= DF5; DF7 <= DF6;
 end
end
endmodule

在这里插入图片描述

                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                  图3-1-2 节拍发生器的RTL图

3.1.2 节拍发生器仿真

       ~~~~~~       要用ModelSim实现图3-1-1节拍发生器脉冲波形图,编写的测试文件,运行结果如图3-1-3。节拍发生器ModelSim仿真的Verilog代码如下。

//-----pulse_tb.v
module pulse_tb;
reg clk,start;
wire [7:0] T;
pulse pulse(
        .CLK(clk),
        .start(start),
        .T(T)
);

initial begin
        clk<=0;start<=0;
    #17 start<=1;
    #5000 $stop;
end
always #5 clk<=~clk;
endmodule

       ~~~~~~       由波形图3-1-3可知,时钟信号CLK周期设为40ns,前20ns设为低电平,后20ns为高电平,之后循环。CLR信号在5-10ns设为低电平,T0~T7初始值为00000001。在8个CLK周期,完成一个节拍器循环。
在这里插入图片描述

图3-1-3 节拍发生器的ModelSim仿真结果

3.1.3 节拍发生器调试

       ~~~~~~       在下载调试前,首先需要配置输入和输出管脚。FPGA开发板所用管脚见表3-1-1,管脚配置结果见图3-1-4,下载运行后的调试结果见图3-1-5。由于采用100MHz时钟,T0~T7使数码管的8个LED始终亮。

表3-1-1 FPGA开发板管脚

名称PIN备注
CLKE3系统时钟100MHz
startJ15系统复位按下低电平
T[0]H17T[0]的LED灯
T[1]K15T[1]的LED灯
T[2]J13T[2]的LED灯
T[3]N14T[3]的LED灯
T[4]R18T[4]的LED灯
T[5]V17T[5]的LED灯
T[6]U17T[6]的LED灯
T[7]U16T[7]的LED灯

图3-1-4 节拍发生器管脚配置Pin Planner 图3-1-5 节拍发生器调试
在这里插入图片描述

3.2、操作控制器

       ~~~~~~       操作控制器用于产生地址寄存信号IMAR、数据寄存输出信号IDR、数据寄存输出信号EDR、累加器的输入信号IA、累加器的输出吸纳后EA、ALU的加法运算信号ISUM、ALU的减法运算信号ISUB、ALU的与法运算信号IAND、ALU的或法运算信号IOR、ALU的输出信号EALU、指令寄存的寄存信号IIR,以便其他器件能正常工作。产生的波形如图3-2-1所示。
在这里插入图片描述
                       ~~~~~~~~~~~~~~~~~~~~~~                        图3-2-1控制器的波形图

3.2.1 操作控制器的Verilog设计

       ~~~~~~       操作控制器是用8个节拍信号、LD信号、ADD信号、SUB信号、AND信号、OR信号、HALT信号组成,编译成功后的RTL如图3-2-2所示。

//操作控制器的Verilog代码:
`timescale 1ns / 10ps
module control(
input wire LD,
input wire ADD,
input wire SUB,
input wire AND,
input wire OR,
input wire HALT,
//input wire CLK,
input wire [7:0]T,
output wire IMAR,
output wire IDR,
output wire IPC,
output wire IIR,
output wire ISUB,
output wire IADD,
output wire IAND,
output wire IOR,
output wire IA,
output wire EALU,
output wire EA,
output wire EDR);

//always @(*)begin
//    if(HALT==1'b1)begin
//        IPC <= 1'b0;
//        EALU <= 1'b0;
//    end
//    else begin
assign        IMAR = ~(T[0] | (T[3] & LD) | (T[3] & ADD) | (T[3] & SUB) | (T[3] & AND) | (T[3] & OR));
assign        IDR = T[1] | (T[4] & LD) | (T[4] & ADD) | (T[4] & SUB) | (T[4] & AND) | (T[4] & OR);
assign        IPC = T[2] + (T[5] & LD) + (T[5] & ADD) + (T[5] & SUB) + (T[5] & AND) + (T[5] & OR);
assign        IIR = ~T[2];
assign        ISUB = ~(T[5] & SUB);
assign        IADD = ~(T[5] & ADD);
assign        IAND = ~(T[5] & AND);
assign        IOR = ~(T[5] & OR);
assign        IA = ~((T[6] & LD) | (T[6] & ADD) | (T[6] & SUB) | (T[6] & AND) | (T[6] & OR));
assign        EALU = ~((T[6] & ADD) | (T[6] & SUB) | (T[6] & AND) | (T[6] & OR));
assign        EA = ~((T[7] & ADD) | (T[7] & SUB) | (T[7] & AND) | (T[7] & OR));
assign        EDR = ((T[6] & ADD) | (T[6] & SUB) | (T[6] & AND) | (T[6] & OR) | (T[7] & ADD) | (T[7] & SUB) | (T[7] & AND) | (T[7] & OR));
//    end
//end
endmodule

操作控制器的RTL可视图:
在这里插入图片描述

                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~                              图3-2-2

3.2.2 操作控制器的仿真

       ~~~~~~       用Modelsim实现图3-2-1操作控制器波形图,编写测试文件,运行文件如图3-2-3所示。

由于此部分与节拍发生器一起仿真,故对齐模块进行了例化:

//顶成例化的Verilog代码:
//控制器与节拍器的例化
`timescale 1ns / 10ps
module control_top(
    input wire CLK,
    input wire start,
    input wire LD,
    input wire ADD,
    input wire SUB,
    input wire AND,
    input wire OR,
    input wire HALT,
    output wire IMAR,
    output wire IDR,
    output wire IPC,
    output wire IIR,
    output wire ISUB,
    output wire IADD,
    output wire IAND,
    output wire IOR,
    output wire IA,
    output wire EALU,
    output wire EA,
    output wire EDR,
    output wire [7:0] T
);

//wire [7:0] T;

pulse p(
        .CLK(CLK),
        .start(start),
        .T(T)
);

control c(
        .LD(LD),
        .ADD(ADD),
        .SUB(SUB),
        .AND(AND),
        .OR(OR),
        .HALT(HALT),
        .T(T),
        .IMAR(IMAR),
        .IDR(IDR),
        .IPC(IPC),
        .IIR(IIR),
        .ISUB(ISUB),
        .IADD(IADD),
        .IAND(IAND),
        .IOR(IOR),
        .IA(IA),
        .EALU(EALU),
        .EA(EA),
        .EDR(EDR)
);
endmodule

//操作控制器仿真的Verilog代码如下:

//----->control_top.v
`timescale 1ns / 10ps
module control_top_tb;

reg clk,start;
reg LD;
reg ADD;
reg SUB;
reg AND;
reg OR;
reg HALT;
wire IMAR;
wire IDR;
wire IPC;
wire IIR;
wire ISUB;
wire IADD;
wire IAND;
wire IOR;
wire IA;
wire EALU;
wire EA;
wire EDR;

control_top control_top(
        .CLK(clk),
        .start(start),
        .LD(LD),
        .ADD(ADD),
        .SUB(SUB),
        .AND(AND),
        .OR(OR),
        .HALT(HALT),
        .IMAR(IMAR),
        .IDR(IDR),
        .IPC(IPC),
        .IIR(IIR),
        .ISUB(ISUB),
        .IADD(IADD),
        .IAND(IAND),
        .IOR(IOR),
        .IA(IA),
        .EALU(EALU),
        .EA(EA),
        .EDR(EDR)
);


initial begin
        clk<=0;start<=0;
    #17 start<=1;
    #200 LD <= 1'b1; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;
    #200 LD <= 1'b0; ADD <= 1'b1; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;
    #200 LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b1; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;
    #200 LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b1; OR <= 1'b0;HALT <= 1'b0;
    #200 LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b1;HALT <= 1'b0;
    #200 LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b1;
    #500 $stop;
end

always #5 clk <= ~clk;

endmodule
 

       ~~~~~~       由波形图3-2-3可知,时钟信号CLK周期设为为10ns,前17ns内start为0,此时为节拍信号,故控制器也未工作。当start为1时,开始有节拍信号,此时由节拍信号,当再过200ns才开给LD,ADD,SUB,AND,OR,HALT赋值。故在仿真前有一段红线(表示状态不确定)
在这里插入图片描述
                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~                              图3-2-3所示

3.3程序计数器74LS161

       ~~~~~~       程序计数器主要用到的是74LS161,起主要作用用于计数(0~10),产生地址数据,通过地址寄存器,以便从ROM存储器中取出数据。接收CLK时钟信号,CLRn,LDn,ENP,ENT,使能信号。输出计数Q。产生波形如下图3-3-1所示
在这里插入图片描述
​ 图3-3-1所示

3.3.1程序计数器

       ~~~~~~        在时钟信号CLK的上升沿完成计数,LDn为预置数控制端,低电平有效;ENP和ENT为工作状态使能控制信号;CLRn 为异步清零端,低电平有效;D0、D1、D2、D3为数据输入信号,Q0、Q1、Q2、Q3为计数输出信号,RCO为进位输出信号。编译成功后的RTL如图3-3-2所示

//程序计数器的Verilog代码:
`timescale 1ns / 10ps
module LS161(
input wire CLK,
input wire CLRn,
input wire LDn,
input wire ENP,
input wire ENT,
input wire[3:0]D,
output reg[3:0]Q,
output wire RCO);
assign RCO =Q[3]&Q[2]&Q[1]&Q[0]&ENT;
always @( posedge CLK or negedge CLRn ) begin
   if(~CLRn ) 
       Q <= 4'b0000;
   else if(~LDn ) 
       Q <=D;
   else begin
       case({ENT, ENP})
           2'b11: if(Q < 4'b1010)
                       Q <= Q + 1;
                   else if(Q == 10)
                       Q <= 4'b0000;
           default: Q <= Q; 
       endcase
   end
end
endmodule

在这里插入图片描述
                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                  图3-3-2所示

3.3.2程序计数器LS161的仿真

用Modelsim实现图3-3-1程序计数器波形图,编写测试文件,运行结果如图3-3-3所示。

//程序计数器仿真的Verilog代码:
//---->Ls161_tb.v

module LS161_tb();
reg  CLK,CLRn,LDn, ENP, ENT;
reg  [3:0] D;
wire [3:0] Q;
wire RCO;

LS161 DUT(
.CLK  (CLK),
.CLRn (CLRn),
.LDn  (LDn),
.ENP  (ENP),	
.ENT  (ENT),
.D    (D),
.Q    (Q),
.RCO  (RCO));

initial begin 
CLK  = 1'b0;
D    = 4'b0000;
LDn  = 1'b1;
CLRn = 1'b1;
ENP  = 1'b0;
ENT  = 1'b0;
end
always #10 CLK = ~ CLK;
initial begin
#10 CLRn = 1'b0;
#15 CLRn = 1'b1;
end
initial begin
#16 D = 4'b1000;
#56 D = 4'b0000;
end  
initial begin
#35 LDn = 1'b0;
#30 LDn = 1'b1;
end 
initial begin
#70  ENP = 1'b1;
#260 ENP = 1'b0;
#60  ENP = 1'b1;
end 
initial begin
#70  ENT = 1'b1;
#425 ENT = 1'b0;
#5   ENT = 1'b1;
#60  $stop;
end 
endmodule 

       ~~~~~~        由波形图可知,时钟信号CLK周期设为20ns,开始10ns将CLRn设为0,之后15ns在设为1,在70ns时,且ENP、ENT都为1的时候才开始计数。

在这里插入图片描述

                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                      图3-3-3所示

3.4地址寄存器MAR

       ~~~~~~        地址寄存器用于保存当前CPU所访问的主存储器单元的地址,在此模型机中 因为使用了11个存储单元,所以用4个D触发器实现其功能。 产生波形如图3-4-1所示,当 IMAR=0 时,且时钟信号 CLK 上升沿将地址存入,并直接输出到存储器 ROM 的地址线上。
在这里插入图片描述

​ 图3-4-1所示

3.4.1 地址寄存器MAR的Verilog设计

       ~~~~~~        接收CLK时钟信号,Q(ADD_in)地址输入信号,IMAR控制信号,输出接受的Q,将其输入到ROM中。当IMAR=0时,且时钟信号CLK上升沿将地址存入,并直接输出到存储器ROM的地址线上。编译成功后的RTL如图3-4-2所示。

`timescale 1ns / 10ps
module LS4_D(
input [3:0]ADD_in, 
input Clk, 
input IMAR,    
output reg [3:0]ADD_out);
always @(posedge Clk or negedge IMAR) begin
   if (IMAR == 1'b0) 
       ADD_out <= ADD_in;
end
   
endmodule

在这里插入图片描述

                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                     图3-4-2所示

3.4.2址寄存器MAR仿真

       ~~~~~~        用Modelsim实现图3-4-1的3.4.1地址寄存器MAR波形图,测试文件,运行如图3-4-3所示。

//--->LS4_D_tb.v
module LS4_D_tb;

reg [3:0]ADD_in;
reg CLK;
reg IMAR;
wire [3:0] ADD_out;

LS4_D LS4_D(
       .ADD_in(ADD_in), 
       .Clk(CLK), 
       .IMAR(IMAR),
       .ADD_out(ADD_out));


initial begin
CLK <= 1'b0;
IMAR <= 1'b0;

#200 ADD_in <= 4'b0000;
#200 ADD_in <= 4'b0001;
#200 ADD_in <= 4'b0010;
#200 ADD_in <= 4'b0011;
#200 ADD_in <= 4'b0100;
#200 ADD_in <= 4'b0101;
#200 ADD_in <= 4'b0110;
#5000 $stop;    
end

always #100 CLK <= ~ CLK;

endmodule 

       ~~~~~~        由波形图3-4-3可知,时钟信号CLK周期设为100ns,每隔200ns,且当时钟上升沿来临时,开始将ADD_in的数转ADD_out上。

在这里插入图片描述
                                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                图3-4-3所示

3.5存储器ROM

       ~~~~~~       计算机是按照事先编写的程序进行运算的,首先将编写好的程序写入存储器,计算机在运行过程中对存储器进行读操作。其中共有6个操作码,5个操作数,共需要11个存储单元(每个存储单元为1个字节),故需要4条地址线。存储器的内容如下图所示:

地址指令或数据说明
000000111110LD的操作码
000100000001操作数1
001011000110ADD的操作码
001100000110操作数6
010010000110SUB的操作码
010100000011操作数3
011000100110AND的操作码
011100000000操作码0
100001111100OR的操作码
100100000100操作数4
101000001110停机指令

3.5.1存储器ROM的Verilog设计

       ~~~~~~       存储器ROM由输入有CE控制信号,addr地址信号,输出有data信号组成。其中编译后的存储器的RTL如图3-5-1所示

//存储器ROM的Verilog代码:
`timescale 1ns / 10ps
module rom4_8(
input wire CE,
input wire [3:0] addr,
output reg [7:0] data );
//ROM功能定义
always @ ( CE or addr ) begin
   if ( !CE ) 
       data <= 8'bzzzz_zzzz;
   else
   case ( addr )
       4'b0000: data <= 8'b00111110;             //LD操作码
       4'b0001: data <= 8'b00000001;             //操作 数1         LD A,1 
       4'b0010: data <= 8'b11000110;             //add操作码
       4'b0011: data <= 8'b00000110;             //操作数6         ADD A,6 
       4'b0100: data <= 8'b10000110;             //sub操作码
       4'b0101: data <= 8'b00000011;             //操作数3          sub A,3;
       4'b0110: data <= 8'b00100110;             //and操作码        
       4'b0111: data <= 8'b00000000;             //操作数 0         and A,0;
       4'b1000: data <= 8'b01111100;             //or操作码         
       4'b1001: data <= 8'b00000100;            //操作数4          or A,4;
       4'b1010: data <= 8'b01110110;             //HALT的操作码
       default: 
       data <= 8'bzzzz_zzzz;
endcase
end
endmodule

在这里插入图片描述
                                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                    图3-5-1所示

3.6数据寄存器

       ~~~~~~       数据寄存器是用来暂时存放由主存储器读出的一条指令或一个数据字。它是8位D触发器,并有三态输出功能,可以直接与总线相连。当IDR=1时,且时钟信号CLK上升沿到来时,将被选中的存储单元中的数据存入DR。当EDR=1时,DR输出呈高阻态;当EDR=0时,DR将所存数据送到数据总线。产生的波形如图3-6-1所示
在这里插入图片描述
                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                       图3-6-1所示

3.6.1数据寄存器的Verilog设计

       ~~~~~~       数据寄存器是8位D触发器,并有三态输出功能,可以直接与总线相连。其中由输入的外部数据总线的数据DATA_in,CLK时钟信号,IDR,EDP控制信号,以及输出为内部数据总线DATA_out组成,编译成功后的RTL如图3-6-2所示

//数据寄存器的Verilog代码:
module data_reg(
input wire [7:0] DATA_in,
input wire IDR,
input wire CLK,
input wire EDP,
output wire [7:0] DATA_out
);

reg [7:0]REGQ;
always @(posedge CLK)begin
   if(IDR==1'b1)begin
       REGQ<=DATA_in;
   end 
end

assign DATA_out = EDP?(8'bzzzz_zzzz):REGQ;

endmodule

在这里插入图片描述
                                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                图3-6-2所示

3.6.2 数据寄存器的仿真

       ~~~~~~       用Modelsim实现图3-6-1的数据寄存器的波形图,编写测试文件,运行结果如图3-6-3所示

//数据寄存器的Verilog仿真代码:
//----->data_reg_tb.v
module data_reg_tb;

reg [7:0]DATA_in;
reg IDR;
reg CLK;
reg EDP;
wire [7:0] DATA_out;

data_reg data_reg(
       .DATA_in(DATA_in),
       .IDR(IDR),
       .CLK(CLK),
       .EDP(EDP),
       .DATA_out(DATA_out)
);

initial begin
IDR<=1'b0;
DATA_in <= 8'b11111111;
CLK<=1'b0;
EDP<=1'b0;
#17 IDR <= 1'b1;
#200 DATA_in <= 8'b00000000;
#200 DATA_in <= 8'b00000001;
#200 DATA_in <= 8'b00000010;
#200 DATA_in <= 8'b00000011;
#50 EDP <= 1'b1;
#200 DATA_in <= 8'b00000100;
#200 DATA_in <= 8'b00000101;
#200 DATA_in <= 8'b00000110;
#200 DATA_in <= 8'b00000111;
#50 EDP <= 1'b0;
#200 DATA_in <= 8'b00001000;
#200 DATA_in <= 8'b00001001;
#200 DATA_in <= 8'b00001010;
#200 DATA_in <= 8'b00001011;
#5000 $stop;
end

always #100 CLK<=~CLK;

endmodule

       ~~~~~~       由波形图3-6-3知,时钟信号CLK周期设为200ns,当IDR为1,EDP为0且时钟上升沿来临时,才将外部总线数据输出到内部数据总线,当EDP为1时,外部数据显示高阻态。
在这里插入图片描述

                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                图3-6-3所示

3.7 累加器

       ~~~~~~       累加器A是一个通用寄存器,当运算器的算术逻辑部件ALU执行算术或逻辑运算时,为ALU提供一个工作区。由于模型计算机是8位,它是8位D触发器。当IA=0时,且时钟信号CLK上升沿将总线上的8位数据存入。产生的波形如图3-7-1所示。
在这里插入图片描述

                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                 图3-7-1所示

3.7.1 累加器的Verilog设计

       ~~~~~~        累加器是8位D触发器,其中由输入的内部总线的数据DATA_in,CLK时钟信号,IA,EA控制信号,以及输出为数据DATA_out组成,编译成功后的RTL如图3-7-2所示

//累加器的Verilog代码:
module acc(
input wire [7:0]DATA_in,
input wire IA,    //输入控制信号
input wire EA,    //输出控制信号
input wire CLK,
output wire [7:0]DATA_out
);

reg [7:0]REGQ;
always @(posedge CLK)begin
   if(IA==1'b0)begin
       REGQ<=DATA_in;
   end
   // if(EA==1'b1)begin
   //     DATA_out<=REGQ;
   // end
   // else begin
   //     DATA_out<=8'bzzzz_zzzz;
   // end
end

assign DATA_out = EA ? REGQ : (8'bzzzz_zzzz);

endmodule

在这里插入图片描述

​ 图3-7-2所示

3.7.2累加器的仿真

       ~~~~~~       用Modelsim实现图3-7-1的累加器的波形图,编写测试文件,运行结果如图3-7-3所示

//累加器modelsim的Verilog仿真仿真代码:
//------>acc_tb.v
module acc_tb;
reg [7:0]DATA_in;
reg IA;
reg CLK;
reg EA;
wire [7:0] DATA_out;

acc acc(
       .DATA_in(DATA_in),
       .IA(IA),
       .CLK(CLK),
       .EA(EA),
       .DATA_out(DATA_out)
);

initial begin
IA<=1'b1;
DATA_in <= 8'b11111111;
CLK<=1'b0;
EA<=1'b0;
#17 IA <= 1'b0;
#200 DATA_in <= 8'b00000000;
#200 DATA_in <= 8'b00000001;
#200 DATA_in <= 8'b00000010;
#200 DATA_in <= 8'b00000011;
#50 EA <= 1'b1;
#200 DATA_in <= 8'b00000100;
#200 DATA_in <= 8'b00000101;
#200 DATA_in <= 8'b00000110;
#200 DATA_in <= 8'b00000111;
#50 EA <= 1'b1;
#200 DATA_in <= 8'b00001000;
#200 DATA_in <= 8'b00001001;
#200 DATA_in <= 8'b00001010;
#200 DATA_in <= 8'b00001011;
#5000 $stop;
end

always #100 CLK<=~CLK;

endmodule

       ~~~~~~       由波形图3-7-3知,时钟信号CLK周期设为200ns,当IA为1,EA为1且时钟上升沿来临时,才将内部总线数据输出到ALU数据线上,当EA为1时,ALU数据线显示高阻态。

在这里插入图片描述

                                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                               图3-7-3知

3.8 算术逻辑单元ALU

       ~~~~~~       算术逻辑单元 ALU 是数据加工处理部件,用来实现基本的算术、逻辑运算功能。在此逻辑单元中,进行加法、减法、与、或逻辑运算。产生的波形如图3-8-1所示

在这里插入图片描述

                                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                               图3-8-1所示

3.8.1 算术逻辑单元ALU的Verilog设计

       ~~~~~~       算术逻辑单元由两个操作数据输入,ISUM,EALU,ISUB,IAND,IOR控制信号,以及数据输出组成。其中ISUM,ISUB,IAND,IOR为运算操作控制信号,EALU为数据输出信号,当EALU为1时,输出数据显示高阻态,当EALU为0时,输出运算数据。编译成功后的RTL如图3-8-2所示。

//算术逻辑单元ALU的Verilog代码:
//ALU
module ALU(
   input wire [7:0]AC,
   input wire [7:0]DR,
   input wire ISUM,
   input wire EALU,
   input wire ISUB,
   input wire IAND,
   input wire IOR,
   output wire [7:0]ALU_out
);

reg [7:0] ALU_temp;

always @(*)begin
   if(ISUM==1'b0)begin
       ALU_temp <= AC + DR;
   end
   else if(ISUB==1'b0)begin
       ALU_temp <= AC - DR;
   end
   else if(IAND==1'b0)begin
       ALU_temp <= AC & DR;
   end
   else if(IOR==1'b0)begin
       ALU_temp <= AC | DR;
   end
//    else begin
//        ALU_temp <= 8'bzzzz_zzzz;
//    end
end

assign ALU_out = EALU ? (8'bzzzz_zzzz) : ALU_temp;

endmodule

在这里插入图片描述

                                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                    图3-8-2所示

3.8.2算术逻辑单元ALU的仿真

       ~~~~~~       用Modelsim实现图3-8-1的算术逻辑单元ALU的波形图,编写测试文件,运行结果如图3-8-3所示

//算术逻辑单元ALU的Verilog仿真代码:
//--------->ALU_tb.v
module ALU_tb;

reg [7:0]AC;
reg [7:0]DR;
reg ISUM;
reg EALU;
reg ISUB;
reg IAND;
reg IOR;
wire [7:0]ALU_out;

AUL AUL(
       .AC(AC),
       .DR(DR),
       .ISUM(ISUM),
       .EALU(EALU),
       .ISUB(ISUB),
       .IAND(IAND),
       .IOR(IOR),
       .ALU_out(ALU_out)
);

initial begin
   
AC<=8'b00000111;
DR<=8'b00000011;
ISUB<=1'b1;
ISUM<=1'b1;
IAND<=1'b1;
IOR<=1'b1;
EALU<=1'b1;

#100  EALU<=1'b0;
     ISUM <=1'b0;  


#200 ISUM <= 1'b1;
    ISUB <= 1'b0;

#200 ISUB <= 1'b1;
    IAND <= 1'b0;

#100 EALU <= 1'b1;

#100 EALU <= 1'b0;

#200 IAND <= 1'b1;
    IOR <= 1'b0;
#200 $stop;
end

Endmodule

       ~~~~~~       由波形图3-8-3可知,开始时100ns内,由于EALU为1,故输出高阻态,当EALU为0时,且有运算控制信号时,输出运算结果。

在这里插入图片描述

                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                  图3-8-3所示

3.9 指令寄存器IR

       ~~~~~~       指令寄存器IR用来保存当前正在执行的一条指令。当执行一条指令时,先把它从主存储器中取到数据寄存器中,然后在传送到指令寄存器。如果IR中存储的是操作码就送入指令译码器,译码器将操作码译成相应的操作指令。产生的波形如图3-9-1所示
在这里插入图片描述

                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                     图3-9-1所示

3.9.1 指令寄存器IR的Verilog设计

       ~~~~~~       算术逻辑单元由一个操作数据输入,CLK时钟信号,IIR控制信号,以LD,ADD,SUB.AND,OR,HALT输出信号组成。当 IIR=0 时,且时钟信号 CLK 上升沿到来时,将指令操作码存入 IR,并经门电路译码,输出 LD、ADD、SUB,AND,OR,HALT 三个操作命令。例如,当指令操作码为 00111110 时,译码器输 出为 LD=1,ADD=0,SUB=0,AND=0,OR=0,HALT=0。 编译成功后的RTL如图3-9-2所示。

//指令寄存器的Verilog代码:
module IR(
input wire [7:0]DATA_in,
input wire IIR,
input wire CLK,
output reg LD,
output reg ADD,
output reg SUB,
output reg AND,
output reg OR,
output reg HALT
);

reg [7:0]REGQ;

always @(posedge CLK)begin
    if(IIR==1'b0)begin
        REGQ <= DATA_in;
    end
//    else begin
//        REGQ <= 8'bzzzz_zzzz;
//    end
    // case (REGQ)
    //     8'b00111110:begin LD <= 1'b1; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;end             //LD A,1;  62
    //     8'b11000110:begin LD <= 1'b0; ADD <= 1'b1; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;end             //ADD A,6;
    //     8'b10000110:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b1; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;end             //SUB A,3;
    //     8'b00100110:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b1; OR <= 1'b0;HALT <= 1'b0;end             //AND A,0;
    //     8'b01111100:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b1;HALT <= 1'b0;end             //OR A,4;
    //     8'b01110110:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b1;end             //HATL;
    //     default: ;  
    // endcase

end

always @(*)begin
    case (REGQ)
        8'b00111110:begin LD <= 1'b1; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;end             //LD A,1;  62
        8'b11000110:begin LD <= 1'b0; ADD <= 1'b1; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;end             //ADD A,6;
        8'b10000110:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b1; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b0;end             //SUB A,3;
        8'b00100110:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b1; OR <= 1'b0;HALT <= 1'b0;end             //AND A,0;
        8'b01111100:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b1;HALT <= 1'b0;end             //OR A,4;
        8'b01110110:begin LD <= 1'b0; ADD <= 1'b0; SUB <= 1'b0; AND <= 1'b0; OR <= 1'b0;HALT <= 1'b1;end             //HATL;
        default: ;
    endcase
end
endmodule

在这里插入图片描述

                                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                      图3-9-2所示

3.9.2 指令寄存器IR的仿真

       ~~~~~~       用Modelsim实现图3-9-1的算术逻辑单元ALU的波形图,编写测试文件,运行结果如图3-9-3所示

指令寄存器Modelsim的Verilog仿真代码:
//----->IR_tb.v
module IR_tb;

reg [7:0]DATA_in;
reg IIR;
reg CLK;
wire LD;
wire ADD;
wire SUB;
wire AND;
wire OR;
wire HALT;

IR IR(.DATA_in(DATA_in),
       .IIR(IIR),
       .CLK(CLK),
       .LD(LD),
       .ADD(ADD),
       .SUB(SUB),
       .AND(AND),
       .OR(OR),
       .HALT(HALT)
);

initial begin
   
   CLK <= 1'b0;
   IIR <= 1'b1;
end

always #100 CLK <= ~CLK;

initial begin
   #100 IIR <= 1'b0;
   #150 DATA_in <= 8'b00111110;
   #150 DATA_in <= 8'b11000110;
   #150 DATA_in <= 8'b10000110;
   #150 DATA_in <= 8'b00100110;
   #150 DATA_in <= 8'b01111100;
   #150 DATA_in <= 8'b01110110;
   #500 $stop;
end

endmodule

       ~~~~~~       由图3-9-3所示,时钟信号CLK周期设为200ns,当IIR为1,且时钟上升沿来临时,才进行信号的输出。
在这里插入图片描述
                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                        图3-9-3所示

3.10 时钟分屏器

       ~~~~~~       时钟信号源用于产生固定频率的方波脉冲,由于所选时钟频率为100MHZ,变化过大,故进行分屏为4HZ。RTL如图3-10-1所示

//时钟分屏的Verilog代码:
module CLK100M_4HZ(
input wire CLK,
input wire CLRn,
output reg T4hz );
reg [24:0] Q_conut;
always @( posedge CLK or negedge CLRn ) begin
 if ( ~CLRn ) Q_conut <= 25'd0;
 else begin
			if (Q_conut < 25'd12499999 )//12499999
			Q_conut <= Q_conut + 1;
			else Q_conut <= 25'd0;
 end
end
always @ ( posedge CLK or negedge CLRn ) begin
 if ( ~CLRn ) T4hz <= 0;
 else if( Q_conut == 25'd0 )
T4hz <= ~ T4hz;
end
endmodule

在这里插入图片描述
                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                        图3-10-1所示

4、模型机系统设计仿真和调试

4.1、模型机系统设计

       ~~~~~~       当子模块设计完成,并仿真验证或调试后,则开始进行顶层模块的组装和连接。顶层CPU的输入有:CLK_100MHZ时钟信号,CLR清零复位信号。输出主要包括分频后的时钟信号,内部总线数据,各个子模块的控制信号,节拍信号,程序计数器的输出数据。

$~~~~~~$8位模型机顶层RTL视图如图4-1-1所示。8位模型机的子模块主要有:存储器RAM、程序计数器PC、地址寄存器MAR、数据寄存器DR、累加器ACC、算术逻辑单元ALU、指令寄存器IR和指令译码器、节拍发生器PULSE、操作控制器。

在这里插入图片描述
                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                     图4-1-1 8位模型机顶层RTL视图

4.2模型机系统仿真

       ~~~~~~       用Verilog语言编写顶层模块测试文件top.v。ModelSim仿真结果如图4-2-1所示。

顶层模块的Verilog代码:
module top (
input wire CLK,
input wire CLRn,
output wire IPC,         //程序计数控制信号
output wire IMAR,        //地址寄存信号
output wire IDR,         //数据寄存输入信号
output wire EDR,         //数据寄存输出信号
output wire IA,          //累加器的输入信号
output wire EA,          //累加器的输出信号
output wire ISUM,        //ALU的加法运算控制信号
output wire EALU,        //ALU的输出控制信号
output wire ISUB,        //ALU的减法控制信号
output wire IAND,        //ALU的与运算控制信号
output wire IOR,         //ALU的或运算控制信号
output wire IIR,         //指令寄存器的寄存信号
output wire [7:0] DATA_out,    //数据寄存器的输出值(注意这个值是总线上的值)
output wire LD,                //输出的赋值指令
output wire ADD,               //输出的加法指令
output wire SUB,               //输出的加法令
output wire AND,               //输出的与指令
output wire OR,                //输出的或指令
output wire HALT,              //输出的停机指令  
output wire [7:0]T,            //节拍器的输出节拍信号
output wire [3:0]Q//,
//output wire [7:0]ALU_out
);
    
wire IPC;
wire CP;
wire LDn;
wire [3:0]D;
//wire [3:0]Q;
wire RCO;
wire [3:0] ADD_out;
//wire CE;                //rom的使能信号
wire [7:0] data_out;    //寄存器的输出操作值
//wire [7:0] DATA_out;    //数据寄存器的输出值(注意这个值是总线上的值)
wire [7:0] acc_data_out;//累加器的输出信号



/*//时钟分屏
CLK100M_4HZ CLK100M_4HZ(
        .CLK(CLK),
        .CLRn(CLRn),
        .T4hz(CP)
);*/


//程序计数器
assign LDn = 1;
assign D = 4'b0000;


LS161 LS161(
        .CLK(CLK),
        .CLRn(CLRn),
        .LDn(LDn),
        .ENP(IPC),
        .ENT(IPC),
        .D(D),
        .Q(Q),
        .RCO(RCO)
);


//地址寄存器
LS4_D LS4_D(
        .ADD_in(Q), 
        .Clk(CLK), 
        .IMAR(IMAR),    
        .ADD_out(ADD_out)
);


//存储器

//assign CE = 0;              //低有效

rom4_8 rom4_8(
        .CE(CLRn),
        .addr(ADD_out),
        .data(data_out) 
);


//数据寄存器

data_reg data_reg(
        .DATA_in(data_out),
        .IDR(IDR),
        .CLK(CLK),
        .EDP(EDR),
        .DATA_out(DATA_out)
);


//累加器
acc acc(
        .DATA_in(DATA_out),
        .IA(IA),    //输入控制信号
        .EA(EA),    //输出控制信号
        .CLK(CLK),
        .DATA_out(acc_data_out)
);


//ALU
ALU ALU(
        .AC(acc_data_out),
        .DR(DATA_out),
        .ISUM(ISUM),
        .EALU(EALU),
        .ISUB(ISUB),
        .IAND(IAND),
        .IOR(IOR),
        .ALU_out(DATA_out)
);



//指令寄存信号
IR IR(
        .DATA_in(DATA_out),
        .IIR(IIR),
        .CLK(CLK),
        .LD(LD),
        .ADD(ADD),
        .SUB(SUB),
        .AND(AND),
        .OR(OR),
        .HALT(HALT)
);


控制器
//control control(
//        .LD(LD),
//        .ADD(ADD),
//        .SUB(SUB),
//        .AND(AND),
//        .OR(OR),
//        .HALT(HALT),
input wire CLK,
//        .T(T),
//        .IMAR(IMAR),
//        .IDR(IDR),
//        .IPC(IPC),
//        .IIR(IIR),
//        .ISUB(ISUB),
//        .IADD(ISUM),
//        .IAND(IAND),
//        .IOR(IOR),
//        .IA(IA),
//        .EALU(EALU),
//        .EA(EA),
//        .EDR(EDR)
//);


节拍器
//pulse pulse(
//        .CLK(CLK),
//        .start(CLRn),
//        .T(T)
//);


control_top control_top(
        .CLK(CLK),
        .start(CLRn),
        .LD(LD),
        .ADD(ADD),
        .SUB(SUB),
        .AND(AND),
        .OR(OR),
        .HALT(HALT),
        .IMAR(IMAR),
        .IDR(IDR),
        .IPC(IPC),
        .IIR(IIR),
        .ISUB(ISUB),
        .IADD(ISUM),
        .IAND(IAND),
        .IOR(IOR),
        .IA(IA),
        .EALU(EALU),
        .EA(EA),
        .EDR(EDR),
        .T(T)
);

endmodule 

在这里插入图片描述

                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                            图4-2-1 顶层模块仿真结果

       ~~~~~~       CLK为100MHZ的时钟信号,CLRn复位信号兼各模块的使能控制信号设置为高有效,之后一直维持高电平状态。地址寄存信号IMAR、数据寄存输出信号IDR、数据寄存输出信号EDR、累加器的输入信号IA、累加器的输出信号EA、ALU的加法运算信号ISUM、ALU的减法运算信号ISUB、ALU的与法运算信号IAND、ALU的或法运算信号IOR、ALU的输出信号EALU、指令寄存的寄存信号IIR,8个时序节拍T。

  1. 当总线操作码为3e,指令寄存器LD为1,ADD、SUB、AND、OR、HALT为0,从ROM中读取操作数1;
  2. 当总线操作码为c6,指令寄存器ADD为1,LD、SUB、AND、OR、HALT为0,从ROM中读取操作数6,并通过ALU相加,将相加的内容有送到总线上,显示7。
  3. 此时由于EA为0,故ALU输出显示为高阻态,接着接受数据寄存器的值6,当IPC为1再次来临时,更新数据寄存器的值,及总线上显示86,指令寄存器SUB为1,ADD、LD、AND、OR、HALT为0,从ROM中读取操作数3,并通过ALU相减,得到操作数4并输出到总线上。
  4. 此时由于EA为0,故ALU输出显示为高阻态,接着接受数据寄存器的值3,当IPC为1再次来临时,更新数据寄存器的值,及总线上显示26,继续通过指令寄存器进行指令信号的输出,直到总线的操作数为76(停机操作码)时,指令寄存器HALT为1,LD、ADD、SUB、AND、OR为0时,停止操作。
  5. 之后又开始循环进行重复的操作。

4.3模型机系统调试

       ~~~~~~       通过quartus的逻辑分析仪进行调试。
在这里插入图片描述
在这里插入图片描述

具体文件下载地址:

github:endeavour-tl/-8-_CPU8 (github.com)

CSDN:数字逻辑课程设计,简单的8位模型计算机verilog设计-单片机文档类资源-CSDN文库

  • 18
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值