zoukankan      html  css  js  c++  java
  • 【原创】DE2实验解答—lab09 (Quartus II)(Verilog HDL)(Digital Logic)

    Laboratory Exercise 9

    简单的处理器

    图1所示的数字系统包含一些16位的寄存器,一个多选器,一个加/减单元,一个计数器和一个控制单元。数据通过16位的DIN输入。经由16位的多选器,数据可加载到多个寄存器,比如:R0,… ,R7和A。当然,多选器也可以使数据从一个寄存器传输到另一个寄存器。图中多选器的输出叫做总线,通常用来作为数据通道。

    加法器或减法器的执行过程:首先通过多选器加载一个16位的数字到寄存器A。然后在总线上加载另一个16位的数字。加/减单元执行指定的运算,结果输出到寄存器G。G中的数据可按需求传输到其他寄存器。

    clip_image002

    由控制单元决定每个时钟系统执行的操作。指定的数据何时加载到总线上和用哪个寄存器加载数据都由控制单元决定。比如:若控制单元指定信号R0out和Ain有效,那木多选器将把寄存器R0的数据放到总线上并且在下一个有效时钟沿这个数据加载到寄存器A。

    类似这样的系统通常叫做处理器。它以指令形式执行操作。表1列出本练习所支持的指令。左列是指令名称和操作数。RX←[RY]的含义是将寄存器RY的数据加载到寄存器RX。指令mv的功能是将数据从一个寄存器复制到另一个寄存器。指令mvi是将常量加载到寄存器。

    clip_image004

    每条指令以9位的IIIXXXYYY的形式存储在IR寄存器中,III表示指令,XXX表示RX寄存器,YYY表示RY寄存器。虽然4条指令只需要2位就可以编码,为后续练习将要添加的指令,我们使用3位来编码。因此,IR必须连接到DIN的16位中的9位,如图一所示。对于mvi指令来说,YYY无含义并且立即数#D必须在mvi指令存储到IR后加载到16位的DIN。

    有些指令,比如加、减,要在总线上多次传输数据,需要多于一个时钟周期才能完成。控制单元使用一个2位的计数器来逐步执行这些指令。当Run信号有效,处理器开始执行DIN输入指令;当指令结束,Done置位。表2列出在表1的指令执行中每步有效的控制信号。注意在最开始只有控制信号IRin有效,表中未列出。

    clip_image006

    Part I

    设计并实现图1所示的处理器。

    1. 为本练习创建一个新工程。

    2. 生成相应的Verilog文件,编译。

    3. 对代码进行功能仿真。

    4. 创建一个新工程,例化本电路。对应DE2的资源添加相应的输入/出。

    SW15-0

    DIN

    SW17

    Run

    KEY0

    Resetn

    KEY1

    Clock

    LEDR15-0

    Buswires

    LEDR17

    Done

    5. 分配引脚,编译、下载。

    6. 测试。

    代码part 1:

    View Code
    1 // a simple processor
    2 //可以实现4种指令。
    3
    4 module proc(DIN,Resetn,Clock,Run,Done,BusWires);
    5 input [15:0] DIN; //16-bit数据输入
    6 input Resetn,Clock,Run;
    7 output Done;
    8 output [15:0] BusWires;
    9
    10 //declare variables
    11
    12 reg [15:0] BusWires;
    13 reg [0:7] Rin,Rout; //8个16-bit寄存器的输入/出控制
    14 reg [15:0] Sum;
    15 reg IRin,Done,DINout,Ain,Gin,Gout,AddSub;
    16 wire [1:0] Tstep_Q; //4个阶段计数输出
    17 wire [2:0] I; //3-bit指令码
    18 wire [0:7] Xreg,Yreg; //2个8-bit寄存器
    19 wire [15:0] R0,R1,R2,R3,R4,R5,R6,R7,A,G; //9个16-bit寄存器
    20 wire [1:9] IR; //IIIXXXYYY
    21 wire [1:10] Sel; //多路器的选择位
    22
    23 wire Clear=~Resetn | Done | (~Run & ~Tstep_Q[1] & ~Tstep_Q[0]); //clear
    24 upcount Tstep(Clear,Clock,Tstep_Q); //T0-T3 4个阶段
    25 assign I=IR[1:3]; //指令位
    26 dec3to8 decX(IR[4:6],1'b1,Xreg); //译码,用于选择R0-R7
    27 dec3to8 decY(IR[7:9],1'b1,Yreg);
    28
    29 //指令列表:
    30 //000: mv
    31 //001: mvi
    32 //010: add
    33 //011: sub
    34
    35 always @(Tstep_Q or I or Xreg or Yreg)
    36 begin
    37 //specify initial values
    38 Done=1'b0;
    39 Ain=1'b0;
    40 Gin=1'b0;
    41 Gout=1'b0;
    42 AddSub=1'b0;
    43 IRin=1'b0;
    44 DINout=1'b0;
    45 Rin=8'b0;
    46 Rout=8'b0;
    47
    48 case(Tstep_Q)
    49 2'b00: //store DIN in IR in time step 0
    50 begin
    51 IRin=1'b1;
    52 end
    53 2'b01: //define signals in time step 1
    54 case(I)
    55 3'b000: //mv Rx,Ry
    56 begin
    57 Rout=Yreg;
    58 Rin=Xreg;
    59 Done=1'b1;
    60 end
    61 3'b001: //mvi Rx,#D
    62 begin
    63 DINout=1'b1;
    64 Rin=Xreg;
    65 Done=1'b1;
    66 end
    67 3'b010,2'b011: //add,sub
    68 begin
    69 Rout=Xreg;
    70 Ain=1'b1;
    71 end
    72 default: ;
    73 endcase
    74 2'b10: //define signals in time step 2
    75 case(I)
    76 3'b010: //add
    77 begin
    78 Rout=Yreg;
    79 Gin=1'b1;
    80 end
    81 3'b011: //sub
    82 begin
    83 Rout=Yreg;
    84 AddSub=1'b1;
    85 Gin=1'b1;
    86 end
    87 default: ;
    88 endcase
    89 2'b11: //define signals in time step 3
    90 case(I)
    91 3'b010,3'b011: //add,sub
    92 begin
    93 Gout=1'b1;
    94 Rin=Xreg;
    95 Done=1'b1;
    96 end
    97 default: ;
    98 endcase
    99 endcase
    100 end
    101
    102 regn reg_0(BusWires,Rin[0],Clock,R0);
    103 //instantiate other registers and the adder/subtracter unit
    104 regn reg_1(BusWires,Rin[1],Clock,R1);
    105 regn reg_2(BusWires,Rin[2],Clock,R2);
    106 regn reg_3(BusWires,Rin[3],Clock,R3);
    107 regn reg_4(BusWires,Rin[4],Clock,R4);
    108 regn reg_5(BusWires,Rin[5],Clock,R5);
    109 regn reg_6(BusWires,Rin[6],Clock,R6);
    110 regn reg_7(BusWires,Rin[7],Clock,R7);
    111 regn reg_A(BusWires,Ain,Clock,A);
    112 regn #(.n(9)) reg_IR(DIN[15:7],IRin,Clock,IR);
    113
    114 //alu
    115 always @(AddSub or A or BusWires)
    116 begin
    117 if(!AddSub)
    118 Sum=A+BusWires;
    119 else
    120 Sum=A-BusWires;
    121 end
    122
    123 regn reg_G(Sum,Gin,Clock,G);
    124
    125 //define the bus
    126 assign Sel={Rout,Gout,DINout};
    127
    128 always @(*)
    129 begin
    130 if(Sel==10'b10_0000_0000)
    131 BusWires=R0;
    132 else if(Sel==10'b01_0000_0000)
    133 BusWires=R1;
    134 else if(Sel==10'b00_1000_0000)
    135 BusWires=R2;
    136 else if(Sel==10'b00_0100_0000)
    137 BusWires=R3;
    138 else if(Sel==10'b00_0010_0000)
    139 BusWires=R4;
    140 else if(Sel==10'b00_0001_0000)
    141 BusWires=R5;
    142 else if(Sel==10'b00_0000_1000)
    143 BusWires=R6;
    144 else if(Sel==10'b00_0000_0100)
    145 BusWires=R7;
    146 else if(Sel==10'b00_0000_0010)
    147 BusWires=G;
    148 else
    149 BusWires=DIN;
    150 end
    151 endmodule
    152
    153 module upcount(Clear,Clock,Q);
    154 input Clear,Clock;
    155 output [1:0] Q;
    156 reg [1:0] Q;
    157
    158 always @(posedge Clock)
    159 if(Clear)
    160 Q<=2'b0;
    161 else
    162 Q<=Q+1'b1;
    163 endmodule
    164
    165 module dec3to8(W,En,Y);
    166 input [2:0] W;
    167 input En;
    168 output [0:7] Y;
    169 reg [0:7] Y;
    170
    171 always @(W or En)
    172 begin
    173 if(En==1)
    174 case(W)
    175 3'b000: Y=8'b1000_0000;
    176 3'b001: Y=8'b0100_0000;
    177 3'b010: Y=8'b0010_0000;
    178 3'b011: Y=8'b0001_0000;
    179 3'b100: Y=8'b0000_1000;
    180 3'b101: Y=8'b0000_0100;
    181 3'b110: Y=8'b0000_0010;
    182 3'b111: Y=8'b0000_0001;
    183 endcase
    184 else
    185 Y=8'b0000_0000;
    186 end
    187 endmodule
    188
    189 module regn(R,Rin,Clock,Q);
    190 parameter n=16;
    191 input [n-1:0] R;
    192 input Rin,Clock;
    193 output [n-1:0] Q;
    194 reg [n-1:0] Q;
    195
    196 always @(posedge Clock)
    197 if(Rin)
    198 Q<=R;
    199 endmodule
    200

    仿真结果:

    clip_image008

    例化:

    View Code
    1 //part 1 top module
    2
    3 module part1(SW,KEY,LEDR);
    4 input [17:0] SW;
    5 input [1:0] KEY;
    6 output [17:0] LEDR;
    7
    8 proc u0(
    9 .DIN(SW[15:0]),
    10 .Resetn(KEY[0]),
    11 .Clock(KEY[1]),
    12 .Run(SW[17]),
    13 .Done(LEDR[17]),
    14 .BusWires(LEDR[15:0])
    15 );
    16
    17 endmodule
    18
    19

    Part II

    本练习给处理器外加一个只读存储器和计数器,计数器用来产生存储器的地址。存储器为32*16-bit。

    clip_image010

    代码part 2:

    View Code
    1 //part 2 top module
    2 //加上外部存储器的处理器
    3
    4 //引脚说明:
    5 //--------------------------------------------------------
    6 // SW17-Run KEY0-Resetn KEY1-MClock
    7 // KEY2-PClock LEDR15-0-BusWires LEDR17-Done
    8
    9 module part2(
    10 input [2:0] KEY,
    11 input [17:17] SW,
    12 output [17:0] LEDR
    13 );
    14
    15 wire Done,Resetn,PClock,MClock,Run;
    16 wire [15:0] DIN,BusWires;
    17 wire [4:0] pc; //计数输出,srom的地址0-31
    18
    19 assign Resetn=KEY[0];
    20 assign PClock=KEY[0]; //processor的时钟
    21 assign MClock=KEY[2]; //srom的时钟
    22 assign Run=SW[17];
    23
    24 proc m0(DIN,Resetn,PClock,Run,Done,Buswires);
    25 assign LEDR[15:0] =BusWires;
    26 assign LEDR[17]=Done;
    27
    28 sromlpm m1(pc,MClock,DIN);
    29 count5 m2(Resetn,MClock,pc);
    30
    31 endmodule
    32
    33 //count5
    34 module count5(Resetn,Clock,Q);
    35 input Resetn,Clock;
    36 output reg [4:0] Q;
    37
    38 always @(posedge Clock)
    39 if(Resetn==0)
    40 Q<=5'b0;
    41 else
    42 Q<=Q+1'b1;
    43 endmodule
    44
    45
    46
    47

    Conclusion

    本实验把简单的处理器拆解成基本逻辑电路。单个实现不难,主要是对控制电路的理解,实现处理器分步执行的概念。

    Reference

    《数字逻辑基础与Verilog设计》2nd ,ch 7.14.2 夏宇闻 译。

  • 相关阅读:
    spring boot单元测试之七:用mockmvc模拟session(spring boot 2.4.3)
    spring boot单元测试之六:用mockmvc模拟cookie(spring boot 2.4.3)
    sql join 注意事项
    见路不走,即见因果
    presto sql 经典sql 应用
    别拿你的职业去拔高你个人的规格, 让人轻看
    《遥远的救世主》经典台词
    《卜算子·自嘲》
    天道连续剧 丁元英语录
    shell diff + kettle = mail 预警
  • 原文地址:https://www.cnblogs.com/halflife/p/2029000.html
Copyright © 2011-2022 走看看