Skip to content

Add behavioral verilog output#9539

Merged
maliberty merged 21 commits intoThe-OpenROAD-Project:masterfrom
tnguy19:add-behavioral-verilog-output
Mar 5, 2026
Merged

Add behavioral verilog output#9539
maliberty merged 21 commits intoThe-OpenROAD-Project:masterfrom
tnguy19:add-behavioral-verilog-output

Conversation

@tnguy19
Copy link
Contributor

@tnguy19 tnguy19 commented Feb 24, 2026

  • add argument -write_behavioral_verilog [filename] to generate_ram allowing the user to generate a behavioral verilog file for RAM
  • update storage_cell in MakeCellInst (line 122) to allow use of CLK and GATE pin for flip flop and latch cells

@rovinski

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a valuable feature to generate a behavioral Verilog model for the RAM. The implementation is largely correct, but I've identified a critical bug in the address width calculation for an edge case that would lead to invalid Verilog. Additionally, I've provided suggestions to enhance code style consistency, aligning with repository guidelines, and to refine the formatting of the generated output.

}

const int word_size_bit = bytes_per_word * 8;
const int address_width = std::ceil(std::log2(word_count));
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The calculation of address_width is incorrect when word_count is 1. In this case, std::log2(1) is 0, so address_width becomes 0. This leads to address_width - 1 being -1, resulting in an invalid Verilog port declaration like input [-1:0] addr;. The address width should be at least 1.

    const int address_width = (word_count <= 1) ? 1 : std::ceil(std::log2(word_count));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated in af4dd47

@tnguy19 tnguy19 force-pushed the add-behavioral-verilog-output branch from e99a104 to 84c0f61 Compare February 24, 2026 23:57
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@tnguy19 tnguy19 force-pushed the add-behavioral-verilog-output branch from 84c0f61 to af4dd47 Compare February 25, 2026 00:08
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

remove redundant initializer

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: tnguy19 <114105118+tnguy19@users.noreply.github.com>
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Collaborator

@rovinski rovinski left a comment

Choose a reason for hiding this comment

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

Can you please add a test against the behavioral verilog file, e.g. adding the model for the 8x8 ram as a .vok file?

I also want to talk about making sure the structural model and behavioral model actually match expected behavior when we next meet.

Comment on lines +925 to +932
std::ofstream vf(filename);
if (!vf.is_open()) {
logger_->error(RAM, 23, "Unable to open file {}", filename);
return;
}

vf << verilog_code;
vf.close();
Copy link
Collaborator

Choose a reason for hiding this comment

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

@maliberty isn't there a utility function for writing files? Should that be used here?

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this need to be a separate test? Can't you just add the flag to the make8x8 test?

@rovinski
Copy link
Collaborator

test still requires fixing for CI

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Collaborator

@rovinski rovinski left a comment

Choose a reason for hiding this comment

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

Go ahead and fix this last item then mark as ready for review.

@maliberty this looks good to me.

Copy link
Collaborator

Choose a reason for hiding this comment

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

A few notes:

  • No indentation for module
  • Please name the module the exact same as the block. This will help developers seamlessly swap between the gate-level and behavioral versions.
  • Indent ports (D, Q0, etc.)
  • Please use 2-space indenting
  • Power and ground ports should not be included
  • Consistent indentation and spacing
    ** e.g. for (i=0; i< 1; i = i +1 ) --> for (i = 0; i < 1; i = i + 1)
    ** e.g. no empty line after // read logic

@rovinski
Copy link
Collaborator

CI is still failing though, please make sure everything is up to date.

…nd .vok files

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@tnguy19 tnguy19 force-pushed the add-behavioral-verilog-output branch from d4d2552 to 576ef0e Compare February 27, 2026 19:12
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

1 similar comment
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@tnguy19 tnguy19 marked this pull request as ready for review February 27, 2026 20:23
std::ofstream vf(filename);
if (!vf.is_open()) {
logger_->error(RAM, 23, "Unable to open file {}", filename);
return;
Copy link
Member

Choose a reason for hiding this comment

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

rm - return is unreachable as error will throw

@tnguy19 tnguy19 marked this pull request as draft February 28, 2026 05:11
Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@maliberty maliberty marked this pull request as ready for review February 28, 2026 05:30
Comment on lines +30 to +36
always @(*) begin
Q0 = mem[addr];
end

always @(*) begin
Q1 = mem[addr];
end
Copy link
Member

Choose a reason for hiding this comment

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

Is this correct? You have two identical read ports using a single address?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because the structural verilog code for the ram that the behavioral code generator is based on uses the same address bus shared with all the read ports. So all read ports currently read from the same address

Copy link
Member

Choose a reason for hiding this comment

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

So a correct description of the hardware but not normal meaning to real ports afaik. @rovinski is this what you intend?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@tnguy yeah, that's not right. If that's what the structural netlist does, then it's wrong.

There should be an address port per read port. Fix up the behavioral model for now and we'll have to modify the netlist to be correct later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rovinski I have added the update in 190a188 please let me know if theres any changes needed in the new behavioral code

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm, I think this raises an issue on the lack of clarity for the tool interface. It is true that there is one write port and two read ports. But it is unclear whether this means that it should be 3 ports total (2 read 1 write) or 2 ports (1 read-write 1 read).

Right now, we only implicitly support 1 write port. I think it should be that there is always 1 read-write port and then additional read ports. In other words, the first addr port is used for both reading and writing, and then any additional ports are only for reading.

If you make this change, then we can mark it done for now and leave an issue to come back to it when more write ports are supported.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added the updated code in 80c67ad, ready for review

Copy link
Member

Choose a reason for hiding this comment

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

@rovinski you are wanting to merge this with code the writes a behavioral model that doesn't match the hardware generated? That seems confusing/dangerous.

Copy link
Collaborator

@rovinski rovinski Mar 3, 2026

Choose a reason for hiding this comment

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

I am inclined to for now with the goal that the hardware is fixed to match. It didn't occur to me until now that essentially only 1rw memories actually work. Everything else is broken because there is no routine to implement multiple decoders.

Perhaps the ok test should be changed to be 1rw rather than having 2 broken read ports.

Copy link
Member

Choose a reason for hiding this comment

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

Then let's put in an error if the user selects a broken configuration. I don't want to give misleading results.

…ort per read port and new address write input

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

clang-tidy review says "All clean, LGTM! 👍"

… read-write port and additional read ports

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

clang-tidy review says "All clean, LGTM! 👍"

@rovinski
Copy link
Collaborator

rovinski commented Mar 3, 2026

@tnguy19 based on conversation, can you please do the following before merge:

  1. Change the ram test and ok files to be based on -read_ports 1.
  2. Add a check for read_ports != 1, and if so, error with "The ram generator currently only supports 1 read port."

…ted read_ports value !=1

Signed-off-by: Thinh Nguyen <nguyenthinh19011@gmail.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

clang-tidy review says "All clean, LGTM! 👍"

@tnguy19
Copy link
Contributor Author

tnguy19 commented Mar 5, 2026

@maliberty I have added the updates in a526f03 code is ready for review

@rovinski
Copy link
Collaborator

rovinski commented Mar 5, 2026

@maliberty CI looks green now, I think this is ready to merge. I added fixing muli-read/write ports as a top priority item in #9392

@maliberty maliberty merged commit 38fe88d into The-OpenROAD-Project:master Mar 5, 2026
13 checks passed
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.

3 participants