diff --git a/LAB2/cons/pins.xdc b/LAB2/cons/pins.xdc new file mode 100644 index 0000000..18ef6bd --- /dev/null +++ b/LAB2/cons/pins.xdc @@ -0,0 +1,6 @@ +set_property IOSTANDARD LVCMOS33 [get_ports led_of] +set_property IOSTANDARD LVCMOS33 [get_ports led_ok] +set_property IOSTANDARD LVCMOS33 [get_ports led_uf] +set_property PACKAGE_PIN U16 [get_ports led_of] +set_property PACKAGE_PIN E19 [get_ports led_ok] +set_property PACKAGE_PIN U19 [get_ports led_uf] diff --git a/LAB2/sim/tb_img_conv.vhd b/LAB2/sim/tb_img_conv.vhd new file mode 100644 index 0000000..58af0cf --- /dev/null +++ b/LAB2/sim/tb_img_conv.vhd @@ -0,0 +1,128 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 03/16/2025 04:23:36 PM +-- Design Name: +-- Module Name: img_conv_tb - Behavioral +-- Project Name: +-- Target Devices: +-- Tool Versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + + +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; + +-- 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; + +architecture Behavioral of img_conv_tb is + + 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 + + ); + end component; + + 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); + + signal mem : mem_type := (0=>"0000001",others => (others => '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 start_conv: std_logic; + signal done_conv: std_logic; + +begin + + m_axis_tready<='1'; + + 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( + clk => clk, + aresetn => aresetn, + m_axis_tdata => m_axis_tdata, + m_axis_tvalid => m_axis_tvalid, + m_axis_tready => m_axis_tready, + m_axis_tlast => m_axis_tlast, + conv_addr => conv_addr, + conv_data => conv_data, + start_conv => start_conv, + 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; + + +end Behavioral; diff --git a/LAB2/src/bram_controller.vhd b/LAB2/src/bram_controller.vhd new file mode 100644 index 0000000..94047d1 --- /dev/null +++ b/LAB2/src/bram_controller.vhd @@ -0,0 +1,94 @@ +library ieee; +use ieee.std_logic_1164.all; + +Library xpm; +use xpm.vcomponents.all; + +entity bram_controller is + generic ( + ADDR_WIDTH: POSITIVE :=16 + ); + port ( + clk : in std_logic; + aresetn : in std_logic; + + addr: in std_logic_vector(ADDR_WIDTH-1 downto 0); + dout: out std_logic_vector(7 downto 0); + din: in std_logic_vector(7 downto 0); + we: in std_logic + ); +end entity bram_controller; + +architecture rtl of bram_controller is + +begin + +-- xpm_memory_spram: Single Port RAM +-- Xilinx Parameterized Macro, version 2020.2 + +xpm_memory_spram_inst : xpm_memory_spram +generic map ( + ADDR_WIDTH_A => ADDR_WIDTH, -- DECIMAL + AUTO_SLEEP_TIME => 0, -- DECIMAL + BYTE_WRITE_WIDTH_A => 8, -- DECIMAL + CASCADE_HEIGHT => 0, -- DECIMAL + ECC_MODE => "no_ecc", -- String + MEMORY_INIT_FILE => "none", -- String + MEMORY_INIT_PARAM => "0", -- String + MEMORY_OPTIMIZATION => "true", -- String + MEMORY_PRIMITIVE => "block", -- String + MEMORY_SIZE => (2**ADDR_WIDTH)*8,-- DECIMAL + MESSAGE_CONTROL => 0, -- DECIMAL + READ_DATA_WIDTH_A => 8, -- DECIMAL + READ_LATENCY_A => 1, -- DECIMAL + READ_RESET_VALUE_A => "0", -- String + RST_MODE_A => "SYNC", -- String + SIM_ASSERT_CHK => 0, -- DECIMAL; 0=disable simulation messages, 1=enable simulation messages + USE_MEM_INIT => 1, -- DECIMAL + WAKEUP_TIME => "disable_sleep", -- String + WRITE_DATA_WIDTH_A => 8, -- DECIMAL + WRITE_MODE_A => "read_first" -- String +) +port map ( + dbiterra => open, -- 1-bit output: Status signal to indicate double bit error occurrence + -- on the data output of port A. + + douta => dout, -- READ_DATA_WIDTH_A-bit output: Data output for port A read operations. + sbiterra => open, -- 1-bit output: Status signal to indicate single bit error occurrence + -- on the data output of port A. + + addra => addr, -- ADDR_WIDTH_A-bit input: Address for port A write and read operations. + clka => clk, -- 1-bit input: Clock signal for port A. + dina => din, -- WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations. + ena => '1', -- 1-bit input: Memory enable signal for port A. Must be high on clock + -- cycles when read or write operations are initiated. Pipelined + -- internally. + + injectdbiterra => '0', -- 1-bit input: Controls double bit error injection on input data when + -- ECC enabled (Error injection capability is not available in + -- "decode_only" mode). + + injectsbiterra => '0', -- 1-bit input: Controls single bit error injection on input data when + -- ECC enabled (Error injection capability is not available in + -- "decode_only" mode). + + regcea => '1', -- 1-bit input: Clock Enable for the last register stage on the output + -- data path. + + rsta => (not aresetn), -- 1-bit input: Reset signal for the final port A output register + -- stage. Synchronously resets output port douta to the value specified + -- by parameter READ_RESET_VALUE_A. + + sleep => '0', -- 1-bit input: sleep signal to enable the dynamic power saving feature. + wea(0) => we -- WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector + -- for port A input data port dina. 1 bit wide when word-wide writes + -- are used. In byte-wide write configurations, each bit controls the + -- writing one byte of dina to address addra. For example, to + -- synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A + -- is 32, wea would be 4'b0010. + +); + +-- End of xpm_memory_spram_inst instantiation + +end architecture; \ No newline at end of file diff --git a/LAB2/src/bram_writer.vhd b/LAB2/src/bram_writer.vhd new file mode 100644 index 0000000..5e0477c --- /dev/null +++ b/LAB2/src/bram_writer.vhd @@ -0,0 +1,54 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity bram_writer is + generic( + ADDR_WIDTH: POSITIVE :=16 + ); + port ( + clk : in std_logic; + aresetn : in std_logic; + + s_axis_tdata : in std_logic_vector(7 downto 0); + s_axis_tvalid : in std_logic; + s_axis_tready : out std_logic; + s_axis_tlast : in std_logic; + + conv_addr: in std_logic_vector(ADDR_WIDTH-1 downto 0); + conv_data: out std_logic_vector(6 downto 0); + + start_conv: out std_logic; + done_conv: in std_logic; + + write_ok : out std_logic; + overflow : out std_logic; + underflow: out std_logic + + ); +end entity bram_writer; + +architecture rtl of bram_writer is + + component bram_controller is + generic ( + ADDR_WIDTH: POSITIVE :=16 + ); + port ( + clk : in std_logic; + aresetn : in std_logic; + + addr: in std_logic_vector(ADDR_WIDTH-1 downto 0); + dout: out std_logic_vector(7 downto 0); + din: in std_logic_vector(7 downto 0); + we: in std_logic + ); + end component; + + + +begin + + + +end architecture; diff --git a/LAB2/src/depacketizer.vhd b/LAB2/src/depacketizer.vhd new file mode 100644 index 0000000..7f979bd --- /dev/null +++ b/LAB2/src/depacketizer.vhd @@ -0,0 +1,35 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +entity depacketizer is + generic ( + HEADER: INTEGER :=16#FF#; + FOOTER: INTEGER :=16#F1# + ); + port ( + clk : in std_logic; + aresetn : in std_logic; + + s_axis_tdata : in std_logic_vector(7 downto 0); + s_axis_tvalid : in std_logic; + s_axis_tready : out 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 + + ); +end entity depacketizer; + +architecture rtl of depacketizer is + + + +begin + + + +end architecture; diff --git a/LAB2/src/img_conv.vhd b/LAB2/src/img_conv.vhd new file mode 100644 index 0000000..731c637 --- /dev/null +++ b/LAB2/src/img_conv.vhd @@ -0,0 +1,41 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity 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 + + ); +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)); + + + +begin + + + +end architecture; diff --git a/LAB2/src/led_blinker.vhd b/LAB2/src/led_blinker.vhd new file mode 100644 index 0000000..5b99495 --- /dev/null +++ b/LAB2/src/led_blinker.vhd @@ -0,0 +1,28 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +entity led_blinker is + generic ( + CLK_PERIOD_NS: POSITIVE :=10; + BLINK_PERIOD_MS : POSITIVE :=1000; + N_BLINKS : POSITIVE := 4 + ); + port ( + clk : in std_logic; + aresetn : in std_logic; + start_blink : in std_logic; + led: out std_logic + ); +end entity led_blinker; + +architecture rtl of led_blinker is + + +begin + + + + +end architecture; diff --git a/LAB2/src/packetizer.vhd b/LAB2/src/packetizer.vhd new file mode 100644 index 0000000..d360967 --- /dev/null +++ b/LAB2/src/packetizer.vhd @@ -0,0 +1,36 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +entity packetizer is + generic ( + HEADER: INTEGER :=16#FF#; + FOOTER: INTEGER :=16#F1# + ); + port ( + clk : in std_logic; + aresetn : in std_logic; + + s_axis_tdata : in std_logic_vector(7 downto 0); + s_axis_tvalid : in std_logic; + s_axis_tready : out std_logic; + s_axis_tlast : 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 + + ); +end entity packetizer; + +architecture rtl of packetizer is + + + +begin + + + + +end architecture; diff --git a/LAB2/src/rgb2gray.vhd b/LAB2/src/rgb2gray.vhd new file mode 100644 index 0000000..65e4f96 --- /dev/null +++ b/LAB2/src/rgb2gray.vhd @@ -0,0 +1,36 @@ +---------- DEFAULT LIBRARIES ------- +library IEEE; + use IEEE.STD_LOGIC_1164.all; + use IEEE.NUMERIC_STD.ALL; + use IEEE.MATH_REAL.all; -- For LOG **FOR A CONSTANT!!** +------------------------------------ + +---------- OTHER LIBRARIES --------- +-- NONE +------------------------------------ + +entity rgb2gray is + Port ( + clk : in std_logic; + resetn : in std_logic; + + m_axis_tvalid : out std_logic; + m_axis_tdata : out std_logic_vector(7 downto 0); + m_axis_tready : in std_logic; + m_axis_tlast : out std_logic; + + s_axis_tvalid : in std_logic; + s_axis_tdata : in std_logic_vector(7 downto 0); + s_axis_tready : out std_logic; + s_axis_tlast : in std_logic + ); +end rgb2gray; + +architecture Behavioral of rgb2gray is + + + +begin + + +end Behavioral; diff --git a/LAB2/test/LAB2-Test.exe b/LAB2/test/LAB2-Test.exe new file mode 100644 index 0000000..bb1c7f0 Binary files /dev/null and b/LAB2/test/LAB2-Test.exe differ diff --git a/LAB2/test/test.py b/LAB2/test/test.py new file mode 100644 index 0000000..7db913f --- /dev/null +++ b/LAB2/test/test.py @@ -0,0 +1,87 @@ +def install_and_import(package, package_name=None): + if package_name is None: + package_name = package + + import importlib + try: + importlib.import_module(package) + except ImportError: + import pip + pip.main(['install', package_name]) + finally: + globals()[package] = importlib.import_module(package) + +install_and_import("Serial", "pyserial") +install_and_import("PIL", "pillow") +install_and_import("tqdm") +install_and_import("numpy") +install_and_import("scipy") + + +from serial import Serial +import serial.tools.list_ports +from tqdm import tqdm + +from PIL import Image + +from scipy.signal import convolve2d +import numpy as np + +IMAGE_NAME2="test2.png" +IMAGE_NAME1="test1.png" + +BASYS3_PID=0x6010 +BASYS3_VID=0x0403 + +IMG_HEIGHT=256 +IMG_WIDTH=256 + +dev="" +for port in serial.tools.list_ports.comports(): + if(port.vid==BASYS3_VID and port.pid==BASYS3_PID): + dev=port.device + +if not dev: + raise RuntimeError("Basys 3 Not Found!") + +test_n=int(input("Insert test number (1 or 2): ").strip()) + +if(test_n not in [1,2]): + raise RuntimeError("Test numer must be be 1 or 2") + +dev=Serial(dev,115200) + +img=Image.open(IMAGE_NAME1 if test_n==1 else IMAGE_NAME2) +mat=np.asarray(img,dtype=np.uint8) + +mat=mat[:,:,:3] +if(mat.max()>127): + mat=mat//2 + +buff=mat.tobytes() + +mat=np.sum(mat,axis=2)//3 + +sim_img=convolve2d(mat,[[-1,-1,-1],[-1,8,-1],[-1,-1,-1]], mode="same") + +sim_img[sim_img<0]=0 +sim_img[sim_img>127]=127 + +dev.write(b'\xff') +for i in tqdm(range(IMG_HEIGHT)): + dev.write(buff[(i)*IMG_WIDTH*3:(i+1)*IMG_WIDTH*3]) + +dev.write(b'\xf1') +dev.flush() + +res=dev.read(IMG_HEIGHT*IMG_WIDTH+2) + +res_img=np.frombuffer(res[1:-1],dtype=np.uint8) + +res_img=res_img.reshape((IMG_HEIGHT,IMG_WIDTH)) + + +assert np.all(res_img==sim_img), "Image Mismatch!" + +im=Image.fromarray(np.uint8(res_img)) +im.show() diff --git a/LAB2/test/test1.png b/LAB2/test/test1.png new file mode 100644 index 0000000..a6dbd6b Binary files /dev/null and b/LAB2/test/test1.png differ diff --git a/LAB2/test/test2.png b/LAB2/test/test2.png new file mode 100644 index 0000000..4982d68 Binary files /dev/null and b/LAB2/test/test2.png differ diff --git a/vhdl_ls.toml b/vhdl_ls.toml index b343e43..3148568 100644 --- a/vhdl_ls.toml +++ b/vhdl_ls.toml @@ -1,6 +1,3 @@ -[server] -enable = true - [libraries] # Assign separate libraries for each project lab0_lib.files = [ @@ -13,25 +10,17 @@ lab1_lib.files = [ "LAB1/sim/**/*.vhd" ] -# lab2_lib.files = [ -# "LAB2/src/**/*.vhd", -# "LAB2/sim/**/*.vhd" -# ] +lab2_lib.files = [ + "LAB2/src/**/*.vhd", + "LAB2/sim/**/*.vhd" +] # lab3_lib.files = [ # "LAB3/src/**/*.vhd", # "LAB3/sim/**/*.vhd" # ] -[analyses] -on_save = true -on_open = true - -[ghdl] -standard = "08" -library_path = [ - "C:/Xilinx/Vivado/2020.2/data/vhdl/src" +xpm.files = [ + "C:/Xilinx/Vivado/2020.2/data/ip/xpm/xpm_VCOMP.vhd" ] - -[vhdl] -standard = "2008" +xpm.is_third_party = true \ No newline at end of file