mirror of
https://github.com/TinyTapeout/tt-support-tools.git
synced 2026-11-03 12:46:08 +01:00
fixed hugo content build
This commit is contained in:
@@ -243,4 +243,5 @@ if __name__ == '__main__':
|
|||||||
docs.dump_markdown()
|
docs.dump_markdown()
|
||||||
|
|
||||||
if args.build_hugo_content:
|
if args.build_hugo_content:
|
||||||
|
caravel.configure_mux()
|
||||||
docs.build_hugo_content()
|
docs.build_hugo_content()
|
||||||
|
|||||||
+43
-60
@@ -1,84 +1,67 @@
|
|||||||
---
|
---
|
||||||
title: "Tiny Tapeout 03"
|
title: "Tiny Tapeout 04"
|
||||||
weight: 20
|
weight: 20
|
||||||
description: 249 designs, closed 24th April 2023
|
description: 143 designs, closed 8th September 2023
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% toc %}}
|
{{% toc %}}
|
||||||
|
|
||||||
# Design details
|
# Design details
|
||||||
|
|
||||||
* [Github repository](https://github.com/TinyTapeout/tinytapeout-03)
|
* [Github repository](https://github.com/TinyTapeout/tinytapeout-04)
|
||||||
* [PDF datasheet](https://github.com/TinyTapeout/tinytapeout-03/raw/main/datasheet.pdf)
|
* [PDF datasheet](https://github.com/TinyTapeout/tinytapeout-04/suites/15974117461/artifacts/912076852)
|
||||||
* [Verification](https://github.com/TinyTapeout/tinytapeout-03/blob/main/VERIFICATION.md)
|
* [Efabless MPW submission](https://repositories.efabless.com/urish/tinytapeout-04)
|
||||||
* [Efabless MPW submission](https://platform.efabless.com/projects/1971)
|
|
||||||
|
|
||||||
# Launch stats
|
# Launch stats
|
||||||
|
|
||||||
* Launched: 1 March 2023
|
* Launched: 1 July 2023
|
||||||
* Submission closed: 24 April 2023
|
* Submission closed: 8 September 2023
|
||||||
* Submitted to Efabless 2304C chipIgnite shuttle using Skywater 130nm open source PDK
|
* Submitted to Efabless 2309C chipIgnite shuttle using Skywater 130nm open source PDK
|
||||||
|
|
||||||
# Project statistics
|
# Project statistics
|
||||||
|
|
||||||
* 100 projects submitted, 149 projects added from [TT02](/runs/tt02)
|
* 143 projects
|
||||||
* build time for all projects 22.68 hours
|
* build time for all projects 8.6 hours
|
||||||
* total cells 79674
|
* total cells 82126
|
||||||
* max cells 1287 for [project 072](./072)
|
* max cells 6813 for [project 089](./089)
|
||||||
* max utilisation 59.95% for [project 044](./044)
|
* max utilisation 87.18% for [project 053](./053)
|
||||||
* total wire length 4079 mm
|
* total wire length 2607 mm
|
||||||
* 94 used Wokwi, 135 Verilog, 1 myhdl, 7 Amaranth, spade 1, xls 2, migen 1, systemverilog 3, mixed radix circuit synthesis (mrcs) 1, chisel 1.
|
* 94 used Wokwi, 135 Verilog, 1 myhdl, 7 Amaranth, spade 1, xls 2, migen 1, systemverilog 3, mixed radix circuit synthesis (mrcs) 1, chisel 1.
|
||||||
|
* 92 used Verilog, 46 Wokwi, 1 SystemVerilog, 1 SpinalHDL, 1 mrcs, 1 spade, 1 RustHDL
|
||||||
* top 10 tags:
|
* top 10 tags:
|
||||||
- test : 21
|
- test : 18
|
||||||
- experiment: 6
|
- timer : 12
|
||||||
- cpu : 6
|
- experiment: 12
|
||||||
- timer : 5
|
- game : 9
|
||||||
- risc : 5
|
- clock : 7
|
||||||
- game : 4
|
- pwm : 5
|
||||||
- pwm : 4
|
- serial : 5
|
||||||
|
- vga : 4
|
||||||
- music : 4
|
- music : 4
|
||||||
- counter : 4
|
|
||||||
|
|
||||||
# Whole die render
|
# Whole die render
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# Project Showcase
|
# Project Showcase
|
||||||
|
|
||||||
* [12 bit PDP8](./019)
|
* [VGA ray caster game](033)
|
||||||
* [Prime detector](./031)
|
* [Chiptune vintage 8 bit sound generator](037)
|
||||||
* [Pulse density modulators](./033)
|
* [PWM peripheral](048)
|
||||||
* [Most of the Sky130 cells](./045)
|
* [String synthesiser with I2S out](052)
|
||||||
* [Synthesizable Digital Temperature Sensor](./047)
|
* [USB fullspeed device](054)
|
||||||
* [Neptune guitar tuner](./052)
|
* [Tiny Breakout](098)
|
||||||
* [MSF clock](./066)
|
* [Tiny processor](102)
|
||||||
* [Ring oscillator temperature sensor](./058)
|
* [Grain-Flex-FPGA](117)
|
||||||
* [Locked QTCore-A1](./072)
|
* [AI decelerator](119)
|
||||||
|
* [Simple as Possible CPU](162)
|
||||||
# Testimonials / Endorsements
|
* [Multi channel pulse counter](163)
|
||||||
|
* [Simple Piano](165)
|
||||||
Awesome! Sent my design to #TinyTapeout ! Emotion! Thanks
|
* [Pong](178)
|
||||||
@matthewvenn , @marunmagesh and crew, for making it possible!
|
* [FM transmitter](195)
|
||||||
|
* [ROT FPGA](197)
|
||||||
---
|
* [LED sequencer](211)
|
||||||
|
* [Clock synchronizer](215)
|
||||||
#tinytapeout 3 submission is in! I'm very thankful to be a part of such an amazing project, even if my project is small.
|
* [Randomizer and status checker](288)
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Just to take moment, thank you! I didn't think I would ever get to do something like this, especially with so little cost or pressure.
|
|
||||||
For context, at work, I was testing an ASIC a supplier designed for us, and that was quite the opposite of both of these.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Hurray, also made a last minute submission, haven't felt that rush since my last university homework submission deadline... Great that a chip design can be done on a weekend, looking forward to getting all the other designs, and thanks everybody who contributed to the platform, it is really easy to use!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
I just submitted a last minute project to tt03, wanted to drop by and say kudos for all the resources and the project in general!
|
|
||||||
|
|
||||||
I've never done any hardware before (just software), but after reading the updated Code by Petzold earlier in the year and listening to an interview with Jim Keller I had my interest peeked to look at whats going on in the layers I usually take for granted. Really cool to find something like tiny tapeout, nice motivating to actually install some of the tools and give it a try.
|
|
||||||
|
|
||||||
---
|
|
||||||
More on [Twitter](https://twitter.com/search?q=tinytapeout).
|
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -1,15 +1,15 @@
|
|||||||
---
|
---
|
||||||
hidden: true
|
hidden: true
|
||||||
title: "{index} {title}"
|
title: "{mux_address} {title}"
|
||||||
weight: {weight}
|
weight: {weight}
|
||||||
---
|
---
|
||||||
|
|
||||||
## {index} : {title}
|
## {mux_address} : {title}
|
||||||
|
|
||||||
* Author: {author}
|
* Author: {author}
|
||||||
* Description: {description}
|
* Description: {description}
|
||||||
* [GitHub repository]({git_url})
|
* [GitHub repository]({git_url})
|
||||||
* [Most recent GDS build]({git_action})
|
* [GDS submitted]({git_action})
|
||||||
* {project_type} project
|
* {project_type} project
|
||||||
* [Extra docs]({doc_link})
|
* [Extra docs]({doc_link})
|
||||||
* Clock: {clock_hz} Hz
|
* Clock: {clock_hz} Hz
|
||||||
@@ -27,13 +27,13 @@ weight: {weight}
|
|||||||
|
|
||||||
### IO
|
### IO
|
||||||
|
|
||||||
| # | Input | Output |
|
| # | Input | Output | Bidirectional |
|
||||||
|---|--------------|--------------|
|
|---|--------------|--------------| -------------------|
|
||||||
| 0 | {inputs[0]} | {outputs[0]} |
|
| 0 | {inputs[0]} | {outputs[0]} | {bidirectional[0]} |
|
||||||
| 1 | {inputs[1]} | {outputs[1]} |
|
| 1 | {inputs[1]} | {outputs[1]} | {bidirectional[1]} |
|
||||||
| 2 | {inputs[2]} | {outputs[2]} |
|
| 2 | {inputs[2]} | {outputs[2]} | {bidirectional[2]} |
|
||||||
| 3 | {inputs[3]} | {outputs[3]} |
|
| 3 | {inputs[3]} | {outputs[3]} | {bidirectional[3]} |
|
||||||
| 4 | {inputs[4]} | {outputs[4]} |
|
| 4 | {inputs[4]} | {outputs[4]} | {bidirectional[4]} |
|
||||||
| 5 | {inputs[5]} | {outputs[5]} |
|
| 5 | {inputs[5]} | {outputs[5]} | {bidirectional[5]} |
|
||||||
| 6 | {inputs[6]} | {outputs[6]} |
|
| 6 | {inputs[6]} | {outputs[6]} | {bidirectional[6]} |
|
||||||
| 7 | {inputs[7]} | {outputs[7]} |
|
| 7 | {inputs[7]} | {outputs[7]} | {bidirectional[7]} |
|
||||||
|
|||||||
+24
-9
@@ -111,7 +111,6 @@ class Docs():
|
|||||||
fh.write(doc)
|
fh.write(doc)
|
||||||
fh.write("\n\clearpage\n")
|
fh.write("\n\clearpage\n")
|
||||||
except IndexError:
|
except IndexError:
|
||||||
import ipdb; ipdb.set_trace()
|
|
||||||
logging.warning("missing pins in info.yaml, skipping")
|
logging.warning("missing pins in info.yaml, skipping")
|
||||||
|
|
||||||
# ending
|
# ending
|
||||||
@@ -142,36 +141,52 @@ class Docs():
|
|||||||
index_template = fh.read()
|
index_template = fh.read()
|
||||||
|
|
||||||
# copy image
|
# copy image
|
||||||
shutil.copyfile('pics/tinytapeout_numbered.png', os.path.join(hugo_images, 'tinytapeout-03.png')) # TODO fix hardcoded run
|
# TODO, need to get image from somewhere
|
||||||
|
shutil.copyfile('tt/docs/pics/tinytapeout_numbered.png', os.path.join(hugo_images, f'tinytapeout-{self.config["id"]}.png'))
|
||||||
|
|
||||||
# index page
|
# index page
|
||||||
logging.info("building pages - can take a minute as fetching latest GDS action URLs for all projects")
|
logging.info("building pages")
|
||||||
with open(os.path.join(hugo_root, '_index.md'), 'w') as fh:
|
with open(os.path.join(hugo_root, '_index.md'), 'w') as fh:
|
||||||
fh.write(index_template)
|
fh.write(index_template)
|
||||||
fh.write('# All projects\n')
|
fh.write('# All projects\n')
|
||||||
fh.write("| Index | Title | Author |\n")
|
fh.write("| Index | Title | Author |\n")
|
||||||
fh.write("| ----- | ----- | -------|\n")
|
fh.write("| ----- | ----- | -------|\n")
|
||||||
|
self.projects.sort(key=lambda x: x.mux_address)
|
||||||
for project in self.projects:
|
for project in self.projects:
|
||||||
logging.info(project)
|
logging.info(project)
|
||||||
fh.write(project.get_hugo_row())
|
fh.write(project.get_hugo_row())
|
||||||
|
|
||||||
project_dir = os.path.join(hugo_root, f'{project.get_index() :03}')
|
project_dir = os.path.join(hugo_root, f'{project.mux_address :03}')
|
||||||
project_image_dir = os.path.join(project_dir, 'images')
|
project_image_dir = os.path.join(project_dir, 'images')
|
||||||
os.makedirs(project_dir)
|
os.makedirs(project_dir)
|
||||||
os.makedirs(project_image_dir)
|
os.makedirs(project_image_dir)
|
||||||
yaml_data = project.get_project_doc_yaml()
|
yaml_data = project.get_project_doc_yaml()
|
||||||
|
yaml_data['mux_address'] = project.mux_address
|
||||||
|
if '""' in yaml_data['title']:
|
||||||
|
yaml_data['title'] = yaml_data['title'].replace('""', '')
|
||||||
|
|
||||||
yaml_data['index'] = project.index
|
yaml_data['index'] = project.index
|
||||||
yaml_data['weight'] = project.index + 1
|
yaml_data['weight'] = project.index + 1
|
||||||
yaml_data['git_action'] = project.get_latest_action_url()
|
yaml_data['git_action'] = project.get_workflow_url_when_submitted()
|
||||||
|
for key in 'external_hw', 'clock_hz':
|
||||||
|
if key not in yaml_data:
|
||||||
|
yaml_data[key] = ''
|
||||||
|
|
||||||
|
# many people remove unused pins in input / output / bidirectional
|
||||||
|
for key in ['inputs', 'outputs', 'bidirectional']:
|
||||||
|
yaml_data[key].extend((8 - len(yaml_data[key])) * ['n/a'])
|
||||||
|
|
||||||
yaml_data['picture_link'] = ''
|
yaml_data['picture_link'] = ''
|
||||||
if yaml_data['picture']:
|
if yaml_data['picture']:
|
||||||
picture_name = yaml_data['picture']
|
extension = os.path.splitext(yaml_data['picture'])[1]
|
||||||
picture_filename = os.path.join(project.local_dir, picture_name)
|
picture_path = os.path.join(project.local_dir, f"picture{extension}")
|
||||||
picture_basename = os.path.basename(picture_filename)
|
picture_basename = os.path.basename(picture_path)
|
||||||
try:
|
try:
|
||||||
shutil.copyfile(picture_filename, os.path.join(project_image_dir, picture_basename))
|
shutil.copyfile(picture_path, os.path.join(project_image_dir, picture_basename))
|
||||||
yaml_data['picture_link'] = f''
|
yaml_data['picture_link'] = f''
|
||||||
|
logging.warning(f"picture found {picture_path}")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
logging.warning(f"picture not found {picture_path}")
|
||||||
yaml_data['picture_link'] = 'Image path is broken'
|
yaml_data['picture_link'] = 'Image path is broken'
|
||||||
doc = doc_template.format(**yaml_data)
|
doc = doc_template.format(**yaml_data)
|
||||||
with open(os.path.join(project_dir, '_index.md'), 'w') as pfh:
|
with open(os.path.join(project_dir, '_index.md'), 'w') as pfh:
|
||||||
|
|||||||
@@ -70,37 +70,5 @@ def split_git_url(url):
|
|||||||
return user_name, repo
|
return user_name, repo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_latest_action_url(url):
|
|
||||||
logging.debug(url)
|
|
||||||
user_name, repo = split_git_url(url)
|
|
||||||
|
|
||||||
headers = {
|
|
||||||
"Accept" : "application/vnd.github+json",
|
|
||||||
}
|
|
||||||
# authenticate for rate limiting
|
|
||||||
headers_try_to_add_authorization_from_environment(headers)
|
|
||||||
|
|
||||||
# first fetch the git commit history
|
|
||||||
api_url = f'https://api.github.com/repos/{user_name}/{repo}/commits'
|
|
||||||
r = requests.get(api_url, headers=headers)
|
|
||||||
check_status(r)
|
|
||||||
requests_remaining = int(r.headers['X-RateLimit-Remaining'])
|
|
||||||
if requests_remaining == 0:
|
|
||||||
logging.error("no API requests remaining")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
commits = r.json()
|
|
||||||
|
|
||||||
# get runs
|
|
||||||
api_url = f'https://api.github.com/repos/{user_name}/{repo}/actions/runs'
|
|
||||||
r = requests.get(api_url, headers=headers, params={'per_page': 100})
|
|
||||||
check_status(r)
|
|
||||||
runs = r.json()
|
|
||||||
page_url = get_most_recent_action_page(commits, runs['workflow_runs'])
|
|
||||||
|
|
||||||
return page_url
|
|
||||||
|
|
||||||
|
|
||||||
def get_first_remote(repo: git.Repo) -> str:
|
def get_first_remote(repo: git.Repo) -> str:
|
||||||
return list(repo.remotes[0].urls)[0]
|
return list(repo.remotes[0].urls)[0]
|
||||||
|
|||||||
+7
-4
@@ -176,7 +176,7 @@ class Project():
|
|||||||
return self.yaml
|
return self.yaml
|
||||||
|
|
||||||
def get_hugo_row(self):
|
def get_hugo_row(self):
|
||||||
return f'| {self.index} | [{self.yaml["documentation"]["title"]}]({self.index :03}) | {self.yaml["documentation"]["author"]}|\n'
|
return f'| {self.mux_address} | [{self.yaml["documentation"]["title"]}]({self.mux_address :03}) | {self.yaml["documentation"]["author"]}|\n'
|
||||||
|
|
||||||
# docs stuff for index on README.md
|
# docs stuff for index on README.md
|
||||||
def get_index_row(self):
|
def get_index_row(self):
|
||||||
@@ -229,6 +229,12 @@ class Project():
|
|||||||
repo = git.Repo(os.path.join(self.local_dir, "tt"))
|
repo = git.Repo(os.path.join(self.local_dir, "tt"))
|
||||||
return f"{repo.active_branch.name} {repo.commit().hexsha[:8]}"
|
return f"{repo.active_branch.name} {repo.commit().hexsha[:8]}"
|
||||||
|
|
||||||
|
def get_workflow_url_when_submitted(self):
|
||||||
|
json_file = os.path.join(self.local_dir, 'commit_id.json')
|
||||||
|
with open(json_file) as fh:
|
||||||
|
commit_info = json.load(fh)
|
||||||
|
return commit_info['workflow_url']
|
||||||
|
|
||||||
def get_workflow_url(self):
|
def get_workflow_url(self):
|
||||||
GITHUB_SERVER_URL = os.getenv('GITHUB_SERVER_URL')
|
GITHUB_SERVER_URL = os.getenv('GITHUB_SERVER_URL')
|
||||||
GITHUB_REPOSITORY = os.getenv('GITHUB_REPOSITORY')
|
GITHUB_REPOSITORY = os.getenv('GITHUB_REPOSITORY')
|
||||||
@@ -244,9 +250,6 @@ class Project():
|
|||||||
"""
|
"""
|
||||||
return f"[{self.index:03} : {self.git_url}]"
|
return f"[{self.index:03} : {self.git_url}]"
|
||||||
|
|
||||||
def get_latest_action_url(self):
|
|
||||||
return git_utils.get_latest_action_url(self.git_url, self.local_dir)
|
|
||||||
|
|
||||||
def get_macro_name(self):
|
def get_macro_name(self):
|
||||||
return self.top_module
|
return self.top_module
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user