Hello!
I have to project a specialized calculator on a Basys3 board using VHDL. The calculator should be able to group numbers using brackets, perform additions and substractions, AND and OR operations. For example, an expression could be: 4 + 5 AND 6 +(2 AND 7 OR 1) - (4 AND 10)
I decided to code it as a RPN calculator and I used Dijkstra's Shunting-yard algorithm to transform the infix expression into a postfix one. I managed to implement this algorithm, I tested it in the simulator and it transformed the expression correctly. I also tried to synthesize it to the Basys3 board and it worked.
However, the part that should calculate the result doesn't work properly and I can't figure out why. This is the code that I have written:
op1, op2 and oper_crt don't seem to modify their values in the process (they remain 0 after the process executes once - I don't understand why) and so when the ALU is called, it will do 0+0 and temp_res will remain 0 and the process won't start again (I think that's what's happening).
I tried to synthesize the whole code (the one I posted above + the Shunting-yard algorithm) on the Basys3 board and the synthesis went on forever.
I'm new to VHDL, I'm a student and I have just started learning it and I got stuck at this part in the project. Could you give me some advice on how I could modify the code that I have written so that the RPN calculator would work corectly?
Thanks!
I have to project a specialized calculator on a Basys3 board using VHDL. The calculator should be able to group numbers using brackets, perform additions and substractions, AND and OR operations. For example, an expression could be: 4 + 5 AND 6 +(2 AND 7 OR 1) - (4 AND 10)
I decided to code it as a RPN calculator and I used Dijkstra's Shunting-yard algorithm to transform the infix expression into a postfix one. I managed to implement this algorithm, I tested it in the simulator and it transformed the expression correctly. I also tried to synthesize it to the Basys3 board and it worked.
However, the part that should calculate the result doesn't work properly and I can't figure out why. This is the code that I have written:
Code:
calc: process(egal, temp_res) is
variable q_front_v: integer := q_front; --inicates the first element from the queue that contains the expression in postfix notation
variable q_last_v: integer := q_last; --indicates the last element from the queue
variable top_res_v: integer := top_res; --indicates the top of the result stack
variable crt_element: std_logic_vector(17 downto 0) := (others => '0'); --will be the first element from the queue
variable i: integer;
variable calculated_v: std_logic := calculated;
variable final_result_v: std_logic_vector(17 downto 0) := final_result;
begin
if egal = '1' then --if the whole expression was introduced
if q_front_v < q_last_v then --if the queue is empty -> we made all the calculations -> we have the final result
final_result_v := temp_res;
else
if calculated_v = '1' then --if we already calculated a partial result -> we add it in the result stack
top_res_v := top_res_v - 1;
res_stack(top_res_v) <= temp_res;
else -- if we didn't yet calculate any partial result => we will after we exit the process
calculated_v := '1';
end if;
crt_element := queue(q_front_v); --the first element from the queue
q_front_v := q_front_v - 1; --dequeue, we eliminate the first element from the queue
i := 1100;
while (crt_element(17) /= '1') and (i /= 0) loop --while the element we take out of the queue isn't an operator
top_res_v := top_res_v - 1; --we add the element in the result stack => push
res_stack(top_res_v) <= crt_element; --we add the element in the result stack => push
crt_element := queue(q_front_v); --first element from the queue
q_front_v := q_front_v - 1; --dequeue
i := i - 1;
end loop;
-- we exited the while loop => crt_element is an operator => we have to make the calculations
op2 <= res_stack(top_res_v); -- the element from the top of the result stack
top_res_v := top_res_v + 1; -- we eliminate the element from the top of the stack => pop
op1 <= res_stack(top_res_v); -- the element from the top of the result stack
top_res_v := top_res_v + 1; -- we eliminate the element from the top of the stack => pop
oper_crt <= crt_element(4 downto 0); --the operator that was dequeued last time
q_front <= q_front_v;
top_res <= top_res_v;
calculated <= calculated_v;
final_result <= final_result_v;
end if;
end if;
end process;
ALU_calc: ALU port map(op1(16 downto 0), op2(16 downto 0), oper_crt, temp_res(16 downto 0));
BCD_afis: BCD_7seg port map(final_result(15 downto 0), clk, clr, a_to_g, an);
negative <= final_result(16);
I tried to synthesize the whole code (the one I posted above + the Shunting-yard algorithm) on the Basys3 board and the synthesis went on forever.
I'm new to VHDL, I'm a student and I have just started learning it and I got stuck at this part in the project. Could you give me some advice on how I could modify the code that I have written so that the RPN calculator would work corectly?
Thanks!