Skip to content
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

Improve xc7 fasm2verilog output #578

Open
4 of 7 tasks
litghost opened this issue Apr 11, 2019 · 5 comments
Open
4 of 7 tasks

Improve xc7 fasm2verilog output #578

litghost opened this issue Apr 11, 2019 · 5 comments
Labels
arch-xc7 Issues related to the XC7 architecture enhancement good first issue help wanted

Comments

@litghost
Copy link
Contributor

litghost commented Apr 11, 2019

With #577, fasm2v is good enough to be useful, however it could be more useful when debugging correctness issues with some more features.

Ideas to improve output, along with difficulty:

  • (easy) Combine carry chain inputs and outputs into wire bus for easier viewing in during simulation. This is a pretty straight forward verilog parsing task, basically join the various CARRY4's that are connected via the chain and emit 4 wire buses, S, DI, CO and O for the entire chain length.
  • (easy to medium) Add a comment above LUT6_2's with the equation form of the LUT from input to output. Ideally they will be reduced equations.

So for example:

    (* KEEP, DONT_TOUCH, LOC = "SLICE_X22Y113", BEL = "B6LUT" *)                 
    LUT6_2 #(                                                                    
      .INIT(64'b0101010101010101010101010101010110101010101010101010101010101010)                                                                                                                                  
    ) CLBLL_R_X15Y113_SLICE_X22Y113_BLUT (                                       
      .I0(CLBLL_R_X15Y113_SLICE_X22Y113_B1),                                     
      .I1(CLBLL_R_X15Y113_SLICE_X22Y113_B2),                                     
      .I2(CLBLL_R_X15Y113_SLICE_X22Y113_B3),                                     
      .I3(CLBLL_R_X15Y113_SLICE_X22Y113_B4),                                     
      .I4(CLBLL_R_X15Y113_SLICE_X22Y113_B5),                                     
      .I5(CLBLL_R_X15Y113_SLICE_X22Y113_B6),                                     
      .O5(CLBLL_R_X15Y113_SLICE_X22Y113_BO5),                                    
      .O6(CLBLL_R_X15Y113_SLICE_X22Y113_BO6)                                     
    );               

becomes:

     // CLBLL_R_X15Y113_SLICE_X22Y113_BO5 = CLBLL_R_X15Y113_SLICE_X22Y113_B1;
     // CLBLL_R_X15Y113_SLICE_X22Y113_BO6 = CLBLL_R_X15Y113_SLICE_X22Y113_B1 ^ CLBLL_R_X15Y113_SLICE_X22Y113_B6;
    (* KEEP, DONT_TOUCH, LOC = "SLICE_X22Y113", BEL = "B6LUT" *)                 
    LUT6_2 #(                                                                    
      .INIT(64'b0101010101010101010101010101010110101010101010101010101010101010)                                                                                                                                  
     ) CLBLL_R_X15Y113_SLICE_X22Y113_BLUT (                                       
      .I0(CLBLL_R_X15Y113_SLICE_X22Y113_B1),                                     
      .I1(CLBLL_R_X15Y113_SLICE_X22Y113_B2),                                     
      .I2(CLBLL_R_X15Y113_SLICE_X22Y113_B3),                                     
      .I3(CLBLL_R_X15Y113_SLICE_X22Y113_B4),                                     
      .I4(CLBLL_R_X15Y113_SLICE_X22Y113_B5),                                     
      .I5(CLBLL_R_X15Y113_SLICE_X22Y113_B6),                                     
      .O5(CLBLL_R_X15Y113_SLICE_X22Y113_BO5),                                    
      .O6(CLBLL_R_X15Y113_SLICE_X22Y113_BO6)                                     
    );                
  • (easy) Merge simple nets, leaving the intermediate wires, but avoiding the chain. So
assign CLBLM_R_X11Y110_SLICE_X14Y110_CMUX = CLBLM_R_X11Y110_SLICE_X14Y110_C5Q;
assign CLBLL_R_X17Y120_SLICE_X26Y120_SR = CLBLM_R_X11Y110_SLICE_X14Y110_CMUX;

Becomes:

assign CLBLM_R_X11Y110_SLICE_X14Y110_CMUX = CLBLM_R_X11Y110_SLICE_X14Y110_C5Q;
assign CLBLL_R_X17Y120_SLICE_X26Y120_SR = CLBLM_R_X11Y110_SLICE_X14Y110_C5Q;

This change leads into the next change:

  • (more difficult) Name nets with same name that VPR used during routing. These names can be found in the route output from VPR. This involves consuming the VPR route output which looks like:
Net 1794 ($abc$11234$n2115)                                                    
                                                                               
Node:  73553   SOURCE (30,22)  Class: 81  Switch: 0                           
Node:  73648     OPIN (30,22)  Pin: 81   BLK_TI-CLBLM_L.CLBLM_M_AMUX[0] Switch: 2

And then matching the VPR rr graph source node OPIN back into a 7-series source, and then renaming the net. In the example above, the AMUX OPIN at grid location (30,22) should be named $abc$11234$n2115. AMUX OPIN at grid location (30, 20) corresponds the SLICEM located at tile CLBLM_L_X10Y128. So the fasm2verilog name in that case is CLBLM_L_X10Y128_SLICE_X12Y128_AMUX.

Getting back to VPR net names probably is a multi-step process:

  • Create a python library for reading in the routing output, and finding the source OPIN information
  • Create a mapping from source OPIN to fasm2verilog net names. The net format is of the form {tile}_{site}_{site pin}. The required map is fasm2verilog net name -> VPR net name.
  • Bind the map into fasm2verilog by adding an argument that consumes the route file output. It would be good to keep both net names. So this:
  wire CLBLM_L_X10Y128_SLICE_X12Y128_AMUX;
  assign CLBLM_L_X10Y128_SLICE_X12Y128_AMUX = CLBLM_L_X10Y128_SLICE_X12Y128_AO5;
  assign CLBLL_L_X12Y128_SLICE_X16Y128_C6 = CLBLM_L_X10Y128_SLICE_X12Y128_AMUX;
  assign CLBLL_L_X12Y128_SLICE_X16Y128_D6 = CLBLM_L_X10Y128_SLICE_X12Y128_AMUX;

  (* KEEP, DONT_TOUCH, LOC = "SLICE_X16Y128", BEL = "D6LUT" *)
  LUT6_2 #(
    .INIT(64'b0111010100110000111101111111001100010000111111110101000111111111)
  ) CLBLL_L_X12Y128_SLICE_X16Y128_DLUT (
    .I0(CLBLL_L_X12Y128_SLICE_X16Y128_D1),
    .I1(CLBLL_L_X12Y128_SLICE_X16Y128_D2),
    .I2(CLBLL_L_X12Y128_SLICE_X16Y128_D3),
    .I3(CLBLL_L_X12Y128_SLICE_X16Y128_D4),
    .I4(CLBLL_L_X12Y128_SLICE_X16Y128_D5),
    .I5(CLBLL_L_X12Y128_SLICE_X16Y128_D6),
    .O5(CLBLL_L_X12Y128_SLICE_X16Y128_DO5),
    .O6(CLBLL_L_X12Y128_SLICE_X16Y128_DO6)
  );

becomes

  wire CLBLM_L_X10Y128_SLICE_X12Y128_AMUX;
  wire $abc$11234$n2115;
  assign $abc$11234$n2115 = CLBLM_L_X10Y128_SLICE_X12Y128_AO5;
  assign CLBLM_L_X10Y128_SLICE_X12Y128_AMUX = $abc$11234$n2115;
  assign CLBLL_L_X12Y128_SLICE_X16Y128_C6 = $abc$11234$n2115;
  assign CLBLL_L_X12Y128_SLICE_X16Y128_D6 = $abc$11234$n2115;

  (* KEEP, DONT_TOUCH, LOC = "SLICE_X16Y128", BEL = "D6LUT" *)
  LUT6_2 #(
    .INIT(64'b0111010100110000111101111111001100010000111111110101000111111111)
  ) CLBLL_L_X12Y128_SLICE_X16Y128_DLUT (
    .I0(CLBLL_L_X12Y128_SLICE_X16Y128_D1),
    .I1(CLBLL_L_X12Y128_SLICE_X16Y128_D2),
    .I2(CLBLL_L_X12Y128_SLICE_X16Y128_D3),
    .I3(CLBLL_L_X12Y128_SLICE_X16Y128_D4),
    .I4(CLBLL_L_X12Y128_SLICE_X16Y128_D5),
    .I5($abc$11234$n2115),
    .O5(CLBLL_L_X12Y128_SLICE_X16Y128_DO5),
    .O6(CLBLL_L_X12Y128_SLICE_X16Y128_DO6)
  );


@litghost litghost added enhancement good first issue help wanted arch-xc7-artix7 Issue related to the Artix 7 architecture description. labels Apr 11, 2019
litghost added a commit to litghost/symbiflow-arch-defs that referenced this issue Apr 13, 2019
This begins to address f4pga#578 by providing a mapping from wire_pkey back
to VPR net name.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
litghost added a commit to litghost/symbiflow-arch-defs that referenced this issue Apr 13, 2019
This begins to address f4pga#578 by providing a mapping from wire_pkey back
to VPR net name.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
@mkurc-ant
Copy link
Collaborator

@litghost Regarding "Add a comment above LUT6_2's with the equation form of the LUT from input to output. Ideally they will be reduced equations.":

You mean to write own implementation of an algorithm which converts a truth table with up to 6 inputs to a boolean equation ? Or use an already available solver for this task ? Pure python or an external library/tool ?

I would gladly go with this task, but the only solution I see right now is to use Karnaugh tables related stuff. Or do you have something else on your mind ?

@litghost
Copy link
Contributor Author

@litghost Regarding "Add a comment above LUT6_2's with the equation form of the LUT from input to output. Ideally they will be reduced equations.":

You mean to write own implementation of an algorithm which converts a truth table with up to 6 inputs to a boolean equation ? Or use an already available solver for this task ? Pure python or an external library/tool ?

Yosys can perform this composition, and I believe there are python libraries too.

I would gladly go with this task, but the only solution I see right now is to use Karnaugh tables related stuff. Or do you have something else on your mind ?

That is what I was thinking, about it doesn't have to be all implemented by us.

@mkurc-ant
Copy link
Collaborator

mkurc-ant commented Apr 19, 2019

@litghost

Yosys can perform this composition

I believe that Yosys can only do the opposite: convert boolean equation to a truth table. Not vice-versa.

I found some implementation of Karnaugh map solvers in python but they are limited to 4 inputs only. We are aiming at LUTs with up to 6 inputs (as they are in 7-series) right? A Karnaugh solver is very straightforward so I can write own implementation for 6-input LUTs.

There is also the Quine-McCluskey algorithm which will always find the optimal solution but it is too much time consuming. AFAIK works for any number of inputs. Implementations are available.

I found also a heuristic algorithm called "Espresso". There is source code available: https://ptolemy.berkeley.edu/projects/embedded/pubs/downloads/espresso/index.htm

I'll keep looking for other solutions. I guess I'll go with this task.

@mithro mithro added arch-xc7 Issues related to the XC7 architecture and removed arch-xc7 Issues related to the XC7 architecture arch-xc7-artix7 Issue related to the Artix 7 architecture description. labels Apr 23, 2019
@litghost
Copy link
Contributor Author

In order to better compare timing information output from VPR and Vivado, it is good to annotate the BEL names with the VPR names. I'll look into improving that next. This should enable side-by-side timing path comparisons.

@mithro
Copy link
Contributor

mithro commented May 17, 2019

@mkurc-ant BTW I found the following - Generate logic expressions for all 64K boolean functions of four variables A, B, C, D

# Generate logic expressions for all 64K boolean functions of four variables A, B, C, D
# The idea is to start with simple expressions, then take all combinations of these to
# generate new expressions, then all combinations of the new expressions, etc. until
# everything has been generated.
#
# Formulas are built up as trees, e.g. ['+', 'A', 'B'] is "A or B"

lpawelcz referenced this issue in antmicro/f4pga-arch-defs Jan 28, 2022
…ird_party/prjuray-bd446a5

Bump third_party/prjuray from `263cbb7` to `bd446a5`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-xc7 Issues related to the XC7 architecture enhancement good first issue help wanted
Projects
None yet
Development

No branches or pull requests

3 participants