Przeszukaj forum
Pokazywanie wyników dla tagów 'chatGPT'.
Znaleziono 1 wynik
-
Cześć, postanowiłem dzisiaj wypróbować generację kodu VHDL z użyciem "chat GPT". Założenia były takie, że mamy tablicę (bufor obrazu) o rozdzielczości VGA (640x480 pikseli, gdzie kazdy piksel ma 16 bitów). Aby kod był niezależny od konkretnej kości FPGA załozyłem, że opis obrazu jest w tablicy języka VHDL: signal image : array(0 to 639, 0 to 479) of STD_LOGIC_VECTOR(15 downto 0); a obraz wyjściowy (krawędzie) są w tablicy: signal edge_buffer : array(0 to 639, 0 to 479) of STD_LOGIC; Jest to po to aby abstrahować od konkretnego miejsca przechowywania obrazu (bufor obrazu), który docelowo może być w pamięci BLOCK_RAM układu FPGA lub w zewnętrznej pamięci RAM. Na początku poprosiłem "chatGPT" o wygenerowanie prostego przykładu filtrowania obrazu filtrem Sobel'a. Kod został szybko wygenerowany i wydawał się być całkiem poprawny (porównałem podstawową implementację filtru Sobel'a w języku C++). Nastepnie prosiłem chatGPT o dodawanie kolejnych opcji zrównoleglania - po kolei: 1) Zrównoleglanie liczby jednocześnie przetwarzanych pikseli - stała: constant PARALLELISM : natural := 4; 2) Podział obrazu FPGA na bloki przetwarzane równolegle: constant NUM_BLOCKS_X : integer := 160; -- Ilość bloków pikseli w poziomie constant NUM_BLOCKS_Y : integer := 120; -- Ilość bloków pikseli w pionie 3) Dodanie pipeline do przetwarzania Tutaj cały wygenerowany kod VHDL: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity SobelEdgeDetection is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; pixel_in : in STD_LOGIC_VECTOR(15 downto 0); edge_out : out STD_LOGIC ); end SobelEdgeDetection; architecture ParallelPipelinedBehavior of SobelEdgeDetection is type PixelBlock is array(0 to 3, 0 to 3) of STD_LOGIC_VECTOR(15 downto 0); signal block_x : integer := 0; signal block_y : integer := 0; signal image : array(0 to 639, 0 to 479) of STD_LOGIC_VECTOR(15 downto 0); signal edge_buffer : array(0 to 639, 0 to 479) of STD_LOGIC; signal sobel_x : integer; signal sobel_y : integer; signal gradient : integer; signal gradient_reg : integer := 0; constant sobel_mask_x : array(0 to 2, 0 to 2) of integer := ((-1, 0, 1), (-2, 0, 2), (-1, 0, 1)); constant sobel_mask_y : array(0 to 2, 0 to 2) of integer := ((-1, -2, -1), ( 0, 0, 0), ( 1, 2, 1)); constant NUM_BLOCKS_X : integer := 160; -- Ilość bloków pikseli w poziomie constant NUM_BLOCKS_Y : integer := 120; -- Ilość bloków pikseli w pionie constant PARALLELISM : natural := 4; signal processing_stage : integer := 0; signal sobel_x_stage : integer; signal sobel_y_stage : integer; signal gradient_stage : integer; signal edge_stage : STD_LOGIC; signal pipeline_ready : boolean := false; begin process(clk) begin if rising_edge(clk) then if reset = '1' then block_x <= 0; block_y <= 0; processing_stage <= 0; for i in 0 to 639 loop for j in 0 to 479 loop image(i, j) <= (others => '0'); edge_buffer(i, j) <= '0'; end loop; end loop; else -- Przetwarzanie równoległe z pipeliningiem if not pipeline_ready then case processing_stage is when 0 => -- Wczytywanie bloku pikseli for i in 0 to 3 loop for j in 0 to 3 loop image(block_x * 4 + i, block_y * 4 + j) <= pixel_in; end loop; end loop; if block_x = NUM_BLOCKS_X - 1 and block_y = NUM_BLOCKS_Y - 1 then pipeline_ready <= true; processing_stage <= 0; -- Reset etapu przetwarzania elsif block_x = NUM_BLOCKS_X - 1 then block_x <= 0; block_y <= block_y + 1; else block_x <= block_x + 1; end if; when 1 => -- Obliczenia gradientów sobel_x_stage <= (to_integer(unsigned(image(block_x * 4 - 1, block_y * 4 - 1))) * sobel_mask_x(0, 0)) + (to_integer(unsigned(image(block_x * 4, block_y * 4 - 1))) * sobel_mask_x(0, 1)) + (to_integer(unsigned(image(block_x * 4 + 1, block_y * 4 - 1))) * sobel_mask_x(0, 2)) + (to_integer(unsigned(image(block_x * 4 - 1, block_y * 4))) * sobel_mask_x(1, 0)) + (to_integer(unsigned(image(block_x * 4 + 1, block_y * 4))) * sobel_mask_x(1, 2)) + (to_integer(unsigned(image(block_x * 4 - 1, block_y * 4 + 1))) * sobel_mask_x(2, 0)) + (to_integer(unsigned(image(block_x * 4, block_y * 4 + 1))) * sobel_mask_x(2, 1)) + (to_integer(unsigned(image(block_x * 4 + 1, block_y * 4 + 1))) * sobel_mask_x(2, 2)); sobel_y_stage <= (to_integer(unsigned(image(block_x * 4 - 1, block_y * 4 - 1))) * sobel_mask_y(0, 0)) + (to_integer(unsigned(image(block_x * 4, block_y * 4 - 1))) * sobel_mask_y(0, 1)) + (to_integer(unsigned(image(block_x * 4 + 1, block_y * 4 - 1))) * sobel_mask_y(0, 2)) + (to_integer(unsigned(image(block_x * 4 - 1, block_y * 4))) * sobel_mask_y(1, 0)) + (to_integer(unsigned(image(block_x * 4 + 1, block_y * 4))) * sobel_mask_y(1, 2)) + (to_integer(unsigned(image(block_x * 4 - 1, block_y * 4 + 1))) * sobel_mask_y(2, 0)) + (to_integer(unsigned(image(block_x * 4, block_y * 4 + 1))) * sobel_mask_y(2, 1)) + (to_integer(unsigned(image(block_x * 4 + 1, block_y * 4 + 1))) * sobel_mask_y(2, 2)); gradient_stage <= abs(sobel_x_stage) + abs(sobel_y_stage); if gradient_stage > 1000 then edge_stage <= '1'; else edge_stage <= '0'; end if; processing_stage <= 2; -- Przejdź do etapu 2 when 2 => -- Wczytywanie wyników do bufora krawędzi edge_buffer(block_x * 4 + 3, block_y * 4 + 3) <= edge_stage; if block_x = NUM_BLOCKS_X - 1 and block_y = NUM_BLOCKS_Y - 1 then pipeline_ready <= false; -- Zakończenie przetwarzania bloku elsif block_x = NUM_BLOCKS_X - 1 then block_x <= 0; block_y <= block_y + 1; else block_x <= block_x + 1; end if; end case; end if; end if; end if; end process; end ParallelPipelinedBehavior; Co sądzicie o wygenerowanym kodzie - wstepnie go przeanalizowałem i na rzaie nie mogę znaleźć błędu. Co sądzicie ogólnie o generacji kodu w róznych językach programowania za pomocą "chatGPT" i ogólnie AI. Tutaj link do dużo potężniejszego narzędzia AI o nazwie kodowej "Gorilla" : https://lablab.ai/tech/gorilla Projekt "Gorilla" można za darmo testować na "Google Clolab". Pozdrawiam