Register problem(long)

M

Morfeusz

Guest
Hi,
I'm new in vhdl. I/m trying to make some simple project using
alliance.
The device has 3 inputs A(7 to 0), B(7 to 0) and s (1 to 0). All the
results should be stored in Q register.
s opertation
00 A+B
11 Q+2
There is my source code:
---------------------------------------
ENTITY ue IS
PORT(
-- 8 bits A
A: IN BIT_VECTOR(7 DOWNTO 0);
-- 8 bits B
B: IN BIT_VECTOR(7 DOWNTO 0);
-- 9 bits Y
Y: OUT BIT_VECTOR(7 DOWNTO 0);
-- 2 bits
s: IN BIT_VECTOR(1 DOWNTO 0);
-- zegar
clk: IN BIT;
vdd: IN BIT;
vss: IN BIT
);
END ue;

ARCHITECTURE data_flow OF ue IS
SIGNAL wyj_sum: BIT_VECTOR(7 DOWNTO 0);
SIGNAL wyjscie: BIT_VECTOR(7 DOWNTO 0);
SIGNAL wyj_plu: BIT_VECTOR(7 DOWNTO 0);
SIGNAL przen: BIT_VECTOR(8 DOWNTO 0);
SIGNAL przen_3: BIT_VECTOR(8 DOWNTO 0);
SIGNAL Q: REG_VECTOR (7 DOWNTO 0) REGISTER;
CONSTANT dwa :BIT_VECTOR(7 DOWNTO 0):="00000010";
BEGIN
WITH s SELECT
wyjscie <= wyj_sum WHEN "00",
wyj_plu WHEN "11";

-- A+B
wyj_sum <= A XOR B XOR przen(7 DOWNTO 0);
przen(0) <= '0';
przen(8 DOWNTO 1) <= (A AND przen(7 DOWNTO 0)) OR (B AND przen(7
DOWNTO 0)) OR (A AND B);

--Q+2
wyj_plu <= Q XOR dwa XOR przen_3(7 DOWNTO 0);
przen_3(0) <= '0';
przen_3(8 DOWNTO 1) <= (Q AND przen_3(7 DOWNTO 0)) OR (dwa AND
przen_3(7 DOWNTO 0)) OR (Q AND dwa);

write: BLOCK (clk = '1' AND clk'STABLE)
BEGIN
Q <= GUARDED wyjscie;
END BLOCK;

Y <= Q;

END;
------------------------------------
The project compiles with no errors, but but while checking it (asimut
-b project pat out) computer hangs.
pat file is:
----------------------------------------
in A(7 to 0);
in B(7 to 0);
in s(1 to 0);
in clk;
out Y(7 to 0);
begin
pat_1: 00000101 00000011 00 1 ? ********;
pat_2: 00001000 00001110 11 1 ? ********;
end;
-----------------------------------------

I think that there is a problem with Q+2 operation, but I don't know
how to fix it.
Could you please help me?
Thanks
Morfi
 
Morfeusz wrote:


BEGIN
WITH s SELECT
wyjscie <= wyj_sum WHEN "00",
wyj_plu WHEN "11";

-- A+B
wyj_sum <= A XOR B XOR przen(7 DOWNTO 0);
przen(0) <= '0';
przen(8 DOWNTO 1) <= (A AND przen(7 DOWNTO 0)) OR (B AND przen(7
DOWNTO 0)) OR (A AND B);
This is a combinational loop. Signal "przen" is read and assigned to
itself. Therefore it is read again and again assigned to itself ... and
so on.

Because you got a clock signal - use template for a flipflop:

process(reset,clock)
begin
if (reset='1') then
-- do some reset if you want and if you have a reset signal
elsif rising_edge(clock) then
przen(8 DOWNTO 1) <= (A AND przen(7 DOWNTO 0)) OR
(B AND przen(7 DOWNTO 0)) OR (A AND B);
end if;
end process;

przen(0)<='0'; -- I can't find any other driver in you code




--Q+2
wyj_plu <= Q XOR dwa XOR przen_3(7 DOWNTO 0);
przen_3(0) <= '0';
przen_3(8 DOWNTO 1) <= (Q AND przen_3(7 DOWNTO 0)) OR (dwa AND
przen_3(7 DOWNTO 0)) OR (Q AND dwa);
For przen_3 you got exactly the same problem - a combinational loop.


The project compiles with no errors, but but while checking it (asimut
-b project pat out) computer hangs.
It is trapped in these infitine combinational loops.

____________
some input | |
------------| |
a signal | |
-------| some logic |--
| | | |
| ------------ |
| |
|----------------------
^
here a register has to be placed
(normally: a flipflop)


Ralf
 
Wow! I've never seen anybody actually try and use a guarded block before!
Generally, you should use processes instead as most synthesis tools don't
support blocks. Anyway, the bug is the guard expression - you want (clk =
'1' and NOT clk'stable), as opposed to (clk='1' and clk'stable), otherwise
you get an infinite loop as soon as S becomes "11" and the clock becomes 1.
Does your simulator support breakpoints, step by step debugging? If not, you
can always download a free copy of Modelsim (bundled with Xilinx's Webpack).

The code you have supplied also has several other bugs which should have
prevented it from compiling:
What is type "REG_VECTOR". It is not in std.standard, and you have no
context clause (library... use)
You can only assign to a resolved type in a guarded signal assignment - what
is the type of Q?
A case statement (and its concurrent equivalent "with") must cover all
possible inputs. But in your code, you have not coded branches for S="01"
and S="10".

I'd suggest looking up processes, libraries, and packages. In particular,
library ieee, and the packages std_logic1164 and numeric_std.

This is also the most amazing implementation of what amounts to TWO lines of
VHDL:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity UE is
PORT(
A: IN unsigned(7 DOWNTO 0);
B: IN unsigned(7 DOWNTO 0);
Y: OUT unsigned(7 DOWNTO 0);
s: IN std_logic_vector(1 DOWNTO 0);
clk: IN std_logic
);
END ue;

ARCHITECTURE data_flow OF ue IS
signal Q : unsigned(7 downto 0);
BEGIN

process(clk)
begin
if (rising_edge(Clk)) then
if (S = "00") then
Q <= A + B;
elsif (S = "11") then
Q <= Q + 2;
end if;
end if;
end process;

Y <= Q;

END;


--
Ian Poole, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: ian.poole@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.


"Morfeusz" <morfeusz_st@wp.pl> wrote in message
news:301aa724.0312011127.58b224fb@posting.google.com...
Hi,
I'm new in vhdl. I/m trying to make some simple project using
alliance.
The device has 3 inputs A(7 to 0), B(7 to 0) and s (1 to 0). All the
results should be stored in Q register.
s opertation
00 A+B
11 Q+2
There is my source code:
---------------------------------------
ENTITY ue IS
PORT(
-- 8 bits A
A: IN BIT_VECTOR(7 DOWNTO 0);
-- 8 bits B
B: IN BIT_VECTOR(7 DOWNTO 0);
-- 9 bits Y
Y: OUT BIT_VECTOR(7 DOWNTO 0);
-- 2 bits
s: IN BIT_VECTOR(1 DOWNTO 0);
-- zegar
clk: IN BIT;
vdd: IN BIT;
vss: IN BIT
);
END ue;

ARCHITECTURE data_flow OF ue IS
SIGNAL wyj_sum: BIT_VECTOR(7 DOWNTO 0);
SIGNAL wyjscie: BIT_VECTOR(7 DOWNTO 0);
SIGNAL wyj_plu: BIT_VECTOR(7 DOWNTO 0);
SIGNAL przen: BIT_VECTOR(8 DOWNTO 0);
SIGNAL przen_3: BIT_VECTOR(8 DOWNTO 0);
SIGNAL Q: REG_VECTOR (7 DOWNTO 0) REGISTER;
CONSTANT dwa :BIT_VECTOR(7 DOWNTO 0):="00000010";
BEGIN
WITH s SELECT
wyjscie <= wyj_sum WHEN "00",
wyj_plu WHEN "11";

-- A+B
wyj_sum <= A XOR B XOR przen(7 DOWNTO 0);
przen(0) <= '0';
przen(8 DOWNTO 1) <= (A AND przen(7 DOWNTO 0)) OR (B AND przen(7
DOWNTO 0)) OR (A AND B);

--Q+2
wyj_plu <= Q XOR dwa XOR przen_3(7 DOWNTO 0);
przen_3(0) <= '0';
przen_3(8 DOWNTO 1) <= (Q AND przen_3(7 DOWNTO 0)) OR (dwa AND
przen_3(7 DOWNTO 0)) OR (Q AND dwa);

write: BLOCK (clk = '1' AND clk'STABLE)
BEGIN
Q <= GUARDED wyjscie;
END BLOCK;

Y <= Q;

END;
------------------------------------
The project compiles with no errors, but but while checking it (asimut
-b project pat out) computer hangs.
pat file is:
----------------------------------------
in A(7 to 0);
in B(7 to 0);
in s(1 to 0);
in clk;
out Y(7 to 0);
begin
pat_1: 00000101 00000011 00 1 ? ********;
pat_2: 00001000 00001110 11 1 ? ********;
end;
-----------------------------------------

I think that there is a problem with Q+2 operation, but I don't know
how to fix it.
Could you please help me?
Thanks
Morfi
 
"Ralf Hildebrandt" <Ralf-Hildebrandt@gmx.de> wrote in message
news:bqib5e$20phog$2@ID-8609.news.uni-berlin.de...
Morfeusz wrote:


BEGIN
WITH s SELECT
wyjscie <= wyj_sum WHEN "00",
wyj_plu WHEN "11";

-- A+B
wyj_sum <= A XOR B XOR przen(7 DOWNTO 0);
przen(0) <= '0';
przen(8 DOWNTO 1) <= (A AND przen(7 DOWNTO 0)) OR (B AND przen(7
DOWNTO 0)) OR (A AND B);

This is a combinational loop. Signal "przen" is read and assigned to
itself. Therefore it is read again and again assigned to itself ... and
so on.
NO! Since he has shifted the bits by one, it doesn't cause an infinite loop.
In fact, this is just working out a series of carry bits in a ripple carry
adder. If you expand the assignment into individual bits you should get:

przen(8) <= (A(7) and przen(7)) or (B(7) and przen(7)) or (a(7) and b(7));
przen(7) <= (A(6) and przen(6)) or (B(6) and przen(6)) or (a(6) and b(6));
przen(6) <= (A(5) and przen(5)) or (B(5) and przen(5)) or (a(5) and b(5));
....
przen(1) <= (A(0) and przen(0)) or (B(0) and przen(0)) or (a(0) and b(0));

The bug in his original code really is the guard expression on the block.
This causes an infinite loop because when S="11", Q is assigned Q+2 on each
delta. When I fixed the guard expression (and a few other minor gremlins) it
all compiled and works in Modelsim.


Because you got a clock signal - use template for a flipflop:
Absolutely, couldn't agree more. However, I don't think he wants przen
registered, just Q.


process(reset,clock)
begin
if (reset='1') then
-- do some reset if you want and if you have a reset signal
elsif rising_edge(clock) then
przen(8 DOWNTO 1) <= (A AND przen(7 DOWNTO 0)) OR
(B AND przen(7 DOWNTO 0)) OR (A AND B);
end if;
end process;

przen(0)<='0'; -- I can't find any other driver in you code




--Q+2
wyj_plu <= Q XOR dwa XOR przen_3(7 DOWNTO 0);
przen_3(0) <= '0';
przen_3(8 DOWNTO 1) <= (Q AND przen_3(7 DOWNTO 0)) OR (dwa AND
przen_3(7 DOWNTO 0)) OR (Q AND dwa);

For przen_3 you got exactly the same problem - a combinational loop.


The project compiles with no errors, but but while checking it (asimut
-b project pat out) computer hangs.

It is trapped in these infitine combinational loops.

____________
some input | |
------------| |
a signal | |
-------| some logic |--
| | | |
| ------------ |
| |
|----------------------
^
here a register has to be placed
(normally: a flipflop)


Ralf



--
Ian Poole, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: ian.poole@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
I'm not sure how familiar you are with Alliance, but did you write
this code or
did you use vasy to generate it?

I know that alliance uses guarded block statements when translating
'normal' VHDL to its own format (vhd -> vbe). If you realy want to use
asimut for simulating your design, I recommend using Ian's description
and using vasy to translate your_design.vhd -> your_design.vbe like
this:

vasy -a -p -I vhd your_design

The option -a tells vasy to generate alliance output. The option -p
tells vasy
to add power supply connectors (vdd and vss), but you don't need this
if you
only want to simulate the design. The option -I tells vasy what format
your
input file has, which in this case is vhd.

You can then use asimut to simulate vasy's output (your_design.vbe).


Hope this is helpful,
Patrick


ENTITY ue IS
PORT(
-- 8 bits A
A: IN BIT_VECTOR(7 DOWNTO 0);
-- 8 bits B
B: IN BIT_VECTOR(7 DOWNTO 0);
-- 9 bits Y
Y: OUT BIT_VECTOR(7 DOWNTO 0);
-- 2 bits
s: IN BIT_VECTOR(1 DOWNTO 0);
-- zegar
clk: IN BIT;
vdd: IN BIT;
vss: IN BIT
);
END ue;

ARCHITECTURE data_flow OF ue IS
SIGNAL wyj_sum: BIT_VECTOR(7 DOWNTO 0);
SIGNAL wyjscie: BIT_VECTOR(7 DOWNTO 0);
SIGNAL wyj_plu: BIT_VECTOR(7 DOWNTO 0);
SIGNAL przen: BIT_VECTOR(8 DOWNTO 0);
SIGNAL przen_3: BIT_VECTOR(8 DOWNTO 0);
SIGNAL Q: REG_VECTOR (7 DOWNTO 0) REGISTER;
CONSTANT dwa :BIT_VECTOR(7 DOWNTO 0):="00000010";
BEGIN
WITH s SELECT
wyjscie <= wyj_sum WHEN "00",
wyj_plu WHEN "11";

-- A+B
wyj_sum <= A XOR B XOR przen(7 DOWNTO 0);
przen(0) <= '0';
przen(8 DOWNTO 1) <= (A AND przen(7 DOWNTO 0)) OR (B AND przen(7
DOWNTO 0)) OR (A AND B);

--Q+2
wyj_plu <= Q XOR dwa XOR przen_3(7 DOWNTO 0);
przen_3(0) <= '0';
przen_3(8 DOWNTO 1) <= (Q AND przen_3(7 DOWNTO 0)) OR (dwa AND
przen_3(7 DOWNTO 0)) OR (Q AND dwa);

write: BLOCK (clk = '1' AND clk'STABLE)
BEGIN
Q <= GUARDED wyjscie;
END BLOCK;

Y <= Q;

END;
------------------------------------
 

Welcome to EDABoard.com

Sponsor

Back
Top