Project4 FPGA完成MIPS微系统开发(支持设备与中断),ISE(IM,DM)简单使用教程

由于最近的计算机组成原理的课设,从modelsim 到iSe的过渡,需要将自己设计的主机和外设下载到芯片(XC6SLX45)上,由于使用IP核封装的IM(指令存储器)在读取指令的时候需要一个时钟clk ,在J,JR ,Jal,BEQ等跳转指令时最后一个状态pc寄存器(地址寄存器)写使能置1,下一条指令的S0状态将地址写入pc寄存器,然后进入下一个状态(译码状态),这时才从指令存储器(IM)中读取到了目的指令,但是这条目的指令写不进指令寄存器(IMREG),所以在跳转类指令后面增加一个延时状态(不为所有的指令增加延时状态,提高机器的运算速度),在延时状态中将新的地址写入pc寄存器,在S0状态时可以读取Im中的内容,然后在S1(译码阶段)写入IM寄存器。其他非跳转指令不存在这种问题。

 

ISE中简单创建IM(指令存储器)教程:

第一步:右键工程名字——>点击new source 

 第二部:

选择IP核然后在filename 填上名字(自己设置) 

第三步:

第四步:

点击next

 

 

第五步:

1024  X 32  4K的存储空间

 点击next

 

点击next   next next generate

 控制器代码:

module controller(op,func,regdst,alusr,memtoreg,regwrite,memwrite,pcwr,imregwr,npc_sel,extop,aluctr,isaddi,stlo,islb,issb,clk,reset,zero,isda,intreq,cp0_wen,bridge_wen,MT,setexl,clearexl,intpc);
    input [5:0] op,func;
	input [4:0] MT;
	input clk,reset,zero,isda,intreq;
	output [1:0] regdst;
	output alusr,regwrite,memwrite,isaddi,stlo,islb,issb,pcwr,imregwr,setexl,clearexl;
	output [1:0] npc_sel;
	output [1:0]memtoreg;
	output[1:0]extop;
	output [1:0] aluctr;
    output cp0_wen,bridge_wen,intpc;
    wire r_type = ~|op;
    wire s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11;
    wire addu     = r_type & func[5] & ~func[4] & ~func[3] & ~func[2] & ~func[1] & func[0];
    wire subu     = r_type & func[5] & ~func[4] & ~func[3] & ~func[2] & func[1] & func[0];
    wire ori      = ~op[5]&~op[4]&op[3]&op[2]&~op[1]&op[0];
	 wire lw       = op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
    wire sw       = op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
	 wire beq      = ~op[5]&~op[4]&~op[3]&op[2]&~op[1]&~op[0];
	 wire lui      = ~op[5]& ~op[4]& op[3]& op[2]& op[1]& op[0];
    wire j        = ~op[5]&~op[4]&~op[3]&~op[2]&op[1]&~op[0];
	 wire addi     = ~op[5] & ~op[4] & op[3] & ~op[2] & ~op[1] & ~op[0];
	 wire addiu    = ~op[5] & ~op[4] & op[3] & ~op[2] & ~op[1] & op[0];
	 wire slt      = r_type & func[5] & ~func[4] & func[3] & ~func[2] & func[1] & ~func[0];
	 wire jal      = ~op[5] & ~op[4] & ~op[3] & ~op[2] & op[1] & op[0];
	 wire jr       = r_type&~func[5]&~func[4]&func[3]&~func[2]&~func[1]&~func[0];
     wire lb       = op[5]&~op[4]&~op[3]&~op[2]&~op[1]& ~op[0];
	 wire sb       = op[5]&~op[4]&op[3]&~op[2]&~op[1]& ~op[0];
	 wire isbgez     = ~op[5]&~op[4]&~op[3]&~op[2]&~op[1]&op[0];
	 wire MTC0=~op[5]&op[4]&~op[3]&~op[2]&~op[1]&~op[0]&~MT[4]&~MT[3]&MT[2]&~MT[1]&~MT[0];
	 wire MFC0=~op[5]&op[4]&~op[3]&~op[2]&~op[1]&~op[0]&~MT[4]&~MT[3]&~MT[2]&~MT[1]&~MT[0];
	 wire ERET=~op[5]&op[4]&~op[3]&~op[2]&~op[1]&~op[0]&MT[4]&~func[5] & func[4] & func[3] & ~func[2] & ~func[1] & ~func[0];
	 parameter [3:0] S0 = 4'b0000,S1 = 4'b0001,S2 = 4'b0010,S3 = 4'b0011,S4 = 4'b0100,S5 = 4'b0101,S6 = 4'b0110,S7 = 4'b0111,S8 = 4'b1000,S9 = 4'b1001,S10=4'b1010,S11=4'b1011,S12=4'b1100;
	reg [3:0] next,current;
	always @(posedge clk,posedge reset)
	 begin
		if(reset==1)
			begin
			current<=S0;
			end
		else
		begin
			current<=next;
		end
	 end
	 always @(current,addu,subu,ori,lw,sw,beq,lui,j,addi,addiu,slt,jal,jr,lb,sb,isbgez,MTC0,MFC0,intreq,ERET)
		begin
		case(current)
		S0:next=S1;
		s1:begin
			if(lw|sw|lb|sb|MTC0|MFC0)
				begin
					next=S2;
				end
			else if(addu|subu|ori|lui|addi|addiu|slt)
					begin
						next=S6;
					end
			else if(beq|isbgez)
				begin
					next=S8;
				end
			else if(j|jal|jr|ERET)
				begin
					next=S9;
				end
		end
		S2:	begin
				if(lw|lb|MFC0)
					begin 
						next=S3;
					end
				else if(sw|sb|MTC0)
					begin
						next=S5;
					end
				end
		S3:begin
			next=S4;
			end
		S4:
			begin
			if(intreq==1)
				begin
					next=S10;
				end
			else
				begin
					next=S0;
				end
			end
		S5:begin
			if(intreq==1)
				begin
					next=S10;
				end
			else
				begin
					next=S0;
				end
			end
		S6:begin
				if(addu|subu|ori|lui|addi|addiu|slt)
					begin
					next=S7;
					end
			end
		S7:begin
			if(intreq==1)
				begin
					next=S10;
				end
			else
				begin
					next=S0;
				end
			end
		S8:begin
			next=S11;
		 end
		S9:begin
			next=S11;
		   end
		S10:next=S12;
		S11:
		begin
			if(intreq==1)
				begin
					next=S10;
				end
			else
				begin
					next=S0;
				end
		end
		default:next=S0;
		endcase
		end

  assign s0=(~current[3])&(~current[2])&(~current[1])&(~current[0]);
  assign s1=(~current[3])&(~current[2])&(~current[1])&( current[0]);
  assign s2=(~current[3])&(~current[2])&( current[1])&(~current[0]);
  assign s3=(~current[3])&(~current[2])&( current[1])&( current[0]);
  assign s4=(~current[3])&( current[2])&(~current[1])&(~current[0]);
  assign s5=(~current[3])&( current[2])&(~current[1])&( current[0]);
  assign s6=(~current[3])&( current[2])&( current[1])&(~current[0]);
  assign s7=(~current[3])&( current[2])&( current[1])&( current[0]);
  assign s8=( current[3])&(~current[2])&(~current[1])&(~current[0]);
  assign s9=( current[3])&(~current[2])&(~current[1])&( current[0]);
  assign s10=( current[3])&(~current[2])&(current[1])&( ~current[0]);
  
	assign intpc=intreq&&s10;
	assign setexl=s10;
	assign clearexl=ERET;
	assign islb=(lb==1)?1:0;
	assign issb=(sb==1)?1:0;
    assign isaddi = (addi==1)?1:0;
	assign stlo=(slt==1)?1:0;
	assign imregwr=(s0==1)?1:0;
	assign pcwr=(s0|(j|jr|jal)&s9|(beq&s8&zero)|(isbgez&s8&isda)|s10|ERET&s9);
    assign regdst[0] = addu | subu | slt;//改动版
    assign regdst[1]= jal;
    assign alusr= ori | sw | lw | lui | addi | addiu | lb | sb ;
    assign memtoreg[0]= lw|lb|MFC0;
	assign memtoreg[1]= jal|MFC0;//MFC0 为11;
    assign regwrite= ((addu | subu | ori | lui | addi | slt | addiu)&&s7)||(lw|lb|MFC0)&s4||(jal&s9);
    assign memwrite= (sw|sb)&s5;
	assign bridge_wen= (sw|sb)&s5;//SW向外设输出
	assign cp0_wen=MTC0&s5;//向CP0写数据
    assign npc_sel[0]= (isbgez|beq|jr)&(~s0);//改动
	assign npc_sel[1]= (jr|jal|j)&(~s0);//改动ai
    assign extop[0]= lw | sw | addi | addiu|lb|sb;
    assign extop[1]= lui;
    assign aluctr[1]= ori;
    assign aluctr[0]= subu | beq | slt;
endmodule

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猪猪小侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值