NightOWL
Newbie level 3
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);