Problem in VHDL code.

Discussion in 'Hardware' started by caylakprogramci, Apr 18, 2007.

  1. caylakprogramci

    caylakprogramci

    Joined:
    Apr 18, 2007
    Messages:
    1
    Likes Received:
    0
    This is my code. At first I want to add 4 four bits variables and then divide the result to 4. But the code that I wrote does not work. I have two other variables except A,B,C and D. These are current and next. Current shows the previous clocks result and next shows the result in current clock. For example at clock0 A,B,C and D are 0010, result is average value 0010. At clock0 current is 0, next is 0010 and at clock1 current is 0010 and next is the new values average.

    LIBRARY IEEE;
    USE IEEE.std_logic_1164.ALL;
    USE ieee.std_logic_unsigned.all;
    USE ieee.std_logic_arith.all;

    ENTITY avg1 IS

    PORT( A,B,C,D : IN std_logic_vector(3 DOWNTO 0);
    current, next_val : INOUT INTEGER );
    END avg1;

    ARCHITECTURE avg1_a OF odev1 IS
    BEGIN
    next_val <= 0;
    next_val <= CONV_INTEGER(A+B+C+D)/4 ;
    current <= next_val;
    END avg1_a ;
     
    caylakprogramci, Apr 18, 2007
    #1
    1. Advertisements

  2. caylakprogramci

    Ahmed Samieh

    Joined:
    Mar 22, 2007
    Messages:
    1
    Likes Received:
    0
    Code:
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.numeric_std.all;
    --
    ENTITY Mean IS
    PORT(clk              : IN  std_logic
         A,B,C,D          : IN  std_logic_vector(3 DOWNTO 0);
         lst_val,crnt_val : OUT std_logic_vector(3 DOWNTO 0));
    END ENTITY Mean;
    --
    ARCHITECTURE Arch OF Mean IS
    BEGIN
      PROCESS(clk,A,B,C,D)
        VARIABLE temp_v : unsigned(4 DOWNTO 0);
      BEGIN
        IF rising_edge(clk) THEN
          lst_val <= std_logic_vector(temp_v(3 DOWNTO 0));
          temp_v  := ( unsigned("0"&A) +
                       unsigned("0"&B) +
                       unsigned("0"&C) +
                       unsigned("0"&D) ) / 4;
          crnt_val  <= std_logic_vector(temp_v(3 DOWNTO 0));
        END IF;
      END PROCESS;
    END ARCHITECTURE Arch;
    1 - use ieee.numeric_std.all instead of ieee.std_logic_unsigned.all, ieee.std_logic_arith.all
    2 - use internal signal/variable insted of using INOUT port
    3 - add clok port to the entity
    4 - use process for this task
     
    Ahmed Samieh, Apr 19, 2007
    #2
    1. Advertisements

  3. caylakprogramci

    scottcarl

    Joined:
    May 4, 2007
    Messages:
    2
    Likes Received:
    0
    Location:
    USA
    This is a more synthesizable type solution for your problem. Put the unsigned library in the header. Don't use a "/" for a synthesizeable divide because it won't work at any decent clock speed. You'll need to use a Core (Xilinx or Altera or whatever) that will have significant amounts of timing delay. So use a bit-chopping whenever you're dividing by a power of 2. Don't forget to round. (Adding the bit below the desired lsb works in most cases. Watch out for signed negative numbers when the cut lsbs are exactly .5. i.e. 10101.100 (-11.5) --> the "100" (.5) should be rounded down in that case making -12.0 (10100), not -11 (10101))
    Code:
    LIBRARY ieee;
    USE ieee.std_logic_1164.all;
    USE ieee.numeric_std.all;
    USE ieee.std_logic_unsigned.all;  -- include your proper library here (unsigned)
    --
    ENTITY Mean IS
    PORT(clk                    : IN  std_logic
         A,B,C,D                 : IN  std_logic_vector(3 DOWNTO 0);
         the_mean              : OUT std_logic_vector(3 DOWNTO 0);
         the_sum                : OUT std_logic_vector(5 DOWNTO 0));
    END ENTITY Mean;
    --
    ARCHITECTURE Arch OF Mean IS
    
    signal sum : std_logic_vector(5 downto 0);
    
    BEGIN
      PROCESS(clk,reset)
      BEGIN
        IF (reset = '1') then  -- never forget the reset condition
          sum          <= (others => '0');
          the_mean  <= (others => '0');
        ELSIF rising_edge(clk) THEN
          sum          <= A+B+C+D;
          the_mean  <= sum(5 DOWNTO 2) + sum(1); -- /4 & round up
        END IF;         -- Never use a "/" in synthesizable code (create a Core)
      END PROCESS;
    
    the_sum <= sum(5 downto 0);  -- This is the current value
    
    END ARCHITECTURE Arch;
     
    Last edited: May 7, 2007
    scottcarl, May 7, 2007
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.