Ok, so test #1 conditions:
In BrianHG_DDR3_PLL:
===================
assign DDR3_CLK = PLL1_clk_out[0]; // DDR3 CK clock running at 1/2 the DQ rate.
assign DDR3_CLK_WDQ = PLL1_clk_out[1]; // DDR3 write data clock 90 degree out of phase running at 1/2 the DQ rate.
assign DDR3_CLK_RDQ = PLL1_clk_out[2]; // DDR3 phase adjustable read data input clock running at 1/2 the DQ rate.
In top.sv:
=========
DDR3_WDQ_PHASE = 270,
In ddr_io_port_gowin:
====================
WDQ_SYNC_CHAIN = 3 + CMD_ADD_DLY - WDQ_CLK_270
route DQ OE directly to IOBUF:
IOBUF gowin_dq_iobuf_inst
(
.O(gowin_dq_in), // IOBUF -> IDDR
.IO(DDR3_DQ[x]), // DQ pad
.I(gowin_dq_out), // ODDR -> IOBUF
.OEN(~PIN_OE_WDQ_wide[x]) // input when 1'b1
Set DQ clock to toggle:
assign dq_clk[x] = (PIN_OE_WDQ_wide[x]) ? DDR_CLK_WDQ : DDR_CLK_RDQ;
I get an error that the top module can't directly drive the IOBUF ...
ERROR (CK0011) : Instance 'DDR3_PHY/BHG_DDR3_IO_PORT_GOWIN/gowin_DQ_bus[0].gowin_dq_oddr_inst'(ODDR) of module 'top' cannot drive instance 'DDR3_PHY/BHG_DDR3_IO_PORT_GOWIN/gowin_DQ_bus[0].gowin_dq_iobuf_inst'(IOBUF)
The code is below: I replaced the commented out part of the DQ IOBUF with the version that does not send OE through the ODDR.
for (x=0; x<DQ_WIDTH; x = x + 1)
begin : gowin_DQ_bus
wire gowin_dq_out;
wire gowin_dq_in;
wire gowin_dq_tx_out;
// See above comment in DQS code for this...
assign dq_clk[x] = (PIN_OE_WDQ_wide[x]) ? DDR_CLK_WDQ : DDR_CLK_RDQ;
ODDR gowin_dq_oddr_inst
(
.Q0(gowin_dq_out), // ODDR -> IOBUF
.Q1(gowin_dq_tx_out), // OE -> IOBUF, 1'b0 => output
.D0(PIN_WDATA_PIPE_h[0][x]), // Input data [SDR]
.D1(PIN_WDATA_PIPE_l[0][x]), // Input data [SDR]
.TX(~PIN_OE_WDQ_wide[x]), // Input 'output enable' 1'b0=out
.CLK(dq_clk[x]) // write clock
);
IDDR gowin_dq_iddr_inst
(
.Q0(RDQ_l[x]), // SDR to app #0
.Q1(RDQ_h[x]), // SDR to app #1
.D(gowin_dq_in), // DDR input signal
.CLK(dq_clk[x]) // read clock
);
// IOBUF gowin_dq_iobuf_inst
// (
// .O(gowin_dq_in), // IOBUF -> IDDR
// .IO(DDR3_DQ[x]), // DQ pad
// .I(gowin_dq_out), // ODDR -> IOBUF
// .OEN(gowin_dq_tx_out) // input when 1'b1
// );
IOBUF gowin_dq_iobuf_inst
(
.O(gowin_dq_in), // IOBUF -> IDDR
.IO(DDR3_DQ[x]), // DQ pad
.I(gowin_dq_out), // ODDR -> IOBUF
.OEN(~PIN_OE_WDQ_wide[x]) // input when 1'b1
);
end
Swapping in the commented section will make it compile again, so it's definitely that single line in the IOBUF OE. I can do the tests without the direct wiring, if that will help ?