[UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals

DH
Davis Hoover
Fri, Dec 20, 2019 5:52 PM

Gotcha. So sounds like modifying the framework for explicit instantiation
of proper output buffer primitives would fix all cases, and would not
require changes to the existing generated tie-off code.

---------- Forwarded message ---------
From: Walters Dominic A dawalters@mail.dstl.gov.uk
Date: Fri, Dec 20, 2019 at 6:58 AM
Subject: RE: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly
code gen caused by unassigned differential signals
To: Davis Hoover dhoover@geontech.com, discuss@lists.opencpi.org <
discuss@lists.opencpi.org>

Classification: UK OFFICIAL

The issue stems from the fact that the differential output signal isn't
used, so the "tie off" code is used to assign it to ground.
The problem there being that if one side of a differential signal is
ground, the other needs to be ¬ground (afaik that's a logical requirement
of all digital differential signals).
The current tie off code drives both sides with ground.
Tieing off one side of the pair with '1' was my attempt to get Vivado to
infer an OBUFDS, which it didn't (probably wasn't reasonable for me to
expect it to!).
For Vivado to realise that a signal on an FPGA output pin is differential
(thereby allowing IOStandard constraints of differential types), the first
thing it needs to see back from the pin is an OBUFDS (or a similar
component).
That last sentence is a guess, but it certainly seems like it's true.

-----Original Message-----
From: discuss discuss-bounces@lists.opencpi.org On Behalf Of Davis Hoover
Sent: 19 December 2019 17:50
To: discuss@lists.opencpi.org
Subject: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code
gen caused by unassigned differential signals

The need to instantiate (or at least infer) OBUFDS for differential signals
makes sense. Curiously, we haven't run into this problem for differential
signals on Zynq 7000 FPGAs which support the same OBUF/OBUFDS primitives.
Perhaps Ultrascale has more strict requirements. We'll make a note to
address this differential I/O buffering problem in the code generator.

FYI the util primitive library in the core project has BUFFER_OUT*
components which are intended to facilitate vendor-agnostic I/O buffering.

What is driving the requirement to tie-off with a value of 1? I'm trying to
determine if this is something the framework needs to support.

Glad you've got a working workaround now.

---------- Forwarded message ---------
From: Walters Dominic A via discuss discuss@lists.opencpi.org
Date: Thu, Dec 19, 2019 at 7:39 AM
Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly
code gen caused by unassigned differential signals
To: discuss@lists.opencpi.org discuss@lists.opencpi.org

Classification: UK OFFICIAL

Forgot to add, obviously this then becomes a Xilinx only solution.
I'm not familiar enough with the codegen to come up with a better one.

-----Original Message-----
From: discuss discuss-bounces@lists.opencpi.org On Behalf Of Walters
Dominic A via discuss
Sent: 19 December 2019 13:25
To: discuss@lists.opencpi.org
Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly
code gen caused by unassigned differential signals

Classification: UK OFFICIAL

Hey,

So simply setting one side of the pair to be high didn't work.
The schematic shows the signal connected to high, but an OBUFDS wasn't
inferred by Vivado (Maybe I'm assuming too much of it tbh :D).
Manually instantiating an OBUFDS at the bottom of the "-assy.vhd" file
where the tie off code is generated does seemingly fix this problem.
Side Note: The schematic diagram moves the driver of these pins inside of
the ftop block (the signals go into ftop rather than being driven in the
layer above).

Anyway, the fix for this would now need to instantiate the OBUFDS block in
code gen (unless there is some way to infer one?).
And either as many OBUFDS blocks as the port is wide, or drive all elements
of the signal off of one OBUFDS (I've done the former).

This is what I've managed to put together to replace the old
"if(s.m_differential)" block (it should even indent correctly!):

if (s.m_differential) {
OU::format(name, s.m_pos.c_str(), s.cname());
std::string index = "";
std::string spacing = "";
if (s.m_width) {
fprintf(f, "  GEN_%s: for GEN_I in 0 to %lu generate\n",
name.c_str(), s.m_width);
index = "(GEN_I)";
spacing = "  ";
}
fprintf(f,
"  %sOBUFDS_%s_inst : OBUFDS\n"
"  %sport map(I => std_logic'('0'),\n", spacing.c_str(),
name.c_str(), spacing.c_str());
OU::format(name, s.m_pos.c_str(), s.cname());
fprintf(f,
"  %s        OB => %s%s,\n", spacing.c_str(),
name.c_str(), index.c_str());
OU::format(name, s.m_neg.c_str(), s.cname());
fprintf(f,
"  %s        O => %s%s);\n", spacing.c_str(),
name.c_str(), index.c_str());
if (s.m_width) {
OU::format(name, s.m_pos.c_str(), s.cname());
fprintf(f, "  end generate %s;\n", name.c_str());
}
} else ...

I haven't got a use case to test the generate parts (all my differential
signals are width 1), but this works on my current device worker for the 2
assemblies that I've tried.
Both generated their bitstreams correctly, with no related errors or
warnings.

Kind Regards,
D. Walters

-----Original Message-----
From: Walters Dominic A
Sent: 19 December 2019 11:20
To: 'Davis Hoover' dhoover@geontech.com; discuss@lists.opencpi.org;
'James Kulp' jek@parera.com
Subject: RE: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly
code gen caused by unassigned differential signals

Classification: UK OFFICIAL

Hey,

I had seen these ARs when trying to look up the problem, but I'm pretty
sure they aren't related.
The pins in question are outputs of a MIG that go directly to an FPGA
output pin, so I don't think I need to manually constrain them?
The MIG core should do that.

I'm relatively confident that this is an OCPI bug.
When you leave pins unconnected in an empty container, they are treated
differently depending on what they are.
From my synthesized opt stage schematic:

    1. Input pins are left unconnected.
    1. Bidirectional pins that aren't driven are left unconnected.
    1. Output pins that aren't driven, are connected to ground through an
      OBUF.

This third one causes a problem with differential signals.
In the synthesized schematic (from opt stage) the _n and _p sides of my
differential signal are separately driven from OBUF primitives connected to
ground, when they should be driven from the paired outputs of an OBUFDS
connected to ground.
As such, both sides of the differential pair are grounded when one of them
should instead be high.
I believe this is caused by the same lines of code that James patched at
the start of this thread.
One side of the differential pair should be tied high instead of low.

I believe the patch should instead be:
--- a/tools/ocpigen/src/hdl-container.cxx
+++ b/tools/ocpigen/src/hdl-container.cxx
@@ -1075,9 +1075,9 @@ emitTieoffSignals(FILE *f) {
"  -- Output signal "%s" is not connected to any instance.\n",
s.cname());
if (s.m_differential) {
OU::format(name, s.m_pos.c_str(), s.cname());

  •  fprintf(f, "  %s => %s,\n", name.c_str(), s.m_width ? "(others =>
    

'0')" : "'0'");

  •  fprintf(f, "  %s <= %s;\n", name.c_str(), s.m_width ? "(others =>
    

'1')" : "'1'");
OU::format(name, s.m_neg.c_str(), s.cname());

  •  fprintf(f, "  %s => %s,\n", name.c_str(), s.m_width ? "(others =>
    

'0')" : "'0'");

  •  fprintf(f, "  %s <= %s;\n", name.c_str(), s.m_width ? "(others =>
    

'0')" : "'0'");
} else
fprintf(f, "  %s <= %s;\n", s.cname(), s.m_width ? "(others =>
'0')" : "'0'");
break;

This corrects the first bug in this thread that James fixed, and this one.
It sets the _p side to be high, and the _n side low. I'm testing this
possible solution now, I'll update when it finishes.

Thanks for your help,
D. Walters

-----Original Message-----
From: discuss discuss-bounces@lists.opencpi.org On Behalf Of Davis Hoover
Sent: 18 December 2019 20:08
To: discuss@lists.opencpi.org
Subject: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code
gen caused by unassigned differential signals

This might fix your issue:
https://scanmail.trustwave.com/?c=7369&d=67j73cx3LGcpR6dEHk-xRYJuFkdQCDR7BpJ_fuoP6A&u=https%3a%2f%2fwww%2exilinx%2ecom%2fsupport%2fanswers%2f57109%2ehtml
Also related:
https://scanmail.trustwave.com/?c=7369&d=67j73cx3LGcpR6dEHk-xRYJuFkdQCDR7BpZ4drkLvg&u=https%3a%2f%2fforums%2exilinx%2ecom%2ft5%2fWelcome-Join%2fSystemclockP-is-a-Single-ended-but-iostandard-is-LVDS-25-which%2ftd-p%2f557165

---------- Forwarded message ---------
From: Walters Dominic A via discuss discuss@lists.opencpi.org
Date: Wed, Dec 18, 2019 at 10:32 AM
Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly
code gen caused by unassigned differential signals
To: James Kulp jek@parera.com, discuss@lists.opencpi.org <
discuss@lists.opencpi.org>

Classification: UK OFFICIAL

Hi again,

I'm having another (possibly related) problem during bitstream generation.
Same build as last email (trying to make an empty container for an fmcomms
card with a device worker available in the BSP but unused).

Vivado is returning the following error:

[DRC IOSTDTYPE-1] IOStandard Type: I/O port <device_worker_name>_ddr4_ck_c
is Single-Ended but has IOStandard of DIFF_SSTL12 which can only support
Differential.
[DRC IOSTDTYPE-1] IOStandard Type: I/O port <device_worker_name>_ddr4_ck_t
is Single-Ended but has IOStandard of DIFF_SSTL12 which can only support
Differential.

This error propagates from the opt stage, which had the above error as a
critical warning (becoming an error during bitstream generation).

The signal in question "<device_worker_name>_ddr4_ck" is defined as
differential in my device worker .xml with the appropriate "pos" and "neg"
formatting strings:
* <signal output='ddr4_ck' differential='1' pos='%s_t' neg='%s_c' />

The IOStandard of DIFF_SSTL12 is correct. My container .xdc has two lines
for each side of the differential (one set_property to designate the pin
its attached to, and another for its IOStandard) I tried changing the names
to the more standard "_n" and "_p" in case it was a parsing error, but that
didn't work.

Again, this error occurs only on a differential output signal. A
bidirectional differential signal of width 2 in the same device worker
isn't having a problem (although it does use a different IOStandard:
DIFF_POD12).
In the synthesised schematic in the .xpr file, both of these pins are
present and are each being driven from ground through an OBUF.

Seems like this is more likely to be caused by something I've written,
rather than being an OCPI bug, as this is the first time that the device
worker is being put through the full vivado build process.
Have I missed out a constraint that I need to apply to the pin (not really
an OCPI question anymore :D)?
Does the signal tag in the xml need a "pin='1'"?

Thanks,
D. Walters

-----Original Message-----
From: James Kulp jek@parera.com
Sent: 17 December 2019 17:08
To: Walters Dominic A dawalters@dstl.gov.uk; discuss@lists.opencpi.org
Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly
code gen caused by unassigned differential signals

Congratulations on stepping on a latent silly bug.
I haven't searched our (soon to be public) bug database for this. Clearly
none of the devices we currently use or test have hit this differential
tieoff issue before.

If you are building from source code and want a quick patch you can try
this (untested) change.
It has been made in our development version.

--- a/tools/ocpigen/src/hdl-container.cxx
+++ b/tools/ocpigen/src/hdl-container.cxx
@@ -1075,9 +1075,9 @@ emitTieoffSignals(FILE *f) {
"  -- Output signal "%s" is not connected to any instance.\n",
s.cname());
if (s.m_differential) {
OU::format(name, s.m_pos.c_str(), s.cname());

  •  fprintf(f, "  %s => %s,\n", name.c_str(), s.m_width ? "(others =>
    

'0')" : "'0'");

  •  fprintf(f, "  %s <= %s;\n", name.c_str(), s.m_width ? "(others =>
    

'0')" : "'0'");
OU::format(name, s.m_neg.c_str(), s.cname());

  •  fprintf(f, "  %s => %s,\n", name.c_str(), s.m_width ? "(others =>
    

'0')" : "'0'");

  •  fprintf(f, "  %s <= %s;\n", name.c_str(), s.m_width ? "(others =>
    

'0')" : "'0'");
} else
fprintf(f, "  %s <= %s;\n", s.cname(), s.m_width ? "(others =>
'0')" : "'0'");
break;

Did you use any of the older MIG code in OpenCPI or did you start from
scratch?

Thanks.

On 12/17/19 11:34 AM, Walters Dominic A via discuss wrote:

Classification: UK OFFICIAL

Hi,

Potentially this might be a bug report.
I've been using the empty assembly from the assets project to build

containers for an fmcomms card on a ZCU102.

This has been working until I added an always enabled device worker to

the platform .xml for my ZCU102 (the worker in question deals with a DDR4
chip on the board).

This caused OCPI to generate two lines of invalid VHDL when rebuilding

the empty assembly. A clean build caused the same problem.

Specifically in the file with the name

"empty_<platform_name><cfg_name><cnt_name>-assy.vhd" that generates
inside the folder
"container-empty_<platform_name><cfg_name><cnt_name>/gen" within the
empty directory.

At the bottom of this file, a selection of output signals that aren't

used in the container are bound to '0' or (others => '0').

In my case these signals were from the interface to my unused device

worker (signals looking like <device_worker_name>_ddr4_addr for example).

There were also comments indicating a selection of input signals that

hadn't been bound to anything (FMC_HPC_...).

Most of these zeroing assignments were fine, looking like:

  •    <device_worker_name>_<signal_name> <= '0';
    

o  OR

  •    <device_worker_name>_<signal_name> <= (others => '0');
    

Except for two of them which looked like:

  •    <device_worker_name>_<signal_name> => '0',
    

o  AND

  •    <device_worker_name>_<signal_name> => (others => '0'),
    

Both of the signals that this happened to were differential

(specifically, they were the only two differential signals that were
unused).

In this case the ck_t and ck_c pins on a DDR4 RAM MIG. Every other
signal

that was treated correctly wasn't differential.

I manually edited this file to correct the VHDL to the former format,
and

it built the container core correctly and has gotten to routing as I type
this.

Any idea what has happened here? Unfortunately I can't provide the
source

code that causes this to happen at this time.

Thanks for any input,

Dominic Walters

"This e-mail and any attachment(s) is intended for the recipient only.

Its unauthorised use,

disclosure, storage or copying is not permitted.  Communications with
Dstl are monitored and/or recorded for system efficiency and other
lawful purposes, including business intelligence, business metrics and

training.  Any views or opinions expressed in this e-mail do not
necessarily reflect Dstl policy."

"If you are not the intended recipient, please remove it from your
system and notify the author of the email and centralenq@dstl.gov.uk"
-------------- next part -------------- An HTML attachment was
scrubbed...
URL:
<http://scanmail.trustwave.com/?c=7369&d=kI353W7H6BuxfeBY9FCIHepnNwyd0
7-FwO_Pc5avAg&u=http%3a%2f%2flists%2eopencpi%2eorg%2fpipermail%2fdiscu
http://scanmail.trustwave.com/?c=7369&d=6Yf63dd-MiuKGnl0TQ4ig56ORSCEZc
k_9ugOskaifw&u=http%3a%2f%2fss%255flists%252eopencpi%252eorg%252fattac
hments%252f20191217%252fe077209a%252fattac
hment%2ehtml> _______________________________________________
discuss mailing list
discuss@lists.opencpi.org
http://scanmail.trustwave.com/?c=7369&d=kI353W7H6BuxfeBY9FCIHepnNwyd07
-FwLqcJ5qsAw&u=http%3a%2f%2flists%2eopencpi%2eorg%2fmailman%2flistinfo
%http://scanmail.trustwave.com/?c=7369&d=6Yf63dd-MiuKGnl0TQ4ig56ORSCEZ
ck_9uoItUagLg&u=http%3a%2f%2f2fdiscuss%255flists%252eopencpi%252eorg

"This e-mail and any attachment(s) is intended for the recipient only.
Its unauthorised use,
disclosure, storage or copying is not permitted.  Communications with Dstl
are monitored and/or recorded for system efficiency and other lawful
purposes, including business intelligence, business metrics and training.
Any views or opinions expressed in this e-mail do not necessarily reflect
Dstl policy."

"If you are not the intended recipient, please remove it from your system
and notify the author of the email and centralenq@dstl.gov.uk"


discuss mailing list
discuss@lists.opencpi.org
http://scanmail.trustwave.com/?c=7369&d=67j73cx3LGcpR6dEHk-xRYJuFkdQCDR7BsQofbcLuQ&u=http%3a%2f%2flists%2eopencpi%2eorg%2fmailman%2flistinfo%2fdiscuss%5flists%2eopencpi%2eorg

Gotcha. So sounds like modifying the framework for explicit instantiation of proper output buffer primitives would fix all cases, and would not require changes to the existing generated tie-off code. ---------- Forwarded message --------- From: Walters Dominic A <dawalters@mail.dstl.gov.uk> Date: Fri, Dec 20, 2019 at 6:58 AM Subject: RE: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals To: Davis Hoover <dhoover@geontech.com>, discuss@lists.opencpi.org < discuss@lists.opencpi.org> Classification: UK OFFICIAL The issue stems from the fact that the differential output signal isn't used, so the "tie off" code is used to assign it to ground. The problem there being that if one side of a differential signal is ground, the other needs to be ¬ground (afaik that's a logical requirement of all digital differential signals). The current tie off code drives both sides with ground. Tieing off one side of the pair with '1' was my attempt to get Vivado to infer an OBUFDS, which it didn't (probably wasn't reasonable for me to expect it to!). For Vivado to realise that a signal on an FPGA output pin is differential (thereby allowing IOStandard constraints of differential types), the first thing it needs to see back from the pin is an OBUFDS (or a similar component). That last sentence is a guess, but it certainly seems like it's true. -----Original Message----- From: discuss <discuss-bounces@lists.opencpi.org> On Behalf Of Davis Hoover Sent: 19 December 2019 17:50 To: discuss@lists.opencpi.org Subject: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals The need to instantiate (or at least infer) OBUFDS for differential signals makes sense. Curiously, we haven't run into this problem for differential signals on Zynq 7000 FPGAs which support the same OBUF/OBUFDS primitives. Perhaps Ultrascale has more strict requirements. We'll make a note to address this differential I/O buffering problem in the code generator. FYI the util primitive library in the core project has BUFFER_OUT* components which are intended to facilitate vendor-agnostic I/O buffering. What is driving the requirement to tie-off with a value of 1? I'm trying to determine if this is something the framework needs to support. Glad you've got a working workaround now. ---------- Forwarded message --------- From: Walters Dominic A via discuss <discuss@lists.opencpi.org> Date: Thu, Dec 19, 2019 at 7:39 AM Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals To: discuss@lists.opencpi.org <discuss@lists.opencpi.org> Classification: UK OFFICIAL Forgot to add, obviously this then becomes a Xilinx only solution. I'm not familiar enough with the codegen to come up with a better one. -----Original Message----- From: discuss <discuss-bounces@lists.opencpi.org> On Behalf Of Walters Dominic A via discuss Sent: 19 December 2019 13:25 To: discuss@lists.opencpi.org Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals Classification: UK OFFICIAL Hey, So simply setting one side of the pair to be high didn't work. The schematic shows the signal connected to high, but an OBUFDS wasn't inferred by Vivado (Maybe I'm assuming too much of it tbh :D). Manually instantiating an OBUFDS at the bottom of the "-assy.vhd" file where the tie off code is generated does seemingly fix this problem. Side Note: The schematic diagram moves the driver of these pins inside of the ftop block (the signals go into ftop rather than being driven in the layer above). Anyway, the fix for this would now need to instantiate the OBUFDS block in code gen (unless there is some way to infer one?). And either as many OBUFDS blocks as the port is wide, or drive all elements of the signal off of one OBUFDS (I've done the former). This is what I've managed to put together to replace the old "if(s.m_differential)" block (it should even indent correctly!): if (s.m_differential) { OU::format(name, s.m_pos.c_str(), s.cname()); std::string index = ""; std::string spacing = ""; if (s.m_width) { fprintf(f, " GEN_%s: for GEN_I in 0 to %lu generate\n", name.c_str(), s.m_width); index = "(GEN_I)"; spacing = " "; } fprintf(f, " %sOBUFDS_%s_inst : OBUFDS\n" " %sport map(I => std_logic'('0'),\n", spacing.c_str(), name.c_str(), spacing.c_str()); OU::format(name, s.m_pos.c_str(), s.cname()); fprintf(f, " %s OB => %s%s,\n", spacing.c_str(), name.c_str(), index.c_str()); OU::format(name, s.m_neg.c_str(), s.cname()); fprintf(f, " %s O => %s%s);\n", spacing.c_str(), name.c_str(), index.c_str()); if (s.m_width) { OU::format(name, s.m_pos.c_str(), s.cname()); fprintf(f, " end generate %s;\n", name.c_str()); } } else ... I haven't got a use case to test the generate parts (all my differential signals are width 1), but this works on my current device worker for the 2 assemblies that I've tried. Both generated their bitstreams correctly, with no related errors or warnings. Kind Regards, D. Walters -----Original Message----- From: Walters Dominic A Sent: 19 December 2019 11:20 To: 'Davis Hoover' <dhoover@geontech.com>; discuss@lists.opencpi.org; 'James Kulp' <jek@parera.com> Subject: RE: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals Classification: UK OFFICIAL Hey, I had seen these ARs when trying to look up the problem, but I'm pretty sure they aren't related. The pins in question are outputs of a MIG that go directly to an FPGA output pin, so I don't think I need to manually constrain them? The MIG core should do that. I'm relatively confident that this is an OCPI bug. When you leave pins unconnected in an empty container, they are treated differently depending on what they are. From my synthesized opt stage schematic: * 1. Input pins are left unconnected. * 2. Bidirectional pins that aren't driven are left unconnected. * 3. Output pins that aren't driven, are connected to ground through an OBUF. This third one causes a problem with differential signals. In the synthesized schematic (from opt stage) the _n and _p sides of my differential signal are separately driven from OBUF primitives connected to ground, when they should be driven from the paired outputs of an OBUFDS connected to ground. As such, both sides of the differential pair are grounded when one of them should instead be high. I believe this is caused by the same lines of code that James patched at the start of this thread. One side of the differential pair should be tied high instead of low. I believe the patch should instead be: --- a/tools/ocpigen/src/hdl-container.cxx +++ b/tools/ocpigen/src/hdl-container.cxx @@ -1075,9 +1075,9 @@ emitTieoffSignals(FILE *f) { " -- Output signal \"%s\" is not connected to any instance.\n", s.cname()); if (s.m_differential) { OU::format(name, s.m_pos.c_str(), s.cname()); - fprintf(f, " %s => %s,\n", name.c_str(), s.m_width ? "(others => '0')" : "'0'"); + fprintf(f, " %s <= %s;\n", name.c_str(), s.m_width ? "(others => '1')" : "'1'"); OU::format(name, s.m_neg.c_str(), s.cname()); - fprintf(f, " %s => %s,\n", name.c_str(), s.m_width ? "(others => '0')" : "'0'"); + fprintf(f, " %s <= %s;\n", name.c_str(), s.m_width ? "(others => '0')" : "'0'"); } else fprintf(f, " %s <= %s;\n", s.cname(), s.m_width ? "(others => '0')" : "'0'"); break; This corrects the first bug in this thread that James fixed, and this one. It sets the _p side to be high, and the _n side low. I'm testing this possible solution now, I'll update when it finishes. Thanks for your help, D. Walters -----Original Message----- From: discuss <discuss-bounces@lists.opencpi.org> On Behalf Of Davis Hoover Sent: 18 December 2019 20:08 To: discuss@lists.opencpi.org Subject: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals This might fix your issue: https://scanmail.trustwave.com/?c=7369&d=67j73cx3LGcpR6dEHk-xRYJuFkdQCDR7BpJ_fuoP6A&u=https%3a%2f%2fwww%2exilinx%2ecom%2fsupport%2fanswers%2f57109%2ehtml Also related: https://scanmail.trustwave.com/?c=7369&d=67j73cx3LGcpR6dEHk-xRYJuFkdQCDR7BpZ4drkLvg&u=https%3a%2f%2fforums%2exilinx%2ecom%2ft5%2fWelcome-Join%2fSystemclockP-is-a-Single-ended-but-iostandard-is-LVDS-25-which%2ftd-p%2f557165 ---------- Forwarded message --------- From: Walters Dominic A via discuss <discuss@lists.opencpi.org> Date: Wed, Dec 18, 2019 at 10:32 AM Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals To: James Kulp <jek@parera.com>, discuss@lists.opencpi.org < discuss@lists.opencpi.org> Classification: UK OFFICIAL Hi again, I'm having another (possibly related) problem during bitstream generation. Same build as last email (trying to make an empty container for an fmcomms card with a device worker available in the BSP but unused). Vivado is returning the following error: [DRC IOSTDTYPE-1] IOStandard Type: I/O port <device_worker_name>_ddr4_ck_c is Single-Ended but has IOStandard of DIFF_SSTL12 which can only support Differential. [DRC IOSTDTYPE-1] IOStandard Type: I/O port <device_worker_name>_ddr4_ck_t is Single-Ended but has IOStandard of DIFF_SSTL12 which can only support Differential. This error propagates from the opt stage, which had the above error as a critical warning (becoming an error during bitstream generation). The signal in question "<device_worker_name>_ddr4_ck" is defined as differential in my device worker .xml with the appropriate "pos" and "neg" formatting strings: * <signal output='ddr4_ck' differential='1' pos='%s_t' neg='%s_c' /> The IOStandard of DIFF_SSTL12 is correct. My container .xdc has two lines for each side of the differential (one set_property to designate the pin its attached to, and another for its IOStandard) I tried changing the names to the more standard "_n" and "_p" in case it was a parsing error, but that didn't work. Again, this error occurs only on a differential output signal. A bidirectional differential signal of width 2 in the same device worker isn't having a problem (although it does use a different IOStandard: DIFF_POD12). In the synthesised schematic in the .xpr file, both of these pins are present and are each being driven from ground through an OBUF. Seems like this is more likely to be caused by something I've written, rather than being an OCPI bug, as this is the first time that the device worker is being put through the full vivado build process. Have I missed out a constraint that I need to apply to the pin (not really an OCPI question anymore :D)? Does the signal tag in the xml need a "pin='1'"? Thanks, D. Walters -----Original Message----- From: James Kulp <jek@parera.com> Sent: 17 December 2019 17:08 To: Walters Dominic A <dawalters@dstl.gov.uk>; discuss@lists.opencpi.org Subject: Re: [Discuss OpenCPI] [UK OFFICIAL] Possible bug in OCPI assembly code gen caused by unassigned differential signals Congratulations on stepping on a latent silly bug. I haven't searched our (soon to be public) bug database for this. Clearly none of the devices we currently use or test have hit this differential tieoff issue before. If you are building from source code and want a quick patch you can try this (untested) change. It has been made in our development version. --- a/tools/ocpigen/src/hdl-container.cxx +++ b/tools/ocpigen/src/hdl-container.cxx @@ -1075,9 +1075,9 @@ emitTieoffSignals(FILE *f) { " -- Output signal \"%s\" is not connected to any instance.\n", s.cname()); if (s.m_differential) { OU::format(name, s.m_pos.c_str(), s.cname()); - fprintf(f, " %s => %s,\n", name.c_str(), s.m_width ? "(others => '0')" : "'0'"); + fprintf(f, " %s <= %s;\n", name.c_str(), s.m_width ? "(others => '0')" : "'0'"); OU::format(name, s.m_neg.c_str(), s.cname()); - fprintf(f, " %s => %s,\n", name.c_str(), s.m_width ? "(others => '0')" : "'0'"); + fprintf(f, " %s <= %s;\n", name.c_str(), s.m_width ? "(others => '0')" : "'0'"); } else fprintf(f, " %s <= %s;\n", s.cname(), s.m_width ? "(others => '0')" : "'0'"); break; Did you use any of the older MIG code in OpenCPI or did you start from scratch? Thanks. On 12/17/19 11:34 AM, Walters Dominic A via discuss wrote: > Classification: UK OFFICIAL > > > Hi, > > Potentially this might be a bug report. > I've been using the empty assembly from the assets project to build containers for an fmcomms card on a ZCU102. > This has been working until I added an always enabled device worker to the platform .xml for my ZCU102 (the worker in question deals with a DDR4 chip on the board). > This caused OCPI to generate two lines of invalid VHDL when rebuilding the empty assembly. A clean build caused the same problem. > > Specifically in the file with the name "empty_<platform_name>_<cfg_name>_<cnt_name>-assy.vhd" that generates inside the folder "container-empty_<platform_name>_<cfg_name>_<cnt_name>/gen" within the empty directory. > At the bottom of this file, a selection of output signals that aren't used in the container are bound to '0' or (others => '0'). > In my case these signals were from the interface to my unused device worker (signals looking like <device_worker_name>_ddr4_addr for example). > There were also comments indicating a selection of input signals that hadn't been bound to anything (FMC_HPC_...). > > Most of these zeroing assignments were fine, looking like: > > * <device_worker_name>_<signal_name> <= '0'; > > o OR > > * <device_worker_name>_<signal_name> <= (others => '0'); > > Except for two of them which looked like: > > * <device_worker_name>_<signal_name> => '0', > > o AND > > * <device_worker_name>_<signal_name> => (others => '0'), > > Both of the signals that this happened to were differential (specifically, they were the only two differential signals that were unused). > In this case the ck_t and ck_c pins on a DDR4 RAM MIG. Every other > signal that was treated correctly wasn't differential. > I manually edited this file to correct the VHDL to the former format, > and it built the container core correctly and has gotten to routing as I type this. > > Any idea what has happened here? Unfortunately I can't provide the > source code that causes this to happen at this time. > > Thanks for any input, > > Dominic Walters > > > "This e-mail and any attachment(s) is intended for the recipient only. Its unauthorised use, > disclosure, storage or copying is not permitted. Communications with > Dstl are monitored and/or recorded for system efficiency and other > lawful purposes, including business intelligence, business metrics and training. Any views or opinions expressed in this e-mail do not necessarily reflect Dstl policy." > > "If you are not the intended recipient, please remove it from your > system and notify the author of the email and centralenq@dstl.gov.uk" > -------------- next part -------------- An HTML attachment was > scrubbed... > URL: > <http://scanmail.trustwave.com/?c=7369&d=kI353W7H6BuxfeBY9FCIHepnNwyd0 > 7-FwO_Pc5avAg&u=http%3a%2f%2flists%2eopencpi%2eorg%2fpipermail%2fdiscu > http://scanmail.trustwave.com/?c=7369&d=6Yf63dd-MiuKGnl0TQ4ig56ORSCEZc > k_9ugOskaifw&u=http%3a%2f%2fss%255flists%252eopencpi%252eorg%252fattac > hments%252f20191217%252fe077209a%252fattac > hment%2ehtml> _______________________________________________ > discuss mailing list > discuss@lists.opencpi.org > http://scanmail.trustwave.com/?c=7369&d=kI353W7H6BuxfeBY9FCIHepnNwyd07 > -FwLqcJ5qsAw&u=http%3a%2f%2flists%2eopencpi%2eorg%2fmailman%2flistinfo > %http://scanmail.trustwave.com/?c=7369&d=6Yf63dd-MiuKGnl0TQ4ig56ORSCEZ > ck_9uoItUagLg&u=http%3a%2f%2f2fdiscuss%255flists%252eopencpi%252eorg "This e-mail and any attachment(s) is intended for the recipient only. Its unauthorised use, disclosure, storage or copying is not permitted. Communications with Dstl are monitored and/or recorded for system efficiency and other lawful purposes, including business intelligence, business metrics and training. Any views or opinions expressed in this e-mail do not necessarily reflect Dstl policy." "If you are not the intended recipient, please remove it from your system and notify the author of the email and centralenq@dstl.gov.uk" _______________________________________________ discuss mailing list discuss@lists.opencpi.org http://scanmail.trustwave.com/?c=7369&d=67j73cx3LGcpR6dEHk-xRYJuFkdQCDR7BsQofbcLuQ&u=http%3a%2f%2flists%2eopencpi%2eorg%2fmailman%2flistinfo%2fdiscuss%5flists%2eopencpi%2eorg