Skip to content

Add support for falling edge clocking #2211

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

Open
wants to merge 55 commits into
base: master
Choose a base branch
from

Conversation

lpawelcz
Copy link
Contributor

[This is a Work in Progress PR]

Description

This PR adds support for falling edge clocking.

Related Issue

#2182

Motivation and Context

All clocks and clock edge sensitivity of flip-flops / latches are implicitly assumed to be rising edge. Static timing analysis does not support falling edge clocking.

How Has This Been Tested?

I'm testing the flow with slightly modified examples given in documentation.

./vpr/vpr vtr_flow/arch/timing/EArch.xml vtr_flow/benchmarks/blif/multiclock/multiclock.blif --timing_report_detail debug --echo_file on --gen_post_synthesis_netlist on --gen_post_implementation_merged_netlist on

Types of changes

  • Bug fix (change which fixes an issue)
  • New feature (change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

@github-actions github-actions bot added external_libs libarchfpga Library for handling FPGA Architecture descriptions VPR VPR FPGA Placement & Routing Tool labels Nov 23, 2022
@lpawelcz lpawelcz force-pushed the pcza/negedge-clocking branch from 2c9b49e to 8727e59 Compare November 23, 2022 11:30
@lpawelcz lpawelcz force-pushed the pcza/negedge-clocking branch 6 times, most recently from f346d81 to 083b4c8 Compare December 9, 2022 08:05
@lpawelcz lpawelcz force-pushed the pcza/negedge-clocking branch 2 times, most recently from d42a69a to 76b9203 Compare December 9, 2022 11:36
Introduce secondary t_model and t_port to t_pb_types
and secondary input/output/clock_pins in t_pb_graph_node.
Also fill those fields with data required for processing.

Signed-off-by: Pawel Czarnecki <[email protected]>
Signed-off-by: Pawel Czarnecki <[email protected]>
@lpawelcz
Copy link
Contributor Author

Thank you for your comments! The code surely needs some fixes and cleanup. I'm working on that, as well as on adding required comments and documentation. I will go back to you as soon as possible after finishing this.

Copy link
Contributor

@vaughnbetz vaughnbetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished the review (part 3 of 3)!
Many detailed comments but the big ones are:

  • Can we find an alternative to the inputs_sec / duplicate latch model? Not crazy about the data and code duplication it has led to, and the fact that it is harder to understand. Possible alternative: add an "is_inverted" property to input pins (or all pins) in the netlist. That would work for clocks and also be potentially useful for other purposes in the future. Currently we'd only set the is_inverted flag in one case: clock port on a falling edge latch, but could be used elsewhere in the future.

Not sure the tatum changes are all necessary; seems like we should be creating the appropriate 180 degree phase shift clock for any clock domain with neg_edge (inverted) registers, and then checking whether a register has the right edge polarity when putting it in the src tag and snk tag lists. I'm not sure the current code is doing that.

arch_model = arch_models;
while (arch_model) {
if (strcmp(MODEL_LATCH, arch_model->name) == 0) {
if (t_edge == arch_model->inputs[1].trigg_edge) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment what inputs[1] is

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a LATCH_CLOCK_INPUT_ID constant for this.

@@ -109,6 +109,7 @@ int get_max_primitives_in_pb_type(t_pb_type* pb_type);
int get_max_depth_of_pb_type(t_pb_type* pb_type);
int get_max_nets_in_pb_type(const t_pb_type* pb_type);
bool primitive_type_feasible(AtomBlockId blk_id, const t_pb_type* cur_pb_type);
bool primitive_type_feasible(AtomBlockId blk_id, t_pb_graph_node* curr_pb_graph_node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment what this does (I know lots of the other functions don't have comments, but we should improve that in new code)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments

@@ -466,6 +471,31 @@ struct BlifAllocCallback : public blifparse::Callback {
return arch_model;
}

const t_model* find_latch_model(TriggeringEdge t_edge) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I saw a header file with this new function declared and a comment on what it does. If there isn't such a declaration it should be added, along with a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seams that this struct don't use a related header with function declarations. I added the comment here instead.


for (int iport = 0; iport < gnode->num_input_ports; ++iport) {
if (gnode->num_input_pins[iport] <= 0) continue;
pins = gnode->input_pins[iport];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good use of a temporary variable to shorten the code below -- thanks!

for (i = 0; i < pb_type->num_ports; i++) {
if (pb_type->ports[i].model_port) {
if (pb_graph_node->has_secondary) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment what this is doing. Also, I'm still concerned about duplicating all our ports and the latch primitive -- seems like there should be a way to control the clock edge that involves less data and code duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments

}
} else {
auto net_aliases = netlist_.net_aliases(clock_name);
for (int i = 0; i < 2; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest renaming i to iclk_edge (or something like that)
Comment what this is doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to clk_variant and added comments

@@ -905,6 +905,91 @@ bool primitive_type_feasible(const AtomBlockId blk_id, const t_pb_type* cur_pb_t
//Feasible
return true;
}
bool primitive_type_feasible(const AtomBlockId blk_id, t_pb_graph_node* curr_pb_graph_node) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a blank line above this (but maybe make format will put it in).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added blank line

@@ -936,20 +1021,32 @@ t_pb_graph_pin* get_pb_graph_node_pin_from_model_port_pin(const t_model_ports* m

if (model_port->dir == IN_PORT) {
if (model_port->is_clock == false) {
t_pb_graph_pin** input_pins;
if (model_port->trigg_edge == TriggeringEdge::FALLING_EDGE)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again I'm not keen on this input_pins_sec etc. code, along with the duplicate latch. It's a lot of extra code and data to sort out if we have a positive or negative register; seems like there should be some additional data we can add to all primitives that would be simpler and cleaner.

Signed-off-by: Pawel Czarnecki <[email protected]>
Signed-off-by: Pawel Czarnecki <[email protected]>
@lpawelcz
Copy link
Contributor Author

For now I will leave the commits with all the fixes in case something needs to be reverted

@lpawelcz lpawelcz force-pushed the pcza/negedge-clocking branch from 13f64eb to c59f504 Compare December 23, 2022 19:07
@lpawelcz lpawelcz changed the title [WIP] Add support for falling edge clocking Add support for falling edge clocking Dec 23, 2022
@lpawelcz lpawelcz marked this pull request as ready for review December 23, 2022 20:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
external_libs libarchfpga Library for handling FPGA Architecture descriptions VPR VPR FPGA Placement & Routing Tool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants