8位12指令

仅供参考,有一些文字描述有误且有一些多余,没有修改

代码已修改,过测试用例

波形图按要求要用红线分隔,标出不同时期

具体一条指令为例,每次变化要标红电路图的自变量与因变量

1实验目标/做什么

在Quartus 软件上用VHDL实现8位12指令硬布线CPU
1.1文字描述,必要时画框图辅助说明

文字描述:

8位12指令硬布线CPU是一种基于硬布线设计的中央处理器,具有8位数据总线和12种指令。

8位12指令硬布线CPU框图


1.2实验原理

以控制器为中心,首控制器从指令寄存器取得指令,编译指令,再输出微控制信号,控制ALU的运算,PC加一,并且从RAM中取出数据运算,运算后再把结果通过数据总线存到RAM,在指令寄存器读去下一条指令,依次循环。

实验结果分析说明

1、CPU电路图

 无

2、ram中测试程序说明

序号

指令字

汇编指令

说明

0

ram(0) <= x"14";

STORE 4

把累加器A中的内容存入4单元

1

ram(1) <= x"30";

SUB 0

ACC中数据减去0号数据结果放到ACC中

2

ram(2) <= x"25";

ADD 5

ACC中数据加上5号单元数据结果放到ACC中

3

ram(3) <= x"15";

STORE 5

把累加器A中的内容存入5单元

4

ram(4) <= x"46";

MUL 6

ACC中数据乘上5号单元数据结果放到ACC中

5

ram(5) <= x"31";

SUB 1

ACC中数据减去1号单元数据结果放到ACC中

6

ram(6) <= x"55";

DIV 5

ACC中数据除以5号单元数据结果放到ACC中

7

ram(7) <= x"06";

LOAD 6

把6单元的内容装入累加器A中

8

ram(8) <= x"01";

halt

终止程序

3、测试程序,波形图及指令的对应关系分析,数据运算过程分析

(1)测试程序: 11+22-10

序号

指令字

汇编指令

说明

0

ram(0) <=x"05"

LOAD 5

把5单元的内容装入累加器A中

1

ram(1) <=x"26"

ADD 6

ACC中数据加上6号单元数据结果放到ACC中

2

ram(2) <=x"37"

SUB 7

ACC中数据减去7号数据结果放到ACC中

3

ram(3)<=x"13"

STORE 3

把累加器A中的内容存入3单元

4

ram(4)<="10100001"

HALT

终止程序

5

ram(5)<=x"11"

 原始数据

6

ram(6)<=x"22"

 原始数据

7

ram(7)<=x"10"

 原始数据

(2)程序数据运算过程分析,波形图及逐条指令、逐个部件逐个数据变化的对应关系分析。

波形图

 需要用红线分隔,标出不同时期

LOAD 5

ADD 6

SUB 7

STORE 3

HALT

因为只出现过MAR,MDR,在下面的地址总线ABUS和数据总线DBUS,要修改为MAR和MDR,该版本未修改

逐条指令运算过程

第一条指令 LOAD 5 : 从指定内存地址('00000101')加载数据到累加器。

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

T2

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

Fetch0:(PC) → MAR,M(MAR) → MDR

Fetch1: (MDR) → IR, (PC) + 1 → PC

Load0:(IR) → MAR,M(MAR) → MDR

Load1:(IR) → MAR,M(MAR) → MDR,MDR → ACC

 取指周期: 从内存地址'00000000'中取出指令'00000101'(LOAD 5),将其存入指令寄存器IR,并将程序计数器PC递增到'00000001'。

执行周期: 根据指令寄存器IR中的指令,将内存地址'00000101'的内容('00010001')加载到累加器ACC。

第二条指令 ADD 6 :将累加器中的数据('00010001')与指定内存地址的数据('00100010')相加,结果存回累加器。

 

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

T2

ACC + MDR → ACC

alu_op=0001,Acc_ld=1,acc_selalu=1

Fetch0:(PC) → MAR,M(MAR) → MDR

Fetch1: (MDR) → IR, (PC) + 1 → PC

ADD0:(IR) → MAR,M(MAR) → MDR

ADD1:(IR) → MAR,M(MAR) → MDR,ACC + MDR→ ACC

取指周期: 从内存地址'00000001'中取出指令'00100110'(ADD 6),将其存入指令寄存器IR,并将程序计数器PC递增到'00000010'。

执行周期: 根据指令寄存器IR中的指令,将内存地址'00000110'的内容('00010010')与累加器ACC中的内容('00010001')相加,结果存回累加器ACC。

第三条指令 SUB 7:将累加器中的数据('00110011')与指定内存地址的数据('00010000')相减,结果存回累加器。

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

T2

ACC - MDR → ACC

alu_op=0101,Acc_ld=1,acc_selalu=1

Fetch0:(PC) → MAR,M(MAR) → MDR

Fetch1: (MDR) → IR, (PC) + 1 → PC

SUB0:(IR) → MAR,M(MAR) → MDR

SUB1:(IR) → MAR,M(MAR) → MDR,ACC - MDR→ ACC

取指周期: 从内存地址'00000010'中取出指令'00110111'(SUB 7),将其存入指令寄存器IR,并将程序计数器PC递增到'00000011'。

执行周期: 根据指令寄存器IR中的指令,将累加器ACC中的内容('00110011')与内存地址'00000111'的内容('00010000')相减,结果存回累加器ACC。

第四条指令 STORE 3:将累加器中的数据('00100011')存储到指定内存地址('00000011')。

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

ACC → MDR

Acc_enD=1

T2

MDR → M(MAR)

mem_rw=0

Fetch0:(PC) → MAR,M(MAR) → MDR

Fetch1: (MDR) → IR, (PC) + 1 → PC

STORE0:(IR) → MAR,ACC → MDR

STORE1:MDR → M(MAR)

 取指周期:从内存地址'00000011'中取出指令'00010011'(STORE 3),将其存入指令寄存器IR,并将程序计数器PC递增到'00000100'。

执行周期:根据指令寄存器IR中的指令,将累加器ACC中的内容('00100011')存储到内存地址'00000011'。

第五条指令 HALT:停止CPU的执行。

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(ABUS) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

停机

halt <= '1' when irReg = "10100001"

Fetch0:(PC) → MAR,M(MAR) → MDR

Fetch1: (MDR) → IR, (PC) + 1 → PC

HALT

取指周期: 从内存地址'00000100'中取出指令'10100001'(HALT),将其存入指令寄存器IR,并将程序计数器PC递增到'00000101'。

执行周期: 根据指令寄存器IR中的指令,CPU停止执行指令。

(3)以任一一条指令为例,必须结合指令周期各个阶段(fetch0、fetch1、add0、add1...)、测试波形、电路图、代码、指令系统设计具体说明,标注控制信号,地址,数据等信息的每一次流动、变化。

以 LOAD 5 指令为例,结合指令周期各个阶段(fetch0、fetch1、add0、add1...)、测试波形、电路图、代码、指令系统设计具体说明,标注控制信号,地址,数据等信息的每一次流动、变化。

在其(LOAD 5 指令)下面有剩余指令的文字描述

 

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

T2

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

取指周期

Fetch0:(PC) → MARM(MAR) → MDR

(PC) → MAR

第一步:PC将指令地址通过地址总线给MAR

每当PC的值放到地址总线时,pc_enA为1,即标志PC访问MAR,即aBus <= pcReg

PC将指令地址直接传给RAM

ABUS中,若传输的为pc中的值,则为递增从0000到1001(9)的数

此时地址总线数值为0000,0000,MAR数值为0000,0000

M(MAR) → MDR

第二步:将MAR所指的内存单元经过数据总线给MDR

mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0000,即RAM中0号存储单元对应的数据;

数据总线的数值为0000,0101,MDR数值为0000,0101

 

Fetch1: (MDR) → IR, (PC) + 1 → PC

(MDR) → IR

第三步:将MDR中的内容给IR

MAR数值与MDR数值不变

此时mem_rw=1,mem_enD=1,ir_ldx为1标志IR被写入数据,即irReg <= dBus;

IR的寄存器数值为0000,0101

 

(PC) + 1 → PC

第四步:形成下一条指令

PC_inc=1,即标志pc移动到下一位,即PC+1

此时,PC寄存器数据数值为0000,0001

 

执行周期

Load0:(IR) → MAR,M(MAR) → MDR

(IR) → MAR

第五步:将指令的操作码部分给CU

ir_enAX = '1',标志着CU用IR的后4位(4到7位)作为操作码,进行译码,

即aBus <= "0000" & irReg(3 downto 0)

IR的寄存器数值为0000,0101,指令为0000,0101

操作码为0000,标志着执行LOAD指令

地址总线数值为0000,0101,MAR数值为0000,0101

 

M(MAR) → MDR

第六步:将MAR所指的内存单元经过数据总线给MDR

reset = '0',mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0101,即RAM中5号存储单元对应的数据;

数据总线的数值为0001,0001

MDR数值为0001,0001

 

Load1:(IR) → MAR,M(MAR) → MDRMDR → ACC

 

(IR) → MAR,M(MAR) → MDR没有数值变化

 电路图如上面的两个图一样

MDR → ACC

第七步:将MDR的数据加载到ACC寄存器中

Acc_ld=1,selAlu = '0',标志着将MDR的数据加载到ACC寄存器中,即DBUS->ACC

accReg <= dBus;

MDR数值为0001,0001,

在执行周期的最后,上升沿时,ACC寄存器的数据数值改为0001,0001

ADD 6

 

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

T2

ACC + MDR → ACC

alu_op=0001,Acc_ld=1,acc_selalu=1

取指周期

Fetch0:(PC) → MAR,M(MAR) → MDR

(PC) → MAR

第一步:PC将指令地址通过地址总线给MAR

每当PC的值放到地址总线时,pc_enA为1,即标志PC访问MAR,即aBus <= pcReg

PC将指令地址直接传给RAM

ABUS中,若传输的为pc中的值,则为递增从0000到1001(9)的数

此时地址总线数值为0000,0001

MAR数值为0000,0001

M(MAR) → MDR

第二步:将MAR所指的内存单元经过数据总线给MDR

mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0001,即RAM中1号存储单元对应的数据;

数据总线的数值为0010,0110

MDR数值为0010,0110

Fetch1: (MDR) → IR, (PC) + 1 → PC

(MDR) → IR

第三步:将MDR中的内容给IR

MAR数值与MDR数值不变

此时mem_rw=1,mem_enD=1,ir_ldx为1,标志IR被写入数据,即irReg <= dBus;

IR的寄存器数值为0010,0110

(PC) + 1 → PC

第四步:形成下一条指令

PC_inc=1,即标志pc移动到下一位,即PC+1

此时,PC寄存器数据数值为0000,0010

执行周期

ADD0:(IR) → MAR,M(MAR) → MDR

(IR) → MAR

第五步:将指令的操作码部分给CU

ir_enAX = '1',标志着CU用IR的后4位(4到7位)作为操作码,进行译码,

即aBus <= "0000" & irReg(3 downto 0)

IR的寄存器数值为0010,0110

指令为0010,0110

操作码为0010,标志着执行ADD指令

地址总线数值为0000,0110

MAR数值为0000,0110

M(MAR) → MDR

第六步:将MAR所指的内存单元经过数据总线给MDR

mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0110,,即RAM中6号存储单元对应的数据;

数据总线的数值为0010,0010

MDR数值为0010,0010

 

ADD1:(IR) → MAR,M(MAR) → MDR,ACC + MDR→ ACC

 

(IR) → MAR,M(MAR) → MDR没有数值变化

 

ACC + MDR → ACC

第七步:将MDR的数据与ACC寄存器的数据累加,放到ACC寄存器中

alu_op="0001",Acc_ld=1,acc_selalu=1,标志着将MDR的数据与ACC寄存器的数据累加,放到ACC寄存器中,即result <=accD + dBus when op ="0001",accReg <= aluD;

ACC寄存器放的数据原来数值为0001,0001

MDR数值为0010,0010

在执行周期的最后,上升沿时,ACC寄存器的数值改为0011,0011

SUB 7

 

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

T2

ACC - MDR → ACC

alu_op=0101,Acc_ld=1,acc_selalu=1

取指周期

Fetch0:(PC) → MAR,M(MAR) → MDR

(PC) → MAR

第一步:PC将指令地址通过地址总线给MAR

每当PC的值放到地址总线时,pc_enA为1,即标志PC访问MAR,即aBus <= pcReg

PC将指令地址直接传给RAM

ABUS中,若传输的为pc中的值,则为递增从0000到1001(9)的数

此时地址总线数值为0000,0010

MAR数值为0000,0010

M(MAR) → MDR

第二步:将MAR所指的内存单元经过数据总线给MDR

mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0010,即RAM中2号存储单元对应的数据;

数据总线的数值为0011,0111,MDR数值为0011,0111

Fetch1: (MDR) → IR, (PC) + 1 → PC

(MDR) → IR

第三步:将MDR中的内容给IR

MAR数值与MDR数值不变

此时mem_rw=1,mem_enD=1,ir_ldx为1,标志IR被写入数据,即irReg <= dBus;

IR的寄存器数值为0011,0111

(PC) + 1 → PC

第四步:形成下一条指令

PC_inc=1,即标志pc移动到下一位,即PC+1

此时,PC寄存器数据数值为0000,0011

执行周期

SUB0:(IR) → MAR,M(MAR) → MDR

(IR) → MAR

第五步:将指令的操作码部分给CU

ir_enAX = '1',标志着CU用IR的后4位(4到7位)作为操作码,进行译码,

即aBus <= "0000" & irReg(3 downto 0)

IR的寄存器数值为0011,0111

指令为0011,0111

操作码为0011,标志着执行SUB指令

地址总线数值为0000,0111

MAR数值为0000,0111

M(MAR) → MDR

第六步:将MAR所指的内存单元经过数据总线给MDR

mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0111,,即RAM中7号存储单元对应的数据;

数据总线的数值为0001,0000

MDR数值为0001,0000

 

SUB1:(IR) → MAR,M(MAR) → MDR,ACC - MDR→ ACC

 

(IR) → MAR,M(MAR) → MDR没有数值变化

 

ACC - MDR→ ACC

第七步:将ACC寄存器的数据减去MDR的数据,放到ACC寄存器中

alu_op="0101",Acc_ld=1,acc_selalu=1,标志着将MDR的数据与ACC寄存器的数据累加,放到ACC寄存器中,即result <=accD-dBus when op="0101",accReg <= aluD;

ACC寄存器放的数据原来数值为0011,0011

MDR数值为0001,0000

在执行周期的最后,上升沿时,ACC寄存器的数值改为0010,0011

STORE 3

 

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(MAR) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

(IR) → MAR

ir_enAX=1

ACC → MDR

Acc_enD=1

T2

MDR → M(MAR)

mem_rw=0

取指周期

Fetch0:(PC) → MAR,M(MAR) → MDR

(PC) → MAR

第一步:PC将指令地址通过地址总线给MAR

每当PC的值放到地址总线时,pc_enA为1,即标志PC访问MAR,即aBus <= pcReg

PC将指令地址直接传给RAM

ABUS中,若传输的为pc中的值,则为递增从0000到1001(9)的数

此时地址总线数值为0000,0011

MAR数值为0000,0011

M(MAR) → MDR

第二步:将MAR所指的内存单元经过数据总线给MDR

mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0011,即RAM中3号存储单元对应的数据;

数据总线的数值为0001,0011

MDR数值为0001,0011

Fetch1: (MDR) → IR, (PC) + 1 → PC

(MDR) → IR

第三步:将MDR中的内容给IR

MAR数值与MDR数值不变

此时mem_rw=1,mem_enD=1,ir_ldx为1,标志IR被写入数据,即irReg <= dBus;

IR的寄存器数值为0001,0011

(PC) + 1 → PC

第四步:形成下一条指令

PC_inc=1,即标志pc移动到下一位,即PC+1

此时,PC寄存器数据数值为0000,0100

执行周期

 

STORE0:(IR) → MAR,ACC → MDR

(IR) → MAR

第五步:将指令的操作码部分给CU

ir_enAX = '1',标志着CU用IR的后4位(4到7位)作为操作码,进行译码,

即aBus <= "0000" & irReg(3 downto 0)

IR的寄存器数值为0001,0011

指令为0001,0011

操作码为0001,标志着执行STORE指令

地址总线数值为0000,0011

MAR数值为0000,0011

ACC → MDR

第六步:将ACC寄存器的数据经过数据总线给MDR

Acc_enD=1,,即标志将ACC寄存器的数据经过数据总线给MDR,即dBus <= accReg when en_D = '1'

此时ACC寄存器的数据数值为0010,0011,

数据总线的数值为0010,0011,MDR数值为0010,0011

 

STORE1:MDR → M(MAR)

 

MDR → M(MAR)

第七步:将MDR的数据存到存储器对应的存储单元中

mem_rw <= '0',标志着写入操作,将MDR的数据存到存储器对应的3号存储单元中,即ram(conv_integer(unsigned(aBus))) <= dBus;

地址总线数值为0000,0011,MAR数值为0000,0011

dBus数据数值为0010,0011,MDR数值为0010,0011

MAR对应的3号存储单元存放数据修改为0010,0011

HALT

 

周期

所执行的操作

对应的微程序操作

T0

(PC) → MAR

PC_enA=1

MEM(ABUS) → MDR

mem_rw=1,mem_enD=1

MDR → IR

ir_ld=1

(PC) + 1 → PC

PC_inc=1

T1

停机

halt <= '1' when irReg = "10100001"

取指周期

Fetch0:(PC) → MAR,M(MAR) → MDR

(PC) → MAR

第一步:PC将指令地址通过地址总线给MAR

每当PC的值放到地址总线时,pc_enA为1,即标志PC访问MAR,即aBus <= pcReg

PC将指令地址直接传给RAM

ABUS中,若传输的为pc中的值,则为递增从0000到1001(9)的数

此时地址总线数值为0000,0100

MAR数值为0000,0100

M(MAR) → MDR

第二步:将MAR所指的内存单元经过数据总线给MDR

mem_rw=1,mem_enD=1,即标志将MAR所指的内存单元经过数据总线给MDR,即dBus <= ram(conv_integer(unsigned(aBus)))

此时地址总线的数值为0000,0100,即RAM中4号存储单元对应的数据;

数据总线的数值为"10100001",MDR数值为"10100001",十六进制表现为A1

Fetch1: (MDR) → IR, (PC) + 1 → PC

(MDR) → IR

第三步:将MDR中的内容给IR

MAR数值与MDR数值不变

此时mem_rw=1,mem_enD=1,ir_ldx为1,标志IR被写入数据,即irReg <= dBus;

IR的寄存器数值为"10100001"

(PC) + 1 → PC

第四步:形成下一条指令

PC_inc=1,即标志pc移动到下一位,即PC+1

此时,PC寄存器数据数值为'0000,0101'

执行周期

 

HALT

停机

ram(4) <= "10100001";

halt    <= '1' when irReg = "10100001"  else '0';

when halt =>  state <= halt;

测试波形

包括且不限类似讲课于PPT中的:

⑴取指周期

取指周期完成的微操作序列是公共的操作,与具体指令无关。

① PCout和MARin有效,完成PC经CPU内部总线送至MAR的操作,记作(PC)→MAR;

代码

附录:8位模型机的VHDL程序

☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆*****************           源   程  序          ********************

1、 累加寄存器accumulator

 

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity accumulator is                   ----声明外部实体接口

    port (

        clk, en_D, ld, selAlu, reset: in STD_LOGIC; --时钟信号

        aluD: in STD_LOGIC_VECTOR(7 downto 0);

        dBus: inout STD_LOGIC_VECTOR(7 downto 0);

        q: out STD_LOGIC_VECTOR(7 downto 0)

    );

end accumulator;

architecture accArch of accumulator is

signal accReg: STD_LOGIC_VECTOR(7 downto 0);

begin

  process(clk) begin

   if clk'event and clk = '1' then

    if reset = '1' then

     accReg <= "00000000";

    elsif ld = '1' and selAlu = '1' then

     accReg <= aluD;

    elsif ld = '1' and selAlu = '0' then

     accReg <= dBus;

    end if;

   end if;

  end process;

  dBus <= accReg when en_D = '1' else

     "ZZZZZZZZ";

  q <= accReg;  

end accArch;

2、 算术运算器 ALU

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity alu is                           -----实体声明外部接口

    port (

        op: in STD_LOGIC_VECTOR(3 downto 0);   --选择控制运算类型

        accD: in STD_LOGIC_VECTOR(7 downto 0); -- 累加器的8位数据

        dBus: in STD_LOGIC_VECTOR(7 downto 0); -- 数据总线用于运算

        result: out STD_LOGIC_VECTOR(7 downto 0);   --结果的输出

  

        accZ: out STD_LOGIC

);

end alu;

architecture aluArch of alu is

begin

  result <= (not accD) + "00000001" when op ="0000" else

       accD + dBus when op ="0001" else

       accD+"10000000" when op="0010" else

       dBus+"10000000" when op="0011" else

       (not accD)-"00000001" when op="0100" else

       accD-dBus when op="0101" else

 accD(3 downto 0)*dBus(3 downto 0) when op="0110" else

       accD(3 downto 0)*(not dBus(3 downto 0)) when op="0111" else

       accD AND  dBus when op="1010" else

       accD NAND dBus when op="1011" else

       accD OR   dBus when op="1100" else

       accD NOR  dBus when op="1101" else

       accD XNOR dBus when op="1110" else

       NOT accD when op="1111" else

       "00000000";

 accZ <= not (accD(0) or  accD(1) or  accD(2) or  accD(3) or

          accD(4) or  accD(5) or  accD(6) or  accD(7)

);

end aluArch;

3、 硬布线控制器(controller)

library IEEE;

use IEEE.std_logic_1164.all;

entity controller is                       ----声明实体外部接口

    port (

     clk, reset:

  in  STD_LOGIC;

     mem_enD, mem_rw:   

out STD_LOGIC;

     pc_enA, pc_ld, pc_inc:   out STD_LOGIC;

     ir_enA, ir_enD, ir_ld:   out STD_LOGIC;

     ir_load, ir_store, ir_add: in  STD_LOGIC;

     ir_sub,ir_mul,ir_div:  in STD_LOGIC;

     ir_and,ir_or, ir_not:  in STD_LOGIC;

     ir_neg, ir_halt, ir_branch:  in  STD_LOGIC;

     acc_enD, acc_ld, acc_selAlu:  out STD_LOGIC;

     alu_op:    out STD_LOGIC_VECTOR(3 downto 0)

    );

end controller;

architecture controllerArch of controller is

type state_type is ( reset_state,

   fetch0, fetch1,

   load0, load1,

   store0, store1,

   add0, add1,

   sub0, sub1,

   mul0, mul1,

   div0, div1,

   and0, and1,

   or0,  or1,

   not0, not1,

   negate0, negate1,

   halt,

   branch0, branch1

   );

signal state: state_type;

begin

  process(clk) begin

   if clk'event and clk = '1' then

    if reset = '1' then state <= reset_state;

      else

       case state is

       when reset_state => state <= fetch0;

       when fetch0 => state <= fetch1;

     when fetch1 =>

      if ir_load = '1' then state <= load0;

      elsif ir_store   = '1' then state <= store0;

      elsif ir_add     = '1' then state <= add0;

      elsif ir_sub     = '1' then state <= sub0;

      elsif ir_mul     = '1' then state <= mul0;

      elsif ir_div     = '1' then state <= div0;

      elsif ir_and     = '1' then state <= and0;

      elsif ir_or      = '1' then state <= or0;

      elsif ir_not     = '1' then state <= not0;

      elsif ir_neg     = '1' then state <= negate0;

      elsif ir_halt    = '1' then state <= halt;

      elsif ir_branch  = '1' then state <= branch0;

      end if;

     when load0 =>  state <= load1;

     when load1 =>  state <= fetch0;

     when store0 =>  state <= store1;

     when store1 => state <= fetch0;

     when add0 =>  state <= add1;

     when add1 =>  state <= fetch0;

     when sub0 =>  state <= sub1;

     when sub1 =>  state <= fetch0;

     when mul0 =>  state <= mul1;

     when mul1 =>  state <=fetch0;

     when div0 =>  state <=div1;

     when div1 =>  state <=fetch0;

     when and0 =>  state <=and1;

     when and1 =>  state <=fetch0;

     when or0  =>  state <=or1;

     when or1  =>  state <=fetch0;

     when not0 =>  state <=not1;

     when not1 =>  state <=fetch0;

     when negate0 => state <= negate1;

     when negate1 => state <= fetch0;

     when halt =>  state <= halt;

     when branch0 => state <= branch1;

     when branch1 => state <= fetch0;

     when others =>  state <= halt;

     end case;

    end if;

   end if;

  end process;

  process(clk) begin -- special process for memory write timing

   if clk'event and clk = '0' then

    if state = store0 then

     mem_rw <= '0';

    else

     mem_rw <= '1';

    end if;

   end if;

  end process;

  mem_enD <= '1'   when state =  fetch0 or state =  fetch1 or

     state =   load0 or state =   load1 or

     state =    add0 or state =    add1 or

     state =    sub0 or state =    sub1 or

     state =    mul0 or state =    mul1 or

     state =    div0 or state =    div1 or

     state =    and0 or state =    and1 or

     state =    or0  or state =    or1 else '0';

  pc_enA <= '1'    when state =  fetch0 or

          state = fetch1   else '0';

  pc_ld <= '1'    when state = branch0  

       else '0';

  pc_inc <= '1'    when state = fetch1

       else '0';

  ir_enA <= '1'    when state = load0 or

     state = load1 or state = store0 or

     state =  store1 or state =  add0 or

     state =  add1 or   state =    sub0 or

     state =    sub1 or state =    mul0 or

     state =    mul1 or state =    div0 or

     state =    div1 or state =    and0 or

     state =    and1 or state =    or0  or

     state =    or1        else '0';

  ir_enD <= '1'    when state = branch0  

       else '0';

  ir_ld <= '1'    when state = fetch1

       else '0';

  acc_enD <= '1'   when state =  store0 or state =  store1  else '0';

  acc_ld <= '1'    when state =  load1 or state =   add1 or state = negate1  

                   or state =  sub1 or state = mul1 or state = div1

                   or state = not1 or state = or1 or state = not1   else '0';

  acc_selAlu <='1' when state = add1 or state = negate1 or state =  sub1 or

                    state = mul1 or state = div1  or state = not1 or

                    state = or1 or state = not1  else '0';

  alu_op <= "0001" when state = add0 or state = add1 ---

       else "0101" when state = sub0 or state = sub1 ---

       else "0110" when state = mul0 or state = mul1 --

       else "0111" when state = div0 or state = div1 --错了吧

       else "0000" when state = negate0 or state = negate1 ---

       else "1010" when state = and0 or state = and1 ---

       else "1100" when state = or0 or state = or1 ----

       else "1111" when state = not0 or state = not1 ---

 else "1000"; --查无此人

       

  --alu_op <= "01"   when state =  add0 or state =  add1  else "00";

end controllerArch;

4、 指令寄存器instruction_register

library IEEE;

use IEEE.std_logic_1164.all;

entity instruction_register is          ----声明实体外部接口

    port (

        clk, en_A, en_D, ld, reset: in STD_LOGIC;

        aBus: out STD_LOGIC_VECTOR(7 downto 0); ----数据总线输出

        dBus: inout STD_LOGIC_VECTOR(7 downto 0);

        load, store, add, sub,mul,div,andd,orr,nott,neg, halt, branch: out STD_LOGIC

        );

end instruction_register;

architecture irArch of instruction_register is

signal irReg: STD_LOGIC_VECTOR(7 downto 0);

begin

  process(clk) begin

   if clk'event and clk = '0' then -- load on falling edge

    if reset = '1' then

     irReg <= "00000000";

    elsif ld = '1' then

     irReg <= dBus;

    end if;

   end if;

  end process;

  aBus <= "0000" & irReg(3 downto 0) when en_A = '1' else

     "ZZZZZZZZ";

  dBus <= "0000" & irReg(3 downto 0) when en_D = '1' else

     "ZZZZZZZZ";

  load    <= '1' when irReg(7 downto 4) = "0000"  else '0';

  store   <= '1' when irReg(7 downto 4) = "0001"  else '0';

  add     <= '1' when irReg(7 downto 4) = "0010"  else '0';

  sub     <= '1' when irReg(7 downto 4) = "0011"  else '0';

  mul     <= '1' when irReg(7 downto 4) = "0100"  else '0';

  div     <= '1' when irReg(7 downto 4) = "0101"  else '0';

  neg     <= '1' when irReg = "0110" & "0000"  else '0';

  andd    <= '1' when irReg (7 downto 4) = "0111" else '0';

  orr     <= '1' when irReg (7 downto 4) = "1000" else '0';

  nott    <= '1' when irReg (7 downto 4) = "1001" else '0';

  halt    <= '1' when irReg = "10100001"  else '0';

  branch  <= '1' when irReg(7 downto 4) = "1011"  else '0';

end irArch;

5. 程序计数器program_counter

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity program_counter is

    port (

        clk, en_A, ld, inc, reset: in STD_LOGIC;

        aBus: out STD_LOGIC_VECTOR(7 downto 0); --数据总线输出

        dBus: in STD_LOGIC_VECTOR(7 downto 0) --数据总线输入

    );

end program_counter;

architecture pcArch of program_counter is

signal pcReg: STD_LOGIC_VECTOR(7 downto 0);

begin

  process(clk) begin

   if clk'event and clk = '1' then

    if reset = '1' then

     pcReg <= "00000000";

    elsif ld = '1' then

     pcReg <= dBus;

    elsif inc = '1' then

     pcReg <= pcReg + "00000001";

    end if;

   end if;

  end process;

  aBus <= pcReg when en_A = '1' else "ZZZZZZZZ";

end pcArch;

6、 存储器RAM

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;

entity ram is

    port (

        r_w, en, reset: in STD_LOGIC;

        aBus: in STD_LOGIC_VECTOR(7 downto 0);  ----数据总线输入

        dBus: inout STD_LOGIC_VECTOR(7 downto 0)

    );

end ram;

architecture ramArch of ram is

type ram_typ is array(0 to 63) of STD_LOGIC_VECTOR(7 downto 0);

signal ram: ram_typ;

begin

  process(

en, reset, r_w, aBus, dBus

) begin

   if reset = '1' then

    --ram(0) <= x"14";

    --ram(1) <= x"30";

    --ram(2) <= x"25";

    --ram(3) <= x"15";

    --ram(4) <= x"46";

    --ram(5) <= x"31";

    --ram(6) <= x"55";

    --ram(7) <= x"06";

--ram(8) <= "10100001";

 ram(0) <= x"05";

    ram(1) <= x"26";

    ram(2) <= x"37";

    ram(3) <= x"13";

 ram(4) <= "10100001";

    ram(5) <= x"11";

    ram(6) <= x"22";

    ram(7) <= x"10";

  elsif r_w = '0' then

    ram(conv_integer(unsigned(aBus))) <= dBus;

   end if;

  end process;

  dBus <= ram(conv_integer(unsigned(aBus)))

    when reset = '0' and en = '1' and r_w = '1' else

   "ZZZZZZZZ";

end ramArch;

7、 由6大模块组成模型机(top_level)

library IEEE;

use IEEE.std_logic_1164.all;

entity top_level is                ----声明实体外部接口

    port (

        clk, reset:   

in  STD_LOGIC;

        abusX:     out STD_LOGIC_VECTOR(7 downto 0); --数据总线输出

        dbusX:     out STD_LOGIC_VECTOR(7 downto 0);

        mem_enDX, mem_rwX:  

 out STD_LOGIC;

        pc_enAX, pc_ldX, pc_incX:

out STD_LOGIC;

        ir_enAX, ir_enDX, ir_ldX:

 out STD_LOGIC;

        acc_enDX, acc_ldX, acc_selAluX:

 out STD_LOGIC;

        acc_QX:    out STD_LOGIC_VECTOR(7 downto 0);

        alu_accZX:   out STD_LOGIC;

        alu_opX:   out STD_LOGIC_VECTOR(3 downto 0)

    );

end top_level;

architecture topArch of top_level is

component program_counter

    port (

        clk, en_A, ld, inc, reset: in STD_LOGIC;

        aBus: out STD_LOGIC_VECTOR(7 downto 0);

        dBus: in STD_LOGIC_VECTOR(7 downto 0)

    );

end component;

component instruction_register

    port (

        clk, en_A, en_D, ld, reset: in STD_LOGIC;

        aBus: out STD_LOGIC_VECTOR(7 downto 0);

        dBus: inout STD_LOGIC_VECTOR(7 downto 0);

        load, store, add, sub,mul,div,neg,andd,orr,nott, halt, branch: out STD_LOGIC

           );

end component;

component accumulator

    port (

        clk, en_D, ld, selAlu, reset: in STD_LOGIC;

        aluD: in STD_LOGIC_VECTOR(7 downto 0);

        dBus: inout STD_LOGIC_VECTOR(7 downto 0);

        q: out STD_LOGIC_VECTOR(7 downto 0)

    );

end component;

component alu

    port (

        op: in STD_LOGIC_VECTOR(3 downto 0);

        accD: in STD_LOGIC_VECTOR(7 downto 0);

        dBus: in STD_LOGIC_VECTOR(7 downto 0);

        result: out STD_LOGIC_VECTOR(7 downto 0);

        accZ: out STD_LOGIC

    );

end component;

component ram

    port (

        r_w, en, reset: in STD_LOGIC;

        aBus: in STD_LOGIC_VECTOR(7 downto 0);

        dBus: inout STD_LOGIC_VECTOR(7 downto 0)

    );

end component;

component controller

    port (

     clk, reset:   in  STD_LOGIC;

     mem_enD, mem_rw:   out STD_LOGIC;

     pc_enA, pc_ld, pc_inc:   out STD_LOGIC;

     ir_enA, ir_enD, ir_ld:   out STD_LOGIC;

     ir_load, ir_store, ir_add: in  STD_LOGIC;

     ir_sub,  ir_mul, ir_div:  in STD_LOGIC;

     ir_and,  ir_or, ir_not: in  STD_LOGIC;

     ir_neg, ir_halt, ir_branch:  in  STD_LOGIC;

     acc_enD, acc_ld, acc_selAlu:  out STD_LOGIC;

     alu_op:    out STD_LOGIC_VECTOR(3 downto 0)

    );

end component;

signal abus: STD_LOGIC_VECTOR(7 downto 0);

signal dbus: STD_LOGIC_VECTOR(7 downto 0);

signal mem_enD, mem_rw:   STD_LOGIC;

signal pc_enA, pc_ld, pc_inc:  STD_LOGIC;

signal ir_enA, ir_enD, ir_ld:  STD_LOGIC;

signal ir_load, ir_store, ir_add: STD_LOGIC;

signal ir_sub,  ir_mul, ir_div: STD_LOGIC;

signal ir_and, ir_or, ir_not: STD_LOGIC;

signal ir_negate, ir_halt, ir_branch: STD_LOGIC;

signal acc_enD, acc_ld, acc_selAlu: STD_LOGIC;

signal acc_Q:    STD_LOGIC_VECTOR(7 downto 0);

signal alu_op:    STD_LOGIC_VECTOR(3 downto 0);

signal alu_accZ:   STD_LOGIC;

signal alu_result:   STD_LOGIC_VECTOR(7 downto 0);

begin

  pc: program_counter port map(clk, pc_enA, pc_ld, pc_inc, reset, abus, dbus);

  ir: instruction_register port map(clk, ir_enA, ir_enD, ir_ld, reset, abus,dbus,ir_load,ir_store,ir_add,ir_sub,ir_mul,ir_div,ir_and,ir_or,ir_not,ir_negate, ir_halt, ir_branch );

  acc: accumulator port map(clk, acc_enD, acc_ld, acc_selAlu, reset, alu_result, dbus, acc_Q);

  aluu: alu port map(alu_op, acc_Q, dbus, alu_result, alu_accZ);

  mem: ram port map(mem_rw, mem_enD, reset, abus, dbus);

  ctl: controller port map (

clk, reset, mem_enD, mem_rw, pc_enA, pc_ld, pc_inc,

      ir_enA, ir_enD, ir_ld, ir_load, ir_store, ir_add,ir_sub,

ir_mul,ir_div,ir_and,ir_or,ir_not,

      ir_negate, ir_halt, ir_branch,acc_enD,

 acc_ld, acc_selAlu, alu_op);

   abusX <= abus;

   dbusX <= dbus;

   mem_enDX <= mem_enD;

   mem_rwX <= mem_rw;

   pc_enAX <= pc_enA;

   pc_ldX <= pc_ld;

   pc_incX <= pc_inc;

   ir_enAX <= ir_enA;

   ir_enDX <= ir_enD;

   ir_ldX <= ir_ld;

   acc_enDX <= acc_enD;

   acc_ldX <= acc_ld;

   acc_selAluX <= acc_selAlu;

   acc_QX <= acc_Q;

   alu_opX <= alu_op;

   alu_accZX <= alu_accZ;

end topArch;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值