Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

VHDL problem?

QUESTION:

Develop a VHDL model for an accumulator that calculates the sum of a sequence of fixed-point numbers.

Each input number is signed with 4 pre-binary-point and 12 post-binary-point bits.

The accumulated sum has 8 pre-binary-point and 12 post-binary-point bits.

A new number arrives at the input during a clock cycle when the data_en control input is 1.

The accumulated sum is cleared to 0 when the reset control input is 1.

Both control inputs are synchronous.

DOUBT:

I want to ask how to insert the first input and second input as it using the pre and post numbers?

How to store the value for the first input for awhile before it add the second input?

The output will light up using LED at the board that we assign it by ourselves.

library ieee;

use ieee.std_logic_1164.all, ieee.numeric_std.all;

entity accumulator is

port (clk,reset, data_en : in std_logic;

data_in : in signed(15 downto 0);

data_out : out signed(19 downto 0) );

end entity accumulator;

architecture rtl of accumulator is

signal sum, new_sum :signed(19 downto 0);

begin

new_sum <= sum + resize(data_in, sum'length);

reg:process (clk) is

begin

if rising_edge(clk) then

if reset = '1' then

sum <= (others => '0');

elsif data_en = '1' then

sum <= new_sum;

end if;

end if;

end process reg;

data_out <= sum;

end architecture rtl;

-KYRA-:)

17 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    --this is my code but there are errors..

    --the errors are

    Error (10344): VHDL expression error at acc.vhd(97): expression has 16 elements, but must have 20 elements

    Error: Can't elaborate top-level user hierarchy

    Error: Quartus II Analysis & Synthesis was unsuccessful. 2 errors, 2 warnings

    Error: Peak virtual memory: 183 megabytes

    Error: Processing ended: Wed Mar 30 08:42:58 2011

    Error: Elapsed time: 00:00:01

    Error: Total CPU time (on all processors): 00:00:01

    Error: Quartus II Full Compilation was unsuccessful. 4 errors, 2 warnings

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity acc is
    port (
    	a: in signed (15 downto 0);
    	b: in signed (15 downto 0);
    	clk: in std_logic;
    	ena: in std_logic; 
    	rst: in std_logic;
    	q: out signed (19 downto 0)
         ) ;
    end acc;
    architecture rtl of acc is
    	signal a_reg, b_reg: signed (15 downto 0);
    	signal q_reg1, q_reg2: signed (15 downto 0);
    	signal acc_out: signed (19 downto 0);
    begin
    	process (clk, rst)
    	begin
    		if (rst = '1') then
    			a_reg <= (others => '0');
    			b_reg <= (others => '0');
    			q <= (others => '0');
    				elsif (clk'event and clk = '1') then
    					
    					a_reg(0) <= a(0);
    					a_reg(1) <= a(1);
    					a_reg(2) <= a(2);
    					a_reg(3) <= a(3);
    					a_reg(4) <= a(4);
    					a_reg(5) <= a(5);
    					a_reg(6) <= a(6);
    					a_reg(7) <= a(7);
    					
    				
    						
    					if (clk'event and clk = '0') then
    							
    						a_reg(8)  <= a(8);
    						a_reg(9)  <= a(9);
    						a_reg(10) <= a(10);
    						a_reg(11) <= a(11);
    						a_reg(12) <= a(12);
    						a_reg(13) <= a(13);
    						a_reg(14) <= a(14);
    						a_reg(15) <= a(15);
    					
    					q_reg1 <= a_reg;
    					end if;
    											
    		end if;
    	end process;
    	
    	process (ena)
    	begin
    		if (ena = '1') then
    			if (clk'event and clk = '1') then
    					
    				b_reg(0) <= b(0);
    				b_reg(1) <= b(1);
    				b_reg(2) <= b(2);
    				b_reg(3) <= b(3);
    				b_reg(4) <= b(4);
    				b_reg(5) <= b(5);
    				b_reg(6) <= b(6);
    				b_reg(7) <= b(7);
    					
    			end if;
    	
    				if (clk'event and clk = '0') then
    							
    					b_reg(8)  <= b(8);
    					b_reg(9)  <= b(9);
    					b_reg(10) <= b(10);
    					b_reg(11) <= b(11);
    					b_reg(12) <= b(12);
    					b_reg(13) <= b(13);
    					b_reg(14) <= b(14);
    					b_reg(15) <= b(15);
    					
    				q_reg2 <= b_reg;
    				end if;
    				
    				acc_out <= q_reg1 + q_reg2;
    		
    		end if;
    	end process;
    	q <= acc_out;
    end rtl;

    --can anybody make it correct??

    --is this code suitable for board DE1?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The problem on this line

    acc_out <= q_reg1 + q_reg2;
    is that acc_out is 20 bits and q_reg1 and q_reg2 are 16 bits. The result of the addition is 16 bits and it won't be resized automatically to 20 bits for you. Try something like that instead:

    acc_out <= resize(q_reg1,20) + resize(q_reg2,20);
    It is better to increase the size before performing the addition in case you need the 17th bit in the result and prevent an overflow.

    And by the way,
    					b_reg(8)  <= b(8);
    					b_reg(9)  <= b(9);
    					b_reg(10) <= b(10);
    					b_reg(11) <= b(11);
    					b_reg(12) <= b(12);
    					b_reg(13) <= b(13);
    					b_reg(14) <= b(14);
    					b_reg(15) <= b(15);
    can be replaced by
    					b_reg(15 downto 8) <= b(15 downto 8);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have never seen two nested clock edge statements...has vhdl standards changed?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I have never seen two nested clock edge statements...has vhdl standards changed?

    --- Quote End ---

    Ill open a book on how long before he comes back asking why his code wont compile!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Ill open a book on how long before he comes back asking why his code wont compile!

    --- Quote End ---

    The nested clock edge condidtion compiles, because it's legal VHDL syntax. But the respective part will be ignored similar to a block under an if false then condition.

    I'll remember it for interview questions.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I think when it comes to synthesis we better stick to the proven predictable templates rather than the legality of code. Tools don't always respect the legalities as they are made by low paid software people.

    Moreover, the above code will lose the intention as the second edge statement overwrites the first edge.

    I believe the intention is DDR, so you can use DDR function or your own.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The code is very unsynthesisable. The second clock edge is looking for falling edge, and because its inside the rising edge if branch, its basically looking for a rising and falling edge at the same time (so as well as looking for both edges which is impossible in an FPGA, it looks for them simultaneously).