`timescale 1us/1us `include "eater_types.sv" module eater_decoder ( input clk_i, input wire [7:0] instruction_i, output CpuControlFlags flags_o ); CpuState internal_state /* verilator public_flat_rd */; CpuState next_state; CpuControlFlags internal_flags; wire [3:0] actual_instruction = instruction_i[7:4]; assign flags_o = internal_flags; initial begin internal_state = INIT; next_state = INIT; // assigned in always_comb // internal_flags = '{default: '0}; end function CpuState insdep_state; case (actual_instruction) LDA: insdep_state = LDA_INS_to_MAR; ADD: insdep_state = ADD_INS_to_MAR; OUT: insdep_state = OUT_A_to_OUT; HALT_op: insdep_state = HALT_st; default: insdep_state = INIT; endcase endfunction // next-state machine always @(posedge clk_i) begin next_state = INIT; case (internal_state) INIT: next_state = PC_to_MAR; PC_to_MAR: next_state = MEM_to_INS; MEM_to_INS: next_state = PC_inc; PC_inc: next_state = insdep_state(); LDA_INS_to_MAR: next_state = LDA_MEM_to_A; LDA_MEM_to_A: next_state = PC_to_MAR; ADD_INS_to_MAR: next_state = ADD_MEM_to_B; ADD_MEM_to_B: next_state = ADD_ALU_to_A; ADD_ALU_to_A: next_state = PC_to_MAR; OUT_A_to_OUT: next_state = PC_to_MAR; HALT_st: next_state = HALT_st; default: begin next_state = INIT; end endcase internal_state <= next_state; end // current-state-to-flags machine // TODO: This is kinda weird, I *can* set "all flags" to zero "in the beginning", // and then only set the required flags "later". // how does that work combinatorically??? always_comb begin `ifdef IVERILOG internal_flags = 'b0; `else internal_flags = '{default: '0}; `endif case (internal_state) // INIT: // left out PC_to_MAR: begin internal_flags.PC_out = 1; internal_flags.MAR_in = 1; end MEM_to_INS: begin internal_flags.RAM_out = 1; internal_flags.INS_in = 1; end PC_inc: begin internal_flags.PC_count = 1; end LDA_INS_to_MAR: begin internal_flags.INS_out = 1; internal_flags.MAR_in = 1; end LDA_MEM_to_A: begin internal_flags.RAM_out = 1; internal_flags.A_in = 1; end ADD_INS_to_MAR: begin internal_flags.INS_out = 1; internal_flags.MAR_in = 1; end ADD_MEM_to_B: begin internal_flags.RAM_out = 1; internal_flags.B_in = 1; end ADD_ALU_to_A: begin internal_flags.ALU_out = 1; internal_flags.A_in = 1; end OUT_A_to_OUT: begin internal_flags.A_out = 1; internal_flags.OUT_in = 1; end HALT_st: begin internal_flags.halt = 1; end default: begin end endcase end endmodule