vhdl
                Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| vhdl [2025/10/29 19:53] – [ghdl memory] 147.32.8.31 | vhdl [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; | ||
| + | </ | ||
| + | |||
| + | ==== 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, | ||
| + | (to_signed(3, | ||
| + | ); | ||
| + | |||
| + | signal B : matrix_t := ( | ||
| + | (to_signed(5, | ||
| + | (to_signed(7, | ||
| + | ); | ||
| + | |||
| + | -- Result matrix C | ||
| + | signal C : matrix_t := ( | ||
| + | (others => (others => ' | ||
| + | ); | ||
| + | |||
| + | -- Loop counters | ||
| + | signal i, j, k : integer range 0 to N-1 := 0; | ||
| + | |||
| + | -- Accumulator for sum | ||
| + | signal sum : data_t := (others => ' | ||
| + | |||
| + | -- State machine states | ||
| + | type state_type is (IDLE, COMPUTE, DONE); | ||
| + | signal state : state_type := IDLE; | ||
| + | |||
| + | begin | ||
| + | |||
| + | process(clk, | ||
| + | begin | ||
| + | if reset = ' | ||
| + | -- Reset all signals | ||
| + | i <= 0; | ||
| + | j <= 0; | ||
| + | k <= 0; | ||
| + | sum <= (others => ' | ||
| + | C <= (others => (others => ' | ||
| + | state <= IDLE; | ||
| + | done <= ' | ||
| + | |||
| + | elsif rising_edge(clk) then | ||
| + | case state is | ||
| + | when IDLE => | ||
| + | if start = ' | ||
| + | -- Initialize counters | ||
| + | i <= 0; | ||
| + | j <= 0; | ||
| + | k <= 0; | ||
| + | sum <= (others => ' | ||
| + | state <= COMPUTE; | ||
| + | done <= ' | ||
| + | end if; | ||
| + | |||
| + | when COMPUTE => | ||
| + | -- Perform multiplication: | ||
| + | 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 => ' | ||
| + | |||
| + | -- 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 <= ' | ||
| + | -- Optionally, stay here or reset | ||
| + | end case; | ||
| + | end if; | ||
| + | end process; | ||
| + | |||
| + | end architecture; | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== 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 | ||
| + | pixel_mem_data | ||
| + | pixel_mem_we | ||
| + | -- Output | ||
| + | conv_pixel_out | ||
| + | done : out std_logic | ||
| + | ); | ||
| + | end entity; | ||
| + | |||
| + | architecture Behavioral of convolution_kernel is | ||
| + | |||
| + | -- Define kernel size | ||
| + | constant KERNEL_SIZE : integer := 3; | ||
| + | constant IMG_WIDTH | ||
| + | constant IMG_HEIGHT | ||
| + | |||
| + | -- Convolution kernel (e.g., sharpening kernel) | ||
| + | type kernel_type is array (0 to KERNEL_SIZE-1, | ||
| + | constant kernel : kernel_type := ( | ||
| + | (0, -1, 0), | ||
| + | (-1, 5, -1), | ||
| + | (0, -1, 0) | ||
| + | ); | ||
| + | |||
| + | -- State machine states | ||
| + | type state_type is (IDLE, READ_PIXELS, | ||
| + | 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, | ||
| + | signal pixel_sum : integer := 0; | ||
| + | signal conv_result : unsigned(7 downto 0) := (others => ' | ||
| + | |||
| + | -- 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, | ||
| + | begin | ||
| + | if reset = ' | ||
| + | state <= IDLE; | ||
| + | pixel_mem_addr <= (others => ' | ||
| + | pixel_mem_we <= ' | ||
| + | conv_pixel_out <= (others => ' | ||
| + | done <= ' | ||
| + | x <= 0; | ||
| + | y <= 0; | ||
| + | row <= 0; | ||
| + | col <= 0; | ||
| + | elsif rising_edge(clk) then | ||
| + | case state is | ||
| + | when IDLE => | ||
| + | if start = ' | ||
| + | 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' | ||
| + | pixel_window(i, | ||
| + | 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, | ||
| + | end loop; | ||
| + | end loop; | ||
| + | |||
| + | -- Clamp the result to 0-255 | ||
| + | if pixel_sum < 0 then | ||
| + | conv_result <= (others => ' | ||
| + | elsif pixel_sum > 255 then | ||
| + | conv_result <= (others => ' | ||
| + | else | ||
| + | conv_result <= to_unsigned(pixel_sum, | ||
| + | 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 <= ' | ||
| + | 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 | + | entity | 
| - | 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 | + | architecture | 
| - | + | -- Declare external procedure | |
| - | -- Define matrix size | + |  | 
| - |  | + | -- Import the procedure from C | 
| - | + |  | |
| - | -- 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, | + | |
| - | (to_signed(3, | + | |
| - | ); | + | |
| - | + | ||
| - | signal B : matrix_t := ( | + | |
| - | (to_signed(5, | + | |
| - | (to_signed(7, | + | |
| - | ); | + | |
| - | + | ||
| - | -- Result matrix | + | |
| - |  | + | |
| - | (others => (others => ' | + | |
| - | ); | + | |
| - | + | ||
| - | -- Loop counters | + | |
| - | signal i, j, k : integer range 0 to N-1 := 0; | + | |
| - | + | ||
| - | -- Accumulator for sum | + | |
| - | signal sum : data_t := (others => ' | + | |
| - | + | ||
| - | -- State machine states | + | |
| - | type state_type | + | |
| - | signal state : state_type := IDLE; | + | |
| + | signal data : std_logic_vector(7 downto 0) := (others => ' | ||
| begin | begin | ||
| - | + |  | |
| - |  | + | |
| begin | begin | ||
| - |  | + |  | 
| - | -- Reset all signals | + |  | 
| - | i <= 0; | + | wait; | 
| - | j <= 0; | + | end process; | 
| - | k <= 0; | + | end architecture; | 
| - | sum <= (others => ' | + | </code> | 
| - |  | + | |
| - | state <= IDLE; | + | |
| - | done <= ' | + | |
| - | elsif rising_edge(clk) then | + | <code c> | 
| - | case state is | + | # | 
| - | when IDLE => | + | #include " | 
| - | if start = ' | + | |
| - | -- Initialize counters | + | |
| - | i <= 0; | + | |
| - | j <= 0; | + | |
| - | k <= 0; | + | |
| - | sum <= (others => ' | + | |
| - | state <= COMPUTE; | + | |
| - | done <= ' | + | |
| - | end if; | + | |
| - | when COMPUTE => | + | // This function will be called from VHDL | 
| - | -- Perform multiplication: | + | void ghdl_fli_example (void *args) { | 
| - | sum <= sum + A(i,k) * B(k,j); | + | // 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; | ||
| - | if k = N-1 then | + | printf(" | 
| - | -- Store result in C[i][j] | + | |
| - | C(i,j) <= sum; | + | |
| - | -- Reset sum for next element | + | |
| - | sum <= (others => ' | + | |
| - | -- Move to next column | + | // Modify the signal (e.g., increment) | 
| - | 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 => | + | printf(" | 
| - | done <= ' | + | } | 
| - | -- Optionally, stay here or reset | + | </ | 
| - | end case; | + | |
| - | end if; | + | |
| - | end process; | + | |
| - | end architecture; | + | < | 
| + | gcc -shared -fPIC -o ghdl_fli_example.so ghdl_fli_example.c | ||
| + | ghdl -a testbench.vhd | ||
| + | ghdl -Wl, | ||
| + | ghdl -r testbench --stop-time=50ns | ||
| </ | </ | ||
| + | https:// | ||
vhdl.1761767604.txt.gz · Last modified: 2025/10/29 19:53 by 147.32.8.31
                
                