Forum Discussion

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

VHDL - bit set, or net set?!?

Hello!

Maybe I am in the wrong forum, but I have a big problem which I am not able to resolve myself. . . . Perhaps, somone can help.

I use a Stratix EP1S10 device for my design. It is on a NIOS Dev Kit, but I use it without NIOS. I have written a design in VHDL and all works pretty fine (for my first big project). Now, my design needs about 82% of the logic elements of the FPGA.

I use Quartus II 7.1 for developing my design.

Now, I reached a point where I need some help because I have an error that I can't solve by myself. First look at this code please:


if(fb_pt_read_byte_counter = 0) then
	if(processing_state_register = b"000") then --0
		temp_type <= (others => '0'); -- reset temp_type & temp_level
		temp_level <= 127;
		processing_state_register <= b"001"; --1
	end if;
	if(processing_state_register = b"001") then --1
		temp_type(0) <= fb(fb_pt_read)(7); -- get msb out of first dataset-byte
		temp_level <= conv_integer(fb(fb_pt_read)(6 downto 0)); -- get level out of first dataset-byte
		processing_state_register <= b"010"; --2
	end if;
	if(processing_state_register = b"010") then --2
		temp_type(0) <= fb(fb_pt_read)(7);
		temp_level <= conv_integer(fb(fb_pt_read)(6 downto 0));
		processing_state_register <= b"011"; --3
	end if;
	elsif(fb_pt_read_byte_counter = 1) then
		if(processing_state_register = b"011") then --3
			temp_type(4 downto 1) <= fb(fb_pt_read)(3 downto 0); -- get next type-bits out of second dataset-byte 
			processing_state_register <= b"100"; --4
		end if;
		if(processing_state_register = b"100") then --4
			case temp_type is
			when "01001" => processing_state_register <= b"000";
			when "01010" => processing_state_register <= b"000";
			when others => 	processing_state_register <= b"101"; --5
			end case;
		end if;				
		elsif(fb_pt_read_byte_counter = 2) then
			if(processing_state_register = b"101") then --5
				case temp_type is
				when "00011" => counter1 <= counter1 + 1;
				when "00110" => counter2 <= counter2 + 1;
				when "00111" => counter3 <= counter3 + 1;
				when "01000" => counter4 <= counter4 + 1;
				when "01011" => counter5 <= counter5 + 1;
				when "01101" => counter6 <= counter6 + 1;
				when "01110" => counter7 <= counter7 + 1;
				when others => nop_bit <= not nop_bit;
				end case;
				processing_state_register <= b"110"; --6
			end if;
			if(processing_state_register = b"110") then --6
				case temp_type is
				when "00011" => if(level1 > temp_level) then
							level1 <= temp_level;
						end if;
				when "00110" => if(level2 > temp_level) then
							level2 <= temp_level;
						end if;
				when "00111" => if(level3 > temp_level) then
							level3 <= temp_level;
						end if;
				when "01000" => if(level4 > temp_level) then
							level4 <= temp_level;
						end if;
				when "01011" => if(level5 > temp_level) then
							level5 <= temp_level;
						end if;
				when "01101" => if(level6 > temp_level) then
							level6 <= temp_level;
						end if;
				when "01110" => if(level7 > temp_level) then
							level7 <= temp_level;
						end if;
				when others => nop_bit <= not nop_bit;
				end case;
				processing_state_register <= b"000"; --0
			end if;			
		end if;

What I posted here is a part of my UART_interface-entity. In this entity I prepare my datasets for to be send via the UART-line. Each dataset consits of three byte. In these three bytes I have packed a signal-level-part, a type-part and a time-part.

Before I send theses datasets I want to count how many datasets of seven different types I send via the serial line and I make a minimum determination for each datatype.

Firstly, I build up my temp-variables, in order to get the actual type and level. The temp_type variable has to be build up in two steps because one bit is packed in the first byte of my dataset and the next 4 bits are packed in the second byte of the pulse dataset.

I set the temp_type value in these two lines:

temp_type(0) <= fb(fb_pt_read)(7);

.

.

temp_type(4 downto 1) <= fb(fb_pt_read)(3 downto 0);

'fb' is my fifo-buffer in which I store the datasets byte-wise. fb_pt_read is the read-pointer which points to the byte in the buffer which is to be send next.

The counter 'fb_pt_read_byte_counter' stores the information about the actual byte of my three-byte-dataset.

If fb_pt_read_byte_counter = 0, I get the level information out of dataset-byte 0 and the first bit for my temp_type signal.

If fb_pt_read_byte_counter = 1, I get the remaining bits for my temp_type signal out of dataset-byte 1.

If fb_pt_read_byte_counter = 1, I analyze the values stored in temp_type and temp_level in order to increment the right counter and to update the right level.

I hope you can follow my description up to now . . . . :D

Now, all works fine EXCEPT when the value in temp_type becomes b01001 -> d9. Then, very often, the counter4 is incremented although it should only increment on the temp_type b01000 -> d8. All other counters work as expected. I do not know what can be wrong.

Is it perhaps because the lsb in temp_value gets lost somehow, so that b01001 changes to b01000? As far as I can say, all timings work fine, because I do not get any warnings from Quartus II.

In the simulation I do not get any errors either. But something has to be wrong, because all works fine except for this one error.

I know, it is very hard for you to help me in this case, bacause you only see this little part of my design, but maybe someone of you sees a fundamental error in this code. I am very desperate, because I don't know what to do anymore about this error.

Greets

Maik

2 Replies

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

    Maik,

    I can't give you a definitive answer as I don't fully understand your code, but what I can see is that you have multiple nested if-statements in a huge process block, with interchanged levels for fb_pt_read_byte_counter and processing_state_register.

    Here are some tips:

    1. Break down the code into multiple smaller process blocks.

    2. Use a FSM.

    3. Remove as much as possible nested if-statement.

    Keep in mind that VHDL is a language to describe parallel hardware.

    Try not to think of it as sequential code.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hello plasma16!

    Thanks for your answer.

    You are right, it is very hard for me to write "real" vhdl code, as I come from normal software languages. I have to work on that in the future.

    For now, I solved the problem by checking the counter4-value-changes if they were valid changes or not. If they were invalid, i undo the change by overwriting the new value with a backup of the old value. I know, that this is an unpleasent solution, but I do not know how to help myself anymore.

    That this "solution" does work shows me, that each time a binary 01001 should be in the temp_type signal it is actually a binary 01000. I don't have a clue why, because the only place I touch the temp_type signal is shown in the code example. I NEVER erase the LSB of temp_value . . . . and it is never erased in the case of e.g. binary 00111, 01011 or 01101 as the counters who increment on these temp_type values always behave as expected. They NEVER count wrong.

    Okay, thanks anyway for trying to help me!

    In my next project I hope my vhdl style will improve a little bit ;) .

    Greets,

    Maik