Xilinx DDR output with tri-state....

  • Thread starter John Providenza
  • Start date
J

John Providenza

Guest
I'm trying to create DDR SRAM data I/O pads and am having problems
"pushing" the tri-state enable flip-flop into the IOB. I get the
DDR in/out DATA flip-flops packed into the IOB correctly, but XST 5.2
refuses to use the IOB's tri-state enable flip-flop. This is
targeted at a V2-Pro part.

I'm "hand" instantiating the output DATA ddr "flops", but, for
a variety of reasons, I REALLY don't want to hand instantiate
components to control the tri-state, I'd really like to infer them.

In this design the tri-state control signals are not really "ddr",
they only need to change on posedge clock.


Here's a snippet of my code:

// instantiate 72 DDR output cells
FDDRRSE u0ddr_q (
.C0 (clk_outn), .C1 (clk_out),
.R (1'b0), .S (1'b0), .CE (1'b1),
.D0 (sr_dout[0]), .D1 (sr_dout[72]), .Q (sr_q[0])
);
FDDRRSE u1ddr_q (
.C0 (clk_outn), .C1 (clk_out),
.R (1'b0), .S (1'b0), .CE (1'b1),
.D0 (sr_dout[1]), .D1 (sr_dout[73]), .Q (sr_q[1])
);
FDDRRSE u2ddr_q (
.C0 (clk_outn), .C1 (clk_out),
.R (1'b0), .S (1'b0), .CE (1'b1),
.D0 (sr_dout[2]), .D1 (sr_dout[74]), .Q (sr_q[2])
);
.......

// infer the tri-state output control
// try to get the control bit 'pushed' into the IOB tri-state control f/f
reg sr_oe;
// synthesis attribute IOB of sr_oe "TRUE"
always @(posedge clk_outn)
sr_oe <= bar;

assign sram_dq[71:0] = (sr_oe) ? 72'bz : sr_q[71:0];

a) I have tried a BUNCH of variations on this scheme with no luck.
1) force sr_oe to be a 72 bit vector
2) add KEEP attributes
3) remove the IOB attribute
4) change the tri-state assign statement to be 72 individual
statements, one for each bit.

b) I have set the synthesis options to use IOB flip-flops.

I suspect the Xilinx tools don't like the combination of instantiated
DDR data output flops and inferred tri-state registers pushed into the
IOB.

Any ideas?

John P
 
I found an answer, and here's the code to implement byte-wide
bi-directional DDR pins. I believe part of the magic it took
to make this work was to
a) keep hierarchy
b) pass the tri-state enable signals as an 8 bit bus so that
XST doesn't optimize them into a single signal.
c) use 8 copies of the tri-state 'assign'


// DDR_TRI
// This module provides a BYTE wide, Bi-directional DDR pad interface
with
// tri-state flip-flop embedded in the IOB.
//
// NOTEs:
// a) you need to bring in 8 copies of the tri-state control
signal so
// that XST doesn't optimize the tri_q signals improperly
//
// b) you must use 8 of the
// assign foo[x] = enable[x] ? 1'bz : q[x];
// if you try to use
// assign foo = enable ? 8'bz : q;
// the tri-state control flip-flop doesn't get packed into the
IOB
//
module ddr_tri(
clk_out,
clk_out_n,
clk_in,
clk_in_n,
data_out_even,
data_out_odd,
data_in_even,
data_in_odd,
tri_ctl,
dq
);
input clk_out;
input clk_out_n;
input clk_in;
input clk_in_n;
input [7:0] data_out_even;
input [7:0] data_out_odd;
output [7:0] data_in_even;
output [7:0] data_in_odd;
input [7:0] tri_ctl;
inout [7:0] dq;

reg [7:0] data_in_even;
reg [7:0] data_in_odd;
reg [7:0] tri_q;
wire [7:0] fddq;

//synthesis attribute IOB of tri_q is "TRUE"
always @(posedge clk_out_n)
tri_q <= tri_ctl;

FDDRRSE u0ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[0]),.D1(data_out_odd[0]),.Q(fddq[0]));
FDDRRSE u1ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[1]),.D1(data_out_odd[1]),.Q(fddq[1]));
FDDRRSE u2ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[2]),.D1(data_out_odd[2]),.Q(fddq[2]));
FDDRRSE u3ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[3]),.D1(data_out_odd[3]),.Q(fddq[3]));
FDDRRSE u4ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[4]),.D1(data_out_odd[4]),.Q(fddq[4]));
FDDRRSE u5ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[5]),.D1(data_out_odd[5]),.Q(fddq[5]));
FDDRRSE u6ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[6]),.D1(data_out_odd[6]),.Q(fddq[6]));
FDDRRSE u7ddr_q (.C0(clk_out_n),.C1(clk_out),.R(1'b0),.S(1'b0),.CE(1'b1),.D0(data_out_even[7]),.D1(data_out_odd[7]),.Q(fddq[7]));

assign `Td dq[0] = tri_q[0] ? 1'bz : fddq[0];
assign `Td dq[1] = tri_q[1] ? 1'bz : fddq[1];
assign `Td dq[2] = tri_q[2] ? 1'bz : fddq[2];
assign `Td dq[3] = tri_q[3] ? 1'bz : fddq[3];
assign `Td dq[4] = tri_q[4] ? 1'bz : fddq[4];
assign `Td dq[5] = tri_q[5] ? 1'bz : fddq[5];
assign `Td dq[6] = tri_q[6] ? 1'bz : fddq[6];
assign `Td dq[7] = tri_q[7] ? 1'bz : fddq[7];

//synthesis attribute IOB of data_in_even is "TRUE"
//synthesis attribute IOB of data_in_odd is "TRUE"
always @(posedge clk_in)
data_in_even <= dq;

always @(posedge clk_in_n)
data_in_odd <= dq;

endmodule



johnp3+nospam@probo.com (John Providenza) wrote in message news:<349ef8f4.0312040932.76fe722@posting.google.com>...
I'm trying to create DDR SRAM data I/O pads and am having problems
"pushing" the tri-state enable flip-flop into the IOB. I get the
DDR in/out DATA flip-flops packed into the IOB correctly, but XST 5.2
refuses to use the IOB's tri-state enable flip-flop. This is
targeted at a V2-Pro part.

I'm "hand" instantiating the output DATA ddr "flops", but, for
a variety of reasons, I REALLY don't want to hand instantiate
components to control the tri-state, I'd really like to infer them.

In this design the tri-state control signals are not really "ddr",
they only need to change on posedge clock.


Here's a snippet of my code:

// instantiate 72 DDR output cells
FDDRRSE u0ddr_q (
.C0 (clk_outn), .C1 (clk_out),
.R (1'b0), .S (1'b0), .CE (1'b1),
.D0 (sr_dout[0]), .D1 (sr_dout[72]), .Q (sr_q[0])
);
FDDRRSE u1ddr_q (
.C0 (clk_outn), .C1 (clk_out),
.R (1'b0), .S (1'b0), .CE (1'b1),
.D0 (sr_dout[1]), .D1 (sr_dout[73]), .Q (sr_q[1])
);
FDDRRSE u2ddr_q (
.C0 (clk_outn), .C1 (clk_out),
.R (1'b0), .S (1'b0), .CE (1'b1),
.D0 (sr_dout[2]), .D1 (sr_dout[74]), .Q (sr_q[2])
);
......

// infer the tri-state output control
// try to get the control bit 'pushed' into the IOB tri-state control f/f
reg sr_oe;
// synthesis attribute IOB of sr_oe "TRUE"
always @(posedge clk_outn)
sr_oe <= bar;

assign sram_dq[71:0] = (sr_oe) ? 72'bz : sr_q[71:0];

a) I have tried a BUNCH of variations on this scheme with no luck.
1) force sr_oe to be a 72 bit vector
2) add KEEP attributes
3) remove the IOB attribute
4) change the tri-state assign statement to be 72 individual
statements, one for each bit.

b) I have set the synthesis options to use IOB flip-flops.

I suspect the Xilinx tools don't like the combination of instantiated
DDR data output flops and inferred tri-state registers pushed into the
IOB.

Any ideas?

John P
 

Welcome to EDABoard.com

Sponsor

Back
Top