+ Post New Thread
Results 1 to 2 of 2
  1. #1
    Newbie level 3
    Points: 42, Level: 1
    NightOWL's Avatar
    Join Date
    May 2017
    Posts
    4
    Helped
    0 / 0
    Points
    42
    Level
    1

    RPN Calculator using VHDL

    Hello! I have to design a RPN calculator that can perform +, -, AND, OR and brackets using VHDL. I used Dijkstra's Shunting Yard Algorithm to transform the introduced expression into a postfix expression (this works fine). However, the calculation part isn't working. I saved the postfixed expression into a queue. I extract elements from the queue. If the extracted element is a number I add it into a temporary result stack if it is an operator than i pop two elements from the temporary result stack, the ALU calculates the temporary result and that temporary result should be added back into the stack. However, the temporary result is added to the stack before the signal actually changes it's value (I think this is what is happening). The temporary result is added correctly to the stack if the introduced expression only has two numbers (it should work for n numbers). This is the part of the code that I have written to describe the calculation. Could you give me some advice on how to change the process so it would work correctly for expressions that have n numbers? Thanks!

    Code:
    calc: process(egal, temp_res, q_front) is
    	
    	variable q_front_v: integer := q_front;
    	variable top_res_v: integer := top_res;
    	
    	variable crt_el: std_logic_vector(17 downto 0) := (others => '0');
    	
    	begin
    		if egal = '1' and finish = '0' then
    			
    			if q_front_v = q_last - 1 then -- the queue is empty => we calculated the whole expression
    				finish <= '1';
    			
    			else  
    				
    				if previous_element(17) = '1' then  --if the previous element was an operator => we have a temporary result we have to add to the stack
    					top_res_v := top_res_v - 1;
    					res_stack(top_res_v) <= temp_res;	
    					
    				else   --the previous element was a number => we don't have to push anything into the stack
    					null;
    					
    				end if;
    				
    				crt_el := queue(q_front_v); --the first element from the queue
    				q_front_v := q_front_v - 1;	--dequeue
    				
    				if crt_el(17) = '0' then --we took out an operand from the queue =>we push it into the stack
    					top_res_v := top_res_v - 1;
    					res_stack(top_res_v) <= crt_el(16 downto 0);
    				
    				else --am scos un operator
    					oper_crt <= crt_el(4 downto 0);
    					
    					-- the first two numbers are poped from the stack
    					
    					op2 <= res_stack(top_res_v);
    					top_res_v := top_res_v + 1;
    					
    					op1 <= res_stack(top_res_v);
    					top_res_v := top_res_v + 1;
    					
    				end if;
    				
    			end if;
    				
    			q_front <= q_front_v;
    			top_res <= top_res_v;
    			previous_element <= crt_el;
    		
    		elsif egal = '1' and finish = '1' then	
    			final_result <= temp_res;
    			top_res_v := top_res - 1;
    			res_stack(top_res_v) <= temp_res; 
    		end if;		
    		
    	end process;
    	
    	calculate: ALU port map(op1, op2, oper_crt, temp_res);
    	afis: BCD_7seg port map(final_result(15 downto 0), clk, clr, a_to_g, an);
    	negative <= final_result(16);

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 29,773, Level: 42
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,857
    Helped
    1635 / 1635
    Points
    29,773
    Level
    42

    Re: RPN Calculator using VHDL

    Use a clocked process and not combonational logic, if you keep using combo logic you'll always have "issues" with your code functioning properly. You've been doing this since the previous design of an infix calculator. I still think you are treating VHDL as a software programming language. As it is a hardware description language you should be knowledgeable about how digital logic is designed and translate it either from a drawn schematic of the logic on paper or a schematic of the design that is all in your head into the VHDL description.

    I repeat, use a clock and use an FSM to control the two queues.

    Right now you have a bunch of latches that get inferred due to missing assignments in different branches of the if statement, to make those signals hold their last value.

    Also why are you using variables? You can design anything you want using only signals and avoid all kinds of pitfall that variables introduce that the majority of new/junior VHDL coders know very little about and inevitably fall into.

    - - - Updated - - -

    Stuff like this looks like a software coder writing VHDL
    Code:
    crt_el := queue(q_front_v); --the first element from the queue
    q_front_v := q_front_v - 1;	--dequeue
    It functions as you expect software to function because you used variables, which is exactly why you should not use variables until you know how to code using only signals. I'd wager you originally used signals and it didn't work and you found out variables behaved the way you wanted your VHDL SOFTWARE to work so you used variables.

    If you keep insisting on writing software, why don't you code this in Python, that's a popular software language. At least it will behave like software just like you expect.


    1 members found this post helpful.

--[[ ]]--