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.

Cannot continue(fatal error) problems with lifo

Status
Not open for further replies.

chenobi

Newbie level 4
Joined
Apr 13, 2018
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
63
Hi everyone im still learning to use vhdl and FPGA. I wanted to try to make a lifo system and this is the code I made:

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
 
ENTITY lifo_datapath IS
 
PORT
(
      clk   : IN     std_logic;
      d_in  : IN     std_logic_vector (3 DOWNTO 0);
      nrst  : IN     std_logic;
      count_down   : IN     std_logic;
      count_up : IN     std_logic;
      d_out : OUT    std_logic_vector (3 DOWNTO 0);
      empty_signal : OUT    std_logic;
      full_signal  : OUT    std_logic
);
 
END lifo_datapath;
 
ARCHITECTURE behaviour OF lifo_datapath IS
 
BEGIN
data_processing: process(clk, nrst, count_down, count_up)
-- size of mem is 4 depth and 4 bits width
type mem_type is array (0 to 3) of std_logic_vector(3 downto 0);
variable stack_mem : mem_type := (others => (others => '0'));
variable stack_ptr : integer := 3;
begin
     if ( nrst ='0') then
          stack_ptr := 3;  --stack grows downwards.
          full_signal <= '0';
          empty_signal <= '0';
          D_out <= (others => '0');
     elsif(rising_edge(Clk)) then
          --check if push has been pressed/push signal has been received
          if (count_up = '1') then
              --data gets pushed/written into address when push signal comes
               stack_mem(stack_ptr) := d_In; 
             --because a stackaddress got filled with data we got one less stack now
             stack_ptr := stack_ptr - 1;
            end if;
            if (count_down = '1') then
              --data gets read from the stack
               D_Out <= stack_mem(stack_ptr);
              --because a stackaddress got emptied we got one more stack address now
               stack_ptr := stack_ptr + 1;
            end if;
            
            --control signal to signal if stack memory is full or not
            if stack_ptr = 3 then
              empty_signal <= '1';
              full_signal <= '0';
            elsif stack_ptr = 0 then --when stack_ptr = 0 all stack mem are full and gives full signal
              empty_signal <= '0';
              full_signal <= '1';
            else
              empty_signal <= '0';
              full_signal <= '0';
            end if;
      end if;   
end process;
    
END behaviour;



compiling works fine, but when i try to simulate it doesn't show the whole test i used in the do-file. It only shows
up to 1000 ns simulation time instead of the 2300 ns total time.
when i looked for a problem it showed this:
# ** Warning: (vsim-8780) Forcing /lifov3/nrst as root of /lifov3/b2v_inst/nrst specified in the force.
# ** Warning: (vsim-8780) Forcing /lifov3/d_in as root of /lifov3/b2v_inst/d_in specified in the force.
# ** Warning: (vsim-8780) Forcing /lifov3/count_down as root of /lifov3/b2v_inst/count_down specified in the force.
# ** Warning: (vsim-8780) Forcing /lifov3/count_up as root of /lifov3/b2v_inst/count_up specified in the force.
# Cannot continue because of fatal error.
# HDL call sequence:
# Stopped at C:/Users/leon-/Documents/elektrotechniek jaar 2/Periode 3/digitaal 3/Practicum lifo V3/lifo_datapath.vhd 40 Process data_processing

when i looked at which place it refers too i found that it said something about this line in my vhdl
stack_mem(stack_ptr) := d_In;
My question is did i do something wrong when writing that line? It seemed fine to me. And also how should i solve this problem?

note: I do not have a testbench or rather i always just tested using do file and looking for answers on the internet if I found
a problem or error.
note2: I also looked here at forums with similar problems and the only thing i can think of is my mem_type being too small
But not sure i what i think is right or not

Used do-file
Code:
##############
#data-path lifo#
##############

restart -f

#reset it once first
force Clk 1 0, 0 50 -r 100 
force nrst 0
force d_in 0000
force count_down 0
force count_up  0
run 100 ns

#one datasteam in
force nrst 1
force d_in 0000
force count_down 0
force count_up  0
run 200 ns

#one data stream out
force nrst 1
force d_in 0000
force count_down 0
force count_up  0
run 200 ns

#first datastream in, total runtime 700 ns
force nrst 1
force d_in 0001
force count_down 0
force count_up  1
run 200 ns

#second datastream in
force nrst 1
force d_in 0011
force count_down 0
force count_up  1
run 200 ns

#third datastream in
force nrst 1
force d_in 0100
force count_down 0
force count_up  1
run 200 ns

#fourth datastream in
force nrst 1
force d_in 0101
force count_down 0
force count_up  1
run 200 ns

#fifth datastream in, test to see what will happen
#force nrst 1
#force d_in 1001
#force count_down 0
#force count_up  1
#run 200 ns

#first datastream out, total runtime 1500 ns
force nrst 1
force d_in 0001
force count_down 1
force count_up  0
run 200 ns

#second datastream out
force nrst 1
force d_in 0011
force count_down 1
force count_up  0
run 200 ns

#third datastream out
force nrst 1
force d_in 1100
force count_down 1
force count_up  0
run 200 ns

#fourth datastream out
force nrst 1
force d_in 0010
force count_down 1
force count_up  0
run 200 ns

#fifth datastream out, total runtime 2300 ns
#force nrst 1
#force d_in 1010
#force count_down 1
#force count_up  0
#run 200 ns
 
Last edited by a moderator:

I'm not a big fan of running a simulation through modelsim, by using signal force. Are you dutch? Ek praat 'n bietjie Afrikaans

You'd be better of having a vhdl testbench.

Point 1 -
What happens when mem_type is out of range?
You can look at variables in modelsim - just google how
 

One thing I noticed in your code is that stack_ptr is not there in the process sensitivity list, I am not sure whether till 1000 ns your simulation results are ok or not.

Second thing is since stack grows downwards so the fatal error might be due to negative index of stack_mem, just verify the value of stack_ptr in your simulation at the time of simulation halt.
 

What happens when mem_type is out of range?


This is a rhetorical question. The problem is you're out of range.

and the reason why
"
stack_ptr := stack_ptr - 1;
end if;
if (count_down = '1') then
--data gets read from the stack
D_Out <= stack_mem(stack_ptr);
"
 

I'm not a big fan of running a simulation through modelsim, by using signal force. Are you dutch? Ek praat 'n bietjie Afrikaans

You'd be better of having a vhdl testbench.

Point 1 -
What happens when mem_type is out of range?
You can look at variables in modelsim - just google how


Well I'm still learning it and this how a teacher taught me it. Yes, I'm dutch haha I don't speak afrikan, but I do know the similarities. Ok i will look up into vhdl testbenches then maybe it will work out better
 

Notes and tips:
1. As a beginner, Dont use variables, ever. You can (and probably be should) do everything you need with signals, and it will make debugging much easier. Only use variables when you understand the consequences.
2. Mem_type is a full 32 bit integer. It is probably going to -1, and the memory only has elemnts 0 to 3, so out of range error.
3. You have a signal called count_up, but the stack_pointer counts down. You should write clear code. (but Im glad you're commenting, and explaining why things are happening).
4. Dont use force to write a testbench. You get much better control writing a HDL testbench.
5. You have signals in the sensitivity list unneccesarily. You only need clk and nrst, as nothing can happen when any other signal changes.
6. What is happening on the waveform when the fatal error happens? Usually it explains what the fatal error is.

One thing I noticed in your code is that stack_ptr is not there in the process sensitivity list

It does not need to be there. Its a synchronous process, so only clk and nrst are needed.
 

One thing I noticed in your code is that stack_ptr is not there in the process sensitivity list, I am not sure whether till 1000 ns your simulation results are ok or not.

Second thing is since stack grows downwards so the fatal error might be due to negative index of stack_mem, just verify the value of stack_ptr in your simulation at the time of simulation halt.

Reply on your first thing: the simulation is not ok. At 800 ns it shows a high signal and i expected it to be at 1500 ns.

On your second thing: I will look into it.

- - - Updated - - -

Ok thx for the answers!

4. My teachter at my school never taught us to use testbenches before so i wouldn't know how to use them, but i will look up how to test it using forums,
youtube and stuff.
6. In the transcript it never stated where or what the fatal error was. But i saw this line:
# Cannot continue because of fatal error.
# HDL call sequence:
# Stopped at C:/Users/leon-/Documents/elektrotechniek jaar 2/Periode 3/digitaal 3/Practicum lifo V3/lifo_datapath.vhd 39 Process data_processing
and when i looked for which line it was, I saw it was pointed to the line where i want to have data put in my memory stack
 

Change lines to these:

Code VHDL - [expand]
1
2
3
4
5
if (stack_ptr /= 0) then
                 stack_ptr := stack_ptr - 1;
         else
           stack_ptr := stack_ptr;
         end if;


and this:

Code VHDL - [expand]
1
2
3
4
5
if (stack_ptr /= 3) then
                 stack_ptr := stack_ptr + 1;
         else
           stack_ptr := stack_ptr;
         end if;


These lines will keep the stack_ptr from rolling over or going negative.

You didn't consider what happens after you push the last value on the stack. You also have an issue with your full flag as it is indicating full before the last stack position is written because of your use of a variable for stack_ptr instead of a signal. This is because variables are evaluated immediately and you are using it to determine empty/full conditions using only 0 and 3 which are only 3 apart not 4 apart (for the depth of 4 stack). Note, changing stack_ptr to a signal fixes the early full, but makes the empty clear on the second push due to the previously mentioned distance of 3.

As another poster mentioned the use of count_up for a push onto the stack, which decrements the stack pointer is very confusing. You need to rethink how you name stuff in your code. I would probably call the signals push_d and pop_d or something equally descriptive of the function.
 

Change lines to these:

Code VHDL - [expand]
1
2
3
4
5
if (stack_ptr /= 0) then
                 stack_ptr := stack_ptr - 1;
         else
           stack_ptr := stack_ptr;
         end if;


and this:

Code VHDL - [expand]
1
2
3
4
5
if (stack_ptr /= 3) then
                 stack_ptr := stack_ptr + 1;
         else
           stack_ptr := stack_ptr;
         end if;


These lines will keep the stack_ptr from rolling over or going negative.

You didn't consider what happens after you push the last value on the stack. You also have an issue with your full flag as it is indicating full before the last stack position is written because of your use of a variable for stack_ptr instead of a signal. This is because variables are evaluated immediately and you are using it to determine empty/full conditions using only 0 and 3 which are only 3 apart not 4 apart (for the depth of 4 stack). Note, changing stack_ptr to a signal fixes the early full, but makes the empty clear on the second push due to the previously mentioned distance of 3.

As another poster mentioned the use of count_up for a push onto the stack, which decrements the stack pointer is very confusing. You need to rethink how you name stuff in your code. I would probably call the signals push_d and pop_d or something equally descriptive of the function.

You are right about it. Thank you I will try again now to see if it helps now.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top