-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added blocks for input, output, and input-output timing closure #691
base: master
Are you sure you want to change the base?
Conversation
Can one of the admins verify this patch? |
ok to test |
These seem functionally identical to a single entry queue where: |
They are functionally identical to a single-entry queue, however their If you wanted to close timing on a Queue at the top level, you would use class WrapQueue { io.enq <> dci.io.c On Wed, Apr 13, 2016 at 11:09 AM, Stephen Twigg notifications@github.com
|
I see the issue: the underlying desire is that the ready or valid ports be driven directly by a register. Although, this is still true in the single-entry queue case (since all the combinatorial logic collapses into constants and a reference to a single register). In a single-entry queue case, ptr_match is always true. Therefore, when pipe is false, io.enq.ready := maybe_full (the Q port of a register) Perhaps Queue could be modified to better exhibit this in the single-entry case and not rely on constant propagation. DCInput and DCOutput could then be defined as specific instantiations of Queue. (Although it would be nice to enforce some sort of check that the respective ready and valid paths do not involve combinational logic.) This avoids having to independently verify DCInput and DCOutput. A concern I have with the current DCInput and DCOutput modules is that they introduce a new convention for interfaces with p and q into the ChiselUtils. Also, the Bits constraint on T and creation of the hold register with UInt in DCInput is concerning. |
Keeping in mind what @sdtwigg said, it's hard to see the opportunity for QoR improvement over 1-entry pipe-/flow queues... the inverter on maybe_full doesn't count. |
I'm still coming up to speed on Chisel, I can easily change the naming for the input and outputs. The producer/consumer naming convention comes from the original verilog designs (https://github.com/hutch31/sdlib). Other names we came up (such as enqueue and dequeue) were specific to what they were being attached to -- "enqueue" doesn't make sense as the input to an arbiter. As far as I know there is no way to have a registered output on c.ready and not have a holding register, as the case where c.ready == 1 and p.ready == 0 needs to be handled. As the output is flopped, the block cannot take away c.ready when the producer side is unable to accept data, and therefore needs a holding register for the 1 cycle it takes to react. |
I generated a single-entry queue and looked at the implementation, with pipe=true it is equivalent in timing performance, so I replaced DCOutput by extending the Queue class. I also looked at Queue(pipe=false, depth=2) implementation, but it goes through at least 3 levels of logic to generate enq.ready and uses 2X the flops of SDInput, so I think this is still an improvement for module input interfaces. |
Created two Chisel blocks for timing closure. These blocks are designed for use in decoupled IO designs, to make closing timing on module boundaries easier.