Refactor img_conv and tb_img_conv: enhance state management, improve signal handling, and add varied memory initialization for convolution processing

This commit is contained in:
2025-04-20 00:37:40 +02:00
parent a054085341
commit 47fca59a97
3 changed files with 616 additions and 190 deletions

View File

@@ -17,90 +17,132 @@
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
USE IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity img_conv_tb is
-- Port ( );
end img_conv_tb;
ENTITY img_conv_tb IS
-- Port ( );
END img_conv_tb;
architecture Behavioral of img_conv_tb is
ARCHITECTURE Behavioral OF img_conv_tb IS
component img_conv is
generic(
LOG2_N_COLS: POSITIVE :=8;
LOG2_N_ROWS: POSITIVE :=8
COMPONENT img_conv IS
GENERIC (
LOG2_N_COLS : POSITIVE := 8;
LOG2_N_ROWS : POSITIVE := 8
);
port (
clk : in std_logic;
aresetn : in std_logic;
m_axis_tdata : out std_logic_vector(7 downto 0);
m_axis_tvalid : out std_logic;
m_axis_tready : in std_logic;
m_axis_tlast : out std_logic;
conv_addr: out std_logic_vector(LOG2_N_COLS+LOG2_N_ROWS-1 downto 0);
conv_data: in std_logic_vector(6 downto 0);
start_conv: in std_logic;
done_conv: out std_logic
PORT (
clk : IN STD_LOGIC;
aresetn : IN STD_LOGIC;
m_axis_tdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
m_axis_tvalid : OUT STD_LOGIC;
m_axis_tready : IN STD_LOGIC;
m_axis_tlast : OUT STD_LOGIC;
conv_addr : OUT STD_LOGIC_VECTOR(LOG2_N_COLS + LOG2_N_ROWS - 1 DOWNTO 0);
conv_data : IN STD_LOGIC_VECTOR(6 DOWNTO 0);
start_conv : IN STD_LOGIC;
done_conv : OUT STD_LOGIC
);
end component;
END COMPONENT;
constant LOG2_N_COLS: POSITIVE :=2;
constant LOG2_N_ROWS: POSITIVE :=2;
CONSTANT LOG2_N_COLS : POSITIVE := 2;
CONSTANT LOG2_N_ROWS : POSITIVE := 2;
type mem_type is array(0 to (2**LOG2_N_COLS)*(2**LOG2_N_ROWS)-1) of std_logic_vector(6 downto 0);
TYPE mem_type IS ARRAY(0 TO (2 ** LOG2_N_COLS) * (2 ** LOG2_N_ROWS) - 1) OF STD_LOGIC_VECTOR(6 DOWNTO 0);
signal mem : mem_type := (0=>"0000001",others => (others => '0'));
-- Fill memory with more varied values
SIGNAL mem : mem_type := (
0 => "0000001",
1 => "0101010",
2 => "0011100",
3 => "1110001",
4 => "0001011",
5 => "0110110",
6 => "1001001",
7 => "1111111",
8 => "0000111",
9 => "0010010",
10 => "0100101",
11 => "0111000",
12 => "1001100",
13 => "1011011",
14 => "1100110",
15 => "1010101"
);
signal clk : std_logic :='0';
signal aresetn : std_logic :='0';
SIGNAL clk : STD_LOGIC := '0';
SIGNAL aresetn : STD_LOGIC := '0';
signal m_axis_tdata : std_logic_vector(7 downto 0);
signal m_axis_tvalid : std_logic;
signal m_axis_tready : std_logic;
signal m_axis_tlast : std_logic;
signal conv_addr: std_logic_vector(LOG2_N_COLS+LOG2_N_ROWS-1 downto 0);
signal conv_data: std_logic_vector(6 downto 0);
SIGNAL m_axis_tdata : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL m_axis_tvalid : STD_LOGIC;
SIGNAL m_axis_tready : STD_LOGIC;
SIGNAL m_axis_tlast : STD_LOGIC;
signal start_conv: std_logic;
signal done_conv: std_logic;
SIGNAL conv_addr : STD_LOGIC_VECTOR(LOG2_N_COLS + LOG2_N_ROWS - 1 DOWNTO 0);
SIGNAL conv_data : STD_LOGIC_VECTOR(6 DOWNTO 0);
begin
SIGNAL start_conv : STD_LOGIC;
SIGNAL done_conv : STD_LOGIC;
m_axis_tready<='1';
SIGNAL tready_block_req : STD_LOGIC := '0';
clk <= not clk after 5 ns;
BEGIN
process (clk)
begin
if(rising_edge(clk)) then
conv_data<=mem(to_integer(unsigned(conv_addr)));
end if;
end process;
-- m_axis_tready logic with blocking step
PROCESS (clk)
VARIABLE block_counter : INTEGER := 0;
VARIABLE tready_blocked : BOOLEAN := FALSE;
BEGIN
IF rising_edge(clk) THEN
IF tready_block_req = '1' AND NOT tready_blocked THEN
tready_blocked := TRUE;
block_counter := 0;
END IF;
img_conv_inst: img_conv
generic map(
IF tready_blocked THEN
IF block_counter < 19 THEN
m_axis_tready <= '0';
block_counter := block_counter + 1;
ELSE
m_axis_tready <= '1';
tready_blocked := FALSE;
block_counter := 0;
END IF;
ELSE
m_axis_tready <= '1';
END IF;
END IF;
END PROCESS;
clk <= NOT clk AFTER 5 ns;
PROCESS (clk)
BEGIN
IF (rising_edge(clk)) THEN
conv_data <= mem(to_integer(unsigned(conv_addr)));
END IF;
END PROCESS;
img_conv_inst : img_conv
GENERIC MAP(
LOG2_N_COLS => LOG2_N_COLS,
LOG2_N_ROWS => LOG2_N_ROWS
)
port map(
PORT MAP(
clk => clk,
aresetn => aresetn,
m_axis_tdata => m_axis_tdata,
@@ -113,16 +155,31 @@ begin
done_conv => done_conv
);
process
begin
wait for 10 ns;
aresetn<='1';
wait until rising_edge(clk);
start_conv<='1';
wait until rising_edge(clk);
start_conv<='0';
wait;
end process;
PROCESS
BEGIN
WAIT FOR 10 ns;
aresetn <= '1';
WAIT UNTIL rising_edge(clk);
start_conv <= '1';
WAIT UNTIL rising_edge(clk);
start_conv <= '0';
-- Wait some cycles, then request tready block for 10 cycles
WAIT FOR 200 ns;
tready_block_req <= '1';
WAIT UNTIL rising_edge(clk);
tready_block_req <= '0';
end Behavioral;
WAIT FOR 300 ns;
tready_block_req <= '1';
WAIT UNTIL rising_edge(clk);
tready_block_req <= '0';
WAIT FOR 200 ns;
tready_block_req <= '1';
WAIT UNTIL rising_edge(clk);
tready_block_req <= '0';
WAIT;
END PROCESS;
END Behavioral;

View File

@@ -27,150 +27,314 @@ ENTITY img_conv IS
END ENTITY img_conv;
ARCHITECTURE rtl OF img_conv IS
TYPE conv_mat_type IS ARRAY(0 TO 2, 0 TO 2) OF INTEGER;
CONSTANT conv_mat : conv_mat_type := ((-1, -1, -1),(-1, 8, -1),(-1, -1, -1));
CONSTANT conv_mat : conv_mat_type := ((-1, -1, -1), (-1, 8, -1), (-1, -1, -1));
-- Definizione della finestra 3x3; ogni pixel <20> rappresentato da 8 bit
TYPE window_array IS ARRAY(0 TO 2, 0 TO 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL window : window_array := (OTHERS => (OTHERS => (OTHERS => '0')));
TYPE offset_array IS ARRAY(0 TO 2) OF INTEGER;
CONSTANT offset : offset_array := (-1, 0, 1);
-- Parametri immagine
CONSTANT IMG_WIDTH : INTEGER := 2 ** LOG2_N_COLS; -- Larghezza dell'immagine
CONSTANT IMG_HEIGHT : INTEGER := 2 ** LOG2_N_ROWS; -- Altezza dell'immagine
-- Indirizzo corrente per la lettura dei pixel
SIGNAL current_addr : STD_LOGIC_VECTOR(LOG2_N_COLS + LOG2_N_ROWS - 1 DOWNTO 0);
-- Variabili per il calcolo della convoluzione
SIGNAL conv_sum : INTEGER := 0; -- Somma dei prodotti
SIGNAL conv_out : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Risultato della convoluzione
-- Stato della macchina a stati
TYPE state_type IS (IDLE, LOAD_PIXEL, COMPUTE, OUTPUT);
TYPE state_type IS (IDLE, START_CONVOLUTING, CONVOLUTING, WAIT_READY);
SIGNAL state : state_type := IDLE;
-- Contatori per riga e colonna
SIGNAL row, col : INTEGER RANGE 0 TO IMG_HEIGHT - 1 := 0;
SIGNAL col : UNSIGNED(LOG2_N_COLS - 1 DOWNTO 0) := (OTHERS => '0');
SIGNAL row : UNSIGNED(LOG2_N_ROWS - 1 DOWNTO 0) := (OTHERS => '0');
SIGNAL col_mat_idx_prv : INTEGER := 0;
SIGNAL row_mat_idx_prv : INTEGER := 0;
SIGNAL col_mat_idx : INTEGER := 0;
SIGNAL row_mat_idx : INTEGER := 0;
SIGNAL col_mat_idx_nxt : INTEGER := 0;
SIGNAL row_mat_idx_nxt : INTEGER := 0;
SIGNAL conv_data_out, conv_data_int, conv_data_mul : SIGNED(10 DOWNTO 0) := (OTHERS => '0');
SIGNAL m_axis_tvalid_int : STD_LOGIC;
SIGNAL trigger, prepare_data, ready_data, send_data : STD_LOGIC := '0';
SIGNAL tlast : STD_LOGIC := '0';
SIGNAL save_data : STD_LOGIC := '0';
BEGIN
-- Aggiornamento dell'indirizzo di lettura (mapping riga-colonna)
conv_addr <= STD_LOGIC_VECTOR(to_unsigned(row * IMG_WIDTH + col, conv_addr'length));
m_axis_tvalid <= m_axis_tvalid_int;
-- Processo principale: macchina a stati per la gestione della convoluzione
PROCESS (clk, aresetn)
PROCESS (clk)
BEGIN
IF aresetn = '0' THEN
-- Reset asincrono: inizializza tutti i segnali
state <= IDLE;
row <= 0;
col <= 0;
window <= (OTHERS => (OTHERS => (OTHERS => '0')));
conv_sum <= 0;
conv_out <= (OTHERS => '0');
m_axis_tdata <= (OTHERS => '0');
m_axis_tvalid <= '0';
m_axis_tlast <= '0';
done_conv <= '0';
current_addr <= (OTHERS => '0');
ELSIF rising_edge(clk) THEN
CASE state IS
IF rising_edge(clk) THEN
IF aresetn = '0' THEN
-- Stato IDLE: attende il segnale di start per iniziare la convoluzione
WHEN IDLE =>
m_axis_tvalid <= '0';
m_axis_tlast <= '0';
IF start_conv = '1' THEN
row <= 0;
col <= 0;
-- Reset all signals
state <= IDLE;
col <= (OTHERS => '0');
row <= (OTHERS => '0');
col_mat_idx_nxt <= 0;
row_mat_idx_nxt <= 0;
col_mat_idx_prv <= 0;
row_mat_idx_prv <= 0;
col_mat_idx <= 0;
row_mat_idx <= 0;
conv_data_out <= (OTHERS => '0');
conv_data_int <= (OTHERS => '0');
conv_data_mul <= (OTHERS => '0');
m_axis_tvalid_int <= '0';
m_axis_tdata <= (OTHERS => '0');
m_axis_tlast <= '0';
done_conv <= '0';
trigger <= '0';
prepare_data <= '0';
ready_data <= '0';
send_data <= '0';
tlast <= '0';
save_data <= '0';
conv_addr <= (OTHERS => '0');
ELSE
-- Default values for signals
done_conv <= '0';
m_axis_tlast <= '0';
CASE state IS
WHEN IDLE =>
-- Default values in IDLE
done_conv <= '0';
-- Inizializza la finestra a zero per gestire il padding superiore
window <= (OTHERS => (OTHERS => (OTHERS => '0')));
state <= LOAD_PIXEL;
END IF;
m_axis_tlast <= '0';
m_axis_tvalid_int <= '0';
m_axis_tdata <= (OTHERS => '0');
conv_data_out <= (OTHERS => '0');
conv_data_int <= (OTHERS => '0');
conv_data_mul <= (OTHERS => '0');
trigger <= '0';
prepare_data <= '0';
ready_data <= '0';
send_data <= '0';
tlast <= '0';
save_data <= '0';
conv_addr <= (OTHERS => '0');
-- Stato LOAD_PIXEL: carica un nuovo pixel e aggiorna la finestra
WHEN LOAD_PIXEL =>
-- Aggiorna la finestra con il nuovo pixel (conv_data)
-- Lo shifting viene realizzato per spostare i dati verso sinistra
IF col = 0 THEN
-- Per ogni riga della finestra si forza la colonna sinistra a zero
FOR i IN 0 TO 2 LOOP
window(i)(0) <= (OTHERS => '0');
END LOOP;
ELSE
FOR i IN 0 TO 2 LOOP
window(i)(0) <= window(i)(1);
window(i)(1) <= window(i)(2);
END LOOP;
END IF;
IF start_conv = '1' THEN
state <= START_CONVOLUTING;
-- Aggiorna la colonna destra della finestra con il nuovo pixel
FOR i IN 0 TO 2 LOOP
window(i)(2) <= conv_data;
END LOOP;
-- Reset the convolution matrix position
row <= (OTHERS => '0');
col <= (OTHERS => '0');
-- Aggiorna i contatori per scorrere l'immagine
IF col = IMG_WIDTH - 1 THEN
col <= 0;
IF row = IMG_HEIGHT - 1 THEN
state <= COMPUTE;
ELSE
row <= row + 1;
END IF;
ELSE
col <= col + 1;
END IF;
-- Request the first pixel and set pointer to second pixel
row_mat_idx_prv <= 0;
col_mat_idx_prv <= 0;
state <= COMPUTE;
row_mat_idx <= 1;
col_mat_idx <= 1;
-- Stato COMPUTE: esegue il calcolo della convoluzione
WHEN COMPUTE =>
-- Gestione dei bordi: imposta il risultato a zero se la finestra non <20> completa
IF (row = 0) OR (row = IMG_HEIGHT - 1) OR (col = 0) OR (col = IMG_WIDTH - 1) THEN
conv_sum <= 0;
ELSE
conv_sum <= 0;
-- Moltiplica cella per cella e somma i prodotti
FOR i IN 0 TO 2 LOOP
FOR j IN 0 TO 2 LOOP
conv_sum <= conv_sum + conv_mat(i, j) * to_integer(unsigned(window(i)(j)));
END LOOP;
END LOOP;
END IF;
row_mat_idx_nxt <= 1;
col_mat_idx_nxt <= 2;
-- Saturazione del risultato
IF conv_sum < 0 THEN
conv_out <= STD_LOGIC_VECTOR(to_unsigned(0, 8));
ELSIF conv_sum >= 256 THEN
conv_out <= STD_LOGIC_VECTOR(to_unsigned(255, 8));
ELSE
conv_out <= STD_LOGIC_VECTOR(to_unsigned(conv_sum, 8));
END IF;
state <= OUTPUT;
-- Stato OUTPUT: invia il risultato tramite l'interfaccia AXIS
WHEN OUTPUT =>
IF m_axis_tready = '1' THEN
m_axis_tdata <= conv_out;
m_axis_tvalid <= '1';
-- Se siamo sull'ultimo pixel dell'immagine, segnaliamo TLAST e il completamento
IF (row = IMG_HEIGHT - 1) AND (col = IMG_WIDTH - 1) THEN
m_axis_tlast <= '1';
done_conv <= '1';
state <= IDLE;
ELSE
conv_addr <= (OTHERS => '0');
conv_data_out <= (OTHERS => '0');
conv_data_int <= (OTHERS => '0');
conv_data_mul <= (OTHERS => '0');
trigger <= '0';
prepare_data <= '0';
ready_data <= '0';
send_data <= '0';
tlast <= '0';
save_data <= '0';
m_axis_tvalid_int <= '0';
m_axis_tdata <= (OTHERS => '0');
m_axis_tlast <= '0';
state <= LOAD_PIXEL;
done_conv <= '0';
END IF;
WHEN START_CONVOLUTING =>
conv_addr <= STD_LOGIC_VECTOR(
TO_UNSIGNED(
(TO_INTEGER(col) + offset(col_mat_idx_nxt)) +
(TO_INTEGER(row) + offset(row_mat_idx_nxt)) * (2 ** LOG2_N_COLS),
conv_addr'length
)
);
state <= CONVOLUTING;
WHEN CONVOLUTING =>
-- Convolution operation: accumulate the result of current pixel and kernel coefficient
conv_addr <= STD_LOGIC_VECTOR(
TO_UNSIGNED(
(TO_INTEGER(col) + offset(col_mat_idx_nxt)) +
(TO_INTEGER(row) + offset(row_mat_idx_nxt)) * (2 ** LOG2_N_COLS),
conv_addr'length
)
);
conv_data_mul <= RESIZE(
SIGNED('0' & conv_data) * TO_SIGNED(conv_mat(col_mat_idx_prv, row_mat_idx_prv), 5),
conv_data_mul'length
);
IF ready_data = '1' THEN
conv_data_out <= conv_data_int + conv_data_mul;
conv_data_int <= (OTHERS => '0');
ELSE
conv_data_int <= conv_data_int + conv_data_mul;
END IF;
trigger <= '0';
WHEN WAIT_READY =>
-- Wait for m_axis_tready signal to be asserted before sending data and continue convolution
IF m_axis_tready = '1' THEN
conv_addr <= STD_LOGIC_VECTOR(
TO_UNSIGNED(
(TO_INTEGER(col) + offset(col_mat_idx_nxt)) +
(TO_INTEGER(row) + offset(row_mat_idx_nxt)) * (2 ** LOG2_N_COLS),
conv_addr'length
)
);
save_data <= '0';
state <= CONVOLUTING;
END IF;
IF save_data = '0' THEN
conv_data_mul <= RESIZE(
SIGNED('0' & conv_data) * TO_SIGNED(conv_mat(col_mat_idx_prv, row_mat_idx_prv), 5),
conv_data_mul'length
);
IF ready_data = '1' THEN
conv_data_out <= conv_data_int + conv_data_mul;
conv_data_int <= (OTHERS => '0');
ELSE
conv_data_int <= conv_data_int + conv_data_mul;
END IF;
save_data <= '1';
END IF;
END CASE;
-- Output data - master
IF m_axis_tready = '1' THEN
m_axis_tvalid_int <= '0';
END IF;
-- Wait for m_axis_tready signal to be asserted before continuing convolution
IF m_axis_tready = '0' AND m_axis_tvalid_int = '1' THEN
state <= WAIT_READY;
END IF;
IF send_data = '1' AND (m_axis_tvalid_int = '0' OR m_axis_tready = '1') THEN
m_axis_tvalid_int <= '1';
IF tlast = '1' THEN
state <= IDLE;
done_conv <= '1';
m_axis_tlast <= '1';
tlast <= '0';
END IF;
-- Stato di default: ritorna a IDLE
WHEN OTHERS =>
state <= IDLE;
END CASE;
IF conv_data_out < 0 THEN
m_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(0, m_axis_tdata'length));
ELSIF conv_data_out > 127 THEN
m_axis_tdata <= STD_LOGIC_VECTOR(TO_UNSIGNED(127, m_axis_tdata'length));
ELSE
m_axis_tdata <= STD_LOGIC_VECTOR(conv_data_out(7 DOWNTO 0));
END IF;
-- Reset accumulator and trigger
conv_data_out <= (OTHERS => '0');
send_data <= '0';
END IF;
IF state = CONVOLUTING OR state = START_CONVOLUTING OR (state = WAIT_READY AND m_axis_tready = '1') THEN
-- Update convolution matrix position, image position and check for zero padding
IF col_mat_idx_nxt = 1 AND col = (2 ** LOG2_N_COLS - 1) THEN
IF row_mat_idx_nxt = 1 AND row = (2 ** LOG2_N_ROWS - 1) THEN
-- Last pixel and last kernel position: finish convolution
IF tlast = '0' THEN
trigger <= '1'; -- Send last data
tlast <= '1';
END IF;
ELSIF row_mat_idx_nxt = 2 THEN
-- End of kernel, move to next image row
col <= (OTHERS => '0');
row <= row + 1;
row_mat_idx_nxt <= 0;
col_mat_idx_nxt <= 1; -- new row adding padding
trigger <= '1'; -- Send data
ELSE
-- Move to next kernel row
row_mat_idx_nxt <= row_mat_idx_nxt + 1;
col_mat_idx_nxt <= 0;
END IF;
ELSIF col_mat_idx_nxt = 2 THEN
IF row_mat_idx_nxt = 1 AND row = (2 ** LOG2_N_ROWS - 1) THEN
-- End of kernel column at last image row, move to next image column
col <= col + 1;
row_mat_idx_nxt <= 0;
col_mat_idx_nxt <= 0;
trigger <= '1'; -- Send data
ELSIF row_mat_idx_nxt = 2 THEN
-- End of kernel column and row, move to next image column
col <= col + 1;
IF row = 0 THEN
row_mat_idx_nxt <= 1; -- first row adding padding
ELSE
row_mat_idx_nxt <= 0;
END IF;
col_mat_idx_nxt <= 0;
trigger <= '1'; -- Send data
ELSE
-- Move to next kernel column
IF col = 0 THEN
col_mat_idx_nxt <= 1; -- first column adding padding
ELSE
col_mat_idx_nxt <= 0;
END IF;
row_mat_idx_nxt <= row_mat_idx_nxt + 1;
END IF;
ELSE
-- Continue kernel sweep: increment kernel column index
col_mat_idx_nxt <= col_mat_idx_nxt + 1;
END IF;
prepare_data <= trigger; -- Pipeline trigger for data output waiting for last data
ready_data <= prepare_data;
send_data <= ready_data;
row_mat_idx_prv <= row_mat_idx;
col_mat_idx_prv <= col_mat_idx;
row_mat_idx <= row_mat_idx_nxt;
col_mat_idx <= col_mat_idx_nxt;
END IF;
END IF;
END IF;
END PROCESS;

View File

@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2020.2 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2020 Xilinx, Inc. All Rights Reserved. -->
<Project Version="7" Minor="54" Path="C:/DESD/LAB2/vivado/img_conv_test/img_conv_test.xpr">
<DefaultLaunch Dir="$PRUNDIR"/>
<Configuration>
<Option Name="Id" Val="ac254788b71e44ff92abc438d357ca04"/>
<Option Name="Part" Val="xc7a35tcpg236-1"/>
<Option Name="CompiledLibDir" Val="$PCACHEDIR/compile_simlib"/>
<Option Name="CompiledLibDirXSim" Val=""/>
<Option Name="CompiledLibDirModelSim" Val="$PCACHEDIR/compile_simlib/modelsim"/>
<Option Name="CompiledLibDirQuesta" Val="$PCACHEDIR/compile_simlib/questa"/>
<Option Name="CompiledLibDirIES" Val="$PCACHEDIR/compile_simlib/ies"/>
<Option Name="CompiledLibDirXcelium" Val="$PCACHEDIR/compile_simlib/xcelium"/>
<Option Name="CompiledLibDirVCS" Val="$PCACHEDIR/compile_simlib/vcs"/>
<Option Name="CompiledLibDirRiviera" Val="$PCACHEDIR/compile_simlib/riviera"/>
<Option Name="CompiledLibDirActivehdl" Val="$PCACHEDIR/compile_simlib/activehdl"/>
<Option Name="SimulatorInstallDirModelSim" Val=""/>
<Option Name="SimulatorInstallDirQuesta" Val=""/>
<Option Name="SimulatorInstallDirIES" Val=""/>
<Option Name="SimulatorInstallDirXcelium" Val=""/>
<Option Name="SimulatorInstallDirVCS" Val=""/>
<Option Name="SimulatorInstallDirRiviera" Val=""/>
<Option Name="SimulatorInstallDirActiveHdl" Val=""/>
<Option Name="SimulatorGccInstallDirModelSim" Val=""/>
<Option Name="SimulatorGccInstallDirQuesta" Val=""/>
<Option Name="SimulatorGccInstallDirIES" Val=""/>
<Option Name="SimulatorGccInstallDirXcelium" Val=""/>
<Option Name="SimulatorGccInstallDirVCS" Val=""/>
<Option Name="SimulatorGccInstallDirRiviera" Val=""/>
<Option Name="SimulatorGccInstallDirActiveHdl" Val=""/>
<Option Name="TargetLanguage" Val="VHDL"/>
<Option Name="BoardPart" Val="digilentinc.com:basys3:part0:1.1"/>
<Option Name="BoardPartRepoPaths" Val="$PPRDIR/../../../../Users/david/AppData/Roaming/Xilinx/Vivado/2020.2/xhub/board_store/xilinx_board_store"/>
<Option Name="ActiveSimSet" Val="sim_1"/>
<Option Name="DefaultLib" Val="xil_defaultlib"/>
<Option Name="ProjectType" Val="Default"/>
<Option Name="IPOutputRepo" Val="$PCACHEDIR/ip"/>
<Option Name="IPDefaultOutputPath" Val="$PGENDIR/sources_1"/>
<Option Name="IPCachePermission" Val="read"/>
<Option Name="IPCachePermission" Val="write"/>
<Option Name="EnableCoreContainer" Val="FALSE"/>
<Option Name="CreateRefXciForCoreContainers" Val="FALSE"/>
<Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="DSABoardId" Val="basys3"/>
<Option Name="WTXSimLaunchSim" Val="150"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>
<Option Name="WTVcsLaunchSim" Val="0"/>
<Option Name="WTRivieraLaunchSim" Val="0"/>
<Option Name="WTActivehdlLaunchSim" Val="0"/>
<Option Name="WTXSimExportSim" Val="0"/>
<Option Name="WTModelSimExportSim" Val="0"/>
<Option Name="WTQuestaExportSim" Val="0"/>
<Option Name="WTIesExportSim" Val="0"/>
<Option Name="WTVcsExportSim" Val="0"/>
<Option Name="WTRivieraExportSim" Val="0"/>
<Option Name="WTActivehdlExportSim" Val="0"/>
<Option Name="GenerateIPUpgradeLog" Val="TRUE"/>
<Option Name="XSimRadix" Val="hex"/>
<Option Name="XSimTimeUnit" Val="ns"/>
<Option Name="XSimArrayDisplayLimit" Val="1024"/>
<Option Name="XSimTraceLimit" Val="65536"/>
<Option Name="SimTypes" Val="rtl"/>
<Option Name="SimTypes" Val="bfm"/>
<Option Name="SimTypes" Val="tlm"/>
<Option Name="SimTypes" Val="tlm_dpi"/>
<Option Name="MEMEnableMemoryMapGeneration" Val="TRUE"/>
<Option Name="DcpsUptoDate" Val="TRUE"/>
</Configuration>
<FileSets Version="1" Minor="31">
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1" RelGenDir="$PGENDIR/sources_1">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/../../src/img_conv.vhd">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="img_conv"/>
<Option Name="TopAutoSet" Val="TRUE"/>
</Config>
</FileSet>
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1" RelGenDir="$PGENDIR/constrs_1">
<Filter Type="Constrs"/>
<Config>
<Option Name="ConstrsType" Val="XDC"/>
</Config>
</FileSet>
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1" RelGenDir="$PGENDIR/sim_1">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/../../sim/tb_img_conv.vhd">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="img_conv_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TopAutoSet" Val="TRUE"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
</Config>
</FileSet>
<FileSet Name="utils_1" Type="Utils" RelSrcDir="$PSRCDIR/utils_1" RelGenDir="$PGENDIR/utils_1">
<Filter Type="Utils"/>
<Config>
<Option Name="TopAutoSet" Val="TRUE"/>
</Config>
</FileSet>
</FileSets>
<Simulators>
<Simulator Name="XSim">
<Option Name="Description" Val="Vivado Simulator"/>
<Option Name="CompiledLib" Val="0"/>
</Simulator>
<Simulator Name="ModelSim">
<Option Name="Description" Val="ModelSim Simulator"/>
</Simulator>
<Simulator Name="Questa">
<Option Name="Description" Val="Questa Advanced Simulator"/>
</Simulator>
<Simulator Name="Riviera">
<Option Name="Description" Val="Riviera-PRO Simulator"/>
</Simulator>
<Simulator Name="ActiveHDL">
<Option Name="Description" Val="Active-HDL Simulator"/>
</Simulator>
</Simulators>
<Runs Version="1" Minor="15">
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a35tcpg236-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" IncludeInArchive="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2020"/>
<Step Id="synth_design"/>
</Strategy>
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2020"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a35tcpg236-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2020"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
<Step Id="place_design"/>
<Step Id="post_place_power_opt_design"/>
<Step Id="phys_opt_design"/>
<Step Id="route_design"/>
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2020"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
</Runs>
<Board>
<Jumpers/>
</Board>
<DashboardSummary Version="1" Minor="0">
<Dashboards>
<Dashboard Name="default_dashboard">
<Gadgets>
<Gadget Name="drc_1" Type="drc" Version="1" Row="2" Column="0">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_drc_0 "/>
</Gadget>
<Gadget Name="methodology_1" Type="methodology" Version="1" Row="2" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_methodology_0 "/>
</Gadget>
<Gadget Name="power_1" Type="power" Version="1" Row="1" Column="0">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_power_0 "/>
</Gadget>
<Gadget Name="timing_1" Type="timing" Version="1" Row="0" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_timing_summary_0 "/>
</Gadget>
<Gadget Name="utilization_1" Type="utilization" Version="1" Row="0" Column="0">
<GadgetParam Name="REPORTS" Type="string_list" Value="synth_1#synth_1_synth_report_utilization_0 "/>
<GadgetParam Name="RUN.STEP" Type="string" Value="synth_design"/>
<GadgetParam Name="RUN.TYPE" Type="string" Value="synthesis"/>
</Gadget>
<Gadget Name="utilization_2" Type="utilization" Version="1" Row="1" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_place_report_utilization_0 "/>
</Gadget>
</Gadgets>
</Dashboard>
<CurrentDashboard>default_dashboard</CurrentDashboard>
</Dashboards>
</DashboardSummary>
</Project>