协处理器访问指令的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
写是时序逻辑;读是组合逻辑

`include "defines.v"

module cp0_reg(

	input	wire							clk,
	input wire							rst,
	
	
	input wire                    we_i,			//是否要写CP0的寄存器
	input wire[4:0]               waddr_i,		//要写寄存器的地址
	input wire[4:0]               raddr_i,		//要读取寄存器的地址
	input wire[`RegBus]           data_i,		//要写入的数据
	
	input wire[5:0]               int_i,		//6个外部硬件中断的输入

	output reg[`RegBus]           data_o,		//读出的值
	
	//相关寄存器的值
	output reg[`RegBus]           count_o,		
	output reg[`RegBus]           compare_o,	
	output reg[`RegBus]           status_o,	
	output reg[`RegBus]           cause_o,		
	output reg[`RegBus]           epc_o,
	output reg[`RegBus]           config_o,
	output reg[`RegBus]           prid_o,
	
	//是否有定时中断发生
	output reg                    timer_int_o    
	
);

	//第一段:对CP0中寄存器的写操作
	always @ (posedge clk) begin
		if(rst == `RstEnable) begin
			count_o   <= `ZeroWord;	
			compare_o <= `ZeroWord;	
			
			//status寄存器的CU为0001,表示协处理器CP0存在
			status_o  <= 32'b00010000000000000000000000000000;
			cause_o   <= `ZeroWord;
			epc_o 	 <= `ZeroWord;
			
			//config寄存器的BE为1,表示Big-Endian;MT为00,表示没有MMU
			config_o <= 32'b00000000000000001000000000000000;
			
			//制作者是L,对应的是0x48,类型是0x1,基本类型,版本号是1.0	
			prid_o <= 32'b00000000010011000000000100000010;
			timer_int_o <= `InterruptNotAssert;
		end 
		
		else begin
			count_o <= count_o + 1 ;	//每个时钟周期自加1
			cause_o[15:10] <= int_i;	//cause[15:11]保存外部中断声明
			
			//当comepare不为0且count值为compare时
			//将输出信号timer_int_o置为1,表示时钟中断发生
			if(compare_o != `ZeroWord && count_o == compare_o) begin
				timer_int_o <= `InterruptAssert;
			end
					
			if(we_i == `WriteEnable) 	begin
				case (waddr_i) 
					`CP0_REG_COUNT:		begin	//写count寄存器
						count_o <= data_i;
					end
					`CP0_REG_COMPARE:		begin	//写compare寄存器
						compare_o <= data_i;
						timer_int_o <= `InterruptNotAssert;
					end
					`CP0_REG_STATUS:	begin		//写state寄存器
						status_o <= data_i;
					end
					`CP0_REG_EPC:	begin			//写EPC寄存器
						epc_o <= data_i;
					end
					`CP0_REG_CAUSE:	begin		//写cause寄存器
					  //cause寄存器只有IP[1:0]、IV、WP字段是可写的
						cause_o[9:8] <= data_i[9:8];
						cause_o[23]  <= data_i[23];
						cause_o[22]  <= data_i[22];
					end					
				endcase  
			end
					
		end   
	end      
	
	//第二段:对cp0寄存器的读操作
	always @ (*) begin
		if(rst == `RstEnable) begin
			data_o <= `ZeroWord;
		end 
		else begin
				case (raddr_i) 
					`CP0_REG_COUNT:	begin
						data_o <= count_o ;
					end
					`CP0_REG_COMPARE:	begin
						data_o <= compare_o ;
					end
					`CP0_REG_STATUS:	begin
						data_o <= status_o ;
					end
					`CP0_REG_CAUSE:	begin
						data_o <= cause_o ;
					end
					`CP0_REG_EPC:	begin
						data_o <= epc_o ;
					end
					`CP0_REG_PrId:	begin
						data_o <= prid_o ;
					end
					`CP0_REG_CONFIG:	begin
						data_o <= config_o ;
					end	
					default: 	begin
					end			
				endcase  	
		end    
	end      
endmodule

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

		  if(inst_i[31:21] == 11'b01000000000 
			 && inst_i[10:0] == 11'b00000000000) begin		
				aluop_o <= `EXE_MFC0_OP;
				alusel_o <= `EXE_RES_MOVE;
				wd_o <= inst_i[20:16];
				wreg_o <= `WriteEnable;
				instvalid <= `InstValid;	   
				reg1_read_o <= 1'b0;
				reg2_read_o <= 1'b0;		
		  end 
		  else if(inst_i[31:21] == 11'b01000000100 
					&& inst_i[10:0] == 11'b00000000000) begin
				aluop_o <= `EXE_MTC0_OP;
				alusel_o <= `EXE_RES_NOP;
				wreg_o <= `WriteDisable;
				instvalid <= `InstValid;	   
				reg1_read_o <= 1'b1;
				reg1_addr_o <= inst_i[20:16];
				reg2_read_o <= 1'b0;					
			end

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值