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.

RPN Calculator using VHDL

Status
Not open for further replies.

NightOWL

Newbie level 3
Joined
May 1, 2017
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
74
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);
 

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.
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top