Tue Aug 16, 2016 7:56 pm
On 8/16/2016 9:41 AM, KJ wrote:
On Tuesday, August 16, 2016 at 12:43:22 AM UTC-4, rickman wrote:
On 8/15/2016 7:55 AM, KJ wrote:
It depends on the algorithm, period. Once the source code for
the module is written, the latency number has been locked down.
The number of pipeline stages will be determined once the
algorithm is coded. At that point you know the number and that
number can then be put into a package along with other module
related things. If you later change the algorithm in some way
that changes the number of pipeline stages, you change the
number...to match the change in the algorithm. Not rocket
No, and the fact that this will cause errors from forgetting to
change corresponding data in other modules is not rocket science
The error gets checked by the assertion in the testbench. So, on the
assumption that one would run their testbench after entering a design
change then the error gets immediately caught. Not much different in
that regard then when I mistype something and the compiler catches
the error. Yes you did have to write the code that does the checking
and get that all working whereas the typo gets caught by code that
has had a lot more eyeballs looking at it and a lot more users using
it, but the point is that once that checking code is debugged and
working then when a design error gets created via a design change,
the code does catch it...if you simulate your design.
Yes, there is the extra code which has to be made to work... but error
checking code is also extra testing. One mistake is to write it so it
doesn't flag errors at all so it has to be tested to show it catches
errors which is a PITA. Eyeballs are not a good way to catch errors
like this. Eyes glaze over reading code and miss important details.
Bottom line is having one location for a constant is a whole lot better
than maintaining values in two places with error checking.
The point is to remove any dependency for the user of the module
from having to know what the latency is exactly. The user of the
module just needs to know where to reference that number from
which is in the package that comes along with the module.
Suggesting that the module should be developed so that the
module creator should somehow be off the hook for defining and
publishing in the package the latency number is misguided.
I don't understand why you say this. If you could design the
module to return a value telling you the number of pipeline stages
so the data did not need to be separately maintained in other
module it would be less error prone. But there doesn't seem to be
a way for a module to return a generic.
I'm not disagreeing that if you could create a constant output that
could in all cases be used just like a real constant then this would
provide a different method to accomplish the goal. Some can see it
as better, some just see it as different, that's OK.
I've identified specifically why this is preferred, unfortunately not
possible to do in the simple way hoped for, but there seems to be a way
to do it, perhaps.
I think it would be useful. But I would want to be able to use that
output constant just like any other constant. So, based on the
latency for a number of modules cascaded together, I could compute
the depth of a memory that will be needed to collect up all the
pipelined data that comes out after the output interface says to
wait. Or to use that constant in a generate statement. Stuff like
That is exactly the point.
But as far I've seen in this discussion, that number still looks like
it gets typed into the architecture and is therefore potentially
wrong. If you change the design to add another pipeline stage, that
number doesn't magically change to the new number so you have an
error. Bantering about whether to change a typed in number in the
architecture or the package ***for that same module*** is splitting
We can't eliminate mistakes. We can minimize the chance they will go
uncaught and minimize the difficulty in finding them. There is no
problem or difficulty with having one constant in the code module it is
related to that doesn't also exist in the method where the same constant
has to be maintained in two locations.
For it truly to be correct by design, that constant output should be
calculated from the number of pipeline stages in the design. So if
you add/remove a pipeline stage, nothing else need be done because
the output constant would have a formula to it not just a number
(i.e. Pipe_Stages <= Pipeline'length). Maybe that is what the OP is
doing anyway rather than actually having a physically typed in number
(i.e. Pipe_Stages <= 3).
Maybe someone should suggest the idea of entity output constants that
can be used as we use constants today as an enhancement to the VHDL
standard. I know Jim Lewis is looking for more work (**not**) to
pile on to the next revision of the standard. But if anyone wants to
take up the torch, go to
Tue Aug 16, 2016 8:04 pm
Maybe that is what the OP is doing anyway rather than actually having a
physically typed in number (i.e. Pipe_Stages <= 3).
Upper levels of design calculate their latency based on the length of lower-lewel
modules and length of latency adjusting buffers of different sub-pipelines, but
modules on the lowest level of hierarchy which really do stuff have their latency
as a physically typed number.
Unfortunately, I don't know how to calculate it automatically.
Tue Aug 16, 2016 10:48 pm
> Bantering about whether to change a typed in number in the architecture or the package ***for that same module*** is splitting hairs.
Asking the object that actually creates the latency property (the module instance) rather than another object (the package) associated with that first object enables better information hiding. We saw that in the example of a latency depending on the generics. This is, to me, a significant difference.. Keeping the property close to its origin is probably less error-prone when we need to remember to keep things in sync but the difference to a package in the same file is probably minor.
> But I would want to be able to use that output constant just like any other constant
An external name like <<constant my_inst.properties.latency : natural>> can be used like any other constant. The only difference I can come to think of is that it can only be used after the target of the reference, in this case my_inst, has been elaborated. This is a bit inconvenient. If, for example, a module's latency depends on the latency for its submodules the latency constant cannot be placed in the architecture declarative part. It has to be placed after the submodules have been instantiated such that their latencies can be referenced with external names. One way of solving this, which I used in my example, is to have a block statement at the end of the architecture that contains the constant. I labeled this statement properties as can be seen in <<constant my_inst.properties.latency : natural>>
As an advocate for unit testing I don't mind at all if I have to add another unit test to check the provided latency. In case my module has no data valid signals there is no extra work since the latency constant will be used and verified anyway (to know when to verify the output for a given test input). If I have data valid signals it's easy to forget verifying the constant but such a design would often have a delayline between the input and output data valid defined as a std_logic_vector of latency length. If that doesn't match the main processing pipeline the tests will fail. There's still a risk that something like a "quick fix", adding an extra pipelining step on top of the original design, creates an off-by-one error in the latency constant not detected by the tests.