Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ poetry.toml
# Temporary files created by the program
/temp
# TODO will be moved to /temp eventually
/Submissions
/submissions

# Student list text files
*student*.txt
Expand Down
23 changes: 21 additions & 2 deletions grader.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
__version__ = '0.3'
# ----------------------------------------------------------
# IMPORTS
# ----------------------------------------------------------

import argparse
import csv
from pathlib import Path
from pickle import encode_long
from scripts import extract_submissions, generate_tcl, StudentData, run_simulations
from shutil import which
import subprocess

# ----------------------------------------------------------
# METHODS
Expand Down Expand Up @@ -43,12 +46,27 @@ def generate_tcl_mpf_filenames(lab_num: int):
def check_vsim_command():
"""Verify that `vsim` is an operable command.
Otherwise, the tool will crash."""

SUPPORTED_VSIM = [
"Model Technology ModelSim - INTEL FPGA STARTER EDITION vsim 2020.1 Simulator 2020.02 Feb 28 2020\n\n"
]

if which("vsim") is None:
print("!"*30)
print("WARNING: `vsim` executable not found.")
print("The autograder will fail when it attempts to run `vsim` later!")
print("!"*30)

else:
stdout = subprocess.run(["vsim", "-version"], capture_output=True, encoding="utf-8").stdout

if stdout not in SUPPORTED_VSIM:
print("!"*30)
print("WARNING: `vsim` is not a supported version for the grader tool.")
print(f"You're using version: {repr(stdout)}")
print("The autograder may fail when it attempts to run `vsim` later!")
print("!"*30)


# ----------------------------------------------------------
# MAIN
Expand All @@ -58,6 +76,8 @@ def main():

parser = argparse.ArgumentParser(description="Interactive ModelSim testbench runner for Digital Design labs.")

parser.add_argument('-v', '--version', action='version', version=f'DD_Grader {__version__}')

# Required arguments
# ----------------------------------------------------------
# Lab number
Expand Down Expand Up @@ -99,7 +119,7 @@ def main():

# Optional Flags (True if included, otherwise False)
# ----------------------------------------------------------
parser.add_argument("--gui", action="store_true", help="Show ModelSim window during simulation.")
# parser.add_argument("--gui", action="store_true", help="Show ModelSim window during simulation.")
parser.add_argument("--delete-zip", action="store_true", help="WARNING: Delete submissions.zip file when done.")
parser.add_argument("--debug", action="store_true", help="Developer: Display argparse tokens and exit.")

Expand Down Expand Up @@ -129,7 +149,6 @@ def main():

run_simulations(
students=students_with_submission,
gui=args.gui
)


Expand Down
10 changes: 5 additions & 5 deletions scripts/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ def extract_submissions(
Returns:
A new list of StudentData, which is a subset of section_students, that contains
student information of those who submitted a .zip file for the current Lab, and
therefore have an unzipped directory with their submission in Submissions/Labx.
therefore have an unzipped directory with their submission in submissions/Labx.
"""
# Create the unzipped Submissions directory, which will be used to store each students' source code.
SUBS_UNZIP_PATH = Path("Submissions/", lab_filename)
# Create the unzipped submissions directory, which will be used to store each students' source code.
SUBS_UNZIP_PATH = Path("submissions/", lab_filename)
SUBS_UNZIP_PATH.mkdir(parents=True, exist_ok=True)

with ZipFile(submissions_zip_path) as z:
Expand All @@ -57,7 +57,7 @@ def extract_submissions(
non_zip_files.append(file)

print(f"There should be {len(students_with_submission)} zip files in the submission dir.")
# Extract those students' .zip files into the Submissions/Labx dir.
# Extract those students' .zip files into the submissions/Labx dir.
z.extractall(SUBS_UNZIP_PATH, [s.zipped_submission for s in students_with_submission] + non_zip_files)

# For each student submission subdir, extract contents and copy all VHDL files to the top.
Expand All @@ -82,7 +82,7 @@ def extract_submissions(
print(e)
pass

# Remove the student submission .zip files from Submissions/Labx
# Remove the student submission .zip files from submissions/Labx
for student in students_with_submission: # TODO bug, in lab4 alexander barrera shows up twice. For some reason alex has two submissions, a zip and a pdf. weird.
# Path.unlink() removes the file
Path(SUBS_UNZIP_PATH, student.zipped_submission).unlink()
Expand Down
24 changes: 19 additions & 5 deletions scripts/run_simulations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,49 @@
from typing import List
from .student_data import StudentData

def run_simulations(students: List[StudentData], gui: bool) -> None:
# Run modelsim (-l "" disables ModelSim logging)
cmd = lambda gui, do_file: f"vsim {'-gui' if gui else '-c'} -l \"\" -do \"{do_file}\""
def run_simulations(students: List[StudentData]) -> None:

total_num_students = len(students)

for i, student in enumerate(students, start=1):
# restart = True
ran_once = False

while True:
# Whether to run the simulation in ModelSim GUI window, or in the CLI.
# This should reset every time the prompt is displayed.
gui = False

print()
print("-"*40)
print(f"({i}/{total_num_students}) {student.name}")
if ran_once:
print("- Press return to move to next student")
print("- Press r to rerun simulation") # Technically any unused key works too
print("- Press g to rerun simulation in the ModelSim GUI")
else:
print("- Press return to run simuation")
print("- Press return to run simuation") # Technically any unused key works too
print("- Press g to run simulation in the ModelSim GUI")
print("- Press n to skip this student")
print("- Press q to quit")
print("-"*40)

choice = input()
choice = input("> ")
if choice == "q":
return
elif ran_once and choice == "": # Pressed enter
break
elif choice == "n": # Skip this student
break
elif choice == "g":
gui = True
print("Notes about the GUI:")
print('- If prompted with "A project of this name already exists. Do you want to overwrite it?", select "Yes".')
print('- To spend more time in the GUI, select "No" when prompted to quit. The grader will continue to new students whenever you choose to quit the GUI.')

# Create the command to run modelsim
# Run modelsim (-l "" disables ModelSim logging)
cmd = lambda gui, do_file: f"vsim {'-gui' if gui else '-c'} -l \"\" -do \"{do_file}\""

# Run the simulation
subprocess.run(
Expand Down