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

Add Lakeroad egglog backend #4

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

Conversation

gussmith23
Copy link

No description provided.

gussmith23 and others added 30 commits September 3, 2023 16:20
Apply the local substitutions stemming from process context when parsing
out format arguments to `$display` or other statements.
- Add support for assignments within expressions, e.g., `x[y++] = z;` or
  `x = (y *= 2) - 1;`. The logic is handled entirely within the parser
  by injecting statements into the current procedural block.
- Add support for pre-increment/decrement statements, which are
  behaviorally equivalent to post-increment/decrement statements.
- Fix non-standard attribute position used for post-increment/decrement
  statements.
* Fixes a non-deterministic polarity error for $eqx/$nex cells
* Fixes a deterministic polarity error for $_NOR_ and $_ORNOT_ cells
* Generates hdlnames when xprop is run after flatten
@thiskappaisgrey
Copy link

thiskappaisgrey commented Dec 6, 2023

How do I add a test to your PR? I found something that doesn't work:

module test 
  (
   i_bit1,
   );
 
  input  i_bit1;
 
  assign o_sum   = ~ i_bit1; 
 
endmodule // half_adder

This is the yosys file:

# read design
read_verilog ./test.v 
write_lakeroad 

I get this error:

; cells
ERROR: Unimplemented cell type $not for cell test.$not$./test.v:10$1.

@gussmith23
Copy link
Author

There are two approaches. In this case, you need a very basic test that just checks to make sure the Lakeroad backend doesn't crash when it runs on a given module. In that case, you should write a test that looks like Yosys's tests. Take a look at backends/lakeroad/example.ys. This test is a Yosys script that reads in a module and runs the backend. If no error is thrown, the test passes. So you could copy this file and change the module.

The second type of test is something that doesn't currently exist in Yosys; this PR adds it. It realistically won't get merged into Yosys itself. But nevertheless, it's useful for doing fine-grained testing -- for example, if you want to make sure that the Lakeroad backend produces SPECIFIC output. For this I use lit and FileCheck, which are LLVM integration testing tools. For an example, look at backends/lakeroad/tests/permuter.sv. The syntax is pretty simple: you have a source file (e.g. a Verilog file). In comments at the top of the file, you give the command to compile the file (in a RUN comment). Then, you write CHECK comments to check that the output is as expected.

@thiskappaisgrey
Copy link

thiskappaisgrey commented Dec 6, 2023

How do I add the basic test then? It seems you only have lit tests in the repo for lakeroad.

Edit, just added a PR: #8 - can you check? Thanks.

@gussmith23
Copy link
Author

gussmith23 commented Dec 6, 2023 via email

@thiskappaisgrey
Copy link

thiskappaisgrey commented Dec 6, 2023 via email

@gussmith23
Copy link
Author

gussmith23 commented Dec 6, 2023 via email

thiskappaisgrey and others added 4 commits December 11, 2023 18:06
…ackend-tests

Add a new test for the not cell.
…out. (#9)

* Add code to write_lakeroad to file instead of stdout

* Fix a bug for writing to stdout as well

* Add suggested code
@thiskappaisgrey
Copy link

How should we make the egglog backend work for clocked designs? For example, this code:

module ALU_32bit (
  input logic [4:0] operandA,
  input logic [4:0] operandB,
  input logic [3:0] control, // Control signal to specify the operation
  output logic [4:0] result
  
);

  always  begin
    case (control)
      // 4'b0000: result = operandA + operandB; // Addition
      2'b00: result = operandA + operandB; // Bitwise XOR
      2'b01: result = operandA - operandB; // Subtraction
      2'b10: result = operandA | operandB; // Bitwise OR
      2'b11: result = operandA & operandB; // Bitwise AND
    endcase
  end
endmodule

implies a clocked design (using a global clock) and this needs the flip-flop cells to be implemented. Maybe I can implement it using assign (which .. maybe doesn't use a mux?? I have no clue on the semantics of verilog).. but for more complex tests, I'll need the flipflops anyways... Maybe there's a way to expand the flip-flops into gates with yosys? If there is, please let me know. Thanks.

@gussmith23
Copy link
Author

gussmith23 commented Jan 8, 2024 via email

@thiskappaisgrey
Copy link

thiskappaisgrey commented Jan 8, 2024

Oh, when I compile it, it adds an $ff yosys cell and in the lake road backend, that (and the other flip flop cells) are not implemented. Idk how to get rid of the flip-flop cells and compile it to other logic. That's what I meant. I meant for the design to be purely combinatorial but the case statement can only be used in an always block, and the compiled yosys code includes an always @* (or something like that), so I'm assuming that's clocked towards a global clock or something idk.. I'll try messing around with the yosys statements later and see.. recurring meetings would be nice! Just lmk.

@gussmith23
Copy link
Author

Can you post the script you're using to compile it? Specifically, what Yosys passes are you running before you run the Lakeroad backend?

@thiskappaisgrey
Copy link

Oh, I can do that when I get the chance! On mobile right now.

@thiskappaisgrey
Copy link

I never figured out how to get the case statement working but I'll add a not-working test case in a branch later. I managed to get it working by using a ternary (the always block adds flip-flops for some reason).

@gussmith23
Copy link
Author

Try always_comb instead of always. You should at least get a more informative error.

It's likely because of case. You think you're handling all cases, but you're not -- what if one or both bits is X or Z? Related to this, you could also just try adding a default: case to your case block. That would probably resolve it.

@gussmith23
Copy link
Author

That is:

      2'b11: result = operandA & operandB; // Bitwise AND
      default: result = 0;    
    endcase

@thiskappaisgrey
Copy link

Oh yeah - the verilog experts in my lab helped resolve the issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.