[FIRRTL][HW] Feature Request to emit FIRRTL Memories Inline
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 524
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 46
Description
FIRRTL memories that do not go through the `--repl-seq-mem` path to replace them with blackboxes always produce a wrapper module around the memory. However, this can result in poorer performance for Vivado tooling for designs which rely on Vivado optimizations to optimize certain memory-to-memory paths.
For more information, see the discussion here: https://matrix.to/#/!jSbgpvvpsPbLpsLZOC:matrix.org/$NRsJEcgzZH0ghUHWnRG00OIqkHOLIIutn9WShxiNK6E?via=matrix.org&via=gitter.im&via=austin-harris.com
Add an option that enables inline emission of memories.
#### Example
Input FIRRTL:
```
FIRRTL version 3.0.0
circuit Foo:
module Foo:
input r: {addr: UInt<3>, en: UInt<1>, clk: Clock, flip data: UInt<32>}
input w: {addr: UInt<3>, en: UInt<1>, clk: Clock, data: UInt<32>, mask: UInt<1>}
mem memory :
data-type => UInt<32>
depth => 8
read-latency => 1
write-latency => 1
reader => r
writer => w
read-under-write => undefined
connect memory.r, r
connect memory.w, w
```
Current output Verilog:
```verilog
module memory_8x32(
input [2:0] R0_addr,
input R0_en,
R0_clk,
input [2:0] W0_addr,
input W0_en,
W0_clk,
input [31:0] W0_data,
output [31:0] R0_data
);
reg [31:0] Memory[0:7];
reg _GEN;
reg [2:0] _GEN_0;
always @(posedge R0_clk) begin
_GEN <= R0_en;
_GEN_0 <= R0_addr;
end // always @(posedge)
always @(posedge W0_clk) begin
if (W0_en)
Memory[W0_addr] <= W0_data;
end // always @(posedge)
assign R0_data = _GEN ? Memory[_GEN_0] : 32'bx;
endmodule
module Foo(
input [2:0] r_addr,
input r_en,
r_clk,
input [2:0] w_addr,
input w_en,
w_clk,
input [31:0] w_data,
input w_mask,
output [31:0] r_data
);
memory_8x32 memory_ext (
.R0_addr (r_addr),
.R0_en (r_en),
.R0_clk (r_clk),
.W0_addr (w_addr),
.W0_en (w_en & w_mask),
.W0_clk (w_clk),
.W0_data (w_data),
.R0_data (r_data)
);
endmodule
```
Desired output Verilog:
```verilog
module Foo(
input [2:0] r_addr,
input r_en,
r_clk,
input [2:0] w_addr,
input w_en,
w_clk,
input [31:0] w_data,
input w_mask,
output [31:0] r_data
);
reg [31:0] Memory[0:7];
reg _GEN;
reg [2:0] _GEN_0;
always @(posedge r_clk) begin
_GEN <= r_en;
_GEN_0 <= r_addr;
end // always @(posedge)
always @(posedge w_clk) begin
if (w_en)
Memory[w_addr] <= w_data;
end // always @(posedge)
assign r_data = _GEN ? Memory[_GEN_0] : 32'bx;
endmodule
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Begin with the FIRRTL memory emission path that produces the wrapper shown in the current Verilog, then compare it with the desired inline output. Define the new option around inline memory emission and verify that this example no longer adds the memory_8x32 module. The issue names no source file or test, so locating the relevant emitter and adding coverage is part of the work.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100