Compare commits

..

4 Commits

22 changed files with 722 additions and 174 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
**/wave **/wave
**/work **/work
**/syn

View File

@ -2,8 +2,8 @@
This repository is the public part of the thesis work created by Adam Magnusson and Erik Örtenberg at Chalmers Univerity of Technology. The work contained wihtin this repo details how a network interface will work, mostly built in VHDL. This repository is the public part of the thesis work created by Adam Magnusson and Erik Örtenberg at Chalmers Univerity of Technology. The work contained wihtin this repo details how a network interface will work, mostly built in VHDL.
# Tool instructions # Tool instructions
Building is facilitated by [Gantry](https://git.kryddan.xyz/kryddan/gantry). A dockerized version of GHDL is available in `scripts` Read the README.md in `./scripts`
# Build instructions # Build instructions
Enter `src/ganimede` and run `gantry elab ganimede_toplevel rtl` to build. Run `gantry run ganimede_toplevel_tb tb` to simulate and view wave forms of the project. TBW

6
scripts/README.md Normal file
View File

@ -0,0 +1,6 @@
# Installation
* Run `python -m venv .`
* Run `./bin/pip install -r requirements.txt`
# Running
* `./bin/python gantry.py --help` documents how it works

68
scripts/build_env.py Normal file
View File

@ -0,0 +1,68 @@
import os
from re import split
import subprocess
def getCfFileId(std: str):
return "08" if std == "08" else "93" ## Weird behaviour from GHDL, but all vhdl versions besides 08 have [...]93.cf
def ghdlEnvExists(std, lib):
## Check if work exists
try:
os.lstat("work")
except:
return False
## Check that work is writable
if not os.access("work", os.W_OK):
print("work is write-protected, please acquire correct permissions")
return False
cfFileExists = False
filesInWork = os.listdir("work")
cfFileId = getCfFileId(std)
for file in filesInWork:
if ".cf" in file and lib in file and cfFileId in file:
cfFileExists = True
if not cfFileExists:
return False
## Nothing bad, continue
return True
def createBuildEnv(std: str, lib: str):
if ghdlEnvExists(std=std, lib=lib):
print("Build environment already exists, exiting...")
return -1
## Create build env
print("Initializing GHDL project in current directory...")
os.makedirs("work",exist_ok=True)
addAllVHDLFiles(std=std, lib=lib, init=True)
return 0
def addAllVHDLFiles(std: str, lib: str, init=False):
## Ensure everything is ready for adding files
## (init exception to avoid one if-case in ghdlEnvExists)
if not ghdlEnvExists(std=std, lib=lib) and not init:
return -1
vhdlFiles = []
currentlyAdded = []
cfFileId = getCfFileId(std)
## Find already present files
if not init:
cfFileName = list(filter(lambda x: ".cf" in x and lib in x and cfFileId in x, os.listdir("work")))[0]
cfFilePath = os.path.join("work",cfFileName)
currentlyAdded = getCurrentlyAddedFiles(cfFilePath)
## Add files not added
for file in os.listdir():
if ".vhd" in file and file not in currentlyAdded:
vhdlFiles.append(file)
if len(vhdlFiles) > 0:
print(f"Detected new files. Adding {vhdlFiles}")
command = ["ghdl", "-i", "--workdir=work", f"--work={lib}", f"--std={std}"] + vhdlFiles
subprocess.run(command)
return 0
def getCurrentlyAddedFiles(cfFilePath:str):
f = open(cfFilePath,"r")
lines = f.readlines()
f.close()
fileLines = filter(lambda x: "file" in x, lines)
files = map(lambda x: split("\" \"",x)[1], fileLines)
return list(files)

4
scripts/dependecies.md Normal file
View File

@ -0,0 +1,4 @@
* GHDL = 4.1.0
* Python >= 3.0.0
* gtkwave >= v3.3.120

39
scripts/elab.py Normal file
View File

@ -0,0 +1,39 @@
import os
import subprocess
import build_env
from typing import List
def generateIncludesForGHDL(includes: List[str]):
cmd = []
for inc in includes:
cmd.append(f"-P{inc}/work")
return cmd
def elabDesign(topDef: str, arch: str, lib: str, std: str, includes: List[str]):
## Add all source files present in pwd
if build_env.addAllVHDLFiles(std, lib) == -1:
print("Adding files failed. GHDL Build environment may be broken...")
return -1
incs = generateIncludesForGHDL(includes)
command = [
"ghdl", "-m", "--workdir=work", f"--work={lib}", f"--std={std}"] + incs + ["-o", f"work/{topDef}-{arch}", f"work.{topDef}", f"{arch}"]
subprocess.run(command)
def runDesign(topDef: str, arch: str, lib: str, std: str, includes):
## elaborate first, then run
if elabDesign(topDef, arch, lib, std, includes) == -1:
print("Elaboration failed...")
return -1
os.makedirs("wave",exist_ok=True)
wavePath = "wave"
incs = generateIncludesForGHDL(includes)
command = [ ## may add -v for verbose
"ghdl", "--elab-run", f"--workdir=work", f"--work={lib}", f"--std={std}"] + incs + ["-o", f"work/{topDef}-{arch}", f"{topDef}", f"{arch}",
f"--wave=wave/{topDef}-{arch}.ghw" ##, "--read-wave-opt=<See"
]
subprocess.run(command)
command = [
"gtkwave", f"{topDef}-{arch}.ghw", "--rcvar",
"do_initial_zoom_fit yes"]
subprocess.run(command, cwd=wavePath)

87
scripts/gantry.py Normal file
View File

@ -0,0 +1,87 @@
import typer
import elab as elaborate
import build_env
from typing import List, Optional
from typing_extensions import Annotated
import subprocess
gantry_install_path = "/home/thesis2/exjobb-public/scripts"
app = typer.Typer()
software = typer.Typer()
hardware = typer.Typer()
app.add_typer(software, name="sim", help="GHDL simulator command group")
app.add_typer(hardware, name="syn", help="Synthesis and deployment command group")
def complete_vhdl_ver():
return ["87", "93", "93c", "00", "02", "08"]
@software.command(help="Initializes the GHDL build environment in a library named \"work\". Adds all files ending in \".vhd\" to the project")
def init(
std: Annotated[str, typer.Option(help="Which VHDL standard to use. 87, 93, 93c, 00, 02 or 08", autocompletion=complete_vhdl_ver)] = "93c",
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile from")] = "defaultLib",
):
return build_env.createBuildEnv(std, library)
@software.command(help="Runs analysis and elaboration on the provided top definition and architecture using GHDL. Automatically adds new files not present in the project")
def elab(
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
arch: Annotated[str, typer.Argument(help="Architecture to synthesize within the top definition provided")] = "",
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile from")] = "defaultLib",
includes: Annotated[Optional[List[str]], typer.Option("--include", "-i", help="Which libraries to include in compile")] = None,
std: Annotated[str, typer.Option(help="Which VHDL standard to use. 87, 93, 93c, 00, 02 or 08", autocompletion=complete_vhdl_ver)] = "93c"
):
print(f"Elaborating {topdef} with arch {arch} in library {library}. VHDL {std}.")
if includes is not None:
print(f"Including libraries: {includes}")
else:
includes = []
return elaborate.elabDesign(topdef, arch, library, std, includes)
@software.command(help="Simulates elaborated design in GHDL and views waves in gtkwave. Automatically runs `gantry elab` on the same top def and arch.")
def run(
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
arch: Annotated[str, typer.Argument(help="Architecture to synthesize within the top definition provided")] = "",
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile from")] = "defaultLib",
includes: Annotated[Optional[List[str]], typer.Option("--include", "-i", help="Which libraries to include in compile")] = None,
std: Annotated[str, typer.Option(help="Which VHDL standard to use. 87, 93, 93c, 00, 02 or 08", autocompletion=complete_vhdl_ver)] = "93c"
):
print(f"Running (and synthesizing if needed) {topdef} with arch {arch} in library {library}. VHDL {std}")
if includes is not None:
print(f"Including libraries: {includes}")
else:
includes = []
return elaborate.runDesign(topdef, arch, library, std, includes)
@hardware.command(help="Synthesizes the provided top level design using NXPython. Make sure you run this with NXPython.")
def synth(
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile from, defaults to \"work\"")] = "defaultLib"
):
proc = subprocess.run(["source_and_run.sh", f"{gantry_install_path}/nxp_script.py", "synthDesign", library, topdef])
@hardware.command(help="Places the provided top level design using NXPython. Make sure you run this with NXPython.")
def place(
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile from, defaults to \"work\"")] = "defaultLib"
):
proc = subprocess.run(["source_and_run.sh", f"{gantry_install_path}/nxp_script.py", "placeDesign", library, topdef])
@hardware.command(help="Routes the provided top level design using NXPython. Make sure you run this with NXPython.")
def route(
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile from, defaults to \"work\"")] = "defaultLib"
):
proc = subprocess.run(["source_and_run.sh", f"{gantry_install_path}/nxp_script.py", "routeDesign", library, topdef])
@hardware.command(help="")
def build():
print("Build!")
if __name__ == "__main__":
app()

View File

@ -1,6 +1,4 @@
#!/bin/bash #!/bin/bash
VARS="$@" VARS="$@"
COMMAND="ghdl $VARS" COMMAND="ghdl $VARS"
PROJ_HOME=/home/thesis1/repos/exjobb-public docker run -it -v .:/src -w /src ghdl/ghdl:5.0.0-dev-gcc-ubuntu-24.04 bash -c "$COMMAND"
RELPATH=$(realpath -m --relative-to="$PROJ_HOME" .)
docker run -it -v "$PROJ_HOME"/src:/src -w /"$RELPATH" ghdl/ghdl:5.0.0-dev-gcc-ubuntu-24.04 bash -c "$COMMAND"

9
scripts/install_gantry.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
PWD=$(pwd)
ESCAPED_PWD=$(printf '%s\n' "$PWD" | sed -e 's/[\/&]/\\&/g')
echo $ESCAPED_PWD
sed -i "0,/gantry_install_path =\"\"/s/gantry_install_path = \"\"/gantry_install_path = \"$ESCAPED_PWD\"/" gantry.py
printf "#!/bin/bash \n$PWD/bin/python3 $PWD/gantry.py \$@" > "$PWD/gantry"
chmod +x "$PWD/gantry"

81
scripts/nxp_script.py Normal file
View File

@ -0,0 +1,81 @@
import os
import subprocess
import build_env
import sys
import traceback
from nxpython import *
artifact_path = ""
# Evaluate whether we want the user to provide a selection of files
def makeProject(library: str, project_name: str, path):
# Create an Impulse project and add all VHDL files to it
print(path)
#Createproject enters the implicitly created directory
print(f"Creating project \'{project_name}\'\n")
getProject().setTopCellName(library, project_name)
getProject().setVariantName("NG-MEDIUM", "LGA-625")
getProject().addParameters({})
print(path)
listed = list(os.listdir(path))
files = list(filter(lambda x: ".vhdl" in x or ".vhd" in x or ".v\0" in x, listed)) # Find VHDL and Verilog files
files = list(map(lambda x: os.path.join(path, x), files))
print(f"Adding the following files to project: {files}\n")
getProject().addFiles(files)
print("Saving project")
getProject().save(os.path.join(artifact_path, project_name + ".nym"))
return 0
# Do we want the user to specify how far they want to progress wach step? What does the number mean?
def synthDesign(library: str, project_name: str, path):
# Synthesize the design of the project of the provided `project_name`
print("Starting synthesis\n")
try:
nymFile = os.path.join(artifact_path, project_name + ".nym")
os.lstat(nymFile)
getProject().loadNative(nymFile)
except:
print("No existing project found, creating new project\n")
makeProject(library, project_name, path)
getProject().loadNative(os.path.join(artifact_path, project_name + ".nym"))
getProject().progress("Synthesize", 3)
getProject().save(os.path.join(artifact_path, project_name + "-synth.nym"))
return 0
def placeDesign(library: str, project_name: str, path):
# Place the given design. Will use a previously synthesized project if available, otherwise one will be created.
print("Starting place\n")
try:
nymFile = os.path.join(artifact_path, project_name + "-synth.nym")
os.lstat(nymFile)
getProject().load(nymFile)
except:
print("No existing synthesis found, entering synthesis stage\n")
synthDesign(library, project_name, path)
getProject().load(os.path.join(artifact_path, project_name + "-synth.nym"))
getProject().progress("Place", 5)
getProject().save(os.path.join(artifact_path, project_name + "-place.nym"))
def routeDesign(library: str, project_name: str, path):
# Route the given design. Will use a previously placed project if available, otherwise one will be created.
print("Starting route\n")
try:
nymFile = os.path.join(artifact_path, project_name + "-place.nym")
os.lstat(nymFile)
getProject().load(nymFile)
except:
print("No existing place found, entering place stage\n")
placeDesign(library, project_name, path)
getProject().load(os.path.join(artifact_path, project_name + "-place.nym"))
getProject().progress("Route", 3)
getProject().save(os.path.join(artifact_path, project_name + "-route.nym"))
if __name__ == "__main__":
path = os.getcwd()
artifact_path = os.path.join(path, "syn")
print(f"Calling {sys.argv[1]}() with arguments {sys.argv[2]}, {sys.argv[3]}")
createProject(artifact_path)
globals()[sys.argv[1]](sys.argv[2], sys.argv[3], path)
getProject().createAnalyzer()
getProject().getAnalyzer().launch(conditions="worstcase", maximumSlack=0, searchPathsLimit=10, synthesisMode=False)

14
scripts/requirements.txt Normal file
View File

@ -0,0 +1,14 @@
attrs==21.4.0
click==8.0.4
commonmark==0.9.1
dataclasses==0.8
importlib-metadata==4.8.3
markdown-it-py==2.0.1
mdurl==0.1.0
Pygments==2.14.0
rich==12.6.0
shellingham==1.4.0
type-extensions==0.1.2
typer==0.10.0
typing_extensions==4.1.1
zipp==3.6.0

View File

@ -23,8 +23,8 @@ architecture tb of control_socbridge_tb is
control => (others => '0') control => (others => '0')
); );
signal socbridge_driver_to_ext : socbridge_driver_to_ext_t; signal socbridge_driver_to_ext : socbridge_driver_to_ext_t;
signal socbridge_driver_to_buffer : socbridge_driver_to_buffer_t; signal socbridge_driver_to_ip : socbridge_driver_to_ip_t;
signal buffer_to_socbridge_driver : buffer_to_socbridge_driver_t := ( signal ip_to_socbridge_driver : ip_to_socbridge_driver_t := (
payload => (others => '0'), payload => (others => '0'),
write_enable_out => '0', write_enable_out => '0',
is_full_in => '0' is_full_in => '0'
@ -35,9 +35,9 @@ architecture tb of control_socbridge_tb is
seq_mem_access_count => 0, seq_mem_access_count => 0,
cmd => "00" cmd => "00"
); );
signal socbridge_driver_to_controller: socbridge_driver_to_controller_t := (is_active => '0'); signal drivers_to_controller: drivers_to_controller_t := (socbridge => (is_active => '0'));
signal controller_to_cpu: controller_to_cpu_t; signal controller_to_cpu: controller_to_cpu_t;
signal controller_to_socbridge_driver: controller_to_socbridge_driver_t; signal controller_to_drivers: controller_to_drivers_t;
signal curr_word : std_logic_vector(ext_to_socbridge_driver.payload'length - 1 downto 0); signal curr_word : std_logic_vector(ext_to_socbridge_driver.payload'length - 1 downto 0);
signal expected_out : std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0); signal expected_out : std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0);
@ -80,12 +80,12 @@ begin
port map( port map(
clk => clk, clk => clk,
rst => rst, rst => rst,
controller_to_socbridge_driver => controller_to_socbridge_driver, controller_to_socbridge_driver => controller_to_drivers.socbridge,
socbridge_driver_to_controller => socbridge_driver_to_controller, socbridge_driver_to_controller => drivers_to_controller.socbridge,
ext_to_socbridge_driver => ext_to_socbridge_driver, ext_to_socbridge_driver => ext_to_socbridge_driver,
socbridge_driver_to_ext => socbridge_driver_to_ext, socbridge_driver_to_ext => socbridge_driver_to_ext,
buffer_to_socbridge_driver => buffer_to_socbridge_driver, ip_to_socbridge_driver => ip_to_socbridge_driver,
socbridge_driver_to_buffer => socbridge_driver_to_buffer socbridge_driver_to_ip => socbridge_driver_to_ip
); );
controller_unit_inst: entity controller.control_unit controller_unit_inst: entity controller.control_unit
@ -94,8 +94,8 @@ begin
rst => rst, rst => rst,
cpu_to_controller => cpu_to_controller, cpu_to_controller => cpu_to_controller,
controller_to_cpu => controller_to_cpu, controller_to_cpu => controller_to_cpu,
socbridge_driver_to_controller => socbridge_driver_to_controller, drivers_to_controller => drivers_to_controller,
controller_to_socbridge_driver => controller_to_socbridge_driver controller_to_drivers => controller_to_drivers
); );
ext_to_socbridge_driver.control(1) <= clk; ext_to_socbridge_driver.control(1) <= clk;
@ -121,21 +121,21 @@ begin
rst <= '0'; rst <= '0';
cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.address <= x"FA0FA0FA";
cpu_to_controller.cmd <= "01"; cpu_to_controller.cmd <= "01";
wait until socbridge_driver_to_controller.is_active = '1'; wait until drivers_to_controller.socbridge.is_active = '1';
report "Task received in driver, awaiting completion..."; report "Task received in driver, awaiting completion...";
cpu_to_controller.address <= (others => '0'); cpu_to_controller.address <= (others => '0');
cpu_to_controller.cmd <= "00"; cpu_to_controller.cmd <= "00";
wait until socbridge_driver_to_controller.is_active = '0'; wait until drivers_to_controller.socbridge.is_active = '0';
wait for CLK_PERIOD; wait for CLK_PERIOD;
report "Task completed in driver, sending next task..."; report "Task completed in driver, sending next task...";
cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.address <= x"FA0FA0FA";
cpu_to_controller.cmd <= "10"; cpu_to_controller.cmd <= "10";
wait for CLK_PERIOD; wait for CLK_PERIOD;
wait until socbridge_driver_to_controller.is_active = '1'; wait until drivers_to_controller.socbridge.is_active = '1';
report "Task received in driver, awaiting completion..."; report "Task received in driver, awaiting completion...";
cpu_to_controller.address <= (others => '0'); cpu_to_controller.address <= (others => '0');
cpu_to_controller.cmd <= "00"; cpu_to_controller.cmd <= "00";
wait until socbridge_driver_to_controller.is_active = '0'; wait until drivers_to_controller.socbridge.is_active = '0';
wait for CLK_PERIOD; wait for CLK_PERIOD;
report "Task completed in driver, ending simulation stimulus"; report "Task completed in driver, ending simulation stimulus";
cpu_to_controller.address <= (others => '0'); cpu_to_controller.address <= (others => '0');
@ -197,19 +197,19 @@ begin
internal_stimulus: process internal_stimulus: process
variable input : positive := 1; variable input : positive := 1;
begin begin
buffer_to_socbridge_driver.is_full_in <= '0'; ip_to_socbridge_driver.is_full_in <= '0';
buffer_to_socbridge_driver.write_enable_out <= '0'; ip_to_socbridge_driver.write_enable_out <= '0';
wait for 3 * CLK_PERIOD; wait for 3 * CLK_PERIOD;
-- stimulus goes here -- stimulus goes here
buffer_to_socbridge_driver.write_enable_out <= '1'; ip_to_socbridge_driver.write_enable_out <= '1';
buffer_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, buffer_to_socbridge_driver.payload'length)); ip_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, ip_to_socbridge_driver.payload'length));
input := input + 1 mod 256; input := input + 1 mod 256;
wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until rising_edge(clk) and socbridge_driver_to_ip.is_full_out = '0';
wait until falling_edge(clk); wait until falling_edge(clk);
for x in 0 to 1000 loop for x in 0 to 1000 loop
buffer_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, buffer_to_socbridge_driver.payload'length)); ip_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, ip_to_socbridge_driver.payload'length));
input := input + 1 mod 256; input := input + 1 mod 256;
wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until rising_edge(clk) and socbridge_driver_to_ip.is_full_out = '0';
wait until falling_edge(clk); wait until falling_edge(clk);
end loop; end loop;
wait; wait;

View File

@ -10,8 +10,8 @@ entity control_unit is
clk, rst : in std_logic; clk, rst : in std_logic;
cpu_to_controller : in cpu_to_controller_t; cpu_to_controller : in cpu_to_controller_t;
controller_to_cpu : out controller_to_cpu_t; controller_to_cpu : out controller_to_cpu_t;
socbridge_driver_to_controller : in socbridge_driver_to_controller_t; drivers_to_controller : in drivers_to_controller_t;
controller_to_socbridge_driver : out controller_to_socbridge_driver_t controller_to_drivers : out controller_to_drivers_t
); );
end entity control_unit; end entity control_unit;
@ -31,17 +31,17 @@ architecture behave of control_unit is
begin begin
comb_proc: process(cpu_to_controller, socbridge_driver_to_controller, state) comb_proc: process(cpu_to_controller, drivers_to_controller, state)
begin begin
ored := '0'; ored := '0';
ready_reduction: for i in 0 to number_of_drivers - 1 loop ready_reduction: for i in 0 to number_of_drivers - 1 loop
ored := ored or socbridge_driver_to_controller.is_active; ored := ored or drivers_to_controller.socbridge.is_active;
end loop ready_reduction; end loop ready_reduction;
controller_to_socbridge_driver.request <= state.curr_driver; controller_to_drivers.socbridge.request <= state.curr_driver;
controller_to_socbridge_driver.address <= state.address; controller_to_drivers.socbridge.address <= state.address;
controller_to_socbridge_driver.seq_mem_access_count <= state.seq_mem_access_count; controller_to_drivers.socbridge.seq_mem_access_count <= state.seq_mem_access_count;
controller_to_cpu.ready <= state.ready; controller_to_cpu.ready <= state.ready;
controller_to_socbridge_driver.instruction <= state.instruction; controller_to_drivers.socbridge.instruction <= state.instruction;
end process comb_proc; end process comb_proc;
sync_proc: process(clk, state) sync_proc: process(clk, state)

View File

@ -19,9 +19,9 @@ architecture tb of control_unit_tb is
(others => '0'), (others => '0'),
0, 0,
"00"); "00");
signal socbridge_driver_to_controller: socbridge_driver_to_controller_t := (is_active => '0'); signal drivers_to_controller: drivers_to_controller_t := (socbridge => (is_active => '0'));
signal controller_to_cpu: controller_to_cpu_t; signal controller_to_cpu: controller_to_cpu_t;
signal controller_to_socbridge_driver: controller_to_socbridge_driver_t; signal controller_to_drivers: controller_to_drivers_t;
signal current_driver : std_logic_vector(0 downto 0) := "0"; signal current_driver : std_logic_vector(0 downto 0) := "0";
shared variable word_counter: natural := 0; shared variable word_counter: natural := 0;
@ -42,8 +42,8 @@ begin
rst => reset, rst => reset,
cpu_to_controller => cpu_to_controller, cpu_to_controller => cpu_to_controller,
controller_to_cpu => controller_to_cpu, controller_to_cpu => controller_to_cpu,
socbridge_driver_to_controller => socbridge_driver_to_controller, drivers_to_controller => drivers_to_controller,
controller_to_socbridge_driver => controller_to_socbridge_driver controller_to_drivers => controller_to_drivers
); );
stimulus_proc: process stimulus_proc: process
@ -51,7 +51,7 @@ begin
wait for cycle; wait for cycle;
cpu_to_controller.driver_id <= "1"; cpu_to_controller.driver_id <= "1";
socbridge_driver_to_controller.is_active <= '0'; drivers_to_controller.socbridge.is_active <= '0';
cpu_to_controller.address <= x"F0F0F0F0"; cpu_to_controller.address <= x"F0F0F0F0";
cpu_to_controller.seq_mem_access_count <= 3; cpu_to_controller.seq_mem_access_count <= 3;
cpu_to_controller.cmd <= "01"; cpu_to_controller.cmd <= "01";
@ -65,7 +65,7 @@ begin
report "words remaining are " & integer'image(i); report "words remaining are " & integer'image(i);
end loop for_loop; end loop for_loop;
socbridge_driver_to_controller.is_active <= '0'; drivers_to_controller.socbridge.is_active <= '0';
report "Stim process done"; report "Stim process done";
wait; wait;
end process stimulus_proc; end process stimulus_proc;
@ -76,9 +76,9 @@ begin
wait for cycle; wait for cycle;
wait for cycle; wait for cycle;
assert controller_to_socbridge_driver.request = '1' report "Incorrect driver_id from control_unit" severity error; assert controller_to_drivers.socbridge.request = '1' report "Incorrect driver_id from control_unit" severity error;
assert controller_to_socbridge_driver.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; assert controller_to_drivers.socbridge.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error;
assert controller_to_socbridge_driver.instruction = WRITE report "Incorrect memory op from control_unit" severity error; assert controller_to_drivers.socbridge.instruction = WRITE report "Incorrect memory op from control_unit" severity error;
wait for 5 * cycle; wait for 5 * cycle;
reset <= '1'; reset <= '1';

View File

@ -1,24 +1,32 @@
library IEEE; library IEEE;
use IEEE.std_logic_1164.all; use IEEE.std_logic_1164.all;
library work; library ganimede;
use work.io_types.all; use ganimede.io_types.all;
library socbridge;
use socbridge.socbridge_driver_tb_pkg.all;
library controller;
entity ganimede is entity ganimede_toplevel is
port ( port (
clk : in std_logic; clk : in std_logic;
reset : in std_logic; rst : in std_logic;
ext_interface_in : in ext_interface_in_t; cpu_to_ganimede : in cpu_to_controller_t;
ext_interface_out : out ext_interface_out_t; ganimede_to_cpu : out controller_to_cpu_t;
int_interface_in : in int_interface_in_t; ext_to_ganimede : in ext_to_ganimede_t;
int_interface_out : out int_interface_out_t ganimede_to_ext : out ganimede_to_ext_t;
ip_to_ganimede : in ip_to_ganimede_t;
ganimede_to_ip : out ganimede_to_ip_t
); );
end entity ganimede; end entity ganimede_toplevel;
architecture rtl of ganimede is architecture rtl of ganimede_toplevel is
--- SIGNAL DECLERATIONS --- --- SIGNAL DECLERATIONS ---
signal gan_int_interface_in : int_interface_in_t; signal ext_to_drivers : ext_to_ganimede_t;
signal gan_int_interface_out : int_interface_out_t; signal drivers_to_ext : ganimede_to_ext_t;
signal gan_ext_interface_in : ext_interface_in_t; signal drivers_to_ip : ganimede_to_ip_t;
signal gan_ext_interface_out : ext_interface_out_t; signal ip_to_drivers : ip_to_ganimede_t;
signal drivers_to_controller : drivers_to_controller_t;
signal controller_to_drivers : controller_to_drivers_t;
--signal gan_socbridge_WE_in : std_logic; --signal gan_socbridge_WE_in : std_logic;
--signal gan_socbridge_WE_out : std_logic; --signal gan_socbridge_WE_out : std_logic;
@ -38,34 +46,34 @@ architecture rtl of ganimede is
-- data_out : out std_logic_vector(WIDTH - 1 downto 0) -- data_out : out std_logic_vector(WIDTH - 1 downto 0)
-- ); -- );
--end component; --end component;
component socbridge_driver is
port(
clk : in std_logic;
reset : in std_logic;
ext_in : in ext_to_socbridge_driver_t;
ext_out : out socbridge_driver_to_ext_t;
int_in : out buffer_to_socbridge_driver_t;
int_out : in socbridge_driver_to_buffer_t
);
end component;
begin begin
--- CONNECT EXTERNAL SIGNALS TO INTERNAL CONNECTIONS --- --- CONNECT EXTERNAL SIGNALS TO INTERNAL CONNECTIONS ---
gan_int_interface_in <= int_interface_in; ip_to_drivers <= ip_to_ganimede;
int_interface_out <= gan_int_interface_out; ganimede_to_ip <= drivers_to_ip;
gan_ext_interface_in <= ext_interface_in; ext_to_drivers <= ext_to_ganimede;
ext_interface_out <= gan_ext_interface_out; ganimede_to_ext <= drivers_to_ext;
--- DRIVER INSTANTIATION --- --- DRIVER INSTANTIATION ---
socbridge_driver_inst: socbridge_driver socbridge_inst: entity socbridge.socbridge_driver
port map( port map(
clk => clk, clk => clk,
reset => reset, rst => rst,
ext_in => gan_ext_interface_in.socbridge, controller_to_socbridge_driver => controller_to_drivers.socbridge,
ext_out => gan_ext_interface_out.socbridge, socbridge_driver_to_controller => drivers_to_controller.socbridge,
int_in => gan_int_interface_in.socbridge, ext_to_socbridge_driver => ext_to_ganimede.socbridge,
int_out => gan_int_interface_out.socbridge socbridge_driver_to_ext => ganimede_to_ext.socbridge,
ip_to_socbridge_driver => ip_to_ganimede.socbridge,
socbridge_driver_to_ip => ganimede_to_ip.socbridge
);
controller_unit_inst: entity controller.control_unit
port map(
clk => clk,
rst => rst,
cpu_to_controller => cpu_to_ganimede,
controller_to_cpu => ganimede_to_cpu,
drivers_to_controller => drivers_to_controller,
controller_to_drivers => controller_to_drivers
); );
--- LATER WE ADD OPTIMIZATIONS HERE --- --- LATER WE ADD OPTIMIZATIONS HERE ---

View File

@ -0,0 +1,215 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;
library ganimede;
use ganimede.io_types.all;
library socbridge;
use socbridge.socbridge_driver_tb_pkg.all;
library controller;
entity ganimede_tb is
end entity ganimede_tb;
architecture tb of ganimede_tb is
constant CLK_PERIOD : Time := 10 ns;
constant SIMULATION_CYCLE_COUNT : integer := 2000;
signal clk, rst : std_logic := '0';
signal controller_to_socbridge_driver_cmd : command_t;
signal controller_to_socbridge_driver_address : std_logic_vector(31 downto 0);
signal cmd_size : positive;
signal ext_to_ganimede : ext_to_ganimede_t := (socbridge => (
payload => (others => '0'),
control => (others => '0')
));
signal ganimede_to_ext : ganimede_to_ext_t;
signal ganimede_to_ip : ganimede_to_ip_t;
signal ganimede_to_cpu : controller_to_cpu_t;
signal cpu_to_ganimede : cpu_to_controller_t := (
driver_id => (others => '0'),
address => (others => '0'),
seq_mem_access_count => 0,
cmd => (others => '0')
);
signal ip_to_ganimede : ip_to_ganimede_t := (socbridge => (
payload => (others => '0'),
write_enable_out => '0',
is_full_in => '0'
));
signal cpu_to_controller: cpu_to_controller_t := (
driver_id => (others => '0'),
address => (others => '0'),
seq_mem_access_count => 0,
cmd => "00"
);
signal drivers_to_controller: drivers_to_controller_t := (socbridge => (is_active => '0'));
signal controller_to_cpu: controller_to_cpu_t;
signal controller_to_drivers: controller_to_drivers_t;
signal curr_word : std_logic_vector(ext_to_ganimede.socbridge.payload'length - 1 downto 0);
signal expected_out : std_logic_vector(ganimede_to_ext.socbridge.payload'length - 1 downto 0);
procedure fail(error_msg : string) is
begin
wait for CLK_PERIOD;
report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE;
end procedure;
procedure check_next_state(correct_state: state_t) is
begin
if(not (correct_state = G_next_state)) then
report "Next State is not what was expected, found " & state_t'image(G_next_state)
& " but expected " & state_t'image(correct_state) severity error;
fail("Next State");
end if;
end procedure;
procedure check_data_out(correct_data: std_logic_vector(ganimede_to_ext.socbridge.payload'length - 1 downto 0)) is
begin
if(not (correct_data = ganimede_to_ext.socbridge.payload)) then
report "Data out is not what was expected, found " & to_string(ganimede_to_ext.socbridge.payload)
& " but expected " & to_string(correct_data) severity error;
fail("Data out");
end if;
end procedure;
procedure check_parity(correct_data: std_logic_vector(ganimede_to_ext.socbridge.payload'length - 1 downto 0)) is
begin
if(not (calc_parity(correct_data) = calc_parity(ganimede_to_ext.socbridge.payload))) then
report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ganimede_to_ext.socbridge.payload))
& " but expected " & std_logic'image(calc_parity(correct_data)) severity error;
fail("Parity out");
end if;
end procedure;
begin
ganimede_inst: entity ganimede.ganimede_toplevel
port map(
clk => clk,
rst => rst,
cpu_to_ganimede => cpu_to_ganimede,
ganimede_to_cpu => ganimede_to_cpu,
ext_to_ganimede => ext_to_ganimede,
ganimede_to_ext => ganimede_to_ext,
ip_to_ganimede => ip_to_ganimede,
ganimede_to_ip => ganimede_to_ip
);
ext_to_ganimede.socbridge.control(1) <= clk;
controller_clock_proc: process
begin
for i in 0 to SIMULATION_CYCLE_COUNT - 1 loop
wait for CLK_PERIOD / 2;
clk <= not clk;
end loop;
wait;
end process controller_clock_proc;
stimulus_proc: process
begin
report "Starting Simulation Stimulus!";
rst <= '1';
cpu_to_controller.address <= (others => '0');
cpu_to_controller.cmd <= "00";
cpu_to_controller.driver_id <= "1";
cpu_to_controller.seq_mem_access_count <= 256;
wait for 3 * CLK_PERIOD;
report "Reset grace period ended, starting stimulus...";
rst <= '0';
cpu_to_controller.address <= x"FA0FA0FA";
cpu_to_controller.cmd <= "01";
wait until drivers_to_controller.socbridge.is_active = '1';
report "Task received in driver, awaiting completion...";
cpu_to_controller.address <= (others => '0');
cpu_to_controller.cmd <= "00";
wait until drivers_to_controller.socbridge.is_active = '0';
wait for CLK_PERIOD;
report "Task completed in driver, sending next task...";
cpu_to_controller.address <= x"FA0FA0FA";
cpu_to_controller.cmd <= "10";
wait for CLK_PERIOD;
wait until drivers_to_controller.socbridge.is_active = '1';
report "Task received in driver, awaiting completion...";
cpu_to_controller.address <= (others => '0');
cpu_to_controller.cmd <= "00";
wait until drivers_to_controller.socbridge.is_active = '0';
wait for CLK_PERIOD;
report "Task completed in driver, ending simulation stimulus";
cpu_to_controller.address <= (others => '0');
cpu_to_controller.cmd <= "00";
cpu_to_controller.driver_id <= "0";
cpu_to_controller.seq_mem_access_count <= 0;
wait;
end process stimulus_proc;
external_stimulus_signal: process(curr_word)
begin
ext_to_ganimede.socbridge.payload <= curr_word;
ext_to_ganimede.socbridge.control(0) <= calc_parity(curr_word);
end process external_stimulus_signal;
external_stimulus: process
variable input : positive := 1;
begin
wait for CLK_PERIOD / 1000;
curr_word <= "00000000";
wait for 999 * CLK_PERIOD / 1000;
wait for 2 * CLK_PERIOD;
wait for CLK_PERIOD / 2;
wait for 10* CLK_PERIOD;
curr_word <= "00001001";
wait for CLK_PERIOD;
curr_word <= "00000000";
wait for CLK_PERIOD * 140;
curr_word <= "00101001";
wait for CLK_PERIOD;
curr_word <= "00000000";
wait for CLK_PERIOD * 140;
curr_word <= "00101001";
wait for CLK_PERIOD;
curr_word <= "00000000";
wait for CLK_PERIOD * 20;
curr_word <= "01100111";
wait for CLK_PERIOD;
for x in 0 to 127 loop
curr_word <= std_logic_vector(to_unsigned(input, 8));
input := input + 1 mod 256;
wait for CLK_PERIOD;
end loop;
curr_word <= "00000000";
wait for CLK_PERIOD * 140;
wait for CLK_PERIOD * 20;
curr_word <= "01100111";
wait for CLK_PERIOD;
for x in 0 to 127 loop
curr_word <= std_logic_vector(to_unsigned(input, 8));
input := input + 1 mod 256;
wait for CLK_PERIOD;
end loop;
wait;
end process external_stimulus;
internal_stimulus: process
variable input : positive := 1;
begin
ip_to_ganimede.socbridge.is_full_in <= '0';
ip_to_ganimede.socbridge.write_enable_out <= '0';
wait for 3 * CLK_PERIOD;
-- stimulus goes here
ip_to_ganimede.socbridge.write_enable_out <= '1';
ip_to_ganimede.socbridge.payload <= std_logic_vector(to_unsigned(input, ip_to_ganimede.socbridge.payload'length));
input := input + 1 mod 256;
wait until rising_edge(clk) and ganimede_to_ip.socbridge.is_full_out = '0';
wait until falling_edge(clk);
for x in 0 to 1000 loop
ip_to_ganimede.socbridge.payload <= std_logic_vector(to_unsigned(input, ip_to_ganimede.socbridge.payload'length));
input := input + 1 mod 256;
wait until rising_edge(clk) and ganimede_to_ip.socbridge.is_full_out = '0';
wait until falling_edge(clk);
end loop;
wait;
end process internal_stimulus;
end architecture tb;

View File

@ -7,7 +7,6 @@ package io_types is
--- CONSTANTS --- --- CONSTANTS ---
constant number_of_drivers : natural := 1; constant number_of_drivers : natural := 1;
constant address_width : natural := 32; constant address_width : natural := 32;
constant seq_vector_length: natural := 8;
constant inst_word_width : natural := 2; constant inst_word_width : natural := 2;
--- STANDARD TYPES --- --- STANDARD TYPES ---
@ -35,17 +34,12 @@ package io_types is
ready : std_logic; ready : std_logic;
end record controller_to_cpu_t; end record controller_to_cpu_t;
--type controller_to_socbridge_driver_t is record --- PROTOCOL INFORMATION ---
-- driver_id: std_logic_vector(number_of_drivers - 1 downto 0); constant interface_inst : interface_inst_t := (
-- address: std_logic_vector(address_width - 1 downto 0); socbridge => ("SoCBridge ", 8, 2, 2)
-- seq_mem_access_count: integer; );
-- instruction: instruction_command_t;
--end record controller_to_socbridge_driver_t;
--type socbridge_driver_to_controller_t is record
-- active_driver: std_logic_vector(number_of_drivers - 1 downto 0);
--end record socbridge_driver_to_controller_t;
--- AUTOGENERATED TYPES ---
type socbridge_driver_to_controller_t is record type socbridge_driver_to_controller_t is record
is_active : std_logic; is_active : std_logic;
end record socbridge_driver_to_controller_t; end record socbridge_driver_to_controller_t;
@ -57,12 +51,6 @@ package io_types is
instruction : instruction_command_t; instruction : instruction_command_t;
end record controller_to_socbridge_driver_t; end record controller_to_socbridge_driver_t;
--- PROTOCOL INFORMATION ---
constant interface_inst : interface_inst_t := (
socbridge => ("SoCBridge ", 8, 2, 2)
);
--- AUTOGENERATED TYPES ---
type ext_to_socbridge_driver_t is record type ext_to_socbridge_driver_t is record
payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0);
control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0);
@ -73,30 +61,38 @@ package io_types is
control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0);
end record socbridge_driver_to_ext_t; end record socbridge_driver_to_ext_t;
type socbridge_driver_to_buffer_t is record type socbridge_driver_to_ip_t is record
payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0);
write_enable_in, is_full_out : std_logic; write_enable_in, is_full_out : std_logic;
end record socbridge_driver_to_buffer_t; end record socbridge_driver_to_ip_t;
type buffer_to_socbridge_driver_t is record type ip_to_socbridge_driver_t is record
payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0);
write_enable_out, is_full_in : std_logic; write_enable_out, is_full_in : std_logic;
end record buffer_to_socbridge_driver_t; end record ip_to_socbridge_driver_t;
type ext_interface_in_t is record type controller_to_drivers_t is record
socbridge : controller_to_socbridge_driver_t;
end record controller_to_drivers_t;
type drivers_to_controller_t is record
socbridge : socbridge_driver_to_controller_t;
end record drivers_to_controller_t;
type ext_to_ganimede_t is record
socbridge : ext_to_socbridge_driver_t; socbridge : ext_to_socbridge_driver_t;
end record ext_interface_in_t; end record ext_to_ganimede_t;
type ext_interface_out_t is record type ganimede_to_ext_t is record
socbridge : socbridge_driver_to_ext_t; socbridge : socbridge_driver_to_ext_t;
end record ext_interface_out_t; end record ganimede_to_ext_t;
type int_interface_out_t is record type ganimede_to_ip_t is record
socbridge : socbridge_driver_to_buffer_t; socbridge : socbridge_driver_to_ip_t;
end record int_interface_out_t; end record ganimede_to_ip_t;
type int_interface_in_t is record type ip_to_ganimede_t is record
socbridge : buffer_to_socbridge_driver_t; socbridge : ip_to_socbridge_driver_t;
end record int_interface_in_t; end record ip_to_ganimede_t;
end package io_types; end package io_types;

21
src/gantry.toml Normal file
View File

@ -0,0 +1,21 @@
title = "ganimede"
createdAt = "2025-03-14"
maintainer = ""
email = ""
version = "0.0.1"
[libraries.socbridge]
vhdl-version = "93"
path = "socbridge"
[libraries.ganimede]
vhdl-version = "93"
path = "ganimede"
[libraries.controller]
vhdl-version = "93"
path = "controller"
[libraries.control_socbridge_merge]
vhdl-version = "93"
path = "control_socbridge_merge"

View File

@ -15,8 +15,8 @@ entity socbridge_driver is
socbridge_driver_to_controller : out socbridge_driver_to_controller_t; socbridge_driver_to_controller : out socbridge_driver_to_controller_t;
ext_to_socbridge_driver : in ext_to_socbridge_driver_t; ext_to_socbridge_driver : in ext_to_socbridge_driver_t;
socbridge_driver_to_ext : out socbridge_driver_to_ext_t; socbridge_driver_to_ext : out socbridge_driver_to_ext_t;
socbridge_driver_to_buffer : out socbridge_driver_to_buffer_t; ip_to_socbridge_driver : in ip_to_socbridge_driver_t;
buffer_to_socbridge_driver : in buffer_to_socbridge_driver_t socbridge_driver_to_ip : out socbridge_driver_to_ip_t
); );
end entity socbridge_driver; end entity socbridge_driver;
@ -77,7 +77,7 @@ begin
READ_RESPONSE when "01000", READ_RESPONSE when "01000",
READ_RESPONSE when "01100", READ_RESPONSE when "01100",
NO_OP when others; NO_OP when others;
comb_proc: process(ext_to_socbridge_driver, buffer_to_socbridge_driver, curr_response, st, controller_to_socbridge_driver, trans_st) comb_proc: process(ext_to_socbridge_driver, ip_to_socbridge_driver, curr_response, st, controller_to_socbridge_driver, trans_st)
begin begin
-- Outputs -- Outputs
socbridge_driver_to_ext <= create_io_type_out_from_ext_protocol(st.socbridge_driver_to_ext_reg); socbridge_driver_to_ext <= create_io_type_out_from_ext_protocol(st.socbridge_driver_to_ext_reg);
@ -194,9 +194,9 @@ begin
--- Combinatorial output based on current state --- --- Combinatorial output based on current state ---
socbridge_driver_to_ext_data_cmd := (others => '0'); socbridge_driver_to_ext_data_cmd := (others => '0');
socbridge_driver_to_buffer.is_full_out <= '1'; socbridge_driver_to_ip.is_full_out <= '1';
socbridge_driver_to_buffer.write_enable_in <= '0'; socbridge_driver_to_ip.write_enable_in <= '0';
socbridge_driver_to_buffer.payload <= (others => '0'); socbridge_driver_to_ip.payload <= (others => '0');
case st.curr_state is case st.curr_state is
when IDLE => when IDLE =>
if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then
@ -209,13 +209,13 @@ begin
if st.curr_cmd = WRITE_ADD then if st.curr_cmd = WRITE_ADD then
socbridge_driver_to_ext_data_cmd := st.curr_addr(7 downto 0); socbridge_driver_to_ext_data_cmd := st.curr_addr(7 downto 0);
else else
socbridge_driver_to_ext_data_cmd := buffer_to_socbridge_driver.payload; socbridge_driver_to_ext_data_cmd := ip_to_socbridge_driver.payload;
socbridge_driver_to_buffer.is_full_out <= '0'; socbridge_driver_to_ip.is_full_out <= '0';
end if; end if;
when TX_BODY => when TX_BODY =>
if st.write_stage > 0 then if st.write_stage > 0 then
socbridge_driver_to_buffer.is_full_out <= '0'; socbridge_driver_to_ip.is_full_out <= '0';
socbridge_driver_to_ext_data_cmd := buffer_to_socbridge_driver.payload; socbridge_driver_to_ext_data_cmd := ip_to_socbridge_driver.payload;
else else
socbridge_driver_to_ext_data_cmd := (others => '0'); socbridge_driver_to_ext_data_cmd := (others => '0');
end if; end if;
@ -226,8 +226,8 @@ begin
end if; end if;
when RX_RESPONSE => when RX_RESPONSE =>
when RX_BODY => when RX_BODY =>
socbridge_driver_to_buffer.payload <= st.ext_to_socbridge_driver_reg.data; socbridge_driver_to_ip.payload <= st.ext_to_socbridge_driver_reg.data;
socbridge_driver_to_buffer.write_enable_in <= '1'; socbridge_driver_to_ip.write_enable_in <= '1';
when ADDR1 => when ADDR1 =>
socbridge_driver_to_ext_data_cmd := st.curr_addr(15 downto 8); socbridge_driver_to_ext_data_cmd := st.curr_addr(15 downto 8);
when ADDR2 => when ADDR2 =>
@ -236,9 +236,9 @@ begin
socbridge_driver_to_ext_data_cmd := st.curr_addr(31 downto 24); socbridge_driver_to_ext_data_cmd := st.curr_addr(31 downto 24);
when ADDR4 => when ADDR4 =>
if st.curr_cmd = WRITE_ADD then if st.curr_cmd = WRITE_ADD then
socbridge_driver_to_buffer.is_full_out <= '0'; socbridge_driver_to_ip.is_full_out <= '0';
socbridge_driver_to_ext_data_cmd := buffer_to_socbridge_driver.payload; socbridge_driver_to_ext_data_cmd := ip_to_socbridge_driver.payload;
report integer'image(to_integer(signed(socbridge_driver_to_ext_data_cmd))) & " "& integer'image(to_integer(signed(buffer_to_socbridge_driver.payload))); report integer'image(to_integer(signed(socbridge_driver_to_ext_data_cmd))) & " "& integer'image(to_integer(signed(ip_to_socbridge_driver.payload)));
end if; end if;
end case; end case;
next_parity_out <= calc_parity(socbridge_driver_to_ext_data_cmd); next_parity_out <= calc_parity(socbridge_driver_to_ext_data_cmd);

View File

@ -19,8 +19,8 @@ architecture tb of socbridge_driver_tb is
signal cmd_size : positive; signal cmd_size : positive;
signal ext_to_socbridge_driver : ext_to_socbridge_driver_t; signal ext_to_socbridge_driver : ext_to_socbridge_driver_t;
signal socbridge_driver_to_ext : socbridge_driver_to_ext_t; signal socbridge_driver_to_ext : socbridge_driver_to_ext_t;
signal buffer_to_socbridge_driver : buffer_to_socbridge_driver_t; signal ip_to_socbridge_driver : ip_to_socbridge_driver_t;
signal socbridge_driver_to_buffer : socbridge_driver_to_buffer_t; signal socbridge_driver_to_ip : socbridge_driver_to_ip_t;
signal controller_to_socbridge_driver : controller_to_socbridge_driver_t; signal controller_to_socbridge_driver : controller_to_socbridge_driver_t;
signal socbridge_driver_controller : socbridge_driver_to_controller_t; signal socbridge_driver_controller : socbridge_driver_to_controller_t;
signal curr_word : std_logic_vector(ext_to_socbridge_driver.payload'length - 1 downto 0); signal curr_word : std_logic_vector(ext_to_socbridge_driver.payload'length - 1 downto 0);
@ -71,8 +71,8 @@ architecture tb of socbridge_driver_tb is
-- cmd_size: in positive; -- cmd_size: in positive;
-- ext_to_socbridge_driver : in ext_to_socbridge_driver_t; -- ext_to_socbridge_driver : in ext_to_socbridge_driver_t;
-- socbridge_driver_to_ext : out socbridge_driver_to_ext_t; -- socbridge_driver_to_ext : out socbridge_driver_to_ext_t;
-- buffer_to_socbridge_driver : out buffer_to_socbridge_driver_t; -- ip_to_socbridge_driver : out ip_to_socbridge_driver_t;
-- socbridge_driver_to_buffer : in socbridge_driver_to_buffer_t -- socbridge_driver_to_ip : in socbridge_driver_to_ip_t
-- ); -- );
-- end component socbridge_driver; -- end component socbridge_driver;
@ -85,8 +85,8 @@ begin
socbridge_driver_to_controller => socbridge_driver_controller, socbridge_driver_to_controller => socbridge_driver_controller,
ext_to_socbridge_driver => ext_to_socbridge_driver, ext_to_socbridge_driver => ext_to_socbridge_driver,
socbridge_driver_to_ext => socbridge_driver_to_ext, socbridge_driver_to_ext => socbridge_driver_to_ext,
buffer_to_socbridge_driver => buffer_to_socbridge_driver, ip_to_socbridge_driver => ip_to_socbridge_driver,
socbridge_driver_to_buffer => socbridge_driver_to_buffer socbridge_driver_to_ip => socbridge_driver_to_ip
); );
ext_to_socbridge_driver.control(1) <= clk; ext_to_socbridge_driver.control(1) <= clk;
@ -299,30 +299,30 @@ begin
internal_stimulus: process internal_stimulus: process
begin begin
buffer_to_socbridge_driver.is_full_in <= '0'; ip_to_socbridge_driver.is_full_in <= '0';
buffer_to_socbridge_driver.write_enable_out <= '0'; ip_to_socbridge_driver.write_enable_out <= '0';
wait for 3 * CLK_PERIOD; wait for 3 * CLK_PERIOD;
-- stimulus goes here -- stimulus goes here
buffer_to_socbridge_driver.write_enable_out <= '1'; ip_to_socbridge_driver.write_enable_out <= '1';
buffer_to_socbridge_driver.payload <= "00000001"; ip_to_socbridge_driver.payload <= "00000001";
wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until rising_edge(clk) and socbridge_driver_to_ip.is_full_out = '0';
wait until falling_edge(clk); wait until falling_edge(clk);
buffer_to_socbridge_driver.payload <= "00000010"; ip_to_socbridge_driver.payload <= "00000010";
wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until rising_edge(clk) and socbridge_driver_to_ip.is_full_out = '0';
wait until falling_edge(clk); wait until falling_edge(clk);
buffer_to_socbridge_driver.payload <= "00000100"; ip_to_socbridge_driver.payload <= "00000100";
wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until rising_edge(clk) and socbridge_driver_to_ip.is_full_out = '0';
wait until falling_edge(clk); wait until falling_edge(clk);
buffer_to_socbridge_driver.payload <= "00001000"; ip_to_socbridge_driver.payload <= "00001000";
wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until rising_edge(clk) and socbridge_driver_to_ip.is_full_out = '0';
wait until falling_edge(clk); wait until falling_edge(clk);
buffer_to_socbridge_driver.payload <= "00010000"; ip_to_socbridge_driver.payload <= "00010000";
wait until socbridge_driver_to_buffer.is_full_out = '0'; wait until socbridge_driver_to_ip.is_full_out = '0';
wait for CLK_PERIOD/2; wait for CLK_PERIOD/2;
wait until rising_edge(clk); wait until rising_edge(clk);
wait until rising_edge(clk); wait until rising_edge(clk);
buffer_to_socbridge_driver.payload <= "00100000"; ip_to_socbridge_driver.payload <= "00100000";
wait until socbridge_driver_to_buffer.is_full_out = '0'; wait until socbridge_driver_to_ip.is_full_out = '0';
wait for CLK_PERIOD/2; wait for CLK_PERIOD/2;
wait until rising_edge(clk); wait until rising_edge(clk);
wait until rising_edge(clk); --- ??? Why all these rising_edge checks? wait until rising_edge(clk); --- ??? Why all these rising_edge checks?

View File

@ -3,7 +3,8 @@ standard = "1993"
# File names are either absolute or relative to the parent folder of the vhdl_ls.toml file # File names are either absolute or relative to the parent folder of the vhdl_ls.toml file
[libraries] [libraries]
ganimede.files = [ ganimede.files = [
'ganimede/io_type_pkg.vhd' 'ganimede/io_type_pkg.vhd',
'ganimede/ganimede.vhd'
] ]
socbridge.files = [ socbridge.files = [
'socbridge/*.vhd' 'socbridge/*.vhd'