Site Tools


vhdl

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
vhdl [2025/10/29 19:53] – [ghdl memory] 147.32.8.31vhdl [2025/10/29 20:27] (current) – [SDRAM Memory] 147.32.8.31
Line 243: Line 243:
     );     );
 end entity; end entity;
- 
-===== DDR Memory ===== 
  
 architecture Behavioral of sdram_controller is architecture Behavioral of sdram_controller is
Line 386: Line 384:
                 when others =>                 when others =>
                     state <= IDLE;                     state <= IDLE;
 +            end case;
 +        end if;
 +    end process;
 +
 +end Behavioral;
 +</code>
 +
 +==== Matrix Multiply =====
 +
 +<code vhdl>
 +library ieee;
 +use ieee.std_logic_1164.all;
 +use ieee.numeric_std.all;
 +
 +entity MatrixMultiplier is
 +    port (
 +        clk       : in std_logic;
 +        reset     : in std_logic;
 +        start     : in std_logic;
 +        done      : out std_logic
 +        -- Optional: ports for memory interface
 +    );
 +end entity;
 +
 +architecture Behavioral of MatrixMultiplier is
 +
 +    -- Define matrix size
 +    constant N : integer := 2;
 +
 +    -- Define data type
 +    subtype data_t is signed(15 downto 0); -- 16-bit signed numbers
 +
 +    -- Define matrices stored in memory (arrays)
 +    type matrix_t is array (0 to N-1, 0 to N-1) of data_t;
 +
 +    -- Initialize matrices A and B
 +    signal A : matrix_t := (
 +        (to_signed(1,16), to_signed(2,16)),
 +        (to_signed(3,16), to_signed(4,16))
 +    );
 +
 +    signal B : matrix_t := (
 +        (to_signed(5,16), to_signed(6,16)),
 +        (to_signed(7,16), to_signed(8,16))
 +    );
 +
 +    -- Result matrix C
 +    signal C : matrix_t := (
 +        (others => (others => '0'))
 +    );
 +
 +    -- Loop counters
 +    signal i, j, k : integer range 0 to N-1 := 0;
 +
 +    -- Accumulator for sum
 +    signal sum : data_t := (others => '0');
 +
 +    -- State machine states
 +    type state_type is (IDLE, COMPUTE, DONE);
 +    signal state : state_type := IDLE;
 +
 +begin
 +
 +    process(clk, reset)
 +    begin
 +        if reset = '1' then
 +            -- Reset all signals
 +            i <= 0;
 +            j <= 0;
 +            k <= 0;
 +            sum <= (others => '0');
 +            C <= (others => (others => '0'));
 +            state <= IDLE;
 +            done <= '0';
 +
 +        elsif rising_edge(clk) then
 +            case state is
 +                when IDLE =>
 +                    if start = '1' then
 +                        -- Initialize counters
 +                        i <= 0;
 +                        j <= 0;
 +                        k <= 0;
 +                        sum <= (others => '0');
 +                        state <= COMPUTE;
 +                        done <= '0';
 +                    end if;
 +
 +                when COMPUTE =>
 +                    -- Perform multiplication: sum += A[i][k] * B[k][j]
 +                    sum <= sum + A(i,k) * B(k,j);
 +
 +                    if k = N-1 then
 +                        -- Store result in C[i][j]
 +                        C(i,j) <= sum;
 +                        -- Reset sum for next element
 +                        sum <= (others => '0');
 +
 +                        -- Move to next column
 +                        if j < N-1 then
 +                            j <= j + 1;
 +                            k <= 0;
 +                        else
 +                            -- Move to next row
 +                            j <= 0;
 +                            if i < N-1 then
 +                                i <= i + 1;
 +                                k <= 0;
 +                            else
 +                                -- Computation done
 +                                state <= DONE;
 +                            end if;
 +                        end if;
 +                    else
 +                        -- Continue summing
 +                        k <= k + 1;
 +                    end if;
 +
 +                when DONE =>
 +                    done <= '1';
 +                    -- Optionally, stay here or reset
 +            end case;
 +        end if;
 +    end process;
 +
 +end architecture;
 +</code>
 +
 +
 +==== Convolution ====
 +
 +<code vhdl>
 +library ieee;
 +use ieee.std_logic_1164.all;
 +use ieee.numeric_std.all;
 +
 +entity convolution_kernel is
 +    Port (
 +        clk         : in std_logic;
 +        reset       : in std_logic;
 +        start       : in std_logic;
 +        -- Memory interface
 +        pixel_mem_addr  : out unsigned(15 downto 0); -- Address for pixel memory
 +        pixel_mem_data  : in  unsigned(7 downto 0);  -- Pixel data (e.g., grayscale 8-bit)
 +        pixel_mem_we    : out std_logic;             -- Write enable if needed
 +        -- Output
 +        conv_pixel_out  : out unsigned(7 downto 0);
 +        done            : out std_logic
 +    );
 +end entity;
 +
 +architecture Behavioral of convolution_kernel is
 +
 +    -- Define kernel size
 +    constant KERNEL_SIZE : integer := 3;
 +    constant IMG_WIDTH   : integer := 256; -- Example image width
 +    constant IMG_HEIGHT  : integer := 256; -- Example image height
 +
 +    -- Convolution kernel (e.g., sharpening kernel)
 +    type kernel_type is array (0 to KERNEL_SIZE-1, 0 to KERNEL_SIZE-1) of integer;
 +    constant kernel : kernel_type := (
 +        (0, -1, 0),
 +        (-1, 5, -1),
 +        (0, -1, 0)
 +    );
 +
 +    -- State machine states
 +    type state_type is (IDLE, READ_PIXELS, APPLY_CONV, WRITE_RESULT, DONE);
 +    signal state : state_type := IDLE;
 +
 +    -- Memory address counters
 +    signal x, y : integer range 0 to IMG_WIDTH-1 := 0;
 +    signal pixel_window : array (0 to KERNEL_SIZE-1, 0 to KERNEL_SIZE-1) of unsigned(7 downto 0);
 +    signal pixel_sum : integer := 0;
 +    signal conv_result : unsigned(7 downto 0) := (others => '0');
 +
 +    -- Internal counters
 +    signal row, col : integer range 0 to IMG_HEIGHT-1 := 0;
 +
 +    -- Helper signals
 +    signal pixel_fetch_count : integer range 0 to KERNEL_SIZE*KERNEL_SIZE := 0;
 +
 +begin
 +
 +    process(clk, reset)
 +    begin
 +        if reset = '1' then
 +            state <= IDLE;
 +            pixel_mem_addr <= (others => '0');
 +            pixel_mem_we <= '0';
 +            conv_pixel_out <= (others => '0');
 +            done <= '0';
 +            x <= 0;
 +            y <= 0;
 +            row <= 0;
 +            col <= 0;
 +        elsif rising_edge(clk) then
 +            case state is
 +                when IDLE =>
 +                    if start = '1' then
 +                        x <= 1; -- Start from pixel (1,1) to avoid border issues
 +                        y <= 1;
 +                        row <= 1;
 +                        col <= 1;
 +                        state <= READ_PIXELS;
 +                        pixel_fetch_count <= 0;
 +                    end if;
 +
 +                when READ_PIXELS =>
 +                    -- Read 3x3 neighborhood
 +                    -- Calculate memory address for each pixel in the window
 +                    -- For simplicity, assume row-major order and no boundary checks
 +                    -- In practice, boundary conditions should be handled
 +                    variable addr_x, addr_y : integer;
 +                    variable addr : unsigned(15 downto 0);
 +                    begin
 +                        for i in 0 to KERNEL_SIZE-1 loop
 +                            for j in 0 to KERNEL_SIZE-1 loop
 +                                addr_x := x + j - 1 + i - 1;
 +                                addr_y := y + j - 1;
 +                                -- Boundary check
 +                                if addr_x < 0 then
 +                                    addr_x := 0;
 +                                elsif addr_x >= IMG_WIDTH then
 +                                    addr_x := IMG_WIDTH - 1;
 +                                end if;
 +                                if addr_y < 0 then
 +                                    addr_y := 0;
 +                                elsif addr_y >= IMG_HEIGHT then
 +                                    addr_y := IMG_HEIGHT - 1;
 +                                end if;
 +                                addr := to_unsigned(addr_y * IMG_WIDTH + addr_x, 16);
 +                                pixel_mem_addr <= addr;
 +                                wait for clk'period; -- Wait for memory read
 +                                pixel_window(i, j) <= pixel_mem_data;
 +                            end loop;
 +                        end loop;
 +                        state <= APPLY_CONV;
 +                    end;
 +
 +                when APPLY_CONV =>
 +                    -- Apply convolution
 +                    pixel_sum <= 0;
 +                    for i in 0 to KERNEL_SIZE-1 loop
 +                        for j in 0 to KERNEL_SIZE-1 loop
 +                            pixel_sum <= pixel_sum + kernel(i, j) * to_integer(pixel_window(i, j));
 +                        end loop;
 +                    end loop;
 +
 +                    -- Clamp the result to 0-255
 +                    if pixel_sum < 0 then
 +                        conv_result <= (others => '0');
 +                    elsif pixel_sum > 255 then
 +                        conv_result <= (others => '1');
 +                    else
 +                        conv_result <= to_unsigned(pixel_sum, 8);
 +                    end if;
 +
 +                    state <= WRITE_RESULT;
 +
 +                when WRITE_RESULT =>
 +                    -- Write the convolved pixel back to memory or output
 +                    -- For simplicity, output directly
 +                    conv_pixel_out <= conv_result;
 +
 +                    -- Move to next pixel
 +                    if x < IMG_WIDTH - 2 then
 +                        x <= x + 1;
 +                    else
 +                        x <= 1;
 +                        if y < IMG_HEIGHT - 2 then
 +                            y <= y + 1;
 +                        else
 +                            state <= DONE;
 +                            done <= '1';
 +                        end if;
 +                    end if;
 +                    state <= IDLE;
 +
 +                when DONE =>
 +                    -- Processing complete
 +                    null;
 +
 +                when others =>
 +                    null;
             end case;             end case;
         end if;         end if;
Line 525: Line 808:
  
  
-==== Matrix Multiply =====+==== GHDL FLI ====
  
 <code vhdl> <code vhdl>
 library ieee; library ieee;
 use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
-use ieee.numeric_std.all; 
  
-entity MatrixMultiplier is +entity testbench is
-    port ( +
-        clk       : in std_logic; +
-        reset     : in std_logic; +
-        start     : in std_logic; +
-        done      : out std_logic +
-        -- Optional: ports for memory interface +
-    );+
 end entity; end entity;
  
-architecture Behavioral of MatrixMultiplier is +architecture sim of testbench is 
- +    -- Declare external procedure 
-    -- Define matrix size +    procedure external_procedure(signal_value inout std_logic_vector(downto 0)); 
-    constant N integer := 2; +    -- Import the procedure from 
- +    attribute foreign of external_procedure procedure is "ghdl_fli_example";
-    -- Define data type +
-    subtype data_t is signed(15 downto 0); -- 16-bit signed numbers +
- +
-    -- Define matrices stored in memory (arrays) +
-    type matrix_t is array (0 to N-1, 0 to N-1) of data_t; +
- +
-    -- Initialize matrices A and B +
-    signal A : matrix_t := ( +
-        (to_signed(1,16), to_signed(2,16)), +
-        (to_signed(3,16), to_signed(4,16)) +
-    ); +
- +
-    signal B : matrix_t := ( +
-        (to_signed(5,16), to_signed(6,16)), +
-        (to_signed(7,16), to_signed(8,16)) +
-    ); +
- +
-    -- Result matrix +
-    signal C matrix_t := ( +
-        (others => (others => '0')) +
-    ); +
- +
-    -- Loop counters +
-    signal i, j, k : integer range 0 to N-1 := 0; +
- +
-    -- Accumulator for sum +
-    signal sum : data_t := (others => '0'); +
- +
-    -- State machine states +
-    type state_type is (IDLE, COMPUTE, DONE); +
-    signal state : state_type := IDLE;+
  
 +    signal data : std_logic_vector(7 downto 0) := (others => '0');
 begin begin
- +    process
-    process(clk, reset)+
     begin     begin
-        if reset = '1' then +        wait for 10 ns; 
-            -- Reset all signals +        external_procedure(data)
-            i <= 0+        wait
-            j <= 0+    end process
-            k <= 0+end architecture
-            sum <= (others => '0')+</code>
-            <= (others =(others => '0')); +
-            state <= IDLE; +
-            done <= '0';+
  
-        elsif rising_edge(clk) then +<code c
-            case state is +#include <stdio.h
-                when IDLE =+#include "ghdl_fli.h"  // GHDL FLI header
-                    if start = '1' then +
-                        -- Initialize counters +
-                        i <= 0; +
-                        j <= 0; +
-                        k <= 0; +
-                        sum <= (others ='0'); +
-                        state <= COMPUTE; +
-                        done <= '0'; +
-                    end if;+
  
-                when COMPUTE => +// This function will be called from VHDL 
-                    -- Perform multiplication: sum += A[i][k] B[k][j] +void ghdl_fli_example (void *args) { 
-                    sum <= sum + A(i,k) B(k,j);+    // args points to the signal 
 +    // For simplicityassume args is a pointer to an array of 8 chars 
 +    unsigned char *signal_value = (unsigned char *args;
  
-                    if k = N-1 then +    printf("C: Received signal value: 0x%02X"*signal_value);
-                        -- Store result in C[i][j] +
-                        C(i,j) <= sum; +
-                        -- Reset sum for next element +
-                        sum <= (others => '0');+
  
-                        -- Move to next column +    // Modify the signal (e.g., increment) 
-                        if j < N-1 then +    *signal_value (*signal_value + 1) & 0xFF;
-                            j <+ 1+
-                            k <= 0; +
-                        else +
-                            -- Move to next row +
-                            j <= 0; +
-                            if i < N-1 then +
-                                i <= i + 1; +
-                                k <= 0; +
-                            else +
-                                -- Computation done +
-                                state <= DONE; +
-                            end if; +
-                        end if; +
-                    else +
-                        -- Continue summing +
-                        k <= k + 1; +
-                    end if;+
  
-                when DONE => +    printf("C: Modified signal value to: 0x%02X"*signal_value)
-                    done <= '1'; +} 
-                    -- Optionallystay here or reset +</code>
-            end case+
-        end if; +
-    end process;+
  
-end architecture;+<code> 
 +gcc -shared -fPIC -o ghdl_fli_example.so ghdl_fli_example.c 
 +ghdl -a testbench.vhd 
 +ghdl -Wl,ghdl_fli_example.so -e testbench 
 +ghdl -r testbench --stop-time=50ns
 </code> </code>
  
 +https://github.com/Paebbels/JSON-for-VHDL
  
vhdl.1761767604.txt.gz · Last modified: 2025/10/29 19:53 by 147.32.8.31