Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

problem in 'while' loop in VHDL

Status
Not open for further replies.

rourabpaul

Member level 3
Member level 3
Joined
Aug 14, 2010
Messages
67
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Location
kolkata
Activity points
1,747
I want to make a modulus program by VHDL program,
I have made this code


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity modulus is
port (clk : in std_logic;
x: in std_logic_vector(2 downto 0);
y: in std_logic_vector(2 downto 0);
p: out std_logic_vector(5 downto 0));
end modulous;
architecture modulus_arch of modulus is
signal n : std_logic_vector(2 downto 0);
signal s1: std_logic_vector(5 downto 0);


begin
main: process(x,y,n,clk)
begin
if(rising_edge(clk)) then
while s1<=x loop
n<=n+"001";
s1<=n*y;
end loop;
p<=x-y*(n-"001");
n1<=n;
end if;
end process main;
end modulus_arch;



there is no error indeed,
compilation,simulation, synthesize , implementation have been done ,

but when i want to see in test bench wave form following warning has been seen


//WARNING:Simulator:29 - at 10.000 ns(1): Warning: There is an 'U'|'X'|'W'|'Z'|'-'//

and dont show the desired output

here i gave "110" in 'x'.& "011" in y,
i want to calculate 5 mod 3,
so output should be 2,
but i found '6hXX'
 

Hi,

Do you have a testbench written in VHDL?
I found this works better than using the waveform editor.

Regards,
scanman
 

actually i am using ISE 7.1i,
here we dnt need to write test bench,it is automatically generated
 

I doubt, that you actually compiled that posted code. It has syntax errors and can't be synthesized because the compiler is unable to determine an upper bound for the loop iteration count.

I fear, that you didn't understand the purpose of a VHDL iteration scheme. It's not working like a C loop.
 

Though this has nothing to do with analog, and my vhdl is a bit rusty, but i recall that synthesis tools don't like recursive calls. This happens as n is part of the sensitivity list. And yes, it seems to be written like a piece of software code rather than hdl.
 

compilation,simulation, synthesize , implementation have been done really.
now i initialize s1 as "000001" and n as "000",but the problem is almost same;
actually i dnt understoand what the problem is?why vhdl doesn't has such type of iteration scheme?

is there any process to execute x mod y in vhdl language.




Rourab
 

A VHDL iteration is a method to build parallel logic, not sequential operation as in C. To do so, the iteration count must
be known at compile time. It can be possibly used e.g. to specify a parallel divider (or modulus operator), but not the
way you did. Because you didn't show legal VHDL code, I can't guess where it fails exactly. I prefer the built-in
division provided by the design compiler or vendor IP blocks.

If you want a sequential operation (one step per clock cycle), you have to write it as such.

The mod operator is supported by ieee.numeric_std for unsigned and signed data type.
 

Hi,

I have written VHDL dividers and such using state machine logic synched to
system clock. This could be applied to replace the while loop in your code.
Let me know and I can send you an example.

scanman
 

i have tried ieee.numeric_std library with unsigned data types,
but is shows "line 20: Operator <MODULUS> must have constant modulo operand."
when i gave a constant(say "110") then it shows
The modulo should be a power of 2
Rourab Paul

Added after 4 minutes:

To scanman

i need a 12 bit divider,
but it would be better if if the divider is 'n' bit,
please post it as early as possible
Rourab Paul
 

Rourab,

Here is N bit divider I wrote recently. Hopefully documentation is good
enough for you to understand. It uses signed math.
I haven't had time to test it thoroughly.
Please give me feedback on how it works for you and
if there are any problems.

Regards,
scanman
 

    rourabpaul

    Points: 2
    Helpful Answer Positive Rating
TO scanman

yes your code works properly,but last two bits of QUE out put which are for fractional purpose do not give the proper result,but the integer part is giving the exact result,by some manipulating i also able to execute the remainder part for my modulus purpose,
but here the result need some clock to execute,is there any process speedy process
to execute remainder,
 

Hi,
Can you give me your input numbers and output results so I can compare and
run some tests.
Thanks,
 

This is correct:

17/5 = 3.4 = 11.01 (13) First bit left of decimal point = 0.5 next one is 0.25
so 0.25 is closest we get to 0.4. If we had four bits after decimal point we would have 11.0110 = 3.0 + 0.0 + 0.25 + 0.125 + 0.0 = 3.375
Do you need the remainder output as a binary number? (no fraction)
I could maybe re-write and add remainder output.

scanman
 

i have made a remainder program as my style,and its also working,
okkay you can post also a remainder code,
is there any faster process?
 

----------------------------------------------------------------------------------
-- Company:
-- Engineer: Rob David
--
-- Create Date: 10:00:00 07/30/2010
-- Design Name:
-- Module Name: fix_pt_div_nr - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description: Fixed point divider based on non-restoring algorithm for integer
-- inputs and optional fractional quotient output. QUO = NUM/DEN
-- The difference between the size of N and Q determines the number
-- of decimal points to the right of N bit positions.
-- Example: If N is 8 and Q is 10 then there will be 2 bits of binary
-- fraction to the right of N bits. 00000000.00
-- Fractional precision is 0.5, 0.25, 0.125, 0.0625 ...
-- Separate sign (SGN) output. Cycle synchronously starts when RST = '1'.
-- RDY output = '1' when done. If error ERR = '1'.
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
--
-- Additional Comments: Copyright ˆ 2009-2010 Robert David (rjdavid1@shaw.ca)
-- Provided WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
--use IEEE.NUMERIC_STD.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity fix_pt_div_nr is

Generic ( N : positive := 8; -- Size of numerator and denominator including the sign bit
Q : positive := 10); -- Number of bits in quotient including extra fractional precision

Port ( CLK : in STD_LOGIC; -- Input clock 50Mhz or ?
RST : in STD_LOGIC; -- Reset to start new cycle active high
NUM : in STD_LOGIC_VECTOR (N-1 downto 0); -- Numerator input
DEN : in STD_LOGIC_VECTOR (N-1 downto 0); -- Denominator input
QUO : out STD_LOGIC_VECTOR (Q-1 downto 0) := (others => '0'); -- Quotient output
SGN : out STD_LOGIC := '0'; -- Sign of quotient '1' = negative
ERR : out STD_LOGIC := '0'; -- Error if '1'
div : inout STD_LOGIC_VECTOR (7 downto 0);
reminder :eek:ut STD_LOGIC_VECTOR (15 downto 0);
RDY : out STD_LOGIC := '0'); -- Data ready output active high

end fix_pt_div_nr;

architecture Behavioral of fix_pt_div_nr is

constant N_MSB : positive := N-1;
constant Q_MSB : positive := Q-1;

type STATE_TYPE is (Init, Sign, Error_Test, Sub_MSB, Append_D, Set_Q, Add_Sub_D, Bound_Test, Idle);
signal CS : STATE_TYPE := Idle; -- CS = Current State

signal Q_Bit : STD_LOGIC_VECTOR (Q_MSB downto 0):= (others => '0');
signal D_Bit : STD_LOGIC_VECTOR (N_MSB downto 0):= (others => '0');

signal Numer : STD_LOGIC_VECTOR (N_MSB downto 0);
signal Denom : STD_LOGIC_VECTOR (N_MSB downto 0);

signal Error : STD_LOGIC := '0';

begin

div_proc : process(CLK) --, RST )

variable i : integer range 0 to Q; -- Bit index

begin

-- if RST = '1' then -- Aynchronous reset
-- RDY <= '0'; -- Reset the Ready and Error outputs immediately
-- SGN <= '0';
-- Error <= '0';
-- CS <= S1;

if CLK'event AND CLK = '1' then -- State machine

if RST = '1' then -- Synchronous reset
RDY <= '0'; -- Reset the Ready and Error outputs immediately
SGN <= '0';
Error <= '0';
CS <= Init;
else
case CS is

when Init => -- Initialize all values
i := 1;
Q_Bit <= (others => '0');

CS <= Sign;

when Sign => -- Determine sign of quotient
if ((CONV_INTEGER(NUM) < 0 AND CONV_INTEGER(DEN) < 0) OR -- Both negative or
(CONV_INTEGER(NUM) >= 0 AND CONV_INTEGER(DEN) >= 0)) then -- both pos?
SGN <= '0'; -- Sign is positive
else
SGN <= '1'; -- Either numerator or denominator is negative so quotient will be also

end if;

Numer <= abs NUM; -- Convert to absolute values (positive numbers)
Denom <= abs DEN;

CS <= Error_Test;

when Error_Test =>
if CONV_INTEGER(Numer) = 0 then -- Numerator = 0 so output quick zero quotient
Error <= '0';
RDY <= '1'; -- Output Ready signal
CS <= Idle; -- Done and idle state
-- Error on divide by zero
elsif (CONV_INTEGER(Denom) = 0) then -- Divide by zero catch
Error <= '1';
RDY <= '1'; -- Output Ready signal
CS <= Idle; -- Error and idle state

else
Error <= '0';
RDY <= '0';
CS <= Sub_MSB; -- No error so continue

end if;

when Sub_MSB =>
D_Bit <= Numer(N_MSB) - Denom; -- Subtract denominator from MSB of numerator
CS <= Append_D;

when Append_D =>
if i > N_MSB then -- Quotient is larger than numerator denominator so do fractional part
D_Bit <= D_Bit(N_MSB - 1 downto 0) & "0";

else
D_Bit <= D_Bit(N_MSB - 1 downto 0) & Numer(N_MSB - i); -- Bring down next MSB and append to D_Bit

end if;
CS <= Set_Q;

when Set_Q =>
if D_Bit >= 0 then -- Is positive ?
Q_Bit(Q - i) <= '1'; -- Set bit to '1'
CS <= Add_Sub_D;

else -- Is negative
Q_Bit(Q - i) <= '0'; -- Set bit to '0'
CS <= Add_Sub_D;

end if;

when Add_Sub_D =>
if D_Bit >= 0 then -- Is positive ?
D_Bit <= D_Bit - Denom;
CS <= Bound_Test;

else -- Is negative
D_Bit <= D_Bit + Denom;
CS <= Bound_Test;

end if;

when Bound_Test => -- Increment bit index check for bounds
i := i + 1;
if i = Q + 1 then -- Done all bits?
RDY <= '1'; -- Output Ready signal
CS <= Idle;

elsif i < Q then
CS <= Append_D; -- Iterate through algorithm

else -- Do last bit and remainder
CS <= Set_Q;

end if;

when Idle => -- Idle state
CS <= Idle;

when others => -- Default reset and restart
RDY <= '0';
Error <= '0';
CS <= Init;

end case;
end if;
end if; -- End clk event

end process div_proc;

QUO <= Q_Bit;
ERR <= Error;
div<=Q_Bit(Q-1 downto 2);

reminder<=NUM-(DEN*div);

end Behavioral;

here "div " output may consider as signal also[/b]
 

i have tried ieee.numeric_std library with unsigned data types,
but is shows "line 20: Operator <MODULUS> must have constant modulo operand
It's apparently a restriction of your design compiler respectively simulator. E.g. Altera Q.uartus is supporting it.
 

rourabpaul,

I added RDR remainder output and set defaults to 12bits.
The remainder only works correctly if QUO is same size as NUM and DEN.
Try it out and let me know.

scanman
 

    rourabpaul

    Points: 2
    Helpful Answer Positive Rating
i have added the picture of my output,
one thing i want to know what is RDY output?
is it high when the output is ready?
and one just another test with this code that i want to
remove the RST input,could we do it??

Rourab Paul

Added after 8 minutes:

this is my output
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top