05-SDRAM:仲裁

SDRAM 仲裁

  1. state
  2. sdram_cmd_reg: 初始化、写操作、读操作、自刷新模块传来的指令,需要内部用sdram_cmd接收,
    然后分别输出为sdram_cs_n、sdram_ras_n、sdram_cas_n、sdram_we_n
  3. aref_en: 当前状态为仲裁状态ARBIT,且aref_req=1 (依赖ARBIT、aref_req)
  4. wr_en: 当前状态为仲裁状态ARBIT,且wr_req=1 (依赖ARBIT、wr_req)
  5. rd_en: 当前状态为仲裁状态ARBIT,且rd_req=1 (依赖ARBIT、rd_req)

设计文件

// SDRAM 仲裁
// 1. state
// 2. sdram_cmd_reg:		初始化、写操作、读操作、自刷新模块传来的指令,需要内部用sdram_cmd接收,
//						然后分别输出为sdram_cs_n、sdram_ras_n、sdram_cas_n、sdram_we_n
// 3. aref_en:			当前状态为仲裁状态ARBIT,且aref_req=1 (依赖ARBIT、aref_req)
// 4. wr_en:			当前状态为仲裁状态ARBIT,且wr_req=1 (依赖ARBIT、wr_req)
// 5. rd_en:			当前状态为仲裁状态ARBIT,且rd_req=1 (依赖ARBIT、rd_req)


module sdram_arbit(
	input 				    clk,
	input 				    rst_n,
	
	input 				    init_end,
	input   	[3:0]		init_cmd,//SDRAM命令,组成{CS#,RAS#,CAS#,WE#}
	input   	[1:0] 		init_bank,//BANK地址,共4个BANK
	input   	[12:0]		init_addr,//SDRAM地址总线	
	
	input 	   	  			auto_ref_req,
	input 	   	  			auto_ref_end,	
	input   	[3:0]		auto_ref_cmd,//SDRAM命令,组成{CS#,RAS#,CAS#,WE#}
	input   	[1:0] 		auto_ref_bank,//BANK地址,共4个BANK
	input   	[12:0]		auto_ref_addr,//SDRAM地址总线

	
	input 	   	  			wr_req,
	input 	   	  			wr_end,	
	input   	[3:0] 		write_cmd,
	input   	[1:0] 		write_bank,
	input   	[12:0] 		write_addr,	
	input   				wr_sdram_en,//三态门的判断条件 
	input       [15:0] 		wr_sdram_data,//如果wr_sdram_en=1,那么sdram_dq为输出端口,将写操作的数据wr_sdram_data输出给SDRAM
	
	input 	   	  			rd_req,
	input 	   	  			rd_end,
	input   	[3:0] 		read_cmd,
	input   	[1:0] 		read_bank,
	input   	[12:0] 		read_addr,	

	
	output   	 			aref_en,
	output   	 			wr_en,
	output  		 		rd_en,
	output    		 		sdram_cke,
	
	output    		 		sdram_cs_n,
	output    		 		sdram_ras_n,
	output    		 		sdram_cas_n,
	output    		 		sdram_we_n,
	
	output reg 	[1:0] 		sdram_bank,
	output reg 	[12:0] 		sdram_addr,
	output reg 	[15:0] 		sdram_dq
);
 

//==========================================parameter===========================================================

//状态机
localparam	IDLE	= 5'b0_0001   ,   	//初始状态
            ARBIT	= 5'b0_0010   ,   	//仲裁状态
            ATREF	= 5'b0_0100   ,   	//自动刷新状态
            WRITE	= 5'b0_1000   ,   	//写状态
            READ	= 5'b1_0000   ;   	//读状态
			
//命令指令参数			
localparam	NOP		= 4'b0111     ;   	//空操作指令

//==========================================reg=================================================================
			
reg [2:0] state;
reg [2:0] next_state;
reg [3:0] sdram_cmd_reg;

//==========================================wire=================================================================


//==========================================assign=================================================================
assign sdram_cke   = 1'd1;
assign sdram_cs_n  = sdram_cmd_reg[3];
assign sdram_ras_n = sdram_cmd_reg[2];
assign sdram_cas_n = sdram_cmd_reg[1];
assign sdram_we_n  = sdram_cmd_reg[0];
//assign  {sdram_cs_n, sdram_ras_n, sdram_cas_n, sdram_we_n} = sdram_cmd; 还可以这样写

assign sdram_dq = (wr_sdram_en) ? wr_sdram_data:16'bz;
//==========================================always=================================================================
always@(posedge clk or negedge rst_n)begin
	if(!rst_n )
		aref_en <= 1'd0;
	else if((state == ARBIT) && auto_ref_req)
		aref_en <= 1'd1;
	else if(auto_ref_end)
		aref_en <= 1'd0;
	else 
		aref_en <= aref_en;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n )
		wr_en <= 1'd0;
	else if((state == ARBIT) && wr_req && (!auto_ref_req))//优先级体现
		wr_en <= 1'd1;
	else if(wr_end)
		wr_en <= 1'd0;
	else 
		wr_en <= wr_en;
end

always@(posedge clk or negedge rst_n)begin
	if(!rst_n )
		rd_en <= 1'd0;
	else if((state == ARBIT) && rd_req && (!auto_ref_req) && (!wr_req))//优先级体现
		rd_en <= 1'd1;
	else if(rd_end)
		rd_en <= 1'd0;
	else 
		rd_en <= rd_en;
end


//==========================================状态机=================================================================

// 第一段
always@(posedge clk or negedge rst_n)begin
	if(!rst_n )begin
		state <= IDLE;
	end
	else 
		state <= next_state;
end
//--状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
always@(*)begin
	case(state)
		IDLE:
			if(init_end)
				next_state = ARBIT;
			else 
				next_state = IDLE;
		ARBIT:  //优先级:自动刷新-写操作-读操作
			if(auto_ref_req)
				next_state = ATREF;
			else if(wr_req )
				next_state = WRITE;
			else if(rd_req)
				next_state = READ;
			else 
				next_state = ARBIT;
		ATREF: 	
			if(auto_ref_end)
				next_state = ARBIT;
			else
				next_state = ATREF;				
		WRITE:
			if(wr_end)
				next_state = ARBIT;
			else 
				next_state = WRITE;
		READ:
			if(rd_end)
				next_state = ARBIT;
			else	
				next_state = READ;

	default:next_state = IDLE;
	endcase

end

// 第三段
always@(*)begin
		case(state)
			IDLE:begin
				sdram_cmd_reg <= 4'd0;
			    sdram_bank 	  <= 2'd0;
			    sdram_addr	  <= 13'd0;
			end
			ATREF:begin
				sdram_cmd_reg <= auto_ref_cmd;
			    sdram_bank 	  <= auto_ref_bank;
			    sdram_addr	  <= auto_ref_addr;			
			end
			WRITE:begin
				sdram_cmd_reg <= write_cmd;
			    sdram_bank 	  <= write_bank;
			    sdram_addr	  <= write_addr;			
			end
			READ:begin
				sdram_cmd_reg <= read_cmd;
			    sdram_bank 	  <= read_bank;
			    sdram_addr	  <= read_addr;			
			end			
		default:begin
				sdram_cmd_reg <= NOP;
			    sdram_bank 	  <= 2'b11;
			    sdram_addr	  <= 13'h1fff;			
			end;
		endcase
end
endmodule 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值