os:我还不太会操作CSDN,实现方面也有很大不足,但敬请批评指正
设计题目(范围): 设计实现一个字长8位的CPU
课程设计内容:
根据数据通路,自行设计指令系统,并设计实现一个字长8位的CPU,所设计的系统能调试通过,通过运行自行编写的程序进行仿真测试,通过检查程序结果的正确性来判断所设计计算机系统的正确性。
课程设计要求:
1、提前熟悉CPU的各个组成部分,以及Verilog语言和Quartus II软件的使用方法。
2、可使用如图1所示的数据通路设计CPU,也可以自行设计数据通路,要求必须包含图1中的部件,且总线位数与寄存器位数保持一致。若自行设计的数据通路合理,则得分高。
说明:CPU具有以下寄存器:
- 4个8位通用寄存器R0[7:0]、R1[7:0]、R2[7:0]和R3[7:0]。
- 8位的地址寄存器 AR[7:0]
- 8位的程序计数器 PC[7:0]
- 8位的数据寄存器 DR[7:0]
- 8位的指令寄存器 IR[7:0]
- 8位的数据暂存器 X[7:0],用于暂存ALU输入端的数据
- 8位的数据暂存器 Y[7:0],用于暂存ALU输出端的数据
- 1位的“0”标志寄存器Z,用于标志运算结果。如果运算结果为0,则Z=1;否则Z=0。
图1数据通路
3、确定指令格式,按照以下要求,至少完成以下(1)-(4)必做指令:
(1)空指令(1条):NOP ;空操作
(2)算术逻辑运算类指令(7条):
- 双操作数算术运算指令:ADD和SUB
-
- ADD Rd,Rs、 SUB Rd,Rs ;Rd和Rs运算,结果送Rd
-
- 双操作数逻辑运算指令:AND和OR
-
- AND Rd,Rs、 OR Rd,Rs ;Rd和Rs运算,结果送Rd
-
- 单操作数指令:INC、DEC、NOT
-
- INC Rd, DEC Rd, NOT Rd ;对Rd运算,结果送Rd
-
(3)移位指令(1条):
- SHL Rd Rs ;对Rd左移Rs位,结果送Rd,移位的位数提前放到Rs
(4)传送指令(2条):
- MVR Rd,Rs ;Rd<—Rs
- MVRD Rd,imm ;Rd<—立即数imm
(5)无条件跳转指令(1条):JMP A(选做) ;A为跳转到的8位地址
(6)条件跳转指令(2条):(选做)
- JMPZ A ;z=1时跳转,A为跳转到的8位地址
- JPNZ A ;z=0时跳转,A为跳转到的8位地址
注意需要加零标志寄存器Z
(7)寄存器-存储器数据传送(2条):(选做)
- LAD Rd,A ;Rd<—M[A],A是8位地址
- STO Rd,Rs ;M[Rd] <—Rs,Rd是寄存器间址
注意:以上指令(必做+选做)一共16条,操作码可以设为4位。必做指令(MVRD除外)都是单字指令,Rd是目的操作数,Rs是源操作数(图1中的R0-R3都可以用于Rd或Rs)。MVRD指令是二字指令。选做指令除了STO外都是二字指令。
4、确定各指令的执行流程图和所需要的控制信号。
5、设计出实现指令功能的硬布线控制器,明确运算器的功能。
6、在TestBench文件中编写由自己所设计的指令系统构成的一段程序,要求:
(1)程序执行功能正确。
(2)使用最少的指令验证所实现的指令功能,即每条指令出现一次。
(3)R0-R3都要出现在程序中。
(4)在MVRD的imm字段使用自己学号的后三位除以100的余数(16进制);例如学号后三位为211,则211/100余数为11(转换为16进制数为B),imm就为B。假设将B送到R1寄存器中,则MVRD的指令为:MVRD R1,BH,再将其转换为对应的二进制语言。
(5)LAD指令的A字段和STO指令的Rd字段内容使用自己学号的后三位除以100的余数+32得到的16进制数。例如学号后三位为322,则322/100余数为22,22+32=54(转换为16进制数为36),地址就为36H。假设将36H地址中的内容送到R2,则LAD的指令为:LAD R2,36H,再将其转换为对应的二进制语言。
7、对程序进行仿真,能够理解仿真波形图,并烧写到开发板上运行。
8、撰写课程设计报告。
课程设计注意事项:
1.Quartus不支持中文路径,如果在自己电脑中安装Quartus软件,一定安装在英文路径下;
2.导入.v文件或新建.v文件时,名称和保存路径一定要为英文,否则会报错;
3.每一个模块一个文件;
4.工程命名和路径必须是英文,否则会报错。
严禁剽窃、抄袭等作弊行为!
语言实现:
/*r0通用寄存器*/
module r0(din, clk, rst,r0load, dout);
input clk,rst,r0load;
input[7:0]din;
output[7:0]dout;
reg[7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(r0load)
dout<=din;
end
endmodule
/*r1通用寄存器*/
module r1(din, clk, rst,r1load, dout);
input clk,rst,r1load;
input[7:0]din;
output[7:0]dout;
reg[7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(r1load)
dout<=din;
end
endmodule
// Copyright (C) 1991-2014 Altera Corporation. All rights reserved.
// Your use of Altera Corporation's design tools, logic functions
// and other software and tools, and its AMPP partner logic
// functions, and any output files from any of the foregoing
// (including device programming or simulation files), and any
// associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License
// Subscription Agreement, the Altera Quartus II License Agreement,
// the Altera MegaCore Function License Agreement, or other
// applicable license agreement, including, without limitation,
// that your use is for the sole purpose of programming logic
// devices manufactured by Altera and sold by Altera or its
// authorized distributors. Please refer to the applicable
// agreement for further details.
// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to
// suit user's needs .Comments are provided in each section to help the user
// fill out necessary details.
// *****************************************************************************
// Generated on "11/25/2020 01:28:30"
// Verilog Test Bench template for design : top
//
// Simulation tool : ModelSim-Altera (Verilog)
//
`timescale 100 us/ 1 ps
module top_vlg_tst();
// constants
// general purpose registers
//reg eachvec;
// test vector input registers
reg A1;
reg [7:0] D;
reg SW1;
reg SW2;
reg SW_choose;
reg clk;
reg rst;
// wires
wire [6:0] HEX0;
wire [6:0] HEX1;
wire [6:0] HEX2;
wire [6:0] HEX3;
wire [6:0] HEX4;
wire [6:0] HEX5;
wire [6:0] HEX6;
wire [6:0] HEX7;
wire r0bus_led;
wire r0load_led;
wire [7:0] addr;
wire r2load_led;
wire arload_led;
wire busmem_led;
wire [7:0] check_out;
wire clr_led;
wire [1:0] cpustate_led;
wire [7:0] data;
wire drbus_led;
wire r2bus_led;
wire drload_led;
wire irload_led;
wire membus_led;
wire pcbus_led;
wire pcinc_led;
wire pcload_led;
wire quick_low_led;
wire [7:0] rambus;
wire r1bus_led;
wire [7:0] r0dbus;
wire [7:0] r1dbus;
wire [7:0] r2dbus;
wire [7:0] r3dbus;
wire read_led;
wire rload_led;
wire r3bus_led;
wire r3load_led;
wire write_led;
wire zload_led;
// assign statements (if any)
top i1 (
// port map - connection between master ports and signals/registers
.A1(A1),
.D(D),
.HEX0(HEX0),
.HEX1(HEX1),
.HEX2(HEX2),
.HEX3(HEX3),
.HEX4(HEX4),
.HEX5(HEX5),
.HEX6(HEX6),
.HEX7(HEX7),
.SW1(SW1),
.SW2(SW2),
.SW_choose(SW_choose),
.r0bus_led(r0bus_led),
.r1bus_led(r1bus_led),
.r0dbus(r0dbus),
.r1dbus(r1dbus),
.r2dbus(r2dbus),
.r3dbus(r3dbus),
.r0load_led(r0load_led),
.addr(addr),
.r2load_led(r2load_led),
.arload_led(arload_led),
.busmem_led(busmem_led),
.check_out(check_out),
.clk(clk),
.clr_led(clr_led),
.cpustate_led(cpustate_led),
.data(data),
.drbus_led(drbus_led),
.r2bus_led(r2bus_led),
.drload_led(drload_led),
.irload_led(irload_led),
.membus_led(membus_led),
.pcbus_led(pcbus_led),
.pcinc_led(pcinc_led),
.pcload_led(pcload_led),
.quick_low_led(quick_low_led),
.rambus(rambus),
.read_led(read_led),
.r1load_led(r1load_led),
.rst(rst),
.r3bus_led(r3bus_led),
.r3load_led(r3load_led),
.write_led(write_led),
.zload_led(zload_led)
);
initial
begin
A1 = 1;
SW1 = 0;
SW2 = 0;
SW_choose = 1;//閫夋嫨蹇椂閽?
clk = 0;
rst = 1;
end
always #2 clk = ~clk;
initial
begin
#50 rst = 0;
SW1 = 1;
#50 rst = 1;
//IN
#50 D = 8'b00000000;//0 nop **0000001
#100 A1 = 0;
#300 A1 = 1;
/*
ADD 0001 RdRs
SUB 0010 RdRs
AND 0011 RdRs
OR 0100 RdRs
INC 0101 Rd00
DEC 0110 Rd00
NOT 0111 Rd00
SHL 1000 RdRs
MVR 1001 RdRs
MVRD 1010 Rd00 imm
JMP 1011 RdRs A
JMPZ 1100 RdRs A
JPNZ 1101 RdRs A
LAD 1110 Rd A
STO 1111 RdRs*/
#50 D=8'b10100000;//1 mvrd r0 00 r0<-10H r0==00010000 r1==00000000 r2==00000000 r3==00000000
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00010000;//2 **100003
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b10010100;//3 mvr r1<-r0 r1==00010000 r0==00010000 r2==00000000 r3==00000000 **101004
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b01011000;//4 inc r2 r2==00000001 r1==00010000 r0==00010000 r3==00000000 **0010005
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b10000110;//5 shl r1 r2 r1==00100000 r2==00000001 r0==00010000 r3==00000000 **0200106
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00010100;//6 add r1 r0 r1==00110000 r0==00010000 r2==00000001 r3==00000000 **0301007
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b01101000;//7 dec r2 跳1:r2==00000000 z==1 r1==00110000 r0==00010000 r3==00000000 **1000008 跳2:z==0 r2==11111111 r1==00110000 r0==00010000 r3==00000000 0ff0008
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b11010000;//8 (z==0)jpnz 11
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00001011;//9 **100000a **000000b
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b01110000;//10 not r0 跳1:r0==11101111 r2==00000000 z==1 r1==00110000 r3==00000000 跳2:skip **1ef00b
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00101110;//11 sub r3 r2 跳1:r0==11101111 r2==00000000 z==1 r1==00110000 r3==00000000 **100000c跳2:r3==00000001 z=0 r2==11111111 r1==00110000 r0==11101111 001ff0c
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b11000000;//12 (z==1)jmpz->7
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00000111;//13 A **1000007 **001010e
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b01000001;//14 or r0 r1 r3==00000001 r2==11111111 r1==00110000 r0==11111111 **0ff300f
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b11110100;//15 sto M[r1] r0 r3==00000001 r2==11111111 r1==00110000 r0==11111111 **030ff10
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b11101100;//16 lad r3 00 r3<-M[30H] r3==1111111 r2==11111111 r1==00110000 r0==11111111 **ffff12
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00110000;//17
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b10110000;//18 jmp->21 **0ffff15
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00010101;//19 A
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00100010;//20 sub r0 r2 skip r3==1111111 r2==11111111 r1==00110000 r0==00000000
#100 A1 = 0;
#300 A1 = 1;
#50 D=8'b00111001;//21 and r2 r1 r3==1111111 r2==00110000 r1==00110000 r0==11111111 **303016
#100 A1 = 0;
#300 A1 = 1;
//CHECK
#50 SW1 = 0;
SW2 = 1;
rst = 0;
#50 rst = 1;
#200 A1 = 0; //0
#300 A1 = 1;
#200 A1 = 0; //1
#300 A1 = 1;
#200 A1 = 0;//2
#300 A1 = 1;
#200 A1 = 0;//3
#300 A1 = 1;
#200 A1 = 0;//4
#300 A1 = 1;
#200 A1 = 0;//5
#300 A1 = 1;
#200 A1 = 0;//6
#300 A1 = 1;
#200 A1 = 0;//7
#300 A1 = 1;
#200 A1 = 0;//8
#300 A1 = 1;
#200 A1 = 0;//9
#300 A1 = 1;
#200 A1 = 0;//10
#300 A1 = 1;
#200 A1 = 0;//11
#300 A1 = 1;
#200 A1 = 0;//12
#300 A1 = 1;
#200 A1 = 0;//13
#300 A1 = 1;
#200 A1 = 0;//14
#300 A1 = 1;
#200 A1 = 0;//15
#300 A1 = 1;
#200 A1 = 0;//16
#300 A1 = 1;
#200 A1 = 0;//17
#300 A1 = 1;
#200 A1 = 0;//18
#300 A1 = 1;
#200 A1 = 0;//19
#300 A1 = 1;
#200 A1 = 0;//20
#300 A1 = 1;
//RUN
#20 rst = 0;
#10 rst = 1;
#20 SW1 = 1;
#100 A1 = 0;//0
#400 A1 = 1;
#100 A1 = 0;//1
#400 A1 = 1;
#100 A1 = 0;//2
#400 A1 = 1;
#100 A1 = 0;//3
#400 A1 = 1;
#100 A1 = 0;//4
#400 A1 = 1;
#100 A1 = 0;//5
#400 A1 = 1;
#100 A1 = 0;//6
#400 A1 = 1;
#100 A1 = 0;//7
#400 A1 = 1;
#100 A1 = 0;//8
#400 A1 = 1;
#100 A1 = 0;//9
#400 A1 = 1;
#100 A1 = 0;//10
#400 A1 = 1;
#100 A1 = 0;//11
#400 A1 = 1;
#100 A1 = 0;//12
#400 A1 = 1;
#100 A1 = 0;//13
#400 A1 = 1;
#100 A1 = 0;//14
#400 A1 = 1;
#100 A1 = 0;//15
#400 A1 = 1;
#100 A1 = 0;//16
#400 A1 = 1;
#100 A1 = 0;//17
#400 A1 = 1;
#100 A1 = 0;//18
#400 A1 = 1;
#100 A1 = 0;//19
#400 A1 = 1;
#100 A1 = 0;//20
#400 A1 = 1;
#100 A1 = 0;//21
#400 A1 = 1;
#100 A1 = 0;//22
#400 A1 = 1;
#300 $finish;
end
endmodule
/*标志寄存器*/
module z(din,clk,rst,zload,dout);
input [7:0]din;
input clk,rst,zload;
output reg[0:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(zload)
begin
if(din==8'b00000000)
dout<=1;
else
dout<=0;
end
end
endmodule
//the relatively complex cpu
//design by cgy,2020.11
//modify by zhy,2024.11
//实例化,将分频模块,cpu模块,存储器模块,显示模块连接到一起。
module top(clk,rst,A1,SW_choose,SW1,SW2,D,addr,rambus,data,HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7,r0dbus,r1dbus,r2dbus,r3dbus,cpustate_led,
check_out,quick_low_led,read_led,write_led,arload_led,r2load_led,pcinc_led,pcload_led,drload_led,r3load_led,irload_led,
r1load_led,r0load_led,zload_led,pcbus_led,drbus_led,r3bus_led,r2bus_led,r1bus_led,r0bus_led,membus_led,busmem_led,clr_led);
input clk, rst;
input A1;
input SW_choose,SW1,SW2;
input [7:0] D;
output[7:0]addr;
output [7:0]rambus;
output [7:0] data;
output [6:0] HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7;
output [7:0] r0dbus;//r0通用寄存器的输出
output [7:0] r1dbus;//r1通用寄存器的输出
output [7:0] r2dbus;//r2通用寄存器的输出
output [7:0] r3dbus;//r3通用寄存器的输出
output [1:0] cpustate_led;
output [7:0] check_out;
output quick_low_led;
output read_led,write_led,arload_led,r2load_led,pcinc_led,pcload_led,drload_led,r3load_led,irload_led,
r1load_led,r0load_led,zload_led,pcbus_led,drbus_led,r3bus_led,r2bus_led,r1bus_led,r0bus_led,membus_led,busmem_led,clr_led;
wire Z;
wire read,write,arload,pcinc,pcload,drload,irload,r1load,r0load,r2load,r3load,xload,yload,zload,pcbus,drbus,r3bus,r2bus,r1bus,r0bus,ybus,membus,busmem,clr;
wire clk_quick,clk_slow,clk_delay,clk_mem,clk_light;
wire [1:0] cpustate;
wire [7:0] irout;
wire [7:0] rs,rd;//rs和rd在数码管上的输出
/*----------分频程序---------------*/
//综合用
clk_div quick(.clk(clk),.reset(rst),.symbol(32'd16384000),.div_clk(clk_quick));
clk_div slow(.clk(clk),.reset(rst),.symbol(32'd49152000),.div_clk(clk_slow));
clk_div delay(.clk(clk),.reset(rst),.symbol(32'd2048000),.div_clk(clk_delay));
clk_div mem(.clk(clk),.reset(rst),.symbol(32'd2048000),.div_clk(clk_mem));
clk_div light(.clk(clk),.reset(rst),.symbol(32'd2048000),.div_clk(clk_light));
//仿真用
/*clk_div quick(.clk(clk),.reset(rst),.symbol(32'd3),.div_clk(clk_quick));
clk_div slow(.clk(clk),.reset(rst),.symbol(32'd6),.div_clk(clk_slow));
clk_div delay(.clk(clk),.reset(rst),.symbol(32'd1),.div_clk(clk_delay));
clk_div mem(.clk(clk),.reset(rst),.symbol(32'd3),.div_clk(clk_mem));
clk_div light(.clk(clk),.reset(rst),.symbol(32'd3),.div_clk(clk_light));*/
/*-------------------------------*/
/*CPU_Controller(SW1,SW2,CPU_state);*/
CPU_Controller controller(.SW1(SW1),.SW2(SW2),.CPU_state(cpustate));
/*ram(clk,data_in,addr,A1,reset,read,write,cpustate,D,data_out,check_out);*/
ram mm(.clk(clk_mem),.data_in(data),.addr(addr),.A1(A1),.reset(rst),.read(read),.write(write),.cpustate(cpustate),.D(D),.data_out(rambus),.check_out(check_out));
//补充cpu实例化的语句
/*//补充cpu实例化的语句
*/
cpu mcpu(.data_in(rambus),.clk_quick(clk_quick),.clk_slow(clk_slow),.clk_delay(clk_delay),.rst(rst),
.SW_choose(SW_choose),.A1(A1),.cpustate(cpustate),.addr(addr),.data_out(data),.r3dbus(r3dbus),.r2dbus(r2dbus),
.r0dbus(r0dbus),.r1dbus(r1dbus),.read(read), .write(write), .arload(arload),.pcinc(pcinc),.pcload(pcload), .drload(drload),
.irload(irload), .r3load(r3load), .r2load(r2load) ,.r1load(r1load), .r0load(r0load), .xload(xload), .zload(zload),
.pcbus(pcbus),.drbus(drbus),.r3bus(r3bus),.r2bus(r2bus),.r1bus(r1bus),.r0bus(r0bus),.membus(membus),.busmem(busmem),
.clr(clr),.zout(Z),.ybus(ybus),.iout(irout),.yload(yload));
//根据irout的高4位对应的指令,再通过irout的第3位和第2位的值给rd赋值,请补充
//例如指令设计了add和sub,irout的高四位分别是0001和0010,则rd可如下赋值,需根据自行设计的指令补充rd的赋值
assign rd=((irout[7:4]==4'b0001)
||(irout[7:4]==4'b0010)
||(irout[7:4]==4'b0011)
||(irout[7:4]==4'b0100)
||(irout[7:4]==4'b0101)
|| (irout[7:4]==4'b0110)
|| (irout[7:4]==4'b0111)
||(irout[7:4]==4'b1010)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001)
|| (irout[7:4]==4'b1110)
|| (irout[7:4]==4'b1111))?((irout[3:2]==2'b00)?r0dbus:8'bzzzzzzzz):8'bzzzzzzzz;
assign rd=((irout[7:4]==4'b0001)
||(irout[7:4]==4'b0010)
||(irout[7:4]==4'b0011)
||(irout[7:4]==4'b0100)
||(irout[7:4]==4'b0101)
|| (irout[7:4]==4'b0110)
|| (irout[7:4]==4'b0111)
||(irout[7:4]==4'b1010)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001)
|| (irout[7:4]==4'b1110)
|| (irout[7:4]==4'b1111))?((irout[3:2]==2'b01)?r1dbus:8'bzzzzzzzz):8'bzzzzzzzz;
assign rd=((irout[7:4]==4'b0001)
||(irout[7:4]==4'b0010)
||(irout[7:4]==4'b0011)
||(irout[7:4]==4'b0100)
||(irout[7:4]==4'b0101)
|| (irout[7:4]==4'b0110)
|| (irout[7:4]==4'b0111)
||(irout[7:4]==4'b1010)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001)
|| (irout[7:4]==4'b1110)
|| (irout[7:4]==4'b1111))?((irout[3:2]==2'b10)?r2dbus:8'bzzzzzzzz):8'bzzzzzzzz;
assign rd=((irout[7:4]==4'b0001)
||(irout[7:4]==4'b0010)
||(irout[7:4]==4'b0011)
||(irout[7:4]==4'b0100)
||(irout[7:4]==4'b0101)
|| (irout[7:4]==4'b0110)
|| (irout[7:4]==4'b0111)
||(irout[7:4]==4'b1010)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001)
|| (irout[7:4]==4'b1110)
|| (irout[7:4]==4'b1111))?((irout[3:2]==2'b11)?r3dbus:8'bzzzzzzzz):8'bzzzzzzzz;
//根据irout的高4位对应的指令,再通过irout的第1位和第0位的值给rs赋值,请补充
//例如指令设计了add和sub,irout的高四位分别是0001和0010,则rs可如下赋值,需根据自行设计的指令补充rs的赋值
assign rs=((irout[7:4]==4'b0001)
|| (irout[7:4]==4'b1111)
|| (irout[7:4]==4'b0010)
|| (irout[7:4]==4'b0011)
|| (irout[7:4]==4'b0100)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001))?((irout[1:0]==2'b00)?r0dbus:8'bzzzzzzzz):8'bzzzzzzzz;
assign rs=((irout[7:4]==4'b0001)
|| (irout[7:4]==4'b1111)
|| (irout[7:4]==4'b0010)
|| (irout[7:4]==4'b0011)
|| (irout[7:4]==4'b0100)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001))?((irout[1:0]==2'b01)?r1dbus:8'bzzzzzzzz):8'bzzzzzzzz;
assign rs=((irout[7:4]==4'b0001)
|| (irout[7:4]==4'b1111)
|| (irout[7:4]==4'b0010)
|| (irout[7:4]==4'b0011)
|| (irout[7:4]==4'b0100)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001))?((irout[1:0]==2'b10)?r2dbus:8'bzzzzzzzz):8'bzzzzzzzz;
assign rs=((irout[7:4]==4'b0001)
|| (irout[7:4]==4'b1111)
|| (irout[7:4]==4'b0010)
|| (irout[7:4]==4'b0011)
|| (irout[7:4]==4'b0100)
|| (irout[7:4]==4'b1000)
|| (irout[7:4]==4'b1001))?((irout[1:0]==2'b11)?r3dbus:8'bzzzzzzzz):8'bzzzzzzzz;
light_show show(.light_clk(clk_light),.SW_choose(SW_choose),.check_in(check_out),.read(read),.write(write),.arload(arload),.pcinc(pcinc),.pcload(pcload),.drload(drload),
.irload(irload),.r1load(r1load),.r0load(r0load),.r2load(r2load),.r3load(r3load),.zload(zload),.pcbus(pcbus),.drbus(drbus),.r3bus(r3bus),.r2bus(r2bus),.r1bus(r1bus),.r0bus(r0bus),
.membus(membus),.busmem(busmem),.clr(clr),.State(cpustate),.MAR(addr[7:0]),.rd(rd),.rs(rs),.Z(Z),.HEX0(HEX0),
.HEX1(HEX1),.HEX2(HEX2),.HEX3(HEX3),.HEX4(HEX4),.HEX5(HEX5),.HEX6(HEX6),.HEX7(HEX7),.State_LED(cpustate_led),
.quick_low_led(quick_low_led),.read_led(read_led),.write_led(write_led),.arload_led(arload_led),.r2load_led(r2load_led),
.pcinc_led(pcinc_led),.pcload_led(pcload_led),.drload_led(drload_led),.r3load_led(r3load_led),.irload_led(irload_led),.r1load_led(r1load_led),.r0load_led(r0load_led),
.zload_led(zload_led),.pcbus_led(pcbus_led),.drbus_led(drbus_led),.r3bus_led(r3bus_led),.r2bus_led(r2bus_led),.r1bus_led(r1bus_led),.r0bus_led(r0bus_led),.membus_led(membus_led),
.busmem_led(busmem_led),.clr_led(clr_led));
endmodule
/*程序计数器,输出当前执行的指令地址*/
module pc(din, clk, rst,pcload, pcinc, dout);
input [7:0]din;
input clk,rst,pcload,pcinc;
output [7:0]dout;
reg[7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else
if(pcload)
dout<=din;
else if(pcinc)
dout<=dout+8'b00000001;
end
endmodule
/*指令寄存器,存储要执行的指令*/
//注意:该寄存器是时钟下降沿有效
module ir(din,clk,rst,irload,dout);
input [7:0]din;
input clk,rst,irload;
output[7:0]dout;
reg[7:0]dout;
always@(negedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(irload)
dout<=din;
end
endmodule
/*数据寄存器*/
module dr(din, clk,rst, drload, dout);
input clk,rst,drload;
input[7:0] din;
output[7:0]dout;
reg[7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(drload)
dout<=din;
end
endmodule
/*CPU
modified by zhy 2024.11
增加了irout输出,用于控制light_show.v文件中rs和rd的值*/
//省略号中是自行设计的控制信号,需要自行补充
module cpu(data_in,clk_quick,clk_slow,clk_delay,rst,SW_choose,A1,cpustate,addr,
data_out,r0dbus,r1dbus,r2dbus,r3dbus,membus,busmem,write,read,clr,zout,r0load,r0bus,r1load,
r1bus,r2load,r2bus,r3load,r3bus,arload,pcinc,pcload,pcbus,drload,drbus,irload,zload,xload,yload,ybus,iout);
input[7:0] data_in;
input clk_quick,clk_slow,clk_delay;
input rst;
input SW_choose,A1;
input [1:0] cpustate;
//output read,write;
output [7:0] addr;
output [7:0] data_out;
output [7:0] r0dbus;//r0
output [7:0] r1dbus;//r1
output [7:0] r2dbus;//r2
output [7:0] r3dbus;//r3
output [7:0] iout;
//补充自行设计的控制信号的端口说明,都是output
output membus,busmem,write,read,clr,zout,r0load,r0bus,r1load,r1bus,
r2load,r2bus,r3load,r3bus,arload,pcinc,pcload,pcbus,drload,drbus,irload,zload,xload,yload,ybus;
wire[3:0] alus;
wire clk_choose,clk_run;
wire[7:0] dbus,pcdbus;
wire[7:0]drdbus,ydbus,xout;
//定义一些需要的内部信号,请补充
wire [7:0]iout,aluss;
wire zout;
//qtsj(clk_quick,clk_slow,clk_delay,clr,rst,SW_choose,A1,cpustate,clk_run,clk_choose);
qtsj qtdl(.clk_quick(clk_quick),.clk_slow(clk_slow),.clk_delay(clk_delay),.clr(clr),.rst(rst),.SW_choose(SW_choose),.A1(A1),.cpustate(cpustate),.clk_run(clk_run),.clk_choose(clk_choose));
//ar(din, clk, rst,arload, dout);
ar mar(.din(dbus),.clk(clk_choose),.rst(rst),.arload(arload),.dout(addr));
//pc(din, clk, rst,pcload, pcinc, dout);
pc mpc(.din(dbus),.clk(clk_choose),.rst(rst),.pcload(pcload),.pcinc(pcinc),.dout(pcdbus));
//dr(din, clk,rst, drload, dout);补充dr实例化语句
dr mdr(.din(dbus),.clk(clk_choose),.rst(rst),.drload(drload),.dout(drdbus));
//ir(din,clk,rst,irload,dout);补充ir实例化语句
ir mir(.din(drdbus),.clk(clk_choose),.rst(rst),.irload(irload),.dout(iout));
//r0(din, clk, rst,r0load, dout);补充r0实例化语句
r0 mr0(.din(dbus),.clk(clk_choose),.rst(rst),.r0load(r0load),.dout(r0dbus));
//r1(din, clk, rst,r1load, dout);补充r1实例化语句
r1 mr1(.din(dbus),.clk(clk_choose),.rst(rst),.r1load(r1load),.dout(r1dbus));
//r2(din, clk, rst,r2load, dout);补充r2实例化语句
r2 mr2(.din(dbus),.clk(clk_choose),.rst(rst),.r2load(r2load),.dout(r2dbus));
//r3(din, clk, rst,r3load, dout);补充r3实例化语句
r3 mr3(.din(dbus),.clk(clk_choose),.rst(rst),.r3load(r3load),.dout(r3dbus));
// x(din, clk, rst,xload, dout);补充x实例化语句
x mx(.din(dbus),.clk(clk_choose),.rst(rst),.xload(xload),.dout(xout));
// y(din, clk, rst,yload, dout);补充y实例化语句
y my(.din(aluss),.clk(clk_choose),.rst(rst),.yload(yload),.dout(ydbus));
//alu(alus,x, bus, dout);补充alu实例化语句
alu malu(.alus(alus),.x(xout),.bus(dbus),.dout(aluss));
//z(din,clk,rst, zload,dout);补充z实例化语句,如果需要的话
z mz(.din(aluss),.clk(clk_choose),.rst(rst),.zload(zload),.dout(zout));
//control(din,clk,rst,z,cpustate,......,clr);补充control实例化语句
control mcontrol(
.din(iout),
.clk(clk_run),
.z(zout),
.cpustate(cpustate),
.rst(rst),
.read(read),
.write(write),
.arload(arload),
.pcinc(pcinc),
.pcload(pcload),
.drload(drload),
.irload(irload),
.r0load(r0load),
.r1load(r1load),
.r2load(r2load),
.r3load(r3load),
.xload(xload),
.yload(yload),
.zload(zload),
.pcbus(pcbus),
.drbus(drbus),
.r0bus(r0bus),
.r1bus(r1bus),
.r2bus(r2bus),
.r3bus(r3bus),
.ybus(ybus),
.membus(membus),
.busmem(busmem)
,.clr(clr),
.alus(alus));
//allocate dbus
assign dbus=(pcbus)?pcdbus:8'bzzzzzzzz;
assign dbus=(drbus)?drdbus:8'bzzzzzzzz;
assign dbus=(r1bus)?r1dbus:8'bzzzzzzzz;
assign dbus=(r0bus)?r0dbus:8'bzzzzzzzz;
assign dbus=(r2bus)?r2dbus:8'bzzzzzzzz;
assign dbus=(r3bus)?r3dbus:8'bzzzzzzzz;
assign dbus=(ybus)?ydbus:8'bzzzzzzzz;
assign dbus=(membus)?data_in:8'bzzzzzzzz;
assign data_out=(busmem)?dbus:8'bzzzzzzzz;
endmodule
/*组合逻辑控制单元,根据时钟生成为控制信号和内部信号*/
/*
输入:
din:指令,8位,来自IR;
clk:时钟信号,1位,上升沿有效;
rst:复位信号,1位,与cpustate共同组成reset信号;
cpustate:当前CPU的状态(IN,CHECK,RUN),2位;
z:零标志,1位,零标志寄存器的输出,如果指令中涉及到z,可加上,否则可去掉;
输出:
clr:清零控制信号
自行设计的各个控制信号
*/
//省略号中是自行设计的控制信号,需要自行补充,没用到z的话去掉z
module control(din,clk,rst,z,cpustate,read, write, arload, pcinc, pcload, drload, irload, r0load, r1load,r2load, r3load, xload, yload, zload, pcbus, drbus,
r1bus, r0bus, r2bus, r3bus, ybus, membus, busmem,clr,alus);
input [7:0]din;
input clk;
input rst,z;
input [1:0] cpustate;
补充输出端口说明
output read, write, arload, pcinc, pcload, drload, irload, r0load, r1load,
r2load, r3load, xload, yload, zload, pcbus, drbus,r1bus, r0bus, r2bus, r3bus, ybus, membus, busmem,clr;
output[3:0]alus;
reg[3:0]alus;
//parameter's define
wire reset;
//在下方补充自行定义的状态
wire fetch1,fetch2,fetch3,nop1;
wire add1,add2,add3;
wire sub1,sub2,sub3;
wire and1,and2,and3;
wire or1,or2,or3;
wire inc1,inc2;
wire dec1,dec2;
wire not1,not2;
wire shl1,shl2,shl3;
wire mvr1;
wire mvrd1,mvrd2,mvrd3;
wire jmp1,jmp2;
wire jmpz1,jmpz2,jmpz3;
wire jpnz1,jpnz2,jpnz3;
wire lad1,lad2,lad3;
wire sto1,sto2;
//加上自行设计的指令,这里是译码器的输出,所以nop指令经译码器输出后为inop。
//类似地,add指令指令经译码器输出后为iadd;inac指令经译码器输出后为iinac,......
reg inop,iadd,isub,iand,ior,iinc,idec,inot,ishl,imvr,imvrd,ijmp,ijmpz,ijpnz,ilad,isto;
//时钟节拍,8个为一个指令周期,t0-t2分别对应fetch1-fetch3,t3-t7分别对应各指令的执行周期,当然不是所有指令都需要5个节拍的。例如add指令只需要3个节拍:t3-t5
reg t0,t1,t2,t3,t4,t5,t6,t7; //时钟节拍,8个为一个cpu周期
// signals for the counter,
wire clr;
wire inc;
//assign clk_choose = (SW_choose)?clk_quick:clk_slow;
assign reset = rst&(cpustate == 2'b11);
// assign signals for the cunter
//clr信号是每条指令执行完毕后必做的清零,下面clr赋值语句要修改,需要“或”各指令的最后一个周期
assign clr=nop1||add3||sub3||and3||or3||inc2||dec2||not2||shl3||mvr1||mvrd3||jmp2||jmpz3||jpnz3||lad3||sto2;
assign inc=~clr;
//generate the control signal using state information
//...
//取公过程
assign fetch1=t0;
assign fetch2=t1;
assign fetch3=t2;
//什么都不做的译码
assign nop1=inop&&t3;//inop表示nop指令,nop1是nop指令的执行周期的第一个状态也是最后一个状态,因为只需要1个节拍t3完成
//以下补充各条指令状态的表达式
assign add1=iadd&&t3;
assign add2=iadd&&t4;
assign add3=iadd&&t5;
assign sub1=isub&&t3;
assign sub2=isub&&t4;
assign sub3=isub&&t5;
assign and1=iand&&t3;
assign and2=iand&&t4;
assign and3=iand&&t5;
assign or1=ior&&t3;
assign or2=ior&&t4;
assign or3=ior&&t5;
assign inc1=iinc&&t3;
assign inc2=iinc&&t4;
assign dec1=idec&&t3;
assign dec2=idec&&t4;
assign not1=inot&&t3;
assign not2=inot&&t4;
assign shl1=ishl&&t3;
assign shl2=ishl&&t4;
assign shl3=ishl&&t5;
assign mvr1=imvr&&t3;
assign mvrd1=imvrd&&t3;
assign mvrd2=imvrd&&t4;
assign mvrd3=imvrd&&t5;
assign jmp1=ijmp&&t3;
assign jmp2=ijmp&&t4;
assign jmpz1=ijmpz&&t3;
assign jmpz2=ijmpz&&t4;
assign jmpz3=ijmpz&&t5;
assign jpnz1=ijpnz&&t3;
assign jpnz2=ijpnz&&t4;
assign jpnz3=ijpnz&&t5;
assign lad1=ilad&&t3;
assign lad2=ilad&&t4;
assign lad3=ilad&&t5;
assign sto1=isto&&t3;
assign sto2=isto&&t4;
//以下补充各个控制信号的逻辑表达式,记得还需要写出alus的逻辑表达式
assign read=fetch2||mvrd2||jmp2||(jmpz2&&z)||(jpnz2&&!z)||lad2||lad3;
assign write=sto2;
assign busmem=sto2;
assign membus=fetch2||mvrd2||jmp2||(jmpz2&&z)||(jpnz2&&!z)||lad2||lad3;
assign arload=fetch1||mvrd1||jmp1||(jmpz1&&z)||(jpnz1&&!z)||lad1||lad2||sto1;
assign pcload=jmp2||(jmpz2&&z)||(jpnz2&&!z);
assign pcinc=fetch2||mvrd2||lad2||jmp2||(jmpz2&&z)||(jpnz2&&!z)||(jmpz3&&!z)||(jpnz3&&z);
assign pcbus=fetch1||mvrd1||jmp1||(jmpz1&&z)||(jpnz1&&!z)||lad1;
assign drload=fetch2||mvrd2;
assign drbus=mvrd3;
assign irload=fetch3;
assign r3load=((add3||sub3||and3||or3||inc2||dec2||not2||shl3||mvr1||mvrd3||lad3))&&(din[3:2]==2'b11);
assign r3bus=((add1||sub1||and1||or1||mvr1||shl1||sto2)&&(din[1:0]==2'b11))||((add2||sub2||and2||or2||inc1||dec1||not1||shl2||sto1)&&(din[3:2]==2'b11));
assign r2load=((add3||sub3||and3||or3||inc2||dec2||not2||shl3||mvr1||mvrd3||lad3))&&(din[3:2]==2'b10);
assign r2bus=((add1||sub1||and1||or1||mvr1||shl1||sto2)&&(din[1:0]==2'b10))||((add2||sub2||and2||or2||inc1||dec1||not1||shl2||sto1)&&(din[3:2]==2'b10));
assign r1load=((add3||sub3||and3||or3||inc2||dec2||not2||shl3||mvr1||mvrd3||lad3))&&(din[3:2]==2'b01);
assign r1bus=((add1||sub1||and1||or1||mvr1||shl1||sto2)&&(din[1:0]==2'b01))||((add2||sub2||and2||or2||inc1||dec1||not1||shl2||sto1)&&(din[3:2]==2'b01));
assign r0load=((add3||sub3||and3||or3||inc2||dec2||not2||shl3||mvr1||mvrd3||lad3))&&(din[3:2]==2'b00);
assign r0bus=((add1||sub1||and1||or1||mvr1||shl1||sto2)&&(din[1:0]==2'b00))||((add2||sub2||and2||or2||inc1||dec1||not1||shl2||sto1)&&(din[3:2]==2'b00));
assign xload=add1||sub1||and1||or1||shl1;
assign yload=add2||sub2||and2||or2||inc1||dec1||not1||shl2;
assign zload=add2||sub2||and2||or2||inc1||dec1||not1||shl2;
assign ybus=add3||sub3||and3||or3||inc2||dec2||not2||shl3;
always @(*) begin
case(din[7:4])
4'd1:alus=4'b0001;
4'd2:alus=4'b0010;
4'd3:alus=4'b0011;
4'd4:alus=4'b0100;
4'd5:alus=4'b0101;
4'd6:alus=4'b0110;
4'd7:alus=4'b0111;
4'd8:alus=4'b1000;
default:alus=4'bzzzz;
endcase
end
always@(posedge clk or negedge reset)
begin
if(!reset)
begin//各指令清零,以下已为nop指令清零,请补充其他指令,为其他指令清零
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
else
begin
case(din[7:4]) //译码
4'd0: begin //op为0000,是nop指令,因此这里inop的值是1,而其他指令应该清零,请补充为其他指令清零的语句
inop<=1;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd1: begin
//op为0001,应该是add指令,因此iadd指令为1,其他指令都应该是0。
//后续各分支类似,只有一条指令为1,其他指令为0,以下分支都给出nop指令的赋值,需要补充其他指令
inop<=0;
iadd<=1;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd2: begin//sub
inop<=0;
iadd<=0;
isub<=1;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd3: begin
inop<=0;
iadd<=0;
isub<=0;
iand<=1;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd4: begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=1;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd5: begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=1;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd6: begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=1;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd7: begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=1;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd8:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=1;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd9:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=1;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd10:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=1;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd11:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=1;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd12:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=1;
ijpnz<=0;
ilad<=0;
isto<=0;
end
4'd13:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=1;
ilad<=0;
isto<=0;
end
4'd14:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=1;
isto<=0;
end
4'd15:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=1;
end
default:begin
inop<=0;
iadd<=0;
isub<=0;
iand<=0;
ior<=0;
iinc<=0;
idec<=0;
inot<=0;
ishl<=0;
imvr<=0;
imvrd<=0;
ijmp<=0;
ijmpz<=0;
ijpnz<=0;
ilad<=0;
isto<=0;
end
endcase
end
end
/*——————8个节拍t0-t7————*/
always @(posedge clk or negedge reset)
begin
if(!reset) //reset清零
begin
t0<=1;
t1<=0;
t2<=0;
t3<=0;
t4<=0;
t5<=0;
t6<=0;
t7<=0;
end
else
begin
if(inc) //运行
begin
t7<=t6;
t6<=t5;
t5<=t4;
t4<=t3;
t3<=t2;
t2<=t1;
t1<=t0;
t0<=0;
end
else if(clr) //清零
begin
t0<=1;
t1<=0;
t2<=0;
t3<=0;
t4<=0;
t5<=0;
t6<=0;
t7<=0;
end
end
end
/*—————结束—————*/
endmodule
/*地址寄存器,输出读写存储器的地址*/
module ar(din, clk, rst,arload, dout);
input [7:0]din;
input clk,rst,arload;
output [7:0]dout;
reg [7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(arload)
dout<=din;
end
endmodule
/*算术逻辑单元,x来自于Rs,bus来自于Rd*/
module alu(alus,x, bus, dout);
input [3:0]alus;
input [7:0]bus,x;
output reg[7:0]dout;
always@(alus or x or bus)
begin
case(alus)
4'b0001:dout=x+bus;//ADD
4'b0010:dout=bus-x;//SUB
4'b0011:dout=x&bus;//AND
4'b0100:dout=x|bus;//OR
4'b0101:dout=bus+8'b00000001;//INC
4'b0110:dout=bus-8'b00000001;//DEC
4'b0111:dout=~bus;//NOT;
4'b1000:dout=bus<<x;//SHL
default:dout=8'bx;
endcase
end
endmodule
/*数据暂存器x,存放ALU的一个输入,另外一个输入来自于总线*/
module x(din, clk, rst,xload, dout);
input [7:0]din;
input clk,rst,xload;
output [7:0]dout;
reg [7:0]dout;
always@(posedge clk or negedge rst)
if(rst==0)
dout<=0;
else if(xload)
dout<=din;
endmodule
/*r2通用寄存器*/
module r2(din, clk, rst,r2load, dout);
input clk,rst,r2load;
input[7:0]din;
output[7:0]dout;
reg[7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(r2load)
dout<=din;
end
endmodule
/*r3通用寄存器*/
module r3(din, clk, rst,r3load, dout);
input clk,rst,r3load;
input[7:0]din;
output[7:0]dout;
reg[7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(r3load)
dout<=din;
end
endmodule
/*暂存器Y,存放ALU的运算结果*/
module y(din, clk, rst,yload, dout);
input[7:0] din;
input clk,rst,yload;
output [7:0]dout;
reg [7:0]dout;
always@(posedge clk or negedge rst)
begin
if(rst==0)
dout<=0;
else if(yload)
dout<=din;
end
endmodule