Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • da/B-ASIC
  • lukja239/B-ASIC
  • robal695/B-ASIC
3 results
Show changes
......@@ -10,9 +10,10 @@ use ieee.numeric_std.all;
entity streaming_matrix_transposition_tester is
generic(
WL : integer;
ROWS : integer;
COLS : integer
WL : integer;
ROWS : integer;
COLS : integer;
ENABLE_DEL_CC : integer := 0 -- CCs after enable to start feeding the circuit
);
port(
clk, rst, en : out std_logic;
......@@ -40,21 +41,36 @@ begin
-- Input generation
input_gen_proc: process begin
wait until en = '1';
for i in 0 to ROWS*COLS-1 loop
wait for ENABLE_DEL_CC*10 ns;
for i in 0 to 4*ROWS*COLS-1 loop
wait until clk = '0';
input <= std_logic_vector(to_unsigned(i, input'length));
end loop;
wait;
end process;
-- Timeout test
timeout_test_proc: process begin
wait until en = '1';
wait for 1 ms;
report "Timeout failure: 1 ms passed after enable=1" severity failure;
end process;
-- Output testing
output_test_proc: process begin
wait until en = '1';
wait until output = std_logic_vector(to_unsigned(0, output'length));
for col in 0 to COLS-1 loop
for row in 0 to ROWS-1 loop
wait until clk = '0';
check(output = std_logic_vector(to_unsigned(row*COLS + col, output'length)));
for i in 0 to 3 loop
for col in 0 to COLS-1 loop
for row in 0 to ROWS-1 loop
wait until clk = '0';
check(
output =
std_logic_vector(
to_unsigned(i*ROWS*COLS + row*COLS + col, output'length)
)
);
end loop;
end loop;
end loop;
done <= true;
......@@ -63,6 +79,48 @@ begin
end architecture behav;
----------------------------------------------------------------------------------------
--- TEST INSTANCES ---
----------------------------------------------------------------------------------------
--
-- 2x2 memory based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_memory_2x2_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_memory_2x2_tb;
architecture behav of streaming_matrix_transposition_memory_2x2_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
signal clk, rst, en : std_logic;
begin
-- VUnit test runner
process begin
test_runner_setup(runner, runner_cfg);
wait until done = true;
test_runner_cleanup(runner);
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_memory_2x2
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>2, COLS=>2) port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 3x3 memory based matrix transposition
--
......@@ -101,21 +159,21 @@ begin
end architecture behav;
--
-- 4x8 memory based matrix transposition
-- 4x4 memory based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_memory_4x8_tb is
entity streaming_matrix_transposition_memory_4x4_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_memory_4x8_tb;
end entity streaming_matrix_transposition_memory_4x4_tb;
architecture behav of streaming_matrix_transposition_memory_4x8_tb is
architecture behav of streaming_matrix_transposition_memory_4x4_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
......@@ -130,13 +188,51 @@ begin
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_memory_4x8
dut : entity work.streaming_matrix_transposition_memory_4x4
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>4, COLS=>8) port map(clk, rst, en, input, output, done);
generic map (WL=>WL, ROWS=>4, COLS=>4, ENABLE_DEL_CC=>1)
port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 5x5 memory based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_memory_5x5_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_memory_5x5_tb;
architecture behav of streaming_matrix_transposition_memory_5x5_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
signal clk, rst, en : std_logic;
begin
-- VUnit test runner
process begin
test_runner_setup(runner, runner_cfg);
wait until done = true;
test_runner_cleanup(runner);
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_memory_5x5
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>5, COLS=>5, ENABLE_DEL_CC=>2)
port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 7x7 memory based matrix transposition
......@@ -171,27 +267,28 @@ begin
dut : entity work.streaming_matrix_transposition_memory_7x7
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>7, COLS=>7) port map(clk, rst, en, input, output, done);
generic map (WL=>WL, ROWS=>7, COLS=>7, ENABLE_DEL_CC=>3)
port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 7x7 register based matrix transposition
-- 4x8 memory based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_register_7x7_tb is
entity streaming_matrix_transposition_memory_4x8_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_register_7x7_tb;
end entity streaming_matrix_transposition_memory_4x8_tb;
architecture behav of streaming_matrix_transposition_register_7x7_tb is
architecture behav of streaming_matrix_transposition_memory_4x8_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
......@@ -206,29 +303,30 @@ begin
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_register_7x7
dut : entity work.streaming_matrix_transposition_memory_4x8
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>7, COLS=>7) port map(clk, rst, en, input, output, done);
generic map (WL=>WL, ROWS=>4, COLS=>8, ENABLE_DEL_CC=>2)
port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 5x5 register based matrix transposition
-- 2x2 register based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_register_5x5_tb is
entity streaming_matrix_transposition_register_2x2_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_register_5x5_tb;
end entity streaming_matrix_transposition_register_2x2_tb;
architecture behav of streaming_matrix_transposition_register_5x5_tb is
architecture behav of streaming_matrix_transposition_register_2x2_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
......@@ -243,10 +341,47 @@ begin
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_register_5x5
dut : entity work.streaming_matrix_transposition_register_2x2
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>5, COLS=>5) port map(clk, rst, en, input, output, done);
generic map (WL=>WL, ROWS=>2, COLS=>2) port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 3x3 register based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_register_3x3_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_register_3x3_tb;
architecture behav of streaming_matrix_transposition_register_3x3_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
signal clk, rst, en : std_logic;
begin
-- VUnit test runner
process begin
test_runner_setup(runner, runner_cfg);
wait until done = true;
test_runner_cleanup(runner);
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_register_3x3
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>3, COLS=>3) port map(clk, rst, en, input, output, done);
end architecture behav;
......@@ -287,23 +422,22 @@ begin
end architecture behav;
--
-- 3x3 register based matrix transposition
-- 5x5 register based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_register_3x3_tb is
entity streaming_matrix_transposition_register_5x5_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_register_3x3_tb;
end entity streaming_matrix_transposition_register_5x5_tb;
architecture behav of streaming_matrix_transposition_register_3x3_tb is
architecture behav of streaming_matrix_transposition_register_5x5_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
......@@ -318,29 +452,29 @@ begin
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_register_3x3
dut : entity work.streaming_matrix_transposition_register_5x5
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>3, COLS=>3) port map(clk, rst, en, input, output, done);
generic map (WL=>WL, ROWS=>5, COLS=>5) port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 2x2 register based matrix transposition
-- 7x7 register based matrix transposition
--
library ieee, vunit_lib;
context vunit_lib.vunit_context;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity streaming_matrix_transposition_register_2x2_tb is
entity streaming_matrix_transposition_register_7x7_tb is
generic (
runner_cfg : string; -- VUnit python pipe
tb_path : string -- Absolute path to this testbench
);
end entity streaming_matrix_transposition_register_2x2_tb;
end entity streaming_matrix_transposition_register_7x7_tb;
architecture behav of streaming_matrix_transposition_register_2x2_tb is
architecture behav of streaming_matrix_transposition_register_7x7_tb is
constant WL : integer := 16;
signal done : boolean;
signal input, output : std_logic_vector(WL-1 downto 0);
......@@ -355,14 +489,13 @@ begin
end process;
-- Run the test baby!
dut : entity work.streaming_matrix_transposition_register_2x2
dut : entity work.streaming_matrix_transposition_register_7x7
generic map(WL=>WL) port map(clk, rst, en, input, output);
tb : entity work.streaming_matrix_transposition_tester
generic map (WL=>WL, ROWS=>2, COLS=>2) port map(clk, rst, en, input, output, done);
generic map (WL=>WL, ROWS=>7, COLS=>7) port map(clk, rst, en, input, output, done);
end architecture behav;
--
-- 4x8 register based matrix transposition
--
......
This diff is collapsed.
......@@ -133,6 +133,17 @@ def signal_declaration(
)
def alias_declaration(
f: TextIO,
name: str,
signal_type: str,
value: Optional[str] = None,
name_pad: Optional[int] = None,
):
name_pad = name_pad or 0
write(f, 1, f'alias {name:<{name_pad}} : {signal_type} is {value};')
def constant_declaration(
f: TextIO,
name: str,
......
......@@ -43,7 +43,7 @@ def memory_based_storage(
write_lines(
f,
[
(0, '-- Clock, synchronous reset and enable signals'),
(2, '-- Clock, synchronous reset and enable signals'),
(2, 'clk : in std_logic;'),
(2, 'rst : in std_logic;'),
(2, 'en : in std_logic;'),
......@@ -53,9 +53,9 @@ def memory_based_storage(
# Write the input port specification
f.write(f'{2*VHDL_TAB}-- Memory port I/O\n')
read_ports: set[Port] = set(
read_ports: set[Port] = {
read_port for mv in collection for read_port in mv.read_ports
) # type: ignore
} # type: ignore
for idx, read_port in enumerate(read_ports):
port_name = read_port if isinstance(read_port, int) else read_port.name
port_name = 'p_' + str(port_name) + '_in'
......
......@@ -2,6 +2,7 @@ import io
import re
from collections import Counter, defaultdict
from functools import reduce
from math import log2
from typing import Dict, Iterable, List, Optional, Tuple, TypeVar, Union
import matplotlib.pyplot as plt
......@@ -97,9 +98,10 @@ def draw_exclusion_graph_coloring(
color_dict: Dict[Process, int],
ax: Optional[Axes] = None,
color_list: Optional[Union[List[str], List[Tuple[float, float, float]]]] = None,
**kwargs,
) -> None:
"""
Helper function for drawing a colored exclusion graphs.
Helper function for drawing colored exclusion graphs.
Example usage:
......@@ -131,6 +133,8 @@ def draw_exclusion_graph_coloring(
A Matplotlib :class:`~matplotlib.axes.Axes` object to draw the exclusion graph.
color_list : iterable of color, optional
A list of colors in Matplotlib format.
**kwargs : Any
Named arguments passed on to :func:`networkx.draw_networkx`
Returns
-------
......@@ -165,6 +169,7 @@ def draw_exclusion_graph_coloring(
node_color=node_color_list,
ax=ax,
pos=nx.spring_layout(exclusion_graph, seed=1),
**kwargs,
)
......@@ -497,6 +502,17 @@ class ProcessCollection:
else:
self.collection.remove(process)
def __contains__(self, process: Process) -> bool:
"""
Test if a process is part of this ProcessCollection
Parameters
----------
process : :class:`~b_asic.process.Process`
The process to test.
"""
return process in self.collection
def plot(
self,
ax: Optional[Axes] = None,
......@@ -1239,7 +1255,10 @@ class ProcessCollection:
read_ports: int = 1,
write_ports: int = 1,
total_ports: int = 2,
*,
input_sync: bool = True,
adr_mux_size: Optional[int] = None,
adr_pipe_depth: Optional[int] = None,
):
"""
Generate VHDL code for memory based storage of processes (MemoryVariables).
......@@ -1274,6 +1293,13 @@ class ProcessCollection:
Adding registers to the inputs allow pipelining of address generation
(which is added automatically). For large interleavers, this can improve
timing significantly.
adr_mux_size : int, optional
Size of multiplexer if using address generation pipelining. Set to `None`
for no multiplexer pipelining. If any other value than `None`, `input_sync`
must also be set.
adr_pipe_depth : int, optional
Depth of address generation pipelining. Set to `None` for no multiplexer
pipelining. If any other value than None, `input_sync` must also be set.
"""
# Check that entity name is a valid VHDL identifier
if not is_valid_vhdl_identifier(entity_name):
......@@ -1329,6 +1355,34 @@ class ProcessCollection:
' generate HDL for this ProcessCollection'
)
# Sanitize the address logic pipeline settings
if adr_mux_size is not None and adr_pipe_depth is not None:
if adr_mux_size < 1:
raise ValueError(
f'adr_mux_size={adr_mux_size} need to be greater than zero'
)
if adr_pipe_depth < 0:
raise ValueError(
f'adr_pipe_depth={adr_pipe_depth} needs to be non-negative'
)
if not input_sync:
raise ValueError('input_sync needs to be set to use address pipelining')
if not log2(adr_mux_size).is_integer():
raise ValueError(
f'adr_mux_size={adr_mux_size} needs to be interger power of two'
)
if adr_mux_size**adr_pipe_depth > assignment[0].schedule_time:
raise ValueError(
f'adr_mux_size={adr_mux_size}, adr_pipe_depth={adr_pipe_depth} => '
'more multiplexer inputs than schedule_time='
f'{assignment[0].schedule_time}'
)
else:
if adr_mux_size is not None or adr_pipe_depth is not None:
raise ValueError(
'both or none of adr_mux_size and adr_pipe_depth needs to be set'
)
with open(filename, 'w') as f:
from b_asic.codegen.vhdl import architecture, common, entity
......@@ -1346,6 +1400,8 @@ class ProcessCollection:
write_ports=write_ports,
total_ports=total_ports,
input_sync=input_sync,
adr_mux_size=1 if adr_mux_size is None else adr_mux_size,
adr_pipe_depth=0 if adr_pipe_depth is None else adr_pipe_depth,
)
def split_on_length(
......
......@@ -38,6 +38,15 @@ class TestProcessCollectionPlainMemoryVariable:
)
assert len(collection_split) == 3
def test_contains(self):
collection = ProcessCollection([], schedule_time=10, cyclic=True)
m1 = PlainMemoryVariable(0, 0, {0: 3})
assert m1 not in collection
collection.add_process(m1)
assert m1 in collection
collection.remove_process(m1)
assert m1 not in collection
def test_split_sequence_raises(self, simple_collection: ProcessCollection):
with pytest.raises(KeyError, match="processes in `sequence` must be"):
simple_collection.split_ports_sequentially(
......@@ -83,17 +92,33 @@ class TestProcessCollectionPlainMemoryVariable:
assert len(assignment_graph_color) == 16
def test_generate_memory_based_vhdl(self):
for rows in [2, 3, 4, 5, 7]:
collection = generate_matrix_transposer(rows, min_lifetime=0)
# fmt: off
variants = [
# rows , cols , #mux , #pipe #
# ------------------------------ #
( 2 , 2 , None , None ),
( 3 , 3 , 1 , 0 ),
( 4 , 4 , 4 , 1 ),
( 5 , 5 , 4 , 2 ),
( 7 , 7 , 4 , 3 ),
( 4 , 8 , 2 , 2 ),
]
# fmt: on
for rows, cols, mux_size, pipe_depth in variants:
collection = generate_matrix_transposer(
rows=rows, cols=cols, min_lifetime=0
)
assignment = collection.split_on_execution_time(heuristic="graph_color")
collection.generate_memory_based_storage_vhdl(
filename=(
'b_asic/codegen/testbench/'
f'streaming_matrix_transposition_memory_{rows}x{rows}.vhdl'
f'streaming_matrix_transposition_memory_{rows}x{cols}.vhdl'
),
entity_name=f'streaming_matrix_transposition_memory_{rows}x{rows}',
entity_name=f'streaming_matrix_transposition_memory_{rows}x{cols}',
assignment=assignment,
word_length=16,
adr_mux_size=mux_size,
adr_pipe_depth=pipe_depth,
)
def test_generate_register_based_vhdl(self):
......@@ -111,16 +136,6 @@ class TestProcessCollectionPlainMemoryVariable:
def test_rectangular_matrix_transposition(self):
collection = generate_matrix_transposer(rows=4, cols=8, min_lifetime=2)
assignment = collection.split_on_execution_time(heuristic="graph_color")
collection.generate_memory_based_storage_vhdl(
filename=(
'b_asic/codegen/testbench/streaming_matrix_transposition_memory_'
'4x8.vhdl'
),
entity_name='streaming_matrix_transposition_memory_4x8',
assignment=assignment,
word_length=16,
)
collection.generate_register_based_storage_vhdl(
filename=(
'b_asic/codegen/testbench/streaming_matrix_transposition_register_'
......