实验6补充修改部分,关于CPU模块仿真

之前的实验6仿真部分,由于端口定义问题,IF阶段出现无法设置reg类型的问题。
这边做补充修改:
在设计模块中,input类型才可以作为仿真时reg类型实例化,output类型只能作为仿真时的wire类型,无法参与仿真过程块。
强制修改一个wire变量为reg变量,无法实现,因为一个变量会同时传递到多个模块,可能会是input,可能会是output。
这边解决办法是将变量多定义一个,单独用于拥有input类型的模块。

(例如new_pc在IF模块中作为input,可以用reg类型,而在cpu控制模块作为output,只能使用wire类型。这边将尾号带有1的reg类型,实例化到IF模块,而wire类型,实例化到控制模块)

因为模块的内部是定义好连接的,所以在实例化过程还是可以进行参数传递。
定义相同变量如下,不同模块实例化如下:

wire    					if_flush;		 // IF stage
reg                          if_flush1;
wire						 if_stall;		 // IF stage
reg                         if_stall1;
wire [`WordAddrBus]			 new_pc;		 // New program counter
reg [`WordAddrBus]			 new_pc1;


 //实例化
    /********** IF stage **********/
	if_stage if_stage (
		/********** Clock & Reset **********/
		.clk			(clk),				
		.reset			(reset),			
		/********** SPM interface **********/
		.spm_rd_data	(if_spm_rd_data),	
		.spm_addr		(if_spm_addr),		
		.spm_as_		(if_spm_as_),		
		.spm_rw			(if_spm_rw),		
		.spm_wr_data	(if_spm_wr_data),	
		/********** Bus interface **********/
		.bus_rd_data	(if_bus_rd_data),	
		.bus_rdy_		(if_bus_rdy_),	
		.bus_grnt_		(if_bus_grnt_),	
		.bus_req_		(if_bus_req_),		
		.bus_addr		(if_bus_addr),		
		.bus_as_		(if_bus_as_),		
		.bus_rw			(if_bus_rw),		
		.bus_wr_data	(if_bus_wr_data),	
		/********** Pipeline control signal **********/
		.stall			(if_stall1),			
		.flush			(if_flush1),			
		.new_pc			(new_pc1),			
		.br_taken		(br_taken),			
		.br_addr		(br_addr),			
		.busy			(if_busy),		
		/********** IF/ID pipeline register **********/
		.if_pc			(if_pc),			
		.if_insn		(if_insn),			
		.if_en			(if_en)				
	);
	/********** Control unit **********/
	ctrl ctrl (
		/********** Clock & Reset **********/
		.clk			(clk),				
		.reset			(reset),			
		/********** Control register interface **********/
		.creg_rd_addr	(creg_rd_addr),		
		.creg_rd_data	(creg_rd_data),		
		.exe_mode		(exe_mode),			
		/********** Interrupt **********/
		.irq			(cpu_irq),			
		.int_detect		(int_detect),		
		/********** ID/EX pipeline register **********/
		.id_pc			(id_pc),			
		/********** MEM/WB pipeline register **********/
		.mem_pc			(mem_pc),			
		.mem_en			(mem_en),			
		.mem_br_flag	(mem_br_flag),		
		.mem_ctrl_op	(mem_ctrl_op),		
		.mem_dst_addr	(mem_dst_addr),		
		.mem_exp_code	(mem_exp_code),		
		.mem_out		(mem_out),			
		/********** Pipeline control signal **********/
		// Status of pipeline
		.if_busy		(if_busy),			
		.ld_hazard		(ld_hazard),		
		.mem_busy		(mem_busy),			
		// stall singal
		.if_stall		(if_stall),			
		.id_stall		(id_stall),			
		.ex_stall		(ex_stall),			
		.mem_stall		(mem_stall),		
		// Flush signal
		.if_flush		(if_flush),			
		.id_flush		(id_flush),			
		.ex_flush		(ex_flush),		
		.mem_flush		(mem_flush),		
		// New program counter
		.new_pc			(new_pc)			
	);

这样我们就可以实现通过流水线刷新,将new_pc作为传递地址指向SPM内存。IF阶段可以从SPM模块中取出指令,进行后续操作。
注意要在SPM的子模块(x_s3e_dpram.v)中添加一行指令:


mem[0] <= {{`ISA_OP_ADDSR},{5'b00001},{5'b00010},{5'b00011},{11{1'b0}}};

仿真代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/02/04 21:25:14
// Design Name: 
// Module Name: cpu_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"

/********** Local header **********/
`include "isa.vh"
`include "cpu.vh"
`include "bus.vh"
`include "spm.vh"

module cpu_test(

    );
         
    //端口定义
     /********** Clock & Reset **********/
	  reg					  clk;			   // Clock
	  reg					  clk_;			   // Clock (180)
	  reg					  reset;		   // Asynchronous reset
	/********** Bus interface **********/
	// IF Stage
	  reg [`WordDataBus]	  if_bus_rd_data;  // Read data
	  reg					  if_bus_rdy_;	   // Ready
	  reg					  if_bus_grnt_;	   // Bus grant
	 wire					  if_bus_req_;	   // Bus request
	 wire [`WordAddrBus]	  if_bus_addr;	   // Address
	 wire					  if_bus_as_;	   // Address strobe
	 wire					  if_bus_rw;	   // Read/Write
	 wire [`WordDataBus]	  if_bus_wr_data;  // Write data
	// MEM Stage
	  reg [`WordDataBus]	  mem_bus_rd_data; // Read data
	  reg					  mem_bus_rdy_;	   // Ready
	  reg					  mem_bus_grnt_;   // Bus grant
	 wire					  mem_bus_req_;	   // Bus reqeuest
	 wire [`WordAddrBus]	  mem_bus_addr;	   // Address
	 wire					  mem_bus_as_;	   // Address strobe
	 wire					  mem_bus_rw;	   // Read/Write
	 wire [`WordDataBus]	  mem_bus_wr_data; // Write data
	/********** Interrupt **********/
	  reg [`CPU_IRQ_CH-1:0] cpu_irq;	   // Interrupt request
	  
	   /********** Pipeline register **********/
	// IF/ID
	
	wire  [`WordAddrBus]		 if_pc;			 
	wire [`WordDataBus]			 if_insn;		 
	wire						 if_en;			
	// ID/EX pipeline register
	wire [`WordAddrBus]			 id_pc;			 
	wire						 id_en;			
	wire [`AluOpBus]			 id_alu_op;		
	wire [`WordDataBus]			 id_alu_in_0;	
	wire [`WordDataBus]			 id_alu_in_1;	 
	wire						 id_br_flag;	
	wire [`MemOpBus]			 id_mem_op;		
	wire [`WordDataBus]			 id_mem_wr_data;
	wire [`CtrlOpBus]			 id_ctrl_op;	
	wire [`RegAddrBus]			 id_dst_addr;	
	wire						 id_gpr_we_;
	wire [`IsaExpBus]			 id_exp_code;
	// EX/MEM pipeline register
	wire [`WordAddrBus]			 ex_pc;	
	wire						 ex_en;			 
	wire						 ex_br_flag;	 
	wire [`MemOpBus]			 ex_mem_op;		 
	wire [`WordDataBus]			 ex_mem_wr_data; 
	wire [`CtrlOpBus]			 ex_ctrl_op;	 
	wire [`RegAddrBus]			 ex_dst_addr;	 
	wire						 ex_gpr_we_;	
	wire [`IsaExpBus]			 ex_exp_code;	
	wire [`WordDataBus]			 ex_out;		
	// MEM/WB pipeline register
	wire [`WordAddrBus]			 mem_pc;		
	wire						 mem_en;		
	wire						 mem_br_flag;	 
	wire [`CtrlOpBus]			 mem_ctrl_op;	
	wire [`RegAddrBus]			 mem_dst_addr;	 
	wire						 mem_gpr_we_;	 
	wire [`IsaExpBus]			 mem_exp_code;	 
	wire [`WordDataBus]			 mem_out;		 
	/********** Pipeline control signal **********/
	// Stall signal
	wire						 if_stall;		 // IF stage
	reg                         if_stall1;
	wire						 id_stall;		 // ID stage
	wire				          ex_stall;		 // EX stage
	wire						 mem_stall;		 // MEM stage
	// Flush signal
	wire    					if_flush;		 // IF stage
	reg                          if_flush1;
	wire						 id_flush;		 // ID stage
	wire						 ex_flush;		 // EX stage
	wire						 mem_flush;		 // MEM stage
	// Busy signal
	wire						 if_busy;		 // IF stage
	wire						 mem_busy;		 // MEM stage
	// Other control signal
	wire [`WordAddrBus]			 new_pc;		 // New program counter
	reg [`WordAddrBus]			 new_pc1;
	wire [`WordAddrBus]			 br_addr;		 // Branch address
	wire						 br_taken;		 // Branch taken
	wire						 ld_hazard;		 // Load hazard
	/********** GPR signal **********/
	wire [`WordDataBus]			 gpr_rd_data_0;	
	wire [`WordDataBus]			 gpr_rd_data_1;	
	wire [`RegAddrBus]			 gpr_rd_addr_0;	
	wire [`RegAddrBus]			 gpr_rd_addr_1;	
	/********** Control register signal **********/
	wire [`CpuExeModeBus]		 exe_mode;		
	wire [`WordDataBus]			 creg_rd_data;	 
	wire [`RegAddrBus]			 creg_rd_addr;	 
	/********** Interrupt Request **********/
	wire						 int_detect;	
	/********** Scratchpad memory signal **********/
	// IF stage
	wire [`WordDataBus]			 if_spm_rd_data; 
	wire [`WordAddrBus]			 if_spm_addr;	 
	wire						 if_spm_as_;	
	wire						 if_spm_rw;		
	wire [`WordDataBus]			 if_spm_wr_data;
	// MEM stage
	wire [`WordDataBus]			 mem_spm_rd_data; 
	wire [`WordAddrBus]			 mem_spm_addr;	  
	wire						 mem_spm_as_;	 
	wire						 mem_spm_rw;
	wire [`WordDataBus]			 mem_spm_wr_data; 
	/********** Forwarding signal **********/
	wire [`WordDataBus]			 ex_fwd_data;	  // EX stage
	wire [`WordDataBus]			 mem_fwd_data;	  // MEM stage
    
    //时钟激励:
             integer i;
             parameter STEP=100;
    
             always#(STEP/2)begin
             clk<=~clk;
             clk_ <=~clk_;
            
             end
    //实例化
    /********** IF stage **********/
	if_stage if_stage (
		/********** Clock & Reset **********/
		.clk			(clk),				
		.reset			(reset),			
		/********** SPM interface **********/
		.spm_rd_data	(if_spm_rd_data),	
		.spm_addr		(if_spm_addr),		
		.spm_as_		(if_spm_as_),		
		.spm_rw			(if_spm_rw),		
		.spm_wr_data	(if_spm_wr_data),	
		/********** Bus interface **********/
		.bus_rd_data	(if_bus_rd_data),	
		.bus_rdy_		(if_bus_rdy_),	
		.bus_grnt_		(if_bus_grnt_),	
		.bus_req_		(if_bus_req_),		
		.bus_addr		(if_bus_addr),		
		.bus_as_		(if_bus_as_),		
		.bus_rw			(if_bus_rw),		
		.bus_wr_data	(if_bus_wr_data),	
		/********** Pipeline control signal **********/
		.stall			(if_stall1),			
		.flush			(if_flush1),			
		.new_pc			(new_pc1),			
		.br_taken		(br_taken),			
		.br_addr		(br_addr),			
		.busy			(if_busy),		
		/********** IF/ID pipeline register **********/
		.if_pc			(if_pc),			
		.if_insn		(if_insn),			
		.if_en			(if_en)				
	);

	/********** ID stage **********/
	id_stage id_stage (
		/********** Clock & Reset **********/
		.clk			(clk),				
		.reset			(reset),			
		/********** GPR interface **********/
		.gpr_rd_data_0	(gpr_rd_data_0),	
		.gpr_rd_data_1	(gpr_rd_data_1),	
		.gpr_rd_addr_0	(gpr_rd_addr_0),	
		.gpr_rd_addr_1	(gpr_rd_addr_1),	
		/********** Forwarding **********/
		// Forwarding from EX stage
		.ex_en			(ex_en),			
		.ex_fwd_data	(ex_fwd_data),		
		.ex_dst_addr	(ex_dst_addr),		
		.ex_gpr_we_		(ex_gpr_we_),		
		// Forwarding from MEM stage
		.mem_fwd_data	(mem_fwd_data),		
		/********** Control register interface **********/
		.exe_mode		(exe_mode),		
		.creg_rd_data	(creg_rd_data),	
		.creg_rd_addr	(creg_rd_addr),		
		/********** Pipeline control signal **********/
	   .stall		   (id_stall),	
		.flush			(id_flush),			
		.br_addr		(br_addr),			
		.br_taken		(br_taken),			
		.ld_hazard		(ld_hazard),		
		/********** IF/ID pipeline register **********/
		.if_pc			(if_pc),			
		.if_insn		(if_insn),			
		.if_en			(if_en),			
		/********** ID/EX pipeline register **********/
		.id_pc			(id_pc),			
		.id_en			(id_en),			
		.id_alu_op		(id_alu_op),		
		.id_alu_in_0	(id_alu_in_0),		
		.id_alu_in_1	(id_alu_in_1),		
		.id_br_flag		(id_br_flag),	
		.id_mem_op		(id_mem_op),		
		.id_mem_wr_data (id_mem_wr_data),	
		.id_ctrl_op		(id_ctrl_op),	
		.id_dst_addr	(id_dst_addr),		
		.id_gpr_we_		(id_gpr_we_),		
		.id_exp_code	(id_exp_code)		
	);

	/********** EX stage **********/
	ex_stage ex_stage (
		/********** Clock & Reset **********/
		.clk			(clk),				
		.reset			(reset),			
		/********** Pipeline control signal **********/
		.stall			(ex_stall),			
		.flush			(ex_flush),			
		.int_detect		(int_detect),		
		/********** Forwarding **********/
		.fwd_data		(ex_fwd_data),		
		/********** ID/EX pipeline register **********/
		.id_pc			(id_pc),			
		.id_en			(id_en),			
		.id_alu_op		(id_alu_op),		
		.id_alu_in_0	(id_alu_in_0),		
		.id_alu_in_1	(id_alu_in_1),		
		.id_br_flag		(id_br_flag),		
		.id_mem_op		(id_mem_op),		
		.id_mem_wr_data (id_mem_wr_data),	
		.id_ctrl_op		(id_ctrl_op),		
		.id_dst_addr	(id_dst_addr),		
		.id_gpr_we_		(id_gpr_we_),		
		.id_exp_code	(id_exp_code),		
		/********** EX/MEM pipeline register **********/
		.ex_pc			(ex_pc),			
		.ex_en			(ex_en),			
		.ex_br_flag		(ex_br_flag),		
		.ex_mem_op		(ex_mem_op),		
		.ex_mem_wr_data (ex_mem_wr_data),	
		.ex_ctrl_op		(ex_ctrl_op),		
		.ex_dst_addr	(ex_dst_addr),		
		.ex_gpr_we_		(ex_gpr_we_),		
		.ex_exp_code	(ex_exp_code),		
		.ex_out			(ex_out)			
	);

	/********** MEM Stage **********/
	mem_stage mem_stage (
		/********** Clock & Reset **********/
		.clk			(clk),				
		.reset			(reset),			
		/********** Pipeline control signal **********/
		.stall			(mem_stall),		
		.flush			(mem_flush),		
		.busy			(mem_busy),			
		/********** Forwarding **********/
		.fwd_data		(mem_fwd_data),		
		/********** SPM interface **********/
		.spm_rd_data	(mem_spm_rd_data),	
		.spm_addr		(mem_spm_addr),		
		.spm_as_		(mem_spm_as_),		
		.spm_rw			(mem_spm_rw),		
		.spm_wr_data	(mem_spm_wr_data),	
		/********** Bus interface **********/
		.bus_rd_data	(mem_bus_rd_data),	
		.bus_rdy_		(mem_bus_rdy_),		
		.bus_grnt_		(mem_bus_grnt_),	
		.bus_req_		(mem_bus_req_),		
		.bus_addr		(mem_bus_addr),		
		.bus_as_		(mem_bus_as_),		
		.bus_rw			(mem_bus_rw),		
		.bus_wr_data	(mem_bus_wr_data),	
		/********** EX/MEM pipeline register **********/
		.ex_pc			(ex_pc),			
		.ex_en			(ex_en),			
		.ex_br_flag		(ex_br_flag),		
		.ex_mem_op		(ex_mem_op),		
		.ex_mem_wr_data (ex_mem_wr_data),	
		.ex_ctrl_op		(ex_ctrl_op),		
		.ex_dst_addr	(ex_dst_addr),		
		.ex_gpr_we_		(ex_gpr_we_),		
		.ex_exp_code	(ex_exp_code),		
		.ex_out			(ex_out),			
		/********** MEM/WB pipeline register **********/
		.mem_pc			(mem_pc),			
		.mem_en			(mem_en),			
		.mem_br_flag	(mem_br_flag),		
		.mem_ctrl_op	(mem_ctrl_op),		
		.mem_dst_addr	(mem_dst_addr),		
		.mem_gpr_we_	(mem_gpr_we_),		
		.mem_exp_code	(mem_exp_code),		
		.mem_out		(mem_out)			
	);

	/********** Control unit **********/
	ctrl ctrl (
		/********** Clock & Reset **********/
		.clk			(clk),				
		.reset			(reset),			
		/********** Control register interface **********/
		.creg_rd_addr	(creg_rd_addr),		
		.creg_rd_data	(creg_rd_data),		
		.exe_mode		(exe_mode),			
		/********** Interrupt **********/
		.irq			(cpu_irq),			
		.int_detect		(int_detect),		
		/********** ID/EX pipeline register **********/
		.id_pc			(id_pc),			
		/********** MEM/WB pipeline register **********/
		.mem_pc			(mem_pc),			
		.mem_en			(mem_en),			
		.mem_br_flag	(mem_br_flag),		
		.mem_ctrl_op	(mem_ctrl_op),		
		.mem_dst_addr	(mem_dst_addr),		
		.mem_exp_code	(mem_exp_code),		
		.mem_out		(mem_out),			
		/********** Pipeline control signal **********/
		// Status of pipeline
		.if_busy		(if_busy),			
		.ld_hazard		(ld_hazard),		
		.mem_busy		(mem_busy),			
		// stall singal
		.if_stall		(if_stall),			
		.id_stall		(id_stall),			
		.ex_stall		(ex_stall),			
		.mem_stall		(mem_stall),		
		// Flush signal
		.if_flush		(if_flush),			
		.id_flush		(id_flush),			
		.ex_flush		(ex_flush),		
		.mem_flush		(mem_flush),		
		// New program counter
		.new_pc			(new_pc)			
	);

	/********** GPR **********/
	gpr gpr (
		/********** Clock & Reset **********/
		.clk	   (clk),					
		.reset	   (reset),					
		/********** Read port 0 **********/
		.rd_addr_0 (gpr_rd_addr_0),			
		.rd_data_0 (gpr_rd_data_0),			
		/********** Read port 1 **********/
		.rd_addr_1 (gpr_rd_addr_1),			
		.rd_data_1 (gpr_rd_data_1),			
		/********** Write port **********/
		.we_	   (mem_gpr_we_),			
		.wr_addr   (mem_dst_addr),			
		.wr_data   (mem_out)				
	);

	/********** Scratchpad memory **********/
	spm spm (
		/********** Clock **********/
		.clk			 (clk_),					 
		/********** PortA : IF stage **********/
		.if_spm_addr	 (if_spm_addr[`SpmAddrLoc]), 
		.if_spm_as_		 (if_spm_as_),				  
		.if_spm_rw		 (if_spm_rw),				
		.if_spm_wr_data	 (if_spm_wr_data),			 
		.if_spm_rd_data	 (if_spm_rd_data),			  
		/********** PortB : MEM stage **********/
		.mem_spm_addr	 (mem_spm_addr[`SpmAddrLoc]), 
		.mem_spm_as_	 (mem_spm_as_),				
		.mem_spm_rw		 (mem_spm_rw),				 
		.mem_spm_wr_data (mem_spm_wr_data),			  
		.mem_spm_rd_data (mem_spm_rd_data)			 
	);
   //测试模式:
  
  
      
          

    initial
     begin
     
    clk<=1;
    clk_<=0;
    reset<=`RESET_ENABLE;
    #(STEP*3/4)
    #STEP begin
    reset<=`RESET_DISABLE;
    #STEP

     if_stall1<=`DISABLE;
     #STEP
     new_pc1<={{3'b001},{27{1'b0}}};
     if_flush1<=`ENABLE;
   
    #STEP
     if_flush1<=`DISABLE;
     
    
           end           
   
  end   
       
    
endmodule

仿真结果如下:

1.IF阶段
通过newPC,将目标地址转向SPM中,实现在SPM中取出指令。
在这里插入图片描述
2.ID阶段
将指令分解,并准备好计算数据(在GPR模块,gpr[1]和gpr[2])
在这里插入图片描述
3.EX阶段
执行指令,将结果输入到MEM中。
在这里插入图片描述
4.MEM阶段
将EX阶段的结果写入寄存器(gpr[3])
在这里插入图片描述
在这里插入图片描述

实现100+200=300的寄存器间加法指令,仿真结束。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值