I am trying to implement the controller for a simple CPU in VHDL. The controller is modeled as an ASM that waits in a decode state until it receives the start signal. The next state that it progresses into depends on the machine code received and determines what operations the CPU performs.
I was intending to implement subtraction as a multicycle instruction. The first step would be to go to the SUB state, where 2's comp would be performed on one of the registers. Then, the controller would progress to the ADD state to perform the subtraction (addition on negative number). The process to implement the state machine in this way is shown below.
ASM: process(CLK, RESET_L) begin
if (RESET_L = '0') then
cur_state <= S_Decode;
DONE <= '0';
elsif (rising_edge(CLK)) then
case cur_state is
when S_Decode =>
if (START = '1' and (DEST(1) /= '1')) then
case instr is
when "000" => cur_state <= S_Load;
when "001" => cur_state <= S_Tab;
when "010" => cur_state <= S_And;
when "011" => cur_state <= S_Or;
when "100" => cur_state <= S_Add;
when "101" => cur_state <= S_Sub;
when "110" => cur_state <= S_Srl;
when "111" => cur_state <= S_out;
end case;
DONE <= '0';
else
DONE <= '0';
end if;
DONE <= '0';
when S_Sub =>
debug_sig <= '1';
cur_state <= S_Add;
when others =>
cur_state <= S_Decode;
DONE <= '1';
end case;
end if;
end process;
However, in simulation, my design appears to be skipping the SUB state all together and progressing directly to the ADD state.
I attached a screenshot of the simulation below. The OP signal shows the opcode passed to the datapath. The opcode circled in blue is the ADD opcode. I would be expecting the 2's comp opcode. The setting of this opcode is done in a separate process, which is sensitive to the cur_state. I didn't include it here because I don't believe the issue lies in the mapping of the opcode to the current state but in the state machine itself.
I also included a debug signal which will go high once the state machine transitions from SUB to ADD. As can be seen in the simulation, this signal goes high as soon as the start signal goes high. From this, I assume that the case statement is executing both the "when S_Decode" block and the "when S_Sub" block together. It appears that as soon as the controller enters the SUB state, it immediately transitions to the ADD state.
Any feedback or help is appreciated. Please let me know if I can provide any more clarification. Thanks in advance.