diff options
Diffstat (limited to 'eater_cpu/eater_decoder.sv')
| -rw-r--r-- | eater_cpu/eater_decoder.sv | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/eater_cpu/eater_decoder.sv b/eater_cpu/eater_decoder.sv new file mode 100644 index 0000000..d6b6c4c --- /dev/null +++ b/eater_cpu/eater_decoder.sv @@ -0,0 +1,92 @@ +`timescale 1us/1us + +`include "eater_types.sv" + +module eater_decoder ( + input clk_i, + input wire enable_control_i, + input wire [7:0] instruction_i, + output CpuControlFlags flags_o +); + +CpuState internal_state; +CpuState next_state; +CpuControlFlags internal_flags; + +always_comb begin + if (enable_control_i) begin + flags_o = internal_flags; + end else begin +`ifdef IVERILOG + flags_o = 'bz; +`else + flags_o = '{default: 'z}; +`endif + end +end + +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 |
