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

Brian opcodes #449

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/regress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,32 @@ jobs:
run: ./bin/build_container
- name: Generate extension PDF
run: ./do gen:profile[MockProfileRelease]

regress-gen-opcode:
runs-on: ubuntu-latest
env:
SINGULARITY: 1
steps:
- name: Clone Github Repo Action
uses: actions/checkout@v4
- name: Setup apptainer
uses: eWaterCycle/[email protected]
- name: Get container from cache
id: cache-sif
uses: actions/cache@v4
with:
path: .singularity/image.sif
key: ${{ hashFiles('container.def', 'bin/.container-tag') }}
- name: Get gems and node files from cache
id: cache-bundle-npm
uses: actions/cache@v4
with:
path: |
.home/.gems
node_modules
key: ${{ hashFiles('Gemfile.lock') }}-${{ hashFiles('package-lock.json') }}
- if: ${{ steps.cache-sif.outputs.cache-hit != 'true' }}
name: Build container
run: ./bin/build_container
- name: Generate opcode outputs
run: ./do gen:opcode_outputs
Empty file modified .pre-commit-config.yaml
100644 → 100755
Empty file.
25 changes: 25 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require "yard"
require "minitest/test_task"

require_relative $root / "lib" / "architecture"
$opcode_outputs = $root / "gen" / "opcodes_outputs"

directory "#{$root}/.stamps"

Expand Down Expand Up @@ -39,6 +40,28 @@ file "#{$root}/.stamps/dev_gems" => ["#{$root}/.stamps"] do |t|
FileUtils.touch t.name
end

namespace :gen do
desc "Generate opcode outputs, optionally specify YAML_DIR=path/to/yaml"
task :opcode_outputs do
yaml_dir = ENV['YAML_DIR'] || "#{$root}/arch/inst"
mkdir_p $opcode_outputs
sh "#{$root}/.home/.venv/bin/python3 #{$root}/backends/opcodes_maker/yaml_to_json.py #{yaml_dir} #{$opcode_outputs}"
sh "#{$root}/.home/.venv/bin/python3 #{$root}/backends/opcodes_maker/generator.py #{$opcode_outputs}/instr_dict.json -c -chisel -spinalhdl -sverilog -rust -go -latex"

# Move generated files to output dir
Dir.chdir("#{$root}") do
mv "encoding.out.h", "#{$opcode_outputs}/", force: true
mv "inst.chisel", "#{$opcode_outputs}/", force: true
mv "inst.spinalhdl", "#{$opcode_outputs}/", force: true
mv "inst.sverilog", "#{$opcode_outputs}/", force: true
mv "inst.rs", "#{$opcode_outputs}/", force: true
mv "inst.go", "#{$opcode_outputs}/", force: true
mv "instr-table.tex", "#{$opcode_outputs}/", force: true
mv "priv-instr-table.tex", "#{$opcode_outputs}/", force: true
end
end
end

namespace :gen do
desc "Generate documentation for the ruby tooling"
task tool_doc: "#{$root}/.stamps/dev_gems" do
Expand Down Expand Up @@ -319,6 +342,8 @@ namespace :test do

Rake::Task["gen:html"].invoke("generic_rv64")

Rake::Task["gen:opcode_outputs"].invoke

Rake::Task["#{$root}/gen/certificate_doc/pdf/MockCertificateModel.pdf"].invoke
Rake::Task["#{$root}/gen/profile_doc/pdf/MockProfileRelease.pdf"].invoke

Expand Down
46 changes: 46 additions & 0 deletions backends/opcodes_maker/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Directories
YAML_DIR ?= ../../arch/inst
OUTPUT_DIR := output

# Python scripts
YAML_TO_JSON := yaml_to_json.py
GENERATOR := generator.py

# Generated files
INSTR_DICT := $(OUTPUT_DIR)/instr_dict.json
C_OUT := $(OUTPUT_DIR)/encoding.out.h
CHISEL_OUT := $(OUTPUT_DIR)/inst.chisel
SPINALHDL_OUT := $(OUTPUT_DIR)/inst.spinalhdl
SVERILOG_OUT := $(OUTPUT_DIR)/inst.sverilog
RUST_OUT := $(OUTPUT_DIR)/inst.rs
GO_OUT := $(OUTPUT_DIR)/inst.go
LATEX_OUT := $(OUTPUT_DIR)/instr-table.tex
LATEX_PRIV_OUT := $(OUTPUT_DIR)/priv-instr-table.tex

# Check for required files
REQUIRED_FILES := $(YAML_TO_JSON) $(GENERATOR)
$(foreach file,$(REQUIRED_FILES),\
$(if $(wildcard $(file)),,$(error Required file $(file) not found)))

# Default target
all: generate

# Create output directory
$(OUTPUT_DIR):
mkdir -p $(OUTPUT_DIR)

# Convert YAML to JSON
$(INSTR_DICT): $(YAML_TO_JSON) | $(OUTPUT_DIR)
python3 $(YAML_TO_JSON) $(YAML_DIR) $(OUTPUT_DIR)

# Generate all outputs
generate: $(INSTR_DICT)
python3 $(GENERATOR) $(INSTR_DICT) -c -chisel -spinalhdl -sverilog -rust -go -latex
mv encoding.out.h inst.chisel inst.spinalhdl inst.sverilog inst.rs inst.go \
instr-table.tex priv-instr-table.tex $(OUTPUT_DIR)/ 2>/dev/null || true

# Clean generated files
clean:
rm -rf $(OUTPUT_DIR)

.PHONY: all generate clean
89 changes: 89 additions & 0 deletions backends/opcodes_maker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# RISC-V Instruction Format Generator

This tool converts RISC-V instruction YAML definitions into various output formats including C headers, Chisel, Rust, Go, and LaTeX documentation.

## Prerequisites

- Python 3
- YAML Python package (`pip install pyyaml`)
- Make

## Directory Structure

```
.
├── yaml_to_json.py # Converts YAML instruction definitions to JSON
├── generator.py # Generates various output formats from JSON
├── output/ # Generated files directory
└── Makefile # Build system configuration
```

## Input/Output Format

### Input
- YAML files containing RISC-V instruction definitions
- Default input directory: `../../arch/inst`
- Can be customized using `YAML_DIR` variable

### Output
All outputs are generated in the `output` directory:
- `encoding.out.h` - C header definitions
- `inst.chisel` - Chisel implementation
- `inst.spinalhdl` - SpinalHDL implementation
- `inst.sverilog` - SystemVerilog implementation
- `inst.rs` - Rust implementation
- `inst.go` - Go implementation
- `instr-table.tex` - LaTeX instruction table
- `priv-instr-table.tex` - LaTeX privileged instruction table
- `instr_dict.json` - Intermediate JSON representation
- `processed_instr_dict.json` - Final processed JSON

## Usage

### Basic Usage
```bash
make # Use default YAML directory
make YAML_DIR=/custom/path # Use custom YAML directory
make clean # Remove all generated files
make help # Show help message
```

### Pipeline Steps
1. YAML to JSON conversion (`yaml_to_json.py`)
- Reads YAML instruction definitions
- Creates intermediate JSON representation

2. Output Generation (`generator.py`)
- Takes JSON input
- Generates all output formats
- Places results in output directory

### Customization
- Input directory can be changed:
```bash
make YAML_DIR=/path/to/yaml/files
```
- Default paths in Makefile:
```makefile
YAML_DIR ?= ../../arch/inst
OPCODES_DIR := ../riscv-opcodes
OUTPUT_DIR := output
```

## Error Handling
- Checks for required Python scripts before execution
- Verifies input directory exists
- Creates output directory if missing
- Shows helpful error messages for missing files/directories

## Cleaning Up
```bash
make clean # Removes all generated files and output directory
```

## Dependencies
- Requires access to RISC-V opcodes repository (expected at `../riscv-opcodes`)
- Python scripts use standard libraries plus PyYAML

## Note
Make sure your input YAML files follow the expected RISC-V instruction definition format. For format details, refer to the RISC-V specification or example YAML files in the arch/inst directory.
Loading
Loading