资讯详情

数字集成电路设计-7-一个简单cpu的设计,实现,仿真与综合

引言 经过对OpenRISC经过近一年的分析和研究,我们了解了计算机系统结构设计的主要概念、重要技术和基本思想。我认为现在有必要练习。

本节将设计一个简单的部分cpu,包括ISA模块,模块划分,RTL实现,编写asm汇编程序,用modelsim模拟和使用quartusII的综合。

1.计算器和计算机 我认为,在EDVAC以前的计算机可以被视为计算器。

原因是冯诺依曼对EDVAC在分析过程中,提出了二进制计算和添加存储部件,在此之前,计算机没有存储功能,例如,我们需要计算(1 2)&(3 4)如果使用计算器,其操作步骤如下:

a,先用计算器计算1 结果3,然后人脑自己记住这个数字。

b,用计算器计算3 4的结果7,人脑也自己记住这个数。

c,最后,用计算器计算3&7的结果3。

若采用计算机,其操作过程如下:

首先,我们需要写一个程序,假设程序放在程序存储器的地址0x55、56、57、58四个地址分别放置在数据存储器中。

程序执行如下:

a,将data_mem的0x放55个数据r1。

b,将data_mem的0x数据放在56处r2。

c,执行add r2,r1,结果放在r2里面。

d,将r写入2的内容data_mem的0x60这个地址。

e,将data_mem的0x数据放在57处r3。

f,将data_mem的0x数据放在58处r4。

g,执行add r4,r3,结果放在r4里面。

h,将r4内容写入data_mem的0x61这个地址。

i,将data_mem的0x放60个数据r5。

j,将data_mem的0x数据放在61处r6。

k,执行and r6,r5,结果放在r6里面。

l,将r内容写入6data_mem的0x62这个地址,最终得到计算结果。

我们可以看到,如果用计算机计算,只需要三个步骤,但如果用计算机,需要12个步骤。使用计算机的效率低吗?今天计算机的蓬勃发展使得答案不言而喻。

原因是只要编写程序,计算机的整个计算过程就不需要人为干预。

我认为这就是计算机发展的根本原因,即计算机的出现对人们来说是一个巨大的解放。只要我们以某种方式写程序,然后交给计算机,计算机就会自动完成任务,我们的手就可以做其他事情!

2,架构设计 1>整体设计 通过上面的例子,我们可以体验到计算机的好处。让我们设计一个cpu,来完成1 2的计算。

关于计算机系统结构,我们之前说过足够多的内容。以下几点仅供说明:

a,我们采用harvard结构,即指令和数据的总线是独立的。

b,流水线,我们暂时不采用流水设计,但最终,我给出了五级流水时的数据通路设计框架。

c,至于指令集,由于是学习目的,我们只实现基本的访问和存储指令、操作指令和分支指令。操作不支持乘除和浮点。详见附录。每个指令为16-bit。

d,为我们设计cpu进行仿真和验证,我们需要设计一个简单的soc才行,这个soc只包括指令存储器,cpu内核,数据存储器。

e,core内总线为8-bit。有一个问题,core外是8-bit,但分支指令的目的地地址是11-bit,所以如果超过8-bit,会有问题,还没有解决。

下面是soc整体架构图:让我们给他取个名字,叫 tiny_soc,小cpu简单地称她为tiny_core。

2>模块划分 cpu core结构如下:

整个cpu core由数据通道、控制通道和调试单元组成。

其中数据通路包括:

PC生成模块:genpc

运算模块:alu,在alu前面是多选一个操作数mux。

寄存器堆:regfile模块

还有栈:stack。

控制数据通路模块ctrl_path控制模块,解码控制通道的指令,并产生相应的控制信号。

由于调试单元只是学习目的,调试单元是最简化的,只输出当前的PC值和当前指令内容两个信息。

3.模块划分和界面定义 在体架构设计完成后,需要进一步细化。此时,需要定义具体的模块名称和模块功能。一旦确定了功能,就可以确定具体的模块接口信号。

如果模块功能太大,我们需要将它们分成更小的模块,即top-down设计方法。关于设计方法(top-down,bottom-up),很多资料都有介绍,这里就不赘述了。

一个完整的项目,不同于理论研究,需要处理很多实现细节。下面,我们来介绍一下更重要的部分:

1>genpc模块 需要考虑三点:上电复位PC默认值是多少?执行正常指令时PC如何变化?遇到分支指令时?PC如何变化?

关于上电默认值,我们可以通过一个define设置句子,方便用户以后修改。

关于正常指令的指令,PC是加1、加2还是加4取决于指令存储器的访问方式。我们的指令存储器在每个地址放一个指令,每个指令放两个字节(16-bit),所以我们只需要PC加1就够了。

对于分支指令,我们直接将解码的跳转地址赋予控制通路PC即可。

genpc模块C语言伪代码如下:

genpc module pseudo code if(rst) { pc= boot_addr; } else { if(branch) { pc = branch_target; } else { pc = pc 1; } }

2>alu模块 alu大家都很熟悉模块,是执行单元部件,负责操作指令。

该模块的输入信号是由控制通路解码的操作数和操作码,输出信号是操作结果。

需要注意的是,该模块可以完全组合逻辑电路。

3>rf模块 register file在物理上,模块是一个模块block ram。

从逻辑上讲,该模块对软件程序员透明,寄存器堆和指令集是软件和硬件之间的交互接口。

4>stack stack(栈)存放在处理分支指令时PC例如,当我们处理子程序调用时,我们需要首先调用当前值PC 1压栈,遇到子程序返回指令时使用。

栈的特点是LIFO(last in first out),这一点与heap(堆)不同。

5>ctrl_path模块 负责控制通道genpc解码模块产生的地址处的指令,并产生相应的操作数、操作代码和控制模型。这部分信号稍多。

6>tiny_soc 为了测试这个cpu我们需要建立一个最小的系统,包括指令只读取存储器insn_rom机器代码存储在模块中。

由于是harvard结构也需要数据存储器ram相当于内存的模块。

当然,如果你想插其他插件,I/O外设,我们只需要定义它的地址空间,需要注意的是I/O外设的地址空间无法与RAM重叠,各个I/O外设不能重叠。

RAM和I/O外设之间可以通过一个arbiter与cpu core实现数据交互。

当然,如果有不止一个地方存储指令,也需要指令arbiter。

4,RTL实现 在完成模块划分、界面定义、仔细分析和考虑模块间时序后,如果没有问题,我们可以编码。

编码,需要注意的是,编码必须标准化,信号命名,代码注释,尽量小心。这里直接给出RTL代码(verilog HDL)

按自上而下顺序给出:

1>tiny_soc顶层模块:soc_top

/* * * file name : soc_top.v * author : Rill * date : 2013-08-11 * */ `timescale 1ns / 1ps module soc_top ( input clk, input rst ); wire read_e; wire write_e; wire [7:0] port_addr; wire [7:0] core_in; wire [7:0] core_out; wire [15:0] instruction; wire [10:0] inst_addr; wire [15:0] debug_insn; wire [10:0] debug_pc; insn_rom insn_rom ( .clk (lk), .rst (rst), .address (inst_addr), .instruction (instruction) );   core core ( .clk (clk), .rst (rst),   .read_e (read_e), .write_e (write_e), .port_addr (port_addr), .data_in (core_in), .data_out (core_out), .inst_addr (inst_addr), .instruction (instruction), .debug_pc (debug_pc), .debug_insn (debug_insn) );   ram ram ( .clk (clk), .rst (rst),   .wr (write_e), .rd (read_e), .addr (port_addr), .din (core_out), .dout(core_in) );          endmodule

2>指令存储器:insn_rom

/* * * file name    : insn_rom.v * author    : Rill * date        : 2013-08-11 * */       module insn_rom ( input clk, input rst, input [10:0] address, output reg [15:0] instruction );   //(* RAM_STYLE="BLOCK" *) reg [15:0] rom [2047:0];   always @(posedge clk) begin     if(rst)         begin             rom[0] <= 16'h5801;//0:            jmp start             rom[1] <= 16'h1101;//1:start     mov r1,1             rom[2] <= 16'h1202;//2:            mov r2,2             rom[3] <= 16'h3220;//3:            add r2,r1             rom[4] <= 16'h2237;//4:            str r2,55             rom[5] <= 16'h5806;//5:            jmp end             rom[6] <= 16'h5806;//6:end        jmp end*/         end     else         begin             instruction <= rom[address];         end end     endmodule

3>数据存储器:ram

* * * file name    : ram.v * author    : Rill * date        : 2013-08-11 * */     module ram(     input clk,     input rst,          input [7:0] din,     input [7:0] addr,     output reg [7:0] dout,     input wr,     input rd     );      (* RAM_STYLE="DISTRIBUTED" *)         reg [7:0] ram [255:0];      always @(posedge clk)     begin         if(rst)             begin                 dout <= 8'b0;                 ram[0] = 0;                 ram[1] = 1;                 ram[2] = 2;                 ram[32] = 32;                 ram[64] = 64;               end         else             begin             if (wr)                 ram[addr] <= din;             else if(rd)                 dout <= ram[addr];         end     end   endmodule

4>CPU核心:core

/* * * file name    : core.v * author    : Rill * date        : 2013-08-11 * */       module core (     input clk,     input rst,     output [7:0] port_addr,     output read_e,     output write_e,     input [7:0] data_in,     output [7:0] data_out,     output [10:0] inst_addr,     input [15:0] instruction,          output [10:0] debug_pc,//debug i/f     output [15:0] debug_insn );   wire z,c; wire insel; wire we; wire [2:0] raa; wire [2:0] rab; wire [2:0] wa; wire [2:0] opalu; wire [2:0] sh; wire selpc; wire ldpc; wire ldflag; wire [10:0] ninst_addr; wire selk; wire [7:0] KTE; wire [10:0] stack_addr; wire wr_en, rd_en; wire [7:0] imm; wire selimm;         control_path control_path ( .clk (clk), .rst (rst), .instruction (instruction), .z (z), .c (c), .port_addr (port_addr), .write_e (write_e), .read_e (read_e), .insel (insel), .we (we), .raa (raa), .rab (rab), .wa (wa), .opalu (opalu), .sh (sh), .selpc (selpc), .ldpc (ldpc), .ldflag (ldflag), .naddress (ninst_addr), .selk (selk), .KTE (KTE), .stack_addr (stack_addr), .wr_en (wr_en), .rd_en (rd_en), .imm (imm), .selimm (selimm) );       data_path data_path_i ( .clk (clk), .rst (rst), .data_in (data_in), .insel (insel), .we (we), .raa (raa), .rab (rab), .wa (wa), .opalu (opalu), .sh (sh), .selpc (selpc), .selk (selk), .ldpc (ldpc), .ldflag (ldflag), .wr_en (wr_en), .rd_en (rd_en), .ninst_addr (ninst_addr), .kte (KTE), .imm (imm), .selimm (selimm), .data_out (data_out), .inst_addr (inst_addr), .stack_addr (stack_addr), .z (z), .c (c) );   debug debug ( .pc_in (inst_addr), .insn_in (instruction),   .pc (debug_pc), .insn (debug_insn) );     endmodule

5>调试单元:debug

/* * * file name    : debug.v * author    : Rill * date        : 2013-08-11 * */       module debug ( input [10:0] pc_in, input [15:0] insn_in,   output [10:0] pc, output [15:0] insn );   assign pc = pc_in; assign insn = insn_in;   endmodule

6>控制通路:control_path

/* * * file name    : control_path.v * author    : Rill * date        : 2013-08-11 * */       module control_path (     input clk,     input rst,     input [15:0] instruction,     input z,     input c,     output reg [7:0] port_addr,     output reg write_e,     output reg read_e,     output reg insel,     output reg we,     output reg [2:0] raa,     output reg [2:0] rab,     output reg [2:0] wa,     output reg [2:0] opalu,     output reg [2:0] sh,     output reg selpc,     output reg ldpc,     output reg ldflag,     output reg [10:0] naddress,     output reg selk,     output reg [7:0] KTE,     input [10:0] stack_addr,     output reg wr_en, rd_en,     output reg [7:0] imm,     output reg selimm     );     parameter fetch=    5'd0; parameter decode=    5'd1;   parameter ldi=        5'd2; parameter ldm=        5'd3; parameter stm=        5'd4; parameter cmp=        5'd5; parameter add=        5'd6; parameter sub=        5'd7; parameter andi=        5'd8; parameter oor=        5'd9; parameter xori=        5'd10; parameter jmp=        5'd11; parameter jpz=        5'd12; parameter jnz=        5'd13; parameter jpc=        5'd14; parameter jnc=        5'd15; parameter csr=        5'd16; parameter ret=        5'd17;   parameter adi=        5'd18; parameter csz=        5'd19; parameter cnz=        5'd20; parameter csc=        5'd21; parameter cnc=        5'd22; parameter sl0=        5'd23; parameter sl1=        5'd24; parameter sr0=        5'd25; parameter sr1=        5'd26; parameter rrl=        5'd27; parameter rrr=        5'd28; parameter noti=        5'd29;   parameter nop=        5'd30;   wire [4:0] opcode; reg [4:0] state;   assign opcode=instruction[15:11];   always@(posedge clk or posedge rst) begin     if (rst)         begin             state<=decode;         end              else         begin             case (state)                 fetch:                      begin                         state<=decode;                     end                   decode:                      begin                         if(opcode >=ldi && opcode <=nop)                             state <= opcode;//state just is the opcode now                         else                             state <= nop;                     end                                      default:                     state<=fetch;             endcase         end          end         always@(*) begin         port_addr<=0;         write_e<=0;         read_e<=0;         insel<=0;         we<=0;         raa<=0;         rab<=0;         wa<=0;         opalu<=4;         sh<=4;         selpc<=0;         ldpc<=1;         ldflag<=0;         naddress<=0;         selk<=0;         KTE<=0;         wr_en<=0;         rd_en<=0;         imm<=0;         selimm<=0;                  case (state)             fetch:     begin                         ldpc<=0;                     end               decode: begin                         ldpc<=0;                         if (opcode==stm)                             begin                                 raa<=instruction[10:8];                                 port_addr<=instruction[7:0];                             end                         else if (opcode==ldm)                             begin                                 wa<=instruction[10:8];                                 port_addr<=instruction[7:0];                             end                         else if (opcode==ret)                             begin                                 rd_en<=1;                             end                     end                              ldi:    begin                         selk<=1;                         KTE<=instruction[7:0];                         we<=1;                         wa<=instruction[10:8];                     end                                  ldm:    begin                         wa<=instruction[10:8];                         we<=1;                         read_e<=1;                         port_addr<=instruction[7:0];                     end                                  stm:    begin                         raa<=instruction[10:8];                         write_e<=1;                         port_addr<=instruction[7:0];                     end                                  cmp:    begin                         ldflag<=1;                         raa<=instruction[10:8];                         rab<=instruction[7:5];                         opalu<=6;                     end                                  add:    begin                         raa<=instruction[10:8];                         rab<=instruction[7:5];                         wa<=instruction[10:8];                         insel<=1;                         opalu<=5;                         we<=1;                     end                                  sub:    begin                         raa<=instruction[10:8];                         rab<=instruction[7:5];                         wa<=instruction[10:8];                         insel<=1;                         opalu<=6;                         we<=1;                     end                                  andi:    begin                         raa<=instruction[10:8];                         rab<=instruction[7:5];                         wa<=instruction[10:8];                         insel<=1;                         opalu<=1;                         we<=1;                     end                                  oor:    begin                         raa<=instruction[10:8];                         rab<=instruction[7:5];                         wa<=instruction[10:8];                         insel<=1;                         opalu<=3;                         we<=1;                     end                                  xori:    begin                         raa<=instruction[10:8];                         rab<=instruction[7:5];                         wa<=instruction[10:8];                         insel<=1;                         opalu<=2;                         we<=1;                     end                                  jmp:    begin                         naddress<=instruction[10:0];                         selpc<=1;                         ldpc<=1;                     end                                  jpz:        if (z)                         begin                             naddress<=instruction[10:0];                             selpc<=1;                             ldpc<=1;                         end                                                      jnz:        if (!z)                             begin                                 naddress<=instruction[10:0];                                 selpc<=1;                                 ldpc<=1;                             end                                                           jpc:    if (c)                             begin                                 naddress<=instruction[10:0];                                 selpc<=1;                                 ldpc<=1;                             end                                                           jnc:    if (!c)                             begin                                 naddress<=instruction[10:0];                                 selpc<=1;                                 ldpc<=1;                             end                                          csr:    begin                         naddress<=instruction[10:0];                         selpc<=1;                         ldpc<=1;                         wr_en<=1;                     end                                  ret:    begin                         naddress<=stack_addr;                         selpc<=1;                         ldpc<=1;                     end                                  adi:    begin                         raa<=instruction[10:8];                         wa<=instruction[10:8];                         imm<=instruction[7:0];                         selimm<=1;                         insel<=1;                         opalu<=5;                         we<=1;                     end                                      csz:    if (z)                         begin                             naddress<=instruction[10:0];                             selpc<=1;                             ldpc<=1;                             wr_en<=1;                         end                                      cnz:    if (!z)                         begin                             naddress<=instruction[10:0];                             selpc<=1;                             ldpc<=1;                             wr_en<=1;                         end                                      csc:    if (c)                         begin                             naddress<=instruction[10:0];                             selpc<=1;                             ldpc<=1;                             wr_en<=1;                         end                                      cnc:    if (!c)                         begin                             naddress<=instruction[10:0];                             selpc<=1;                             ldpc<=1;                             wr_en<=1;                         end                          sl0:    begin                             raa<=instruction[10:8];                         wa<=instruction[10:8];                         insel<=1;                         sh<=0;                         we<=1;                     end                                  sl1:    begin                             raa<=instruction[10:8];                         wa<=instruction[10:8];                         insel<=1;                         sh<=5;                         we<=1;                     end                                  sr0:    begin                             raa<=instruction[10:8];                         wa<=instruction[10:8];                         insel<=1;                         sh<=2;                         we<=1;                     end                                  sr1:    begin                             raa<=instruction[10:8];                         wa<=instruction[10:8];                         insel<=1;                         sh<=6;                         we<=1;                     end                   rrl:    begin                             raa<=instruction[10:8];                         wa<=instruction[10:8];                         insel<=1;                         sh<=1;                         we<=1;                     end                                                          rrr:    begin                             raa<=instruction[10:8];                         wa<=instruction[10:8];                         insel<=1;                         sh<=3;                         we<=1;                     end                                  noti:    begin                         raa<=instruction[10:8];                         wa<=instruction[10:8];                         insel<=1;                         opalu<=0;                         we<=1;                     end               nop:    begin                         opalu<=4;                     end             endcase end     endmodule

7>数据通路:data_path

/* * * file name    : data_path.v * author    : Rill * date        : 2013-08-11 * */       module data_path (     input clk,     input rst,     input [7:0] data_in,     input insel,     input we,     input [2:0] raa,     input [2:0] rab,     input [2:0] wa,     input [2:0] opalu,     input [2:0] sh,     input selpc,     input selk,     input ldpc,     input ldflag,     input wr_en, rd_en,     input [10:0] ninst_addr,     input [7:0] kte,     input [7:0] imm,     input selimm,     output [7:0] data_out,     output [10:0] inst_addr,     output [10:0] stack_addr,     output  z,c );   wire [7:0] regmux, muximm; wire [7:0] portA, portB;   wire [7:0] shiftout;   assign data_out=shiftout;     genpc genpc ( .clk (clk), .rst (rst),   .ldpc (ldpc), .selpc (selpc), .ninst_addr (ninst_addr),   .inst_addr (inst_addr) );     alu_mux alu_mux ( .selimm (selimm), .imm (imm), .portB (portB),   .muximm (muximm) );   alu alu ( .a (portA), .b (muximm), .opalu (opalu), .ldflag (ldflag), .zero (z), .carry (c), .sh (sh), .dshift (shiftout) );     stack stack ( .clk (clk), .rst (rst), .wr_en (wr_en), .rd_en (rd_en), .din (inst_addr), .dout (stack_addr) );     regfile_mux regfile_mux ( .insel (insel), .selk (selk), .shiftout (shiftout), .kte (kte), .data_in (data_in),   .regmux (regmux) );   regfile regfile ( .datain (regmux), .clk (clk), .we (we), .wa (wa), .raa (raa), .rab (rab), .porta (portA), .portb (portB) );       endmodule

8>程序计算器:genpc

/* * * file name    : genpc.v * author    : Rill * date        : 2013-08-11 * */   `define boot_addr 0     //boot address after power on   module genpc ( input clk, input rst,   input ldpc, input selpc, input [10:0] ninst_addr,   output [10:0] inst_addr );   reg [10:0] pc;   assign inst_addr=pc;   always@(posedge clk or posedge rst) begin     if (rst)         pc <=`boot_addr;     else         if (ldpc)                 if(selpc)                 pc<=ninst_addr;             else                 pc<=pc+1; end     endmodule    

9>运算单元:alu ,alu_mux

/* * * file name    : alu_mux.v * author    : Rill * date        : 2013-08-11 * */       module alu_mux ( input selimm, input [7:0] imm, input [7:0] portB,   output [7:0] muximm );   assign muximm = selimm? imm : portB;//result : imm if ldi insn,portb if ldm insn     endmodule

/* * * file name    : alu.v * author    : Rill * date        : 2013-08-11 * */       module alu ( input [7:0] a, input [7:0] b, input [2:0] opalu, input ldflag, output zero, output carry, input [2:0] sh, output reg [7:0] dshift );   reg [7:0] resu;   assign zero=ldflag?(resu==0):1'b0;   assign carry=ldflag?(a<b):1'b0;   always@(*)     case (opalu)         0: resu <= ~a;         1: resu <= a & b;         2: resu <= a ^ b;         3: resu <= a | b;         4: resu <= a;         5: resu <= a + b;         6: resu <= a - b;         default: resu <= a + 1;     endcase           always@*         case (sh)             0: dshift <= {resu[6:0], 1'b0};             1: dshift <= {resu[6:0], resu[7]};             2: dshift <= {1'b0, resu[7:1]};             3: dshift <= {resu[0], resu[7:1]};             4: dshift <= resu;             5: dshift <= {resu[6:0], 1'b1};             6: dshift <= {1'b1, resu[7:1]};             default: dshift <= resu;         endcase   endmodule

10>寄存器堆:regfile,regfile_mux

/* * * file name    : regfile_mux.v * author    : Rill * date        : 2013-08-11 * */       module regfile_mux ( input insel, input selk, input [7:0] shiftout, input [7:0] kte, input [7:0] data_in,   output [7:0] regmux );   wire [7:0] muxkte;   assign regmux=insel? shiftout : muxkte; assign muxkte=selk? kte : data_in;     endmodule

/* * * file name    : regfile.v * author    : Rill * date        : 2013-08-11 * */       module regfile(     input [7:0] datain,     input clk, we,     input [2:0] wa,     input [2:0] raa,     input [2:0] rab,     output [7:0] porta,     output [7:0] portb     );     reg [7:0] mem [7:0];//r0 ~r255   always@(posedge clk) begin     mem[0]<=0;//r0 always is 0              if(we)         mem[wa]<=datain; end           assign porta=mem[raa]; assign portb=mem[rab];     endmodule

11>栈:stack

/* * * file name    : stack.v * author    : Rill * date        : 2013-08-11 * */       module stack(     input clk,      input rst,     input wr_en,     input rd_en,     input [10:0] din,     output [10:0] dout     );        (* RAM_STYLE="DISTRIBUTED" *) reg [3:0] addr; reg [10:0] ram [15:0];   assign dout = ram[addr] +1;   always@(posedge clk) begin     if (rst)         addr<=0;     else          begin              if (wr_en==0 && rd_en==1)  //leer                 if (addr>0)                     addr<=addr-1;             if (wr_en==1 && rd_en==0)  //guardar                 if (addr<15)                     addr<=addr+1;         end end          always @(posedge clk) begin     if (wr_en)         ram[addr] <= din; end   endmodule

5,modelsim仿真 1>编写testbench 要进行仿真,需要编写对应的testbench,由于咱们这个cpu很简单,所以测试激励也很简单,代码如下:

/* * * file name    : tiny_soc_tb.v * atthor    : Rill * date        : 2013-08-11 * */   `timescale 1ns / 1ps   module tiny_soc_tb;     reg clk; reg rst;     always #5 clk = ~clk;   initial begin     #0          clk = 0;         rst = 0;     #15          rst = 1;     #10          rst = 0;              #1000         $stop; end   soc_top soc_top ( .clk (clk), .rst (rst) );     endmodule

2>编写汇编代码及手动汇编 当然还要编写其汇编代码,如下:

然后我们要手动汇编成机器码,指令集都是自己定义的,所以是没有现成的compiler,只能手动汇编了,还好手动汇编要比手动反汇编轻松多了(之前,我们手动反汇编过OpenRISC的启动代码)。

汇编完成后,我们将机器码放到指令存储器里,如下,共七条指令。

3>仿真结果 完成上面的工作之后,我们就可以用仿真工具进行仿真了,下面是我用modelsim仿真的结果。

从波形可以清晰的看出七条指令的执行过程。在运算完成后拉高write_e信号并将1+2的运算结果3写到了ram地址是55(0x37)的地方

标签: sa12集成电路

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台