2020-11-25

秦韵FPGA 转载或原创(十) -------Intel FPGA

DDR2 ip信号简介
  • ddr ip 端口信号简介
wire clk_x1; 		//来自pll,clk == 50Mhz

QY_DDR2_ip u_QY_DDR2_ip(
	.pll_ref_clk				(clk_x1 			),  //输入时钟,50Mhz
	.phy_clk					(phy_clk			),  //半速率参考时钟,与ip配置有关
	.global_reset_n				(global_reset_n 	),  //全局复位信号,低电平有效
	
	.local_address				(local_address		),	//24bit地址
	.local_write_req			(local_write_req	),	//写请求
	.local_read_req				(local_read_req		),	//读请求
	.local_burstbegin			(local_burstbegin	),	//突发传输开始信号
	.local_wdata				(local_wdata		),	//写数据 64bit
	.local_be					(local_be			),	//数据掩码
	.local_size					(local_size			), 	//突发传输的数据个数


	.soft_reset_n				(soft_reset_n		),  //软复位,默认直接置1'b1
	.local_ready				(local_ready		),	//在该信号为高的情况下,读写请求有效,加载地址
	.local_rdata				(local_rdata		),	//读数据 64bit
	.local_rdata_valid			(local_rdata_valid	),	//读数据有效
	.local_init_done			(local_init_done	),	//初始化完成,高有效
	.reset_phy_clk_n			(reset_phy_clk_n	),	//可以复位phy_clk时钟域的所有逻辑
	
	.mem_odt					(qy_mem_odt			),
	.mem_cs_n					(qy_mem_cs_n		),
	.mem_cke					(qy_mem_cke			),
	.mem_addr					(qy_mem_addr		),
	.mem_ba						(qy_mem_ba 			),
	.mem_ras_n					(qy_mem_ras_n 		),
	.mem_cas_n					(qy_mem_cas_n		),
	.mem_we_n					(qy_mem_we_n		),
	.mem_dm						(qy_mem_dm			),
	.mem_clk					(qy_mem_clk			),
	.mem_clk_n					(qy_mem_clk_n		),
	.mem_dq						(qy_mem_dq			),
	.mem_dqs					(qy_mem_dqs			)
);`
  • 简单的用户端口介绍,使用这些逻辑就可以操作ddr2 ip,该ip采用的半速率模式,有兴趣的可以测试full-rate模式。
DDR2 ip控制逻辑思路简介
  • 配置pll,产生50Mhz信号clk_x1,和locked 的信号,global_reset_n = reset_n & leocked;
  • 完成读写逻辑,在写代码之前,大概的画出代码的逻辑框架,包括状态机的状态图,简单的介绍一下读写ddr2的状态,在真正的逻辑开始之前,首先要做的是等待ddr2 ip 初始化完成,即local_init_done = 1’b1;
  • 完成了初始化,就进入了仲裁状态,即在local_ready信号为高的情况下,等待写请求信号,或者读请求信号,进入写请求状态或者读请求状态,为第二个状态。
  • 直接从请求状态进入写数据或者读数据状态,完成数据的写或者读,这里就基本完成了读或者写,可以加一个或者两个end状态,也可以不加,直接进入仲裁状态,等待下一次请求。
  • 到这里ddr2 ip的控制逻辑就完成了,有需要的就在封装一层,将控制接口封装成类fifo接口,容易控制,也容易理解。
DDR2 ip代码浏览
parameter QY_INIT 		= 4'h0;
parameter QY_ARBIR 		= 4'h1;
parameter QY_WRITE_REQ 	= 4'h2;
parameter QY_WRITE 		= 4'h3;
parameter QY_WRITE_END  = 4'h4;
parameter QY_READ_REQ 	= 4'h5;
parameter QY_READ 		= 4'h6;
parameter QY_READ_END 	= 4'h7;
parameter QY_OVER       = 4'H8;

reg [3:0] qy_state_cs;
reg [3:0] qy_state_ns;

reg [3:0] Write_count;
reg [3:0] Read_count;
always@(posedge clk or negedge reset_n)
if(!reset_n)
    qy_state_cs <= QY_INIT;
else
    qy_state_cs <= qy_state_ns;


always@(*) begin
    case(qy_state_cs)
        QY_INIT :  if(local_init_done)
                        qy_state_ns = QY_ARBIR;
                    else
                        qy_state_ns = QY_INIT;
        QY_ARBIR :  if(qy_write_req && local_ready)
                        qy_state_ns = QY_WRITE_REQ;
                    else if(qy_read_req && local_ready)
                        qy_state_ns = QY_READ_REQ;
                    else
                        qy_state_ns = QY_ARBIR;
        QY_WRITE_REQ :   qy_state_ns = QY_WRITE;
        QY_WRITE :  if(Write_count < local_size)
                        qy_state_ns = QY_WRITE;
                    else
                        qy_state_ns = QY_WRITE_END;
        QY_WRITE_END :  qy_state_ns = QY_ARBIR;
        QY_READ_REQ : qy_state_ns = QY_READ;
        QY_READ :   if(Read_count < local_size)
                        qy_state_ns = QY_READ;
                    else
                        qy_state_ns = QY_READ_END;
        QY_READ_END :   qy_state_ns = QY_ARBIR;
        default : qy_state_ns = QY_INIT;
    endcase
end

always@(posedge clk or negedge reset_n)
if(!reset_n) begin
    local_write_req <= 1'b0;
    local_read_req <= 1'b0;
    local_burstbegin <= 1'b0;
    local_address <= 24'd0;
    Write_count <= 4'd0;
    Read_count <= 4'h0;
    local_wdata <= 64'd0;
    qy_read_data <= 64'd0;
    qy_write_brustend <= 1'b0;
    qy_read_brustend <= 1'b0;
end
else if(qy_state_cs == QY_INIT)begin
    local_write_req <= 1'b0;
    local_read_req <= 1'b0;
    local_burstbegin <= 1'b0;
    local_address <= 24'd0;
    Write_count <= 4'd0;
    Read_count <= 4'h0;
end
else if(qy_state_cs == QY_WRITE_REQ && local_ready) begin
    local_write_req <= 1'b1;
    local_read_req <= 1'b0;
    local_burstbegin <= 1'b1;
    local_address <= qy_write_init_addr;
    Write_count <= 4'd1;
    Read_count <= 4'h0;
end
else if(qy_state_cs == QY_WRITE && local_ready ) begin
    local_write_req <= 1'b1;
    local_burstbegin <= 1'b0;
    local_wdata <= qy_write_data;
    local_address <= local_address + local_size;
    Write_count <= Write_count + 1'b1;
end
else if(qy_state_cs == QY_WRITE_END ) begin
    local_write_req <= 1'b0;
    local_burstbegin <= 1'b0;
    local_wdata <= local_wdata;
    local_address <= 25'd0 ;
    Write_count <= 4'd0;
    qy_write_brustend <= 1'b1;
    qy_read_brustend <= 1'b0;
end
else if(qy_state_cs == QY_READ_REQ && local_ready) begin
    local_write_req <= 1'b0;
    local_read_req <= 1'b1;
    local_burstbegin <= 1'b1;
    local_address <= qy_read_init_addr;
    Write_count <= 4'd0;
    Read_count <= 4'h1;
end
else if(qy_state_cs == QY_READ && local_ready ) begin
    //local_write_req <= 1'b0;
    local_read_req <= 1'b1;
    local_burstbegin <= 1'b0;
    //local_wdata <= qy_write_data;
    if(local_rdata_valid) begin
        local_address <= local_address + local_size;
        Read_count <= Read_count + 1'b1;
        qy_read_data <= local_rdata;
    end
    else begin
        local_address <= 25'd0;
        Read_count <= 4'd1;
        qy_read_data <= 63'd0;
    end
end
else if(qy_state_cs == QY_READ_END ) begin
    local_write_req <= 1'b0;
    local_burstbegin <= 1'b0;
    local_read_req <= 1'b0;
    //local_wdata <= local_wdata;
    local_address <= 25'd0 ;
    Read_count <= 4'h0;
    qy_write_brustend <= 1'b0;
    qy_read_brustend <= 1'b1;
end
else begin
    qy_write_brustend <= 1'b0;
    qy_read_brustend <= 1'b0;
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值