关于Sdram_Control_4Port的修改问题
sdram_control_4port控制器是altera提供的其中包含了它的fifo ip核,现在我想把它改成xilinx能用的,其他的功能暂时不变,2个wr口,2个rd口,并且可以异步。主要就是把altera的fifo ip核改成xilinx的,
altera的fifo配置是异步,16bit*512,例化:
Sdram_FIFO write_fifo1(
.data(),
.wrreq(),
.wrclk(),
.aclr(),
.rdreq(),
.rdclk(),
.q(),
.wrfull(),
.wrusedw(),
.rdusedw()
);
改成对应的xilinx ip核 例化如下:
Sdram_FIFO write_fifo1(
.rst(),
.wr_clk(),
.rd_clk(),
.din(),
.wr_en(),
.rd_en(),
.dout(),
.full(),
.rd_data_count(),
.wr_data_count()
);
其中aclr管脚对应xilinx的rst管脚。
个人感觉两个ip核的功能应该是一样的,为什么我仿真下来发现数据进了写fifo里填满后不向sdram里写,同样不会自动从sdram中读数据到读fifo中?
是不是有什么区别我忽略了,大家有没有谁也做过类似的修改,希望能给我点指点,谢谢了 这两个公司的IP不一样的啊,没有源码的东西基本是不能改用来共用的吧 gnocy 发表于 2012-7-2 20:37 static/image/common/back.gif
这两个公司的IP不一样的啊,没有源码的东西基本是不能改用来共用的吧
是不一样但是ip调用就fifo这个模块,根据他们两家公司给的ip,都有互相对应功能的接口,例如xilinx的wr_en对应altera的wrreq.sdram_control_4port这个控制器是有源码的不是ip核 你用的sdram_control_4port那应该是DE2开发板的历程,那里面确实是有一些相关的源码,但有一点要还是要注意,FIFO这个是用IP核哦,也就是说如果你想用,那么你就必须把FIFO的IP改成xilinx的。接口命名一样的不太表就是一样的功能,比如说对于LCD基本都有CS、RD、WR那你能说他们的驱动能共用吗? 你用的sdram_control_4port那应该是DE2开发板的历程,那里面确实是有一些相关的源码,但有一点要还是要注意,FIFO这个是用IP核哦,也就是说如果你想用,那么你就必须把FIFO的IP改成xilinx的。接口命名一样的不太表就是一样的功能,比如说对于LCD基本都有CS、RD、WR那你能说他们的驱动能共用吗? gnocy 发表于 2012-7-3 08:25 static/image/common/back.gif
你用的sdram_control_4port那应该是DE2开发板的历程,那里面确实是有一些相关的源码,但有一点要还是要注意 ...
我就改了FIFO这个ip,主要我看了sdram_control_4port源码感觉这个控制器对于异步自动读写很不错,比较适合我做的东西,后来确定是我改的FIFO问题,写端填满后不写入sdram,然后我又单独仿真了xilinx的fifo ip 发现他的rd_data_count 记到0x10就不计了,wr_data_count也是计到0x1010就没了,我发的是6500个递增数。 你的FIFO没写好吧。我给你个我写的通用FIFO程序:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 10:06:33 04/08/2012
// Design Name:
// Module Name: BlockRamFIFOx16
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module BlockRamFIFO256x16(
input int_in_GCLK,
input int_in_GRST,
input int_in_PortA_in,
input int_in_PortA_WE_in, // Active 1
output int_out_PortA_Full,
output int_out_PortB_out,
output int_out_PortB_out_DRDY,
input int_in_PortB_RD_in, // Active 1
output int_out_PortB_Empty
);
reg r_Addr_int_in_PortA_in;
reg r_PortA_WE;
reg r_int_in_PortA_in;
reg r_Addr_int_out_PortB_out;
reg r_int_out_PortB_out;
wire w_PortB_out;
reg r_int_out_PortB_out_DRDY;
assign int_out_PortB_out = r_int_out_PortB_out;
assign int_out_PortB_out_DRDY = r_int_out_PortB_out_DRDY;
wire w_FIFOEmpty = (r_Addr_int_in_PortA_in == r_Addr_int_out_PortB_out);
wire w_FIFOFull= (r_Addr_int_in_PortA_in == {~r_Addr_int_out_PortB_out,r_Addr_int_out_PortB_out});
assign int_out_PortA_Full = w_FIFOFull;
assign int_out_PortB_Empty = w_FIFOEmpty;
reg r_int_in_PortB_RD_in_delay;
always @(posedge int_in_GCLK or negedge int_in_GRST)
begin
if(~int_in_GRST)
begin
r_Addr_int_in_PortA_in <= 0;
r_Addr_int_out_PortB_out <= 0;
r_PortA_WE <= 0;
end
else
begin
if(int_in_PortA_WE_in & ~w_FIFOFull)
begin
// Address inc first, then write
r_int_in_PortA_in <= int_in_PortA_in;
r_Addr_int_in_PortA_in <= r_Addr_int_in_PortA_in + 1;
r_PortA_WE <= 1;
end
else
begin
r_PortA_WE <= 0;
end
r_int_in_PortB_RD_in_delay <= {r_int_in_PortB_RD_in_delay,int_in_PortB_RD_in};
if(r_int_in_PortB_RD_in_delay)
begin
r_int_out_PortB_out_DRDY <= 1;
r_int_out_PortB_out <= w_PortB_out;
end
else
begin
r_int_out_PortB_out_DRDY <= 0;
r_int_out_PortB_out <= r_int_out_PortB_out;
end
if(int_in_PortB_RD_in & ~w_FIFOEmpty)
begin
// Address inc first, then read after 1 cycle
r_Addr_int_out_PortB_out <= r_Addr_int_out_PortB_out + 1;
end
else
begin
r_Addr_int_out_PortB_out <= r_Addr_int_out_PortB_out;
end
end
end
RAMB4_S16_S16 RAMS16FIFOAIBO(
.DIA(r_int_in_PortA_in), // Port A 8-bit data input
.WEA(r_PortA_WE), // Port A RAM write enable input
.DOB(w_PortB_out), // Port B 8-bit data output
.ADDRA(r_Addr_int_in_PortA_in), // Port A 9-bit address input
.ADDRB(r_Addr_int_out_PortB_out), // Port B 9-bit address input
.CLKA(int_in_GCLK), // Port A clock input
.CLKB(int_in_GCLK), // Port B clock input
.ENA(1'b1), // Port A RAM enable input
.ENB(1'b1), // Port B RAM enable input
.RSTA(1'b0), // Port A Synchronous reset input
.RSTB(1'b0), // Port B Synchronous reset input
.WEB(1'b0)// Port B RAM write enable input
);
endmodule
我的片子只有4Kb的小块,老片子,新的可以照改,只要保证地址位宽等等一致就行了。注意我这是同步FIFO。异步的我还没搞,不容易搞。 还有一点,我那个同步FIFO的输出是有延时的,只有当int_out_PortB_out_DRDY为高时才说明数据有效,int_out_PortB_out_DRDY只维持一个周期。 wye11083 发表于 2012-7-4 10:12 static/image/common/back.gif
还有一点,我那个同步FIFO的输出是有延时的,只有当int_out_PortB_out_DRDY为高时才说明数据有效,int_out_ ...
我直接用的xilinx的fifo ip核。。。。DCM的输出端口不能单独相移,输入50Mclk,控制clk100M,sdr_clk 100M相移90或270的话就要2个dcm(dcm没有clk2X270只有clk270),我应用2个dcm就报错,能有个在xilinx上实现了的sdr控制器就好了,感觉在这上面太花时间了 不要移相。我的SDRAM只用了两个时钟,一个DLL从50升到100,另一个从100升到200,然后就用这两个时钟读写SDRAM。移相之后一是建立时间难以满足,导致布线难以布通,二是凡是涉及到移相,最后你的输出就算是寄存器输出,延时也难以计算。你可以用我发的那个控制器,用1个DCM产生100M和200M的时钟接到GCLK,GCLK2X上就行了。例程我回头也贴上去。要注意的是需要在XST和MAP中把IOB Register Packing全部选中,否则会出现时序问题,导致读写异常。
页:
[1]