实验5:CUP的内存MEM阶段实现

Memory阶段(MEM)

mem阶段主要负责内存的访问。在执行LDW和STW等指令时,内存访问操作是在MEM阶段进行的
端口模块定义:

part7.MEM阶段
mem阶段主要负责内存的访问。在执行LDW和STW等指令时,内存访问操作是在MEM阶段进行的
1.mem_ctrl:
基于EX阶段流水线寄存器输入的内存操作(ex_mem_op),实施内存访问操作
     /********** EX/MEM pipeline register **********/
	input  wire				   ex_en,		   // Enable pipline ata
	input  wire [`MemOpBus]	   ex_mem_op,	   // Memory operation
	input  wire [`WordDataBus] ex_mem_wr_data, // Memory write data
	input  wire [`WordDataBus] ex_out,		   // Processing result
	/********** Memory access interface **********/
	input  wire [`WordDataBus] rd_data,		   // Read data
	output wire [`WordAddrBus] addr,		   // Address
	output reg				   as_,			   // Address enable
	output reg				   rw,			   // Read/Write
	output wire [`WordDataBus] wr_data,		   // Write data
	/********** Memory access result **********/
	output reg [`WordDataBus]  out	 ,		   // Memory access result
	output reg				   miss_align	   // Misalign 未对齐
2.mem_reg:
MEM阶段流水线寄存器
     /********** Clock & Reset **********/
	input  wire				   clk,			
	input  wire				   reset,		
	/********** Memory access result **********/
	input  wire [`WordDataBus] out,			 // Memory access result
	input  wire				   miss_align,	 // Misalignment
	/********** Pipeline control signal **********/
	input  wire				   stall,		 // Stall
	input  wire				   flush,		 // Flush
	/********** EX/MEM pipeline register **********/
	input  wire [`WordAddrBus] ex_pc,		 // Program counter
	input  wire				   ex_en,		 // Enable pipeline data
	input  wire				   ex_br_flag,	 // Branch flag
	input  wire [`CtrlOpBus]   ex_ctrl_op,	 // Control register operation
	input  wire [`RegAddrBus]  ex_dst_addr,	 // GPR write address
	input  wire				   ex_gpr_we_,	 // GPR register write enable
	input  wire [`IsaExpBus]   ex_exp_code,	 // Exception code
	/********** MEM/WB pipeline register **********/
	output reg	[`WordAddrBus] mem_pc,		 // Program counter
	output reg				   mem_en,		 // Enable pipeline data
	output reg				   mem_br_flag,	 // Branch flag
	output reg	[`CtrlOpBus]   mem_ctrl_op,	 // Control register operation
	output reg	[`RegAddrBus]  mem_dst_addr, // GPR write address
	output reg				   mem_gpr_we_,	 // GPR register write enable
	output reg	[`IsaExpBus]   mem_exp_code, // Exception code
	output reg	[`WordDataBus] mem_out		 // Processing result
	
3.top模块
mem_stage:
     /********** Clock & Reset **********/
	input  wire				   clk,			 
	input  wire				   reset,		  
	/********** Pipeline control signal **********/
	input  wire				   stall,		   // Stall
	input  wire				   flush,		   // Flush
	output wire				   busy,		   // Busy signal
	/********** Forwarding **********/
	output wire [`WordDataBus] fwd_data,	   // Forwarding
	/********** SPM interface **********/
	input  wire [`WordDataBus] spm_rd_data,	   // Read data
	output wire [`WordAddrBus] spm_addr,	   // Address
	output wire				   spm_as_,		   // Address strobe
	output wire				   spm_rw,		   // Read/Write
	output wire [`WordDataBus] spm_wr_data,	   // Write data
	/********** Bus interface **********/
	input  wire [`WordDataBus] bus_rd_data,	   // Read data
	input  wire				   bus_rdy_,	   // Ready
	input  wire				   bus_grnt_,	   // Bus grant
	output wire				   bus_req_,	   // Bus request
	output wire [`WordAddrBus] bus_addr,	   // Address
	output wire				   bus_as_,		   // Address strobe
	output wire				   bus_rw,		   // Read/Write
	output wire [`WordDataBus] bus_wr_data,	   // Write data
	/********** EX/MEM pipeline register **********/
	input  wire [`WordAddrBus] ex_pc,		   // Program counter
	input  wire				   ex_en,		   // Enable pipeline data
	input  wire				   ex_br_flag,	   // Branch flag
	input  wire [`MemOpBus]	   ex_mem_op,	   // Memory opeartion
	input  wire [`WordDataBus] ex_mem_wr_data, // Data to write to memory
	input  wire [`CtrlOpBus]   ex_ctrl_op,	   // Control register operation
	input  wire [`RegAddrBus]  ex_dst_addr,	   // GPR write address
	input  wire				   ex_gpr_we_,	   // GPR write enable
	input  wire [`IsaExpBus]   ex_exp_code,	   // Exception code
	input  wire [`WordDataBus] ex_out,		   // Processing result
	/********** MEM/WB pipeline register **********/
	output wire [`WordAddrBus] mem_pc,		   // Program counter
	output wire				   mem_en,		   // Enable pipeline data僷
	output wire				   mem_br_flag,	   // Branch flag
	output wire [`CtrlOpBus]   mem_ctrl_op,	   // Control register opeartion
	output wire [`RegAddrBus]  mem_dst_addr,   // GPR write address
	output wire				   mem_gpr_we_,	   // GPR write enable
	output wire [`IsaExpBus]   mem_exp_code,   // Exception code
	output wire [`WordDataBus] mem_out		   // Processing result
    
4.spm模块
    //时钟
    input wire clk,
    //portA:IF阶段
    input  wire [`SpmAddrBus]  if_spm_addr,		// Address 位宽12
	input  wire				   if_spm_as_,		// Address strobe
	input  wire				   if_spm_rw,		// Read/Write
	input  wire [`WordDataBus] if_spm_wr_data,	// Write data 位宽32
	output wire [`WordDataBus] if_spm_rd_data,	// Read data 位宽32
     //portB:MEM阶段
    input  wire [`SpmAddrBus]  mem_spm_addr,		// Address 位宽12
	input  wire				   mem_spm_as_,		// Address strobe
	input  wire				   mem_spm_rw,		// Read/Write
	input  wire [`WordDataBus] mem_spm_wr_data,	// Write data 位宽32
	output wire [`WordDataBus] mem_spm_rd_data	// Read data 位宽32

1.mem_ctrl模块

基于EX阶段流水线寄存器输入的内存操作(ex_mem_op),实施内存访问操作。在此模块需要判断是否地址字对齐。
代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/02/04 16:57:37
// Design Name: 
// Module Name: mem_ctrl
// 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"




module mem_ctrl(
    /********** EX/MEM pipeline register **********/
	input  wire				   ex_en,		   // Enable pipline ata
	input  wire [`MemOpBus]	   ex_mem_op,	   // Memory operation
	input  wire [`WordDataBus] ex_mem_wr_data, // Memory write data
	input  wire [`WordDataBus] ex_out,		   // Processing result
	/********** Memory access interface **********/
	input  wire [`WordDataBus] rd_data,		   // Read data
	output wire [`WordAddrBus] addr,		   // Address
	output reg				   as_,			   // Address enable
	output reg				   rw,			   // Read/Write
	output wire [`WordDataBus] wr_data,		   // Write data
	/********** Memory access result **********/
	output reg [`WordDataBus]  out	 ,		   // Memory access result
	output reg				   miss_align	   // Misalign 未对齐

    );
    /********** Internal signal **********/
	wire [`ByteOffsetBus]	 offset;		   // Offset

    /********** Assign output **********/
    //`define ByteOffsetLoc		1:0		
    //`define WordAddrLoc		31:2	
	assign wr_data = ex_mem_wr_data;		   // Write data
	assign addr	   = ex_out[`WordAddrLoc];	   // Address这边地址是ra寄存器和立即数相加得到的地址,到指定内存位置得到数据存入rb
	assign offset  = ex_out[`ByteOffsetLoc];   // Offset

	/********** Memory access control **********/
	always @(*) begin
		/* Default value */
		miss_align = `DISABLE;
		out		   = `WORD_DATA_W'h0;
		as_		   = `DISABLE_;
		rw		   = `READ;
		/* Memory access */
		if (ex_en == `ENABLE) begin
			case (ex_mem_op)
				`MEM_OP_LDW : begin // Read word
					/* Byte offset check */
					//`define BYTE_OFFSET_WORD	2'b00
					if (offset == `BYTE_OFFSET_WORD) begin // Align 判断是否按字对齐,这边地址只有30位,cpu内部以字编址,处理器而32位以字节编址,
					                                       //最后俩位为偏移地址,如果偏移为0,则说明地址对齐。
					                                       //其中偏移用于寻找对应字节,详细可见书籍字节编址和字编址内容
						out			= rd_data;
						as_		   = `ENABLE_;
					end else begin						   // Misalign
						miss_align	= `ENABLE;
					end
				end
				`MEM_OP_STW : begin // Write word
					/* Byte offset check */
					if (offset == `BYTE_OFFSET_WORD) begin // Align
						rw			= `WRITE;
						as_		   = `ENABLE_;
					end else begin						   // Misalign
						miss_align	= `ENABLE;
					end
				end
				default		: begin // No memory access
					out			= ex_out;
				end
			endcase
		end
	end


endmodule

2.MEM阶段流水线寄存器

主要将EX阶段寄存器信号输出给MEM阶段寄存器
代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/02/04 17:45:02
// Design Name: 
// Module Name: mem_reg
// 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"

module mem_reg(
    /********** Clock & Reset **********/
	input  wire				   clk,			
	input  wire				   reset,		
	/********** Memory access result **********/
	input  wire [`WordDataBus] out,			 // Memory access result
	input  wire				   miss_align,	 // Misalignment
	/********** Pipeline control signal **********/
	input  wire				   stall,		 // Stall
	input  wire				   flush,		 // Flush
	/********** EX/MEM pipeline register **********/
	input  wire [`WordAddrBus] ex_pc,		 // Program counter
	input  wire				   ex_en,		 // Enable pipeline data
	input  wire				   ex_br_flag,	 // Branch flag
	input  wire [`CtrlOpBus]   ex_ctrl_op,	 // Control register operation
	input  wire [`RegAddrBus]  ex_dst_addr,	 // GPR write address
	input  wire				   ex_gpr_we_,	 // GPR register write enable
	input  wire [`IsaExpBus]   ex_exp_code,	 // Exception code
	/********** MEM/WB pipeline register **********/
	output reg	[`WordAddrBus] mem_pc,		 // Program counter
	output reg				   mem_en,		 // Enable pipeline data
	output reg				   mem_br_flag,	 // Branch flag
	output reg	[`CtrlOpBus]   mem_ctrl_op,	 // Control register operation
	output reg	[`RegAddrBus]  mem_dst_addr, // GPR write address
	output reg				   mem_gpr_we_,	 // GPR register write enable
	output reg	[`IsaExpBus]   mem_exp_code, // Exception code
	output reg	[`WordDataBus] mem_out		 // Processing result

    );
    
    /********** Pipeline register **********/
	always @(posedge clk or `RESET_EDGE reset) begin
		if (reset == `RESET_ENABLE) begin	 
			/* Asynchronous Reset */
			mem_pc		 <= #1 `WORD_ADDR_W'h0;
			mem_en		 <= #1 `DISABLE;
			mem_br_flag	 <= #1 `DISABLE;
			mem_ctrl_op	 <= #1 `CTRL_OP_NOP;
			mem_dst_addr <= #1 `REG_ADDR_W'h0;
			mem_gpr_we_	 <= #1 `DISABLE_;
			mem_exp_code <= #1 `ISA_EXP_NO_EXP;
			mem_out		 <= #1 `WORD_DATA_W'h0;
		end else begin
			if (stall == `DISABLE) begin 
				/* Update pipeline register */
				if (flush == `ENABLE) begin				  // Flush
					mem_pc		 <= #1 `WORD_ADDR_W'h0;
					mem_en		 <= #1 `DISABLE;
					mem_br_flag	 <= #1 `DISABLE;
					mem_ctrl_op	 <= #1 `CTRL_OP_NOP;
					mem_dst_addr <= #1 `REG_ADDR_W'h0;
					mem_gpr_we_	 <= #1 `DISABLE_;
					mem_exp_code <= #1 `ISA_EXP_NO_EXP;
					mem_out		 <= #1 `WORD_DATA_W'h0;
				end else if (miss_align == `ENABLE) begin // Misalignment exception
					mem_pc		 <= #1 ex_pc;
					mem_en		 <= #1 ex_en;
					mem_br_flag	 <= #1 ex_br_flag;
					mem_ctrl_op	 <= #1 `CTRL_OP_NOP;
					mem_dst_addr <= #1 `REG_ADDR_W'h0;
					mem_gpr_we_	 <= #1 `DISABLE_;
					mem_exp_code <= #1 `ISA_EXP_MISS_ALIGN;
					mem_out		 <= #1 `WORD_DATA_W'h0;
				end else begin							  // Next data
					mem_pc		 <= #1 ex_pc;
					mem_en		 <= #1 ex_en;
					mem_br_flag	 <= #1 ex_br_flag;
					mem_ctrl_op	 <= #1 ex_ctrl_op;
					mem_dst_addr <= #1 ex_dst_addr;
					mem_gpr_we_	 <= #1 ex_gpr_we_;
					mem_exp_code <= #1 ex_exp_code;
					mem_out		 <= #1 out;
				end
			end
		end
	end

    
endmodule

3.TOP模块,进行模块间连接

这边也连接了bus_if模块,此模块在IF阶段已经创建,这边连接主要实现MEM阶段的直通。并且可以访问SPM内存。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/02/04 18:02:34
// Design Name: 
// Module Name: mem_stage
// 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"

module mem_stage(
    /********** Clock & Reset **********/
	input  wire				   clk,			 
	input  wire				   reset,		  
	/********** Pipeline control signal **********/
	input  wire				   stall,		   // Stall
	input  wire				   flush,		   // Flush
	output wire				   busy,		   // Busy signal
	/********** Forwarding **********/
	output wire [`WordDataBus] fwd_data,	   // Forwarding
	/********** SPM interface **********/
	input  wire [`WordDataBus] spm_rd_data,	   // Read data
	output wire [`WordAddrBus] spm_addr,	   // Address
	output wire				   spm_as_,		   // Address strobe
	output wire				   spm_rw,		   // Read/Write
	output wire [`WordDataBus] spm_wr_data,	   // Write data
	/********** Bus interface **********/
	input  wire [`WordDataBus] bus_rd_data,	   // Read data
	input  wire				   bus_rdy_,	   // Ready
	input  wire				   bus_grnt_,	   // Bus grant
	output wire				   bus_req_,	   // Bus request
	output wire [`WordAddrBus] bus_addr,	   // Address
	output wire				   bus_as_,		   // Address strobe
	output wire				   bus_rw,		   // Read/Write
	output wire [`WordDataBus] bus_wr_data,	   // Write data
	/********** EX/MEM pipeline register **********/
	input  wire [`WordAddrBus] ex_pc,		   // Program counter
	input  wire				   ex_en,		   // Enable pipeline data
	input  wire				   ex_br_flag,	   // Branch flag
	input  wire [`MemOpBus]	   ex_mem_op,	   // Memory opeartion
	input  wire [`WordDataBus] ex_mem_wr_data, // Data to write to memory
	input  wire [`CtrlOpBus]   ex_ctrl_op,	   // Control register operation
	input  wire [`RegAddrBus]  ex_dst_addr,	   // GPR write address
	input  wire				   ex_gpr_we_,	   // GPR write enable
	input  wire [`IsaExpBus]   ex_exp_code,	   // Exception code
	input  wire [`WordDataBus] ex_out,		   // Processing result
	/********** MEM/WB pipeline register **********/
	output wire [`WordAddrBus] mem_pc,		   // Program counter
	output wire				   mem_en,		   // Enable pipeline data僷
	output wire				   mem_br_flag,	   // Branch flag
	output wire [`CtrlOpBus]   mem_ctrl_op,	   // Control register opeartion
	output wire [`RegAddrBus]  mem_dst_addr,   // GPR write address
	output wire				   mem_gpr_we_,	   // GPR write enable
	output wire [`IsaExpBus]   mem_exp_code,   // Exception code
	output wire [`WordDataBus] mem_out		   // Processing result
    
    );
    
    /********** Internal signal **********/
	wire [`WordDataBus]		   rd_data;		
	wire [`WordAddrBus]		   addr;		
	wire					   as_;		
	wire					   rw;		
	wire [`WordDataBus]		   wr_data;		  
	wire [`WordDataBus]		   out;			
	wire					   miss_align;	 

	/********** Result forwarding **********/
	assign fwd_data	 = out;

	/********** Memory access control unit **********/
	mem_ctrl mem_ctrl (
		/********** EX/MEM pipeline register **********/
		.ex_en			(ex_en),			
		.ex_mem_op		(ex_mem_op),		
		.ex_mem_wr_data (ex_mem_wr_data),	 
		.ex_out			(ex_out),		
		/********** Memory access interface **********/
		.rd_data		(rd_data),			
		.addr			(addr),			
		.as_			(as_),			
		.rw				(rw),		
		.wr_data		(wr_data),			
		/********** Memory access result **********/
		.out			(out),				
		.miss_align		(miss_align)		
	);

	/********** Bus interface **********/
	bus_if bus_if (
		/********** Clock & Reset **********/
		.clk		 (clk),				
		.reset		 (reset),				
		/********** Pipeline control signal **********/
		.stall		 (stall),				 
		.flush		 (flush),				
		.busy		 (busy),				 
		/********** CPU interface **********/
		.addr		 (addr),				
		.as_		 (as_),					 
		.rw			 (rw),				
		.wr_data	 (wr_data),				
		.rd_data	 (rd_data),				  
		/********** Scrachpad memory interface **********/
		.spm_rd_data (spm_rd_data),			  
		.spm_addr	 (spm_addr),			   
		.spm_as_	 (spm_as_),				  
		.spm_rw		 (spm_rw),				
		.spm_wr_data (spm_wr_data),			
		/********** Bus interface **********/
		.bus_rd_data (bus_rd_data),			 
		.bus_rdy_	 (bus_rdy_),			
		.bus_grnt_	 (bus_grnt_),			 
		.bus_req_	 (bus_req_),			 
		.bus_addr	 (bus_addr),			
		.bus_as_	 (bus_as_),				
		.bus_rw		 (bus_rw),				  
		.bus_wr_data (bus_wr_data)			   
	);

	/********** MEM stage pipeline register **********/
	mem_reg mem_reg (
		/********** Clock & Reset **********/
		.clk		  (clk),				
		.reset		  (reset),				
		/********** Memory access result **********/
		.out		  (out),				
		.miss_align	  (miss_align),			
		/********** Pipeline control signal **********/
		.stall		  (stall),				 
		.flush		  (flush),				 
		/********** EX/MEM pipeline register **********/
		.ex_pc		  (ex_pc),				  
		.ex_en		  (ex_en),				
		.ex_br_flag	  (ex_br_flag),			 
		.ex_ctrl_op	  (ex_ctrl_op),			 
		.ex_dst_addr  (ex_dst_addr),		  
		.ex_gpr_we_	  (ex_gpr_we_),			 
		.ex_exp_code  (ex_exp_code),		
		/********** 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)				  
	);

    
    
endmodule

4.测试仿真

这边多添加了SPM模块(用于写入内存)
之前的实验已经建立过此模块,只需测试时候实例化即可。
测试思路:
1.将EX阶段的MEM信号作为输入,我们这边将会测试内存访问指令`ISA_OP_STW,用于值写入,将寄存器的一个字写入内存。

   ex_mem_op<=`MEM_OP_STW;

这边将使用SPM作为内存,ex_mem_wr_data作为写入的数据。

     ex_mem_wr_data<=32'hffff_ffff;

2.设置ex_out,这边ex的结果(即ra和立即数相加)是作为内存地址进行传递,详细见下图描述:
在这里插入图片描述
3.地址传递到bus_if模块,作为cpu控制地址,接着利用spm接口,连接spm模块,用于内存访问。
4.最后将结果返回到mem流水线寄存器用于输出。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/02/10 17:00:22
// Design Name: 
// Module Name: mem_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"


module mem_test(

    );
    //定义端口:
    /********** Clock & Reset **********/
	reg  				   clk;			 
	reg  				   reset;		  
	/********** Pipeline control signal **********/
	reg  				   stall;		   // Stall
	reg  				   flush;		   // Flush
	wire 				   busy;		   // Busy signal
	/********** Forwarding **********/
	wire  [`WordDataBus] fwd_data;	   // Forwarding
	/********** SPM interface **********/
	wire   [`WordDataBus] spm_rd_data;	   // Read data
	wire  [`WordAddrBus] spm_addr;	   // Address
	wire 				   spm_as_;		   // Address strobe
	wire 				   spm_rw;		   // Read/Write
	wire  [`WordDataBus] spm_wr_data;	   // Write data
	/********** Bus interface **********/
	reg   [`WordDataBus] bus_rd_data;	   // Read data
	reg  				   bus_rdy_;	   // Ready
	reg  				   bus_grnt_;	   // Bus grant
	wire 				   bus_req_;	   // Bus request
	wire  [`WordAddrBus] bus_addr;	   // Address
	wire 				   bus_as_;		   // Address strobe
	wire 				   bus_rw;		   // Read/Write
	wire  [`WordDataBus] bus_wr_data;	   // Write data
	/********** EX/MEM pipeline register **********/
	reg   [`WordAddrBus] ex_pc;		   // Program counter
	reg  				   ex_en;		   // Enable pipeline data
	reg  				   ex_br_flag;	   // Branch flag
	reg   [`MemOpBus]	   ex_mem_op;	   // Memory opeartion
	reg   [`WordDataBus] ex_mem_wr_data; // Data to write to memory
	reg   [`CtrlOpBus]   ex_ctrl_op;	   // Control register operation
	reg   [`RegAddrBus]  ex_dst_addr;	   // GPR write address
	reg  				   ex_gpr_we_;	   // GPR write enable
	reg   [`IsaExpBus]   ex_exp_code;	   // Exception code
	reg   [`WordDataBus] ex_out;		   // Processing result
	/********** MEM/WB pipeline register **********/
	wire  [`WordAddrBus] mem_pc;		   // Program counter
	wire 				   mem_en;		   // Enable pipeline data僷
	wire 				   mem_br_flag;	   // Branch flag
	wire  [`CtrlOpBus]   mem_ctrl_op;	   // Control register opeartion
	wire  [`RegAddrBus]  mem_dst_addr;   // GPR write address
	wire 				   mem_gpr_we_;	   // GPR write enable
	wire  [`IsaExpBus]   mem_exp_code;   // Exception code
	wire  [`WordDataBus] mem_out;		   // Processing result
     /********** Internal signal **********/
	wire [`WordDataBus]		   rd_data;		
	wire [`WordAddrBus]		   addr;		
	wire					   as_;		
	wire					   rw;		
	wire [`WordDataBus]		   wr_data;		  
	wire [`WordDataBus]		   out;			
	wire					   miss_align;	 
	assign fwd_data	 = out;
	
	integer i;
    parameter STEP=100;
    
    always#(STEP/2)begin
    clk<=~clk;
    end
    
    //实例化
    /********** Memory access control unit **********/
	mem_ctrl mem_ctrl (
		/********** EX/MEM pipeline register **********/
		.ex_en			(ex_en),			
		.ex_mem_op		(ex_mem_op),		
		.ex_mem_wr_data (ex_mem_wr_data),	 
		.ex_out			(ex_out),		
		/********** Memory access interface **********/
		.rd_data		(rd_data),			
		.addr			(addr),			
		.as_			(as_),			
		.rw				(rw),		
		.wr_data		(wr_data),			
		/********** Memory access result **********/
		.out			(out),				
		.miss_align		(miss_align)		
	);

	/********** Bus interface **********/
	bus_if bus_if (
		/********** Clock & Reset **********/
		.clk		 (clk),				
		.reset		 (reset),				
		/********** Pipeline control signal **********/
		.stall		 (stall),				 
		.flush		 (flush),				
		.busy		 (busy),				 
		/********** CPU interface **********/
		.addr		 (addr),				
		.as_		 (as_),					 
		.rw			 (rw),				
		.wr_data	 (wr_data),				
		.rd_data	 (rd_data),				  
		/********** Scrachpad memory interface **********/
		.spm_rd_data (spm_rd_data),			  
		.spm_addr	 (spm_addr),			   
		.spm_as_	 (spm_as_),				  
		.spm_rw		 (spm_rw),				
		.spm_wr_data (spm_wr_data),			
		/********** Bus interface **********/
		.bus_rd_data (bus_rd_data),			 
		.bus_rdy_	 (bus_rdy_),			
		.bus_grnt_	 (bus_grnt_),			 
		.bus_req_	 (bus_req_),			 
		.bus_addr	 (bus_addr),			
		.bus_as_	 (bus_as_),				
		.bus_rw		 (bus_rw),				  
		.bus_wr_data (bus_wr_data)			   
	);

	/********** MEM stage pipeline register **********/
	mem_reg mem_reg (
		/********** Clock & Reset **********/
		.clk		  (clk),				
		.reset		  (reset),				
		/********** Memory access result **********/
		.out		  (out),				
		.miss_align	  (miss_align),			
		/********** Pipeline control signal **********/
		.stall		  (stall),				 
		.flush		  (flush),				 
		/********** EX/MEM pipeline register **********/
		.ex_pc		  (ex_pc),				  
		.ex_en		  (ex_en),				
		.ex_br_flag	  (ex_br_flag),			 
		.ex_ctrl_op	  (ex_ctrl_op),			 
		.ex_dst_addr  (ex_dst_addr),		  
		.ex_gpr_we_	  (ex_gpr_we_),			 
		.ex_exp_code  (ex_exp_code),		
		/********** 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)				  
	);
    //spm实例化
   spm spm(
     //时钟
     .clk(clk),
    //portA:IF阶段
      .if_spm_addr(12'b0),		// Address 位宽12
	  .if_spm_as_(`DISABLE_),		// Address strobe
      .if_spm_rw(`READ),		// Read/Write
	 .if_spm_wr_data(32'h0),	// Write data 位宽32
	 .if_spm_rd_data(spm_rd_data),	// Read data 位宽32
     //portB:MEM阶段
    .mem_spm_addr(spm_addr),		// Address 位宽12
	.mem_spm_as_(spm_as_),		// Address strobe
	.mem_spm_rw(spm_rw),		// Read/Write
	 .mem_spm_wr_data(spm_wr_data),	// Write data 位宽32
	 .mem_spm_rd_data(spm_rd_data)	// Read data 位宽32

   );
    
    //测试
     initial begin
    #10 begin
    clk<=1;
    reset<=`RESET_ENABLE;
    end
    #(STEP*3/4)
    #STEP begin
    reset<=`RESET_DISABLE;
    #STEP
    stall <=`DISABLE;
     #STEP
     ex_en <= `ENABLE;
     ex_mem_op<=`MEM_OP_STW;
     ex_mem_wr_data<=32'hffff_ffff;
     #STEP
     ex_out<={{3'b001},{27{1'b0}},{2'b00}};
      #STEP
      flush<=`DISABLE;
     
      end
    #STEP
    $finish;
    
  end
     
    
    
endmodule

仿真结果:
ex_mem_op的指令为`MEM_OP_STW(数据写入内存)
我们将store data :hffff_ffff,作为写入数据
ex_mem_wr_data<=32’hffff_ffff;
ex_out的前30位作为SPM的访问地址(具体数值可以参考IF阶段的实验),我们将写入SPM的地址0空间
ex_out<={{3’b001},{27{1’b0}},{2’b00}};
可以看到仿真结果:SPM模块的mem【0】写入数据。
仿真结束
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这一个 16 行 8 列的双端口 RAM,每个 RAM 单元的数据位宽为 8 位。其中 `reg` 表示这是一个寄存器变量,`[7:0]` 表示数据位宽为 8 位,`mem` 是变量名,`[15:0]` 表示有 16 行,每行对应一个 8 位寄存器。这个 RAM 有两个端口,可以同时实现读和写。读操作通过 `mem` 数组的索引和读写端口控制信号实现,写操作通过写入数据、地址和写使能信号实现。以下是一个简单的 Verilog 代码实现: ``` module dual_port_ram( input clk, // 时钟信号 input [3:0] r_addr1, // 1 号读地址 input [3:0] r_addr2, // 2 号读地址 input [3:0] w_addr, // 写地址 input [7:0] w_data, // 写数据 input w_en, // 写使能信号 input [1:0] r_en, // 读使能信号 output reg [7:0] r_data1, // 1 号读数据 output reg [7:0] r_data2 // 2 号读数据 ); reg [7:0] mem [15:0]; // 双端口 RAM always @(posedge clk) begin if (w_en) begin // 写使能信号为高电平时,将写入数据存入指定地址的 RAM 单元中 mem[w_addr] <= w_data; end if (r_en[0]) begin // 1 号读使能信号为高电平时,将指定地址的 RAM 单元中的数据输出到 1 号输出端口 r_data1 <= mem[r_addr1]; end if (r_en[1]) begin // 2 号读使能信号为高电平时,将指定地址的 RAM 单元中的数据输出到 2 号输出端口 r_data2 <= mem[r_addr2]; end end endmodule ``` 这个 RAM 模块有一个时钟输入,三个地址输入,一个写数据输入,一个写使能信号输入,两个读使能信号输入,两个输出端口,并声明了一个 16 行 8 列的内部寄存器数组 `mem`。在时钟上升沿时,如果写使能信号为高电平,则将写数据存储到指定地址的 RAM 单元中;如果 1 号读使能信号为高电平,则将指定地址的 RAM 单元中的数据输出到 1 号输出端口;如果 2 号读使能信号为高电平,则将指定地址的 RAM 单元中的数据输出到 2 号输出端口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值