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:45] 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 392: Line 390:
 end Behavioral; end Behavioral;
 </code> </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 if;
 +    end process;
 +
 +end Behavioral;
 +</code>
 +
 +==== ghdl memory ====
 +
 +<code vhdl>
 +library ieee;
 +use ieee.std_logic_1164.all;
 +use ieee.numeric_std.all;
 +
 +entity ram is
 +    generic (
 +        DATA_WIDTH : integer := 8;  -- Width of data bus
 +        ADDR_WIDTH : integer := 4   -- Width of address bus (16 addresses)
 +    );
 +    port (
 +        clk      : in std_logic;
 +        we       : in std_logic; -- Write enable
 +        addr     : in std_logic_vector(ADDR_WIDTH-1 downto 0);
 +        data_in  : in std_logic_vector(DATA_WIDTH-1 downto 0);
 +        data_out : out std_logic_vector(DATA_WIDTH-1 downto 0)
 +    );
 +end entity;
 +
 +architecture Behavioral of ram is
 +    type mem_type is array (0 to 2**ADDR_WIDTH - 1) of std_logic_vector(DATA_WIDTH-1 downto 0);
 +    signal mem : mem_type := (others => (others => '0'));
 +begin
 +    process(clk)
 +    begin
 +        if rising_edge(clk) then
 +            if we = '1' then
 +                -- Write operation
 +                mem(to_integer(unsigned(addr))) <= data_in;
 +            end if;
 +            -- Read operation
 +            data_out <= mem(to_integer(unsigned(addr)));
 +        end if;
 +    end process;
 +end architecture;
 +</code>
 +
 +<code vhdl>
 +library ieee;
 +use ieee.std_logic_1164.all;
 +use ieee.numeric_std.all;
 +
 +entity tb_ram is
 +end entity;
 +
 +architecture Behavioral of tb_ram is
 +    signal clk      : std_logic := '0';
 +    signal we       : std_logic := '0';
 +    signal addr     : std_logic_vector(3 downto 0);
 +    signal data_in  : std_logic_vector(7 downto 0);
 +    signal data_out : std_logic_vector(7 downto 0);
 +    
 +    component ram
 +        generic (
 +            DATA_WIDTH : integer := 8;
 +            ADDR_WIDTH : integer := 4
 +        );
 +        port (
 +            clk      : in std_logic;
 +            we       : in std_logic;
 +            addr     : in std_logic_vector(ADDR_WIDTH-1 downto 0);
 +            data_in  : in std_logic_vector(DATA_WIDTH-1 downto 0);
 +            data_out : out std_logic_vector(DATA_WIDTH-1 downto 0)
 +        );
 +    end component;
 +begin
 +    uut: ram
 +        port map (
 +            clk => clk,
 +            we => we,
 +            addr => addr,
 +            data_in => data_in,
 +            data_out => data_out
 +        );
 +
 +    -- Clock generation
 +    clk_process : process
 +    begin
 +        while true loop
 +            clk <= '0';
 +            wait for 10 ns;
 +            clk <= '1';
 +            wait for 10 ns;
 +        end loop;
 +    end process;
 +
 +    -- Test sequence
 +    stim_proc: process
 +    begin
 +        -- Write data to address 0x1
 +        addr <= "0001";
 +        data_in <= "10101010";
 +        we <= '1';
 +        wait for 20 ns;
 +
 +        -- Disable write
 +        we <= '0';
 +        wait for 20 ns;
 +
 +        -- Read from address 0x1
 +        addr <= "0001";
 +        wait for 20 ns;
 +
 +        -- Write data to address 0x2
 +        addr <= "0010";
 +        data_in <= "11001100";
 +        we <= '1';
 +        wait for 20 ns;
 +
 +        -- Disable write
 +        we <= '0';
 +        wait for 20 ns;
 +
 +        -- Read from address 0x2
 +        addr <= "0010";
 +        wait for 20 ns;
 +
 +        wait;
 +    end process;
 +end architecture;
 +</code>
 +
 +<code>
 +Compile:            ghdl -a ram.vhd tb_ram.vhd
 +Elaborate:          ghdl -e tb_ram
 +Run the simulation: ghdl -r tb_ram --wave=wave.ghw
 +View waveform:      gtkwave wave.ghw
 +</code>
 +
 +
 +==== GHDL FLI ====
 +
 +<code vhdl>
 +library ieee;
 +use ieee.std_logic_1164.all;
 +
 +entity testbench is
 +end entity;
 +
 +architecture sim of testbench is
 +    -- Declare external procedure
 +    procedure external_procedure(signal_value : inout std_logic_vector(7 downto 0));
 +    -- Import the procedure from C
 +    attribute foreign of external_procedure : procedure is "ghdl_fli_example";
 +
 +    signal data : std_logic_vector(7 downto 0) := (others => '0');
 +begin
 +    process
 +    begin
 +        wait for 10 ns;
 +        external_procedure(data);
 +        wait;
 +    end process;
 +end architecture;
 +</code>
 +
 +<code c>
 +#include <stdio.h>
 +#include "ghdl_fli.h"  // GHDL FLI header
 +
 +// This function will be called from VHDL
 +void ghdl_fli_example (void *args) {
 +    // args points to the signal
 +    // For simplicity, assume args is a pointer to an array of 8 chars
 +    unsigned char *signal_value = (unsigned char *) args;
 +
 +    printf("C: Received signal value: 0x%02X", *signal_value);
 +
 +    // Modify the signal (e.g., increment)
 +    *signal_value = (*signal_value + 1) & 0xFF;
 +
 +    printf("C: Modified signal value to: 0x%02X", *signal_value);
 +}
 +</code>
 +
 +<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>
 +
 +https://github.com/Paebbels/JSON-for-VHDL
 +
vhdl.1761767120.txt.gz · Last modified: 2025/10/29 19:45 by 147.32.8.31