Showing posts with label vhdl. Show all posts
Showing posts with label vhdl. Show all posts

Programming problem: Synthsizable filter design in C++

Problem statement: Develop a synthesizable C/C++ function which is capable of performing image filtering. The filtering operation is defined by following equation:


// B -> filtered image
// A -> Input image
// h -> filter coefficients
int filter_func() {
                const int L = 1;
                const int x_size = 255;
                const int y_size = 255;
                int A_image[x_size][y_size];
                int B_image[x_size][y_size];
                int h[2*L+1][2*L+1];
                // Initializing the filtered image
                for (int i = 0; i < x_size; i++) {
                                for (int j = 0; j < y_size; j++) {
                                                B_image[i][j] = 0;
                                }
                }
                for (int i = 0; i < x_size; i++) {
                                for (int j = 0; j < y_size; j++) {
                                                for (int l = -L; l <= L; l++) {
                                                                for (int k = -L; k <= L; k++) {
                                                                                B_image[i][j] = B_image[i][j] + A_image[i-k][j-l]*h[k+L][l+L];
                                                                }
                                                }
                                }
                }
}

Hope you’ve found this post useful. Let us know what you think in the comments.

VHDL code for clock divider

A clock divider is used to get a divided version of a clock. Clock dividers are a very important component of digital design, and are used ubiquitously.

VHDL code for a configurable clock divider: Following is the VHDL code for a configurable divider. It can divide by any number with 50% duty cycle. It makes use of a dual edge-triggered decrement counter, with configurable load; thereby enabling it to divide by any number.

Following is the entity and architecture definitions of top module for clock divider. It takes generic parameter max_bits, which puts a limit on the maximum division that can be obtained with the help of this divider. It takes the divide_value as input, the division ratio of output clock with respect to input clock. The output clock is a divided version of input clock depending on the value of divide_value. We have instantiated a component decr_counter, which takes a parameter and counts downto 0 as discussed in further detail below.

-- This module is for a configurable divider that takes value from a counter and toggles the output clock whenever it receives all zero count.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

ENTITY configurable_divider IS
    GENERIC (
        MAX_BITS : INTEGER := 10
            );
    PORT (
        in_clk : IN bit;
        rst : IN bit;
        out_clk : OUT bit;
        divide_value : IN bit_vector(MAX_BITS DOWNTO 0)
         );
END ENTITY;

ARCHITECTURE behavioral OF configurable_divider IS
    -- Declaring a component of configurable_decr_counter
    COMPONENT configurable_decr_counter
        GENERIC (
            MAX_BITS : INTEGER := 10
                );
        PORT (
            clk : IN bit;
            rst : IN bit;
            load_count : IN bit_vector (MAX_BITS DOWNTO 0);
            count : OUT bit_vector (MAX_BITS DOWNTO 0)
             );
    END COMPONENT;
    -- signal declarations
    SIGNAL load_count_reg : bit_vector (MAX_BITS DOWNTO 0);
    SIGNAL curr_count_value : bit_vector (MAX_BITS DOWNTO 0);
    signal out_clk_int : bit;
BEGIN
    PROCESS
    BEGIN
        WAIT UNTIL in_clk'EVENT;
            IF to_StdLogicVector(curr_count_value) = 1 THEN
                out_clk_int <= NOT out_clk_int;
            END IF;
    END PROCESS;
    out_clk <= out_clk_int;
    -- Instantiating configurable_decr_counter
    decr_counter : configurable_decr_counter GENERIC MAP (
                                                            MAX_BITS
                                                                      )
                                                          PORT MAP (
                                                            clk => in_clk,
                                                            rst => rst,
                                                            load_count => divide_value,
                                                            count => curr_count_value
                                                                   );

END ARCHITECTURE behavioral;


Given below is the entity and architecture definition of decr_counter module. It keeps on decrementing until it reaches value 0. On reaching zero, it loads itself with a pre-determined value that is provided as an input to the counter from its top module.

-- This is the VHDL code for a configurable dual edge-triggered decrement counter.
library IEEE;

use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

ENTITY configurable_decr_counter IS
    GENERIC (
        MAX_BITS : INTEGER := 10
            );
    -- Port definitions
    PORT (
        clk : IN bit;
        rst : IN bit;
        load_count : IN bit_vector (MAX_BITS DOWNTO 0);
        count : OUT bit_vector (MAX_BITS DOWNTO 0)
         );
END ENTITY;


ARCHITECTURE behavioral OF configurable_decr_counter IS
    SIGNAL count_value : std_logic_vector (MAX_BITS DOWNTO 0);
BEGIN
    PROCESS(clk,rst)
    BEGIN
        IF rst = '1' THEN
            count <= "000000";
            count_value <= "000001";
        ELSIF clk'EVENT THEN
            IF count_value = 1 THEN
                count_value <= to_StdLogicVector(load_count);
            ELSE
                count_value <= count_value - 1;
            END IF;
            count <= to_bitvector(count_value);
        END IF;
    END PROCESS;
END ARCHITECTURE behavioral;


By the way, this code is not synthesizable, although it will simulate perfectly. We have to make a simple modification to the code to make it synthesizable. Any guesses what makes this code not being synthesized by a synthesis tool? Hope you’ve found this post useful. Let us know what you think in the comments.

Also read:



Defining a clock signal in VHDL

Defining a clock signal in VHDL
Clock is the backbone of any synchronous design. For test-benches, a clock is the most desired signal as almost every design requires a clock. Going a bit deeper, a clock signal is a binary signal that changes state every few time units. So, defining a clock in VHDL is pretty simple, as shown below in the following code:
                signal my_clock : std_logic;
                process               
                                my_clock <= ‘0’;
                                wait for 5 ns;
                                my_clock = ‘1’;
                                wait for 5 ns;
                end process;
The above code defines a clock of  period 10 ns with 5 ns high time and 5 ns low time, hence, 50% duty cycle. Since, we are assigning a value to my_clock in the code, it can wither be defines as a signal or an output. Most probably, clocks are defined in test-benches, hence, are internal signals. High time and low time don’t always need to be same. You can always define a clock that has different high and low times as shown below:
signal my_clock : std_logic;
                process
                                my_clock <= ‘0’;
                                wait for 8 ns;
                                my_clock = ‘1’;
                                wait for 2 ns;
                end process;
As we can see, now, my_clock has a duty cycle of 80%; i.e. a high time of 80% and a low time of 20%.

Defining a clock in this way, obviously, is not synthesizable as we are using delays in code, and delays cannot be synthesized. Hence, this way of defining a clock can only be used in a test-bench to test a piece of code. If you need to write a synthesizable clock, then you have to use structural coding. The simplest of clock generation circuits is a ring counter (a chain of inverters connected back-to-back), but it will have a variable frequency clock because delay of inverters changes on change in operating conditions.