`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; CpuState next_state; CpuControlFlags internal_flags; assign flags_o = internal_flags; initial begin internal_state = INIT; next_state = INIT; // assigned in always_comb // internal_flags = '{default: '0}; end // next-state machine always @(posedge clk_i) begin next_state = INIT; case (internal_state) INIT: begin next_state = PC_to_MAR; end PC_to_MAR: begin next_state = MEM_to_INS; end MEM_to_INS: begin next_state = PC_inc; end PC_inc: begin next_state = PC_to_MAR; end 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 default: begin end endcase end endmodule