Site Tools


vhdl

This is an old revision of the document!


Table of Contents

VHDL

https://www.mouser.com/datasheet/2/598/DE25_Standard_User_manual_revC-3680989.pdf

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity Conv2D is
    generic (
        KERNEL_SIZE : integer := 3;    -- e.g., 3x3 kernel
        IMG_SIZE    : integer := 8;    -- Input image size (e.g., 8x8)
        -- Kernel weights (example: simple edge detection)
        -- For real use, replace with learned weights from ONNX model
        -- For 3x3 kernel
        kernel_weights : array (0 to KERNEL_SIZE-1, 0 to KERNEL_SIZE-1) of signed(7 downto 0) := (
            (to_signed(-1,8), to_signed(-1,8), to_signed(-1,8)),
            (to_signed(-1,8), to_signed(8,8),  to_signed(-1,8)),
            (to_signed(-1,8), to_signed(-1,8), to_signed(-1,8))
        )
    );
    port (
        clk       : in std_logic;
        reset     : in std_logic;
        input_pixel  : in std_logic_vector(7 downto 0);
        -- For simplicity, assuming streaming input pixel by pixel
        -- Implement line buffers to handle 2D windowing
        -- Output
        conv_out  : out std_logic_vector(15 downto 0)
    );
end Conv2D;
 
architecture Behavioral of Conv2D is
 
    -- Line buffers to store previous rows
    type line_buffer_type is array (0 to KERNEL_SIZE-2, 0 to IMG_SIZE-1) of signed(7 downto 0);
    signal line_buffer : line_buffer_type;
 
    -- Window buffer to hold current KxK pixels
    type window_type is array (0 to KERNEL_SIZE-1, 0 to KERNEL_SIZE-1) of signed(7 downto 0);
    signal window : window_type;
 
    -- Counters to track position
    signal row_cnt, col_cnt : integer range 0 to IMG_SIZE-1 := 0;
 
begin
 
    process(clk, reset)
    begin
        if reset = '1' then
            row_cnt <= 0;
            col_cnt <= 0;
            -- Initialize buffers if needed
        elsif rising_edge(clk) then
            -- Shift input pixel into line buffers
            -- Update line buffers
            for i in 0 to KERNEL_SIZE-2 loop
                line_buffer(i, col_cnt) <= line_buffer(i+1, col_cnt);
            end loop;
            if row_cnt = 0 then
                -- First row, no previous data
                line_buffer(0, col_cnt) <= signed(input_pixel);
            else
                line_buffer(0, col_cnt) <= signed(input_pixel);
            end if;
 
            -- Fill window
            if row_cnt >= KERNEL_SIZE-1 and col_cnt >= KERNEL_SIZE-1 then
                -- Collect window pixels
                for i in 0 to KERNEL_SIZE-1 loop
                    for j in 0 to KERNEL_SIZE-1 loop
                        if i = KERNEL_SIZE-1 and j = KERNEL_SIZE-1 then
                            -- current pixel
                            window(i,j) <= signed(input_pixel);
                        elsif i = KERNEL_SIZE-1 then
                            -- same row, from line buffer
                            window(i,j) <= line_buffer(i-1, col_cnt - (KERNEL_SIZE - 1 - j));
                        elsif j = KERNEL_SIZE-1 then
                            -- from previous line buffer
                            window(i,j) <= line_buffer(i-1, col_cnt - (KERNEL_SIZE - 1 - j));
                        else
                            -- For simplicity, assume all data is available
                            -- In practice, implement proper line buffering
                        end if;
                    end loop;
                end loop;
 
                -- Perform convolution
                variable sum : signed(15 downto 0) := (others => '0');
                for i in 0 to KERNEL_SIZE-1 loop
                    for j in 0 to KERNEL_SIZE-1 loop
                        sum := sum + resize(window(i,j), 16) * resize(kernel_weights(i,j), 16);
                    end loop;
                end loop;
 
                conv_out <= std_logic_vector(sum);
            end if;
 
            -- Update column counter
            if col_cnt = IMG_SIZE - 1 then
                col_cnt <= 0;
                if row_cnt = IMG_SIZE - 1 then
                    row_cnt <= 0;
                else
                    row_cnt <= row_cnt + 1;
                end if;
            else
                col_cnt <= col_cnt + 1;
            end if;
        end if;
    end process;
end Behavioral;

DDR Memory

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity DDR_Read_Write is
    port (
        clk           : in std_logic;            -- System clock
        reset_n       : in std_logic;            -- Active low reset
        -- DDR controller interface signals
        -- These are placeholder signals; replace with your DDR controller's interface
        ddr_addr      : out std_logic_vector(31 downto 0);
        ddr_dq        : inout std_logic_vector(63 downto 0); -- Data bus
        ddr_dqs       : inout std_logic_vector(7 downto 0);
        ddr_we_n      : out std_logic;
        ddr_oe_n      : out std_logic;
        ddr_cs_n      : out std_logic;
        -- Control signals for read/write
        start_write   : in std_logic;
        start_read    : in std_logic;
        write_data    : in std_logic_vector(63 downto 0);
        read_data     : out std_logic_vector(63 downto 0);
        write_done    : out std_logic;
        read_done     : out std_logic
    );
end entity;
 
architecture Behavioral of DDR_Read_Write is
 
    type state_type is (IDLE, WRITE, READ, DONE);
    signal state : state_type := IDLE;
 
    signal addr_reg : std_logic_vector(31 downto 0) := (others => '0');
    signal data_reg : std_logic_vector(63 downto 0) := (others => '0');
 
begin
 
    process(clk, reset_n)
    begin
        if reset_n = '0' then
            state <= IDLE;
            ddr_we_n <= '1';
            ddr_oe_n <= '1';
            ddr_cs_n <= '1';
            write_done <= '0';
            read_done <= '0';
            read_data <= (others => '0');
            addr_reg <= (others => '0');
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    write_done <= '0';
                    read_done <= '0';
                    if start_write = '1' then
                        addr_reg <= (others => '0'); -- Set your address here
                        data_reg <= write_data;
                        state <= WRITE;
                    elsif start_read = '1' then
                        addr_reg <= (others => '0'); -- Set your address here
                        state <= READ;
                    end if;
 
                when WRITE =>
                    -- Drive DDR signals for write
                    ddr_addr <= addr_reg;
                    ddr_dq <= data_reg;
                    ddr_we_n <= '0'; -- Assert write enable
                    ddr_oe_n <= '1'; -- Disable output during write
                    ddr_cs_n <= '0'; -- Chip select active
                    -- Add necessary timing delays as per DDR spec
                    -- For simplicity, assume one cycle write
                    write_done <= '1';
                    ddr_we_n <= '1'; -- Deassert write enable
                    ddr_cs_n <= '1';
                    state <= IDLE;
 
                when READ =>
                    -- Drive DDR signals for read
                    ddr_addr <= addr_reg;
                    ddr_we_n <= '1';
                    ddr_oe_n <= '0'; -- Enable output
                    ddr_cs_n <= '0';
                    -- Wait for data to be valid (depends on DDR timing)
                    -- For simplicity, assume data is ready immediately
                    read_data <= ddr_dq;
                    read_done <= '1';
                    ddr_oe_n <= '1';
                    ddr_cs_n <= '1';
                    state <= IDLE;
 
                when others =>
                    state <= IDLE;
            end case;
        end if;
    end process;
 
end architecture;

SDRAM Memory

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity sdram_controller is
    port (
        clk          : in  std_logic;
        reset        : in  std_logic;
        -- Control signals
        wr_enable    : in  std_logic; -- Write enable
        rd_enable    : in  std_logic; -- Read enable
        address      : in  std_logic_vector(23 downto 0); -- Address bus
        write_data   : in  std_logic_vector(15 downto 0); -- Data to write
        read_data    : out std_logic_vector(15 downto 0); -- Data read from SDRAM
        read_valid   : out std_logic; -- Indicates valid read data
        -- SDRAM interface signals (simplified)
        sdram_dq     : inout std_logic_vector(15 downto 0);
        sdram_addr   : out std_logic_vector(12 downto 0);
        sdram_ba     : out std_logic_vector(1 downto 0);
        sdram_cs_n   : out std_logic;
        sdram_ras_n  : out std_logic;
        sdram_cas_n  : out std_logic;
        sdram_we_n   : out std_logic
    );
end entity;
 
===== DDR Memory =====
 
architecture Behavioral of sdram_controller is
 
    type state_type is (
        IDLE,
        PRECHARGE,
        ACTIVATE,
        WRITE,
        READ,
        PRECHARGE_AFTER,
        WAIT
    );
    signal state       : state_type := IDLE;
    signal next_state  : state_type;
 
    -- Internal signals
    signal row_address : std_logic_vector(12 downto 0);
    signal col_address : std_logic_vector(9 downto 0);
    signal data_out    : std_logic_vector(15 downto 0);
    signal data_in     : std_logic_vector(15 downto 0);
    signal data_valid  : std_logic := '0';
 
    -- Timing counters (simplified)
    signal wait_counter : integer := 0;
 
begin
 
    process(clk, reset)
    begin
        if reset = '1' then
            state <= IDLE;
            sdram_cs_n <= '1';
            sdram_ras_n <= '1';
            sdram_cas_n <= '1';
            sdram_we_n <= '1';
            sdram_addr <= (others => '0');
            sdram_ba <= (others => '0');
            read_data <= (others => '0');
            read_valid <= '0';
            wait_counter <= 0;
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    read_valid <= '0';
                    if wr_enable = '1' then
                        -- Initiate write sequence
                        sdram_cs_n <= '0';
                        sdram_ras_n <= '0';
                        sdram_cas_n <= '1';
                        sdram_we_n <= '0'; -- Write command
                        sdram_addr <= address(12 downto 0); -- Column address
                        sdram_ba <= "00"; -- Bank address, adapt as needed
                        state <= PRECHARGE;
                        wait_counter <= 2; -- Wait cycles for command
                        data_out <= write_data;
                    elsif rd_enable = '1' then
                        -- Initiate read sequence
                        sdram_cs_n <= '0';
                        sdram_ras_n <= '0';
                        sdram_cas_n <= '0'; -- Read command
                        sdram_we_n <= '1';
                        sdram_addr <= address(12 downto 0);
                        sdram_ba <= "00"; -- Bank address
                        state <= PRECHARGE;
                        wait_counter <= 2; -- Wait cycles for command
                    end if;
 
                when PRECHARGE =>
                    if wait_counter > 0 then
                        wait_counter <= wait_counter - 1;
                    else
                        -- Activate row
                        sdram_ras_n <= '0';
                        sdram_cas_n <= '1';
                        sdram_we_n <= '1';
                        sdram_addr <= address(23 downto 11); -- Row address
                        state <= ACTIVATE;
                        wait_counter <= 2;
                    end if;
 
                when ACTIVATE =>
                    if wait_counter > 0 then
                        wait_counter <= wait_counter - 1;
                    else
                        if wr_enable = '1' then
                            -- Issue write command
                            sdram_ras_n <= '1';
                            sdram_cas_n <= '0';
                            sdram_we_n <= '0';
                            sdram_addr <= address(12 downto 0); -- Column address
                            state <= WRITE;
                            wait_counter <= 2;
                        elsif rd_enable = '1' then
                            -- Issue read command
                            sdram_ras_n <= '1';
                            sdram_cas_n <= '0';
                            sdram_we_n <= '1';
                            sdram_addr <= address(12 downto 0); -- Column address
                            state <= READ;
                            wait_counter <= 2;
                        end if;
                    end if;
 
                when WRITE =>
                    if wait_counter > 0 then
                        wait_counter <= wait_counter - 1;
                        sdram_dq <= data_out;
                    else
                        -- Finish write
                        sdram_cs_n <= '1';
                        sdram_ras_n <= '1';
                        sdram_cas_n <= '1';
                        sdram_we_n <= '1';
                        state <= WAIT;
                        wait_counter <= 2; -- Wait before next command
                    end if;
 
                when READ =>
                    if wait_counter > 0 then
                        wait_counter <= wait_counter - 1;
                    else
                        -- Read data (assuming data is valid after tRCD)
                        read_data <= sdram_dq;
                        read_valid <= '1';
                        sdram_cs_n <= '1';
                        sdram_ras_n <= '1';
                        sdram_cas_n <= '1';
                        sdram_we_n <= '1';
                        state <= WAIT;
                        wait_counter <= 2;
                    end if;
 
                when WAIT =>
                    if wait_counter > 0 then
                        wait_counter <= wait_counter - 1;
                    else
                        state <= IDLE; -- Ready for next operation
                    end if;
 
                when others =>
                    state <= IDLE;
            end case;
        end if;
    end process;
 
end Behavioral;
vhdl.1761767120.txt.gz · Last modified: 2025/10/29 19:45 by 147.32.8.31