计算机组成实验——指令分析与执行

一、实验分析与设计

由实验内容可得,本实验需要实现将存储器模块的值取出并作为指令,在寄存器组中进行XOR和Shr两种运算。可将程序分为:外部输入模块,PC模块,存储器模块、ALU计算模块,外部显示模块。

外部输入模块:获取矩阵键盘输入值D。可参考本专栏文章

PC模块:实现PC的加一、减一、置数功能。

存储器模块:以PC值作为地址,取出对应位置的值作为指令M。可参考本专栏文章

ALU计算模块:将外部输入值D存入寄存器组R中,执行指令M。通过将M分为操作字段和地址字段,利用状态机实现:依靠地址字段取寄存器值——依靠操作字段执行运算——依靠地址字段存回运算结果。

外部显示模块:通过变量s控制显示为:D、PC、M或者寄存器组R的值。

二、程序代码

顶层模块

module sy8(clk,key_R,key_C,D,Sel,PC,M,RA,Wr,R,s,SEL,code);
	input clk;
	input[3:0]key_R;
	output [3:0]key_C;
	output [7:0]D;
	
	input [1:0]Sel;
	output [7:0]PC;
	output [15:0]M;
	
	input [1:0]RA;
	input Wr;
	output [31:0]R;
	
	input s;
	output [2:0]SEL;
	output [7:0]code;
	
	sy8_input s1(clk,key_R,key_C,D);	//获取键盘输入
	
	sy8_PC s2(clk,D,Sel,PC);	//PC值加一、减一、置数
	my_rom s3(.clock(clk),.address(PC),.q(M));	//存储器取出指令
	sy8_ALU s4(clk,D,RA,Wr,M,R,PC);	//存入寄存器,指令计算
	
	sy8_show s5(clk,D,PC,M,R,s,SEL,code);	//显示D、PC、M,R值
	
endmodule

外部输入模块

module sy8_input(clk,key_R,key_C,D);
	input clk;
	input[3:0]key_R;
	output reg[3:0]key_C;
	output reg[7:0]D;
	
	reg flag;
	reg [1:0]row;
	reg [3:0]Q;

	always @(posedge clk)
	begin
		if(key_R==4'b1111)
			flag=0;
		else
			flag=1;
		if(flag==0)
			row=row+1;
	end

	always @(posedge clk)
	begin
		case(row)
			0:key_C=4'b1110;
			1:key_C=4'b1101;
			2:key_C=4'b1011;
			3:key_C=4'b0111;
		endcase
	end

	always @(posedge clk)
	begin
		case({key_C,key_R})
			8'b11101110:Q=4'hd;
			8'b11101101:Q=4'hf;
			8'b11101011:Q=4'h0;
			8'b11100111:Q=4'he;
			8'b11011110:Q=4'hc;
			8'b11011101:Q=4'h9;
			8'b11011011:Q=4'h8;
			8'b11010111:Q=4'h7;
			8'b10111110:Q=4'hb;
			8'b10111101:Q=4'h6;
			8'b10111011:Q=4'h5;
			8'b10110111:Q=4'h4;
			8'b01111110:Q=4'ha;
			8'b01111101:Q=4'h3;
			8'b01111011:Q=4'h2;
			8'b01110111:Q=4'h1;
		endcase
	end
	//状态机实现取值-等待-取值-等待
	reg [1:0]state=2'b00;
	integer k = 0;
	
	always @(posedge clk)
	begin
		if(state == 2'b00 && flag)
			begin
				k = 0;
				D[7:4] = Q;
				state = 2'b01;
			end
		else if(state == 2'b01)
			begin
				if(k > 50000) state = 2'b10;
				else k = k + 1;
			end
		else if(state == 2'b10 && flag) 
			begin
				k = 0;
				D[3:0] = Q;
				state = 2'b11;
			end
		else if(state == 2'b11)
			begin
				if(k > 50000) state = 2'b00;
				else k = k + 1;
			end
	end
endmodule

PC模块

module sy8_PC(clk,D,Sel,PC);
	input clk;
	input [7:0]D;
	input [1:0]Sel;
	output reg[7:0]PC;
	
	integer k = 1;
	
	always@(posedge clk)
	begin
		if(k < 100000) k = k + 1;
		else
			begin
				k = 1;
			end
	end
	
	always@(posedge clk)
	begin
		case(Sel)
			2'b00 : PC = PC;
			2'b01 :	//加一
				begin
					if(k == 100000) PC = PC + 1'b1;
				end
			2'b10 : 	//减一
				begin
					if(k == 100000) PC = PC - 1'b1;
				end
			2'b11 : PC = D;	//置数
		endcase
	end
	
endmodule

ALU计算模块

module sy8_ALU(clk,D,RA,Wr,M,R,PC);
	input clk;
	input [7:0]D;
	input [1:0]RA;
	input Wr;
	input [15:0]M;
	input [7:0]PC;
	
	output reg[31:0]R;

	reg [7:0]R1,R2,R3;
	reg [7:0]T;
	reg [2:0]state = 3'b000;
	
	always@(posedge clk)
	begin
		if(state < 3'b101)	//寄存器输入
		begin
			if(!Wr)
			begin
				case(RA)
					2'b00 : R[7:0] = D;
					2'b01 : R[15:8] = D;
					2'b10 : R[23:16] = D;
					2'b11 : R[31:24] = D;
				endcase
			end
			if(PC != T) state = state + 1'b1;	//PC = T表示指令已经执行完毕,此时状态不变
		end
		else if(state == 3'b101)	//从寄存器中获取值
		begin
			case(M[9:8])
				2'b00 : R1 = R[7:0];
				2'b01 : R1 = R[15:8];
				2'b10 : R1 = R[23:16];
				2'b11 : R1 = R[31:24];
			endcase
			case(M[7:6])
				2'b00 : R2 = R[7:0];
				2'b01 : R2 = R[15:8];
				2'b10 : R2 = R[23:16];
				2'b11 : R2 = R[31:24];
			endcase
			state = 3'b110;
		end
		else if(state == 3'b110)	//计算并存回寄存器
		begin
			if(M[15:12] == 4'b0111)
			begin
				R3 = R1 ^ R2;
				case(M[11:10])
					2'b00 : R[7:0] = R3;
					2'b01 : R[15:8] = R3;
					2'b10 : R[23:16] = R3;
					2'b11 : R[31:24] = R3;
				endcase
			end
			else if(M[15:12] == 4'b1000)
			begin
				R3 = {1'b0,R1[7:1]};
				case(M[11:10])
					2'b00 : R[7:0] = R3;
					2'b01 : R[15:8] = R3;
					2'b10 : R[23:16] = R3;
					2'b11 : R[31:24] = R3;
				endcase
			end
			state = 3'b111;
		end
		else
		begin
			state = 3'b000;
			T = PC;
		end
	end
	
endmodule

外部显示模块

module sy8_show(clk,D,PC,M,R,s,SEL,code);
	input clk,s;
	input [7:0]D,PC;
	input [15:0]M;
	input [31:0]R;
	output reg[2:0]SEL;
	output reg[7:0]code;
	
	reg[4:0]Data;
	
	always@(posedge clk)
	begin
		if(SEL < 3'b111) SEL = SEL + 1;
		else SEL = 3'b000;
	end
	
	always@(s,SEL)
	begin
		if(s == 0)	//显示D、PC、M值
		case(SEL)
			3'b000 : Data = D[7:4];
		   3'b001 : Data = D[3:0];
			3'b010 : Data = PC[7:4];
			3'b011 : Data = PC[3:0];
		   3'b100 : Data = M[15:12];
			3'b101 : Data = M[11:8];
			3'b110 : Data = M[7:4];
		   3'b111 : Data = M[3:0];
		endcase
		else			//显示R寄存器组值
		case(SEL)
			3'b000 : Data = R[31:28];
		   3'b001 : Data = R[27:24];
			3'b010 : Data = R[23:20];
			3'b011 : Data = R[19:16];
		   3'b100 : Data = R[15:12];
			3'b101 : Data = R[11:8];
			3'b110 : Data = R[7:4];
		   3'b111 : Data = R[3:0];
		endcase
	end
	
	always @(Data)	//译码
	begin
		case(Data)
			4'd0 : code = 8'h3f;
			4'd1 : code = 8'h06;
			4'd2 : code = 8'h5b;
			4'd3 : code = 8'h4f;
			4'd4 : code = 8'h66;
			4'd5 : code = 8'h6d;
			4'd6 : code = 8'h7d;
			4'd7 : code = 8'h07;
			4'd8 : code = 8'h7f;
			4'd9 : code = 8'h6f;
				
			4'd10: code = 8'h77;
			4'd11: code = 8'h7c;
			4'd12: code = 8'h39;
			4'd13: code = 8'h5e;
			4'd14: code = 8'h79;
			4'd15: code = 8'h71;
			default : code = 8'bx;
		endcase
	end
endmodule

引脚分配图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值