wk_LinProg/LinProg_Scripts/lib_vhdl_gen.py

616 lines
No EOL
21 KiB
Python

import xml.etree.ElementTree as ET
import warnings
template_task_in1_out1="""
T{process_num} : process (data_out({router_num}), local_stream_out({router_num}), local_tail_out({router_num}), array_of_task_send_instant_internal({router_num}), rst, clk)
constant task_num : natural := {Task_num};
constant router_num : natural := {router_num};
constant task_num_inPE : natural := {task_num_inPE_1};
variable n_1 : natural := 0;
variable do_fire_1 : boolean;
variable fire_count : natural;
variable p_vc : array_current_task(3 downto 0);
variable CS_current : current_task;
constant start_task : boolean := {start_task};
constant configure : boolean := {configure};
constant consume_task : boolean := {consume_task};
constant src_task_1 : natural := {src_task_1};
constant req_flits_1 : natural := {req_flits_1};
constant CS_in_1 : boolean := {CS_in_1};
constant dst_router_1 : natural := {dst_element_1};
constant snd_out : natural := {snd_out_1};
constant delay : time := {delay} ns;
constant max_repeat : natural := {max_repeat};
constant CS_out_1 : boolean := {CS_out_1};
begin
task_in1_out1(
name => "Task" & integer'image(task_num),
task_num => task_num,
start => start_task,
configure => configure,
consume_task => consume_task,
debug => {debug},
log_msg =>log_msg{process_num},
src_task_1 => src_task_1,
TH_1 => req_flits_1,
rec_sync => data_out(router_num),
vc_valid_in => local_vc_write_tx((router_num + 1) * 4 - 1 downto router_num * 4),
task_send_instant => array_of_task_send_instant_internal(router_num),
circuit_stream_in => local_stream_out(router_num),
circuit_tail_in => local_tail_out(router_num),
circuit_data_in => local_data_out(router_num),
CS_in_1 => CS_in_1,
dst_element_1 => dst_router_1,
snd_out => snd_out,
task_send_out_1 => array_of_array_task_send_in(router_num)(task_num_inPE),
CS_out_1 => CS_out_1,
delay => delay,
max_repeat => max_repeat,
n_1 => n_1,
do_fire_1 => do_fire_1,
fire_count => fire_count,
p_vc => p_vc,
CS_current => CS_current,
rst => rst,
clk => clk
);
end process T{process_num};
"""
template_Task_Module_top="""
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use std.textio.all;
use work.NOC_3D_PACKAGE.all;
use work.NoC_package.all;
use ieee.math_real.all;
use work.task_pkg.all;
use work.pkg_cp_model.all;
entity Task_Module_test is
generic (
noc_x_sync : integer := 4;
noc_y_sync : integer := 4;
noc_z_sync : integer := 3;
noc_x_async : integer := 4;
noc_y_async : integer := 4;
noc_z_async : integer := 3
);
port (
clk : in std_logic;
rst : in std_logic;
data_out : in flit_vector(noc_x_sync * noc_y_sync * noc_z_sync - 1 downto 0);
local_stream_out : in std_logic_vector (noc_x_async * noc_y_async * noc_z_async - 1 downto 0);
local_tail_out : in std_logic_vector (noc_x_async * noc_y_async * noc_z_async - 1 downto 0);
array_of_task_send_instant_internal : in array_task_send_instant (noc_x_async * noc_y_async * noc_z_async - 1 downto 0);
local_vc_write_tx : in std_logic_vector(noc_x_sync * noc_y_sync * noc_z_sync * 4 - 1 downto 0);
local_data_out : in arraycdata (noc_x_async*noc_y_async*noc_z_async-1 downto 0);
array_of_array_task_send_in : out array_of_array_task_send_5 (noc_x_async * noc_y_async * noc_z_async - 1 downto 0)
);
end entity Task_Module_test;
architecture rtl of Task_Module_test is
"""
template_Task_Module_bot="""
begin
FILE_WRITER_PROC : process
variable out_line : line;
file out_file : text;
variable status : file_open_status;
variable counter : integer := 0;
begin
file_open(status, out_file, "/home/sfischer/Documents/projects/wk_hybridNoC_VHDL/Results/raw_log.txt", write_mode);
loop
wait on {msg_log};
"""
template_Timeout="""
Timeout_PROC : process ({msg_log},clk)
variable counter : integer := 0;
begin
if clk'event then
counter:=counter+1;
else
counter:=0;
end if;
if counter >100000 then
assert false report "Simulation Failed due to timeout" severity failure;
end if;
end process;
"""
template_Task_Module_bot2="""
end loop;
end process;
"""
template_Task_Module_bottom="""
end architecture;
"""
template_task_in1_out2="""
T{process_num} : process (data_out({router_num}), local_stream_out({router_num}), local_tail_out({router_num}), array_of_task_send_instant_internal({router_num}), rst, clk)
constant task_num : natural := {Task_num};
constant router_num : natural := {router_num};
constant task_num_inPE_1 : natural := {task_num_inPE_1};
constant task_num_inPE_2 : natural := {task_num_inPE_2};
variable n_1 : natural := 0;
variable do_fire_1 : boolean;
variable fire_count : natural;
variable p_vc : array_current_task(3 downto 0);
variable CS_current : current_task;
constant start_task : boolean := {start_task};
constant configure : boolean := {configure};
constant consume_task : boolean := {consume_task};
constant src_task_1 : natural := {src_task_1};
constant req_flits_1 : natural := {req_flits_1};
constant CS_in_1 : boolean := {CS_in_1};
constant dst_router_1 : natural := {dst_element_1};
constant dst_router_2 : natural := {dst_element_2};
constant snd_out_1 : natural := {snd_out_1};
constant snd_out_2 : natural := {snd_out_2};
constant delay : time := {delay} ns;
constant max_repeat : natural := {max_repeat};
constant CS_out_1 : boolean := {CS_out_1};
constant CS_out_2 : boolean := {CS_out_2};
begin
task_in1_out2(
name => "Task" & integer'image(task_num),
task_num => task_num,
start => start_task,
configure => configure,
consume_task => consume_task,
debug => {debug},
log_msg =>log_msg{process_num},
src_task_1 => src_task_1,
TH_1 => req_flits_1,
rec_sync => data_out(router_num),
vc_valid_in => local_vc_write_tx((router_num + 1) * 4 - 1 downto router_num * 4),
task_send_instant => array_of_task_send_instant_internal(router_num),
circuit_stream_in => local_stream_out(router_num),
circuit_tail_in => local_tail_out(router_num),
circuit_data_in => local_data_out(router_num),
CS_in_1 => CS_in_1,
dst_element_1 => dst_router_1,
dst_element_2 => dst_router_2,
snd_out_1 => snd_out_1,
snd_out_2 => snd_out_2,
task_send_out_1 => array_of_array_task_send_in(router_num)(task_num_inPE_1),
task_send_out_2 => array_of_array_task_send_in(router_num)(task_num_inPE_2),
CS_out_1 => CS_out_1,
CS_out_2 => CS_out_2,
delay => delay,
max_repeat => max_repeat,
n_1 => n_1,
do_fire_1 => do_fire_1,
fire_count => fire_count,
p_vc => p_vc,
CS_current => CS_current,
rst => rst,
clk => clk
);
end process T{process_num};
"""
template_task_in2_out1="""
T{process_num} : process (data_out({router_num}), local_stream_out({router_num}), local_tail_out({router_num}), array_of_task_send_instant_internal({router_num}), rst, clk)
constant task_num : natural := {Task_num};
constant router_num : natural := {router_num};
constant task_num_inPE_1 : natural := {task_num_inPE_1};
variable n_1 : natural := 0;
variable n_2 : natural := 0;
variable do_fire_1 : boolean;
variable fire_count : natural;
variable p_vc : array_current_task(3 downto 0);
variable CS_current : current_task;
constant start_task : boolean := {start_task};
constant start_1 : boolean := {start_1};
constant start_2 : boolean := {start_2};
constant configure : boolean := {configure};
constant consume_task : boolean := {consume_task};
constant src_task_1 : natural := {src_task_1};
constant src_task_2 : natural := {src_task_2};
constant req_flits_1 : natural := {req_flits_1};
constant req_flits_2 : natural := {req_flits_2};
constant CS_in_1 : boolean := {CS_in_1};
constant CS_in_2 : boolean := {CS_in_2};
constant dst_router_1 : natural := {dst_element_1};
constant snd_out_1 : natural := {snd_out_1};
constant delay : time := {delay} ns;
constant max_repeat : natural := {max_repeat};
constant CS_out_1 : boolean := {CS_out_1};
begin
task_in2_out1(
name => "Task" & integer'image(task_num),
task_num => task_num,
start => start_task,
start_1 => start_1,
start_2 => start_2,
configure => configure,
consume_task => consume_task,
debug => {debug},
log_msg =>log_msg{process_num},
src_task_1 => src_task_1,
src_task_2 => src_task_2,
TH_1 => req_flits_1,
TH_2 => req_flits_2,
rec_sync => data_out(router_num),
vc_valid_in => local_vc_write_tx((router_num + 1) * 4 - 1 downto router_num * 4),
task_send_instant => array_of_task_send_instant_internal(router_num),
circuit_stream_in => local_stream_out(router_num),
circuit_tail_in => local_tail_out(router_num),
circuit_data_in => local_data_out(router_num),
CS_in_1 => CS_in_1,
CS_in_2 => CS_in_2,
dst_element_1 => dst_router_1,
snd_out_1 => snd_out_1,
task_send_out_1 => array_of_array_task_send_in(router_num)(task_num_inPE_1),
CS_out_1 => CS_out_1,
delay => delay,
max_repeat => max_repeat,
n_1 => n_1,
n_2 => n_2,
do_fire_1 => do_fire_1,
fire_count => fire_count,
p_vc => p_vc,
CS_current => CS_current,
rst => rst,
clk => clk
);
end process T{process_num};
"""
template_task_in2_out2="""
T{process_num} : process (data_out({router_num}), local_stream_out({router_num}), local_tail_out({router_num}), array_of_task_send_instant_internal({router_num}), rst, clk)
constant task_num : natural := {Task_num};
constant router_num : natural := {router_num};
constant task_num_inPE_1 : natural := {task_num_inPE_1};
constant task_num_inPE_2 : natural := {task_num_inPE_2};
variable n_1 : natural := 0;
variable n_2 : natural := 0;
variable do_fire_1 : boolean;
variable fire_count : natural;
variable p_vc : array_current_task(3 downto 0);
variable CS_current : current_task;
constant start_task : boolean := {start_task};
constant start_1 : boolean := {start_1};
constant start_2 : boolean := {start_2};
constant configure : boolean := {configure};
constant consume_task : boolean := {consume_task};
constant src_task_1 : natural := {src_task_1};
constant src_task_2 : natural := {src_task_2};
constant req_flits_1 : natural := {req_flits_1};
constant req_flits_2 : natural := {req_flits_2};
constant CS_in_1 : boolean := {CS_in_1};
constant CS_in_2 : boolean := {CS_in_2};
constant dst_router_1 : natural := {dst_element_1};
constant dst_router_2 : natural := {dst_element_2};
constant snd_out_1 : natural := {snd_out_1};
constant snd_out_2 : natural := {snd_out_2};
constant delay : time := {delay} ns;
constant max_repeat : natural := {max_repeat};
constant CS_out_1 : boolean := {CS_out_1};
constant CS_out_2 : boolean := {CS_out_2};
begin
task_in2_out2(
name => "Task" & integer'image(task_num),
task_num => task_num,
start => start_task,
start_1 => start_1,
start_2 => start_2,
configure => configure,
consume_task => consume_task,
debug => {debug},
log_msg =>log_msg{process_num},
src_task_1 => src_task_1,
src_task_2 => src_task_2,
TH_1 => req_flits_1,
TH_2 => req_flits_2,
rec_sync => data_out(router_num),
vc_valid_in => local_vc_write_tx((router_num + 1) * 4 - 1 downto router_num * 4),
task_send_instant => array_of_task_send_instant_internal(router_num),
circuit_stream_in => local_stream_out(router_num),
circuit_tail_in => local_tail_out(router_num),
circuit_data_in => local_data_out(router_num),
CS_in_1 => CS_in_1,
CS_in_2 => CS_in_2,
dst_element_1 => dst_router_1,
dst_element_2 => dst_router_2,
snd_out_1 => snd_out_1,
snd_out_2 => snd_out_2,
task_send_out_1 => array_of_array_task_send_in(router_num)(task_num_inPE_1),
task_send_out_2 => array_of_array_task_send_in(router_num)(task_num_inPE_2),
CS_out_1 => CS_out_1,
CS_out_2 => CS_out_2,
delay => delay,
max_repeat => max_repeat,
n_1 => n_1,
n_2 => n_2,
do_fire_1 => do_fire_1,
fire_count => fire_count,
p_vc => p_vc,
CS_current => CS_current,
rst => rst,
clk => clk
);
end process T{process_num};
"""
class Task:
def __init__(
self,
task_num,
process_num,
router_num,
task_num_inPE_1,
task_num_inPE_2,
start_task,
start_1,
start_2,
configure,
src_task_1,
src_task_2,
req_flits_1,
req_flits_2,
CS_in_1,
CS_in_2,
dst_element_1,
dst_element_2,
snd_out_1,
snd_out_2,
delay,
max_repeat,
CS_out_1,
CS_out_2,
dest_num,
src_num,
consume_task,
memory_bits,
func,
debug=False
):
self.task_num = task_num
self.process_num = process_num
self.router_num = router_num
self.task_num_inPE_1 = task_num_inPE_1
self.task_num_inPE_2 = task_num_inPE_2
self.start_task = start_task
self.configure = configure
self.src_task_1 = src_task_1
self.src_task_2 = src_task_2
self.req_flits_1 = req_flits_1
self.req_flits_2 = req_flits_2
self.CS_in_1 = CS_in_1
self.CS_in_2 = CS_in_2
self.dst_element_1 = dst_element_1
self.dst_element_2 = dst_element_2
self.snd_out_1 = snd_out_1
self.snd_out_2 = snd_out_2
self.delay = delay
self.max_repeat = max_repeat
self.CS_out_1 = CS_out_1
self.CS_out_2 = CS_out_2
self.debug = debug
self.dest_num=dest_num
self.src_num=src_num
self.consume_task=consume_task
self.start_1=start_1
self.start_2=start_2
self.memory_bits=memory_bits
self.func=func
def get_params(self):
return {
"Task_num": self.task_num,
"process_num": self.process_num,
"router_num": self.router_num,
"src_task_1": self.src_task_1,
"src_task_2": self.src_task_2,
"dst_element_1": self.dst_element_1,
"dst_element_2": self.dst_element_2,
"task_num_inPE_1": self.task_num_inPE_1,
"task_num_inPE_2": self.task_num_inPE_2,
"req_flits_1": self.req_flits_1,
"req_flits_2": self.req_flits_2,
"snd_out_1": self.snd_out_1,
"snd_out_2": self.snd_out_2,
"delay": self.delay,
"max_repeat": self.max_repeat,
"start_task": str(self.start_task).upper(),
"configure": str(self.configure).upper(),
"CS_out_1": str(self.CS_out_1).upper(),
"CS_out_2": str(self.CS_out_2).upper(),
"CS_in_1": str(self.CS_in_1).upper(),
"CS_in_2": str(self.CS_in_2).upper(),
"debug": str(self.debug).upper(),
"consume_task": str(self.consume_task).upper(),
"start_1": str(self.start_1).upper(),
"start_2": str(self.start_2).upper()
}
def task2memory_bits(task_num,map_additional_path):
"""
memory in map_addition saved as bytes with speedup factor
convert to bytes because gem5 expects memory in bytes
"""
float32_bits=32
prepend_str = """<root>\n"""
append_str = "\n</root>"
with open(map_additional_path, "r") as file:
original_content = file.read()
cleaned_content = original_content.replace('<?xml version="1.0" ?>', '').strip()
modified_content = prepend_str + cleaned_content + append_str
root = ET.fromstring(modified_content)
task_parameters=root.find("task_parameters")
task_parameters_list=[]
memory_data_bits=0
found=False
for bind in task_parameters:
node = bind.find('node')
if node is not None and node.attrib.get('value') == str(task_num):
list_string=bind.find('param_list').attrib.get('value')
exe_str="task_parameters_list+="+list_string
exec(exe_str)
found=True
for i in task_parameters_list:
for bind in root.find("map_parameters"):
param = bind.find('param')
size = bind.find('size')
if i==int(param.attrib.get('value')):
memory_data_bits+=int(size.attrib.get('value'))
memory_data_bits=memory_data_bits
return(memory_data_bits)
def write_to_file(filename, content):
"""
Writes content to the specified file. If the file exists, append content to the end.
Args:
filename (str): Path to the file.
content (str): The content to write to the file.
"""
try:
with open(filename, 'a') as file: # 'a' mode opens the file for appending
file.write(content + '\n') # Add a newline after the content
# print(f"Content added to {filename}")
except Exception as e:
print(f"An error occurred: {e}")
def update_xml_map(xml_file, task_to_node, output_file):
"""
Update the XML map to reflect the new task-to-node mappings.
Args:
xml_file (str): Input XML file path.
task_to_node (dict): Dictionary mapping tasks to nodes.
output_file (str): Output XML file path.
"""
# Parse the XML file
tree = ET.parse(xml_file)
root = tree.getroot()
# Iterate through <bind> elements and update node values
for bind in root.findall("bind"):
task = bind.find("task")
node = bind.find("node")
if task is not None and node is not None:
task_value = int(task.attrib["value"])
# Update node value based on the task_to_node mapping
if task_value in task_to_node:
node.attrib["value"] = str(task_to_node[task_value])
# Save the updated XML to the output file
tree.write(output_file, encoding="utf-8", xml_declaration=True)
print(f"Updated XML saved to {output_file}")
import random
def assign_nodes_to_tasks_unique(num_tasks, num_nodes):
"""
Randomly assign nodes to tasks while ensuring:
- Consecutive task pairs are mapped to the same node.
- Each node is assigned to only one pair of tasks.
Args:
num_tasks (int): Total number of tasks.
num_nodes (int): Total number of nodes.
Returns:
dict: A dictionary mapping tasks to nodes.
"""
if num_tasks % 2 != 0:
raise ValueError("Number of tasks must be even for pairwise mapping.")
if num_tasks // 2 > num_nodes:
raise ValueError("Not enough nodes to map task pairs uniquely.")
# Shuffle node IDs and map each pair to a unique node
nodes = list(range(num_nodes))
random.shuffle(nodes)
node_assignments = nodes[:num_tasks // 2]
# Create the task-to-node mapping
task_to_node = {}
for pair_index, node in enumerate(node_assignments):
task_to_node[pair_index * 2] = node # Assign the first task in the pair
task_to_node[pair_index * 2 + 1] = node # Assign the second task in the pair
return task_to_node