feat: Chip ROM auto generation with OpenLane 2

So we can generate the ROM while building the shuttle's GDS
This commit is contained in:
Uri Shaked
2023-09-10 20:17:58 +03:00
parent 5e863fc333
commit cadbfbcd25
6 changed files with 87 additions and 8 deletions
+1 -1
View File
@@ -244,7 +244,7 @@ if __name__ == '__main__':
shuttle.configure_mux()
if args.test:
shuttle.write_gl_config()
#rom.write_rom()
rom.write_rom()
if not args.test:
docs.build_index()
+18 -6
View File
@@ -1,4 +1,8 @@
import git
import os
from urllib.parse import urlparse
MAX_ROM_TEXT_SIZE = 92
segment_font = {
" ": 0b00000000,
@@ -30,7 +34,8 @@ class ROMFile:
self.config = config
def get_git_remote(self):
return list(git.Repo(".").remotes[0].urls)[0]
repo_url = list(git.Repo(".").remotes[0].urls)[0]
return urlparse(repo_url).path[1:]
def get_git_commit_hash(self):
return git.Repo(".").commit().hexsha
@@ -39,18 +44,25 @@ class ROMFile:
rom = bytearray(256)
short_sha = self.get_git_commit_hash()[:8]
rom_text = f"shuttle={self.config['name']}\n"
rom_text = f"shuttle={self.config['id']}\n"
rom_text += f"repo={self.get_git_remote()}\n"
rom_text += f"commit={short_sha}\n"
assert len(rom_text) < 96, "ROM text too long"
print(f"\nROM text: {len(rom_text)} bytes (max={MAX_ROM_TEXT_SIZE})\n")
print(" " + "\n ".join(rom_text.split("\n")))
rom[0:4] = map(segment_char, "tt04")
assert len(rom_text) < MAX_ROM_TEXT_SIZE, "ROM text too long"
rom[0:4] = map(segment_char, self.config['id'])
rom[8:16] = map(segment_char, short_sha.upper())
rom[32 : 32 + len(rom_text)] = rom_text.encode("ascii")
# build complete list of filenames for sim
with open("verilog/includes/rom_tile.vmem", "w") as fh:
with open(os.path.join(os.path.dirname(__file__), "rom/rom.vmem"), "w") as fh:
for line in rom_text.split("\n"):
if len(line) == 0:
continue
fh.write(f"// {line}\n")
fh.write("\n")
for line in range(0, len(rom), 16):
for byte in range(0, 16):
fh.write("{:02x} ".format(rom[line + byte]))
+2
View File
@@ -0,0 +1,2 @@
runs
rom.vmem
+31
View File
@@ -0,0 +1,31 @@
{
"DESIGN_NAME": "tt_um_chip_rom",
"VERILOG_FILES": "dir::tt_um_chip_rom.v",
"FP_SIZING": "absolute",
"DIE_AREA": "0 0 168.36 111.52",
"FP_DEF_TEMPLATE": "ref::$DESIGN_DIR/../def/tt_block_1x1.def",
"FP_IO_HLENGTH": 2,
"FP_IO_VLENGTH": 2,
"//": "use alternative efabless decap cells to solve LI density issue",
"DECAP_CELL": "sky130_fd_sc_hd__decap_3 sky130_fd_sc_hd__decap_4 sky130_fd_sc_hd__decap_6 sky130_fd_sc_hd__decap_8 sky130_ef_sc_hd__decap_12",
"//": "period is in ns, so 20ns == 50mHz",
"CLOCK_PERIOD": 20,
"CLOCK_PORT": "clk",
"//": "don't use power rings or met5",
"DESIGN_IS_CORE": false,
"RT_MAX_LAYER": "met4",
"//": "save some time",
"RUN_KLAYOUT_XOR": false,
"//": "reduce wasted space",
"TOP_MARGIN_MULT": 1,
"BOTTOM_MARGIN_MULT": 1,
"LEFT_MARGIN_MULT": 6,
"RIGHT_MARGIN_MULT": 6
}
+32
View File
@@ -0,0 +1,32 @@
/*
* tt_um_chip_rom.v
*
* ROM module for Tiny Tapeout chips
*
* Author: Uri Shaked
*/
`default_nettype none
module tt_um_chip_rom (
input wire [7:0] ui_in, // Dedicated inputs
output wire [7:0] uo_out, // Dedicated outputs
input wire [7:0] uio_in, // IOs: Input path
output wire [7:0] uio_out,// IOs: Output path
output wire [7:0] uio_oe, // IOs: Enable path (active high: 0=input, 1=output)
input wire ena,
input wire clk,
input wire rst_n
);
reg [7:0] rom_data [0:255];
initial begin
$readmemh("rom.vmem", rom_data);
end
assign uo_out = rom_data[ui_in];
assign uio_out = 8'h00;
assign uio_oe = 8'h00;
endmodule // tt_um_chip_rom
+3 -1
View File
@@ -100,6 +100,8 @@ class ShuttleConfig():
def find_last_run(self, macro: str):
runs = f"tt-multiplexer/ol2/{macro}/runs/"
if macro == "tt_um_chip_rom":
runs = "tt/rom/runs/"
runlist = sorted(
[r for r in os.listdir(runs) if r.startswith("RUN_") and os.path.isdir(os.path.join(runs, r))]
)
@@ -115,7 +117,7 @@ class ShuttleConfig():
copy_print_glob("projects/*/*.gds", "tt-multiplexer/ol2/tt_top/gds")
copy_print_glob("projects/*/*.lef", "tt-multiplexer/ol2/tt_top/lef")
copy_print_glob("projects/*/*.v", "tt-multiplexer/ol2/tt_top/verilog")
macros = ["tt_ctrl", "tt_mux"]
macros = ["tt_um_chip_rom", "tt_ctrl", "tt_mux"]
for macro in macros:
lastrun = self.find_last_run(macro)
copy_print(f"{lastrun}/final/gds/{macro}.gds", f"tt-multiplexer/ol2/tt_top/gds/{macro}.gds")