diff options
Diffstat (limited to 'eater_cpu')
| -rw-r--r-- | eater_cpu/Makefile | 4 | ||||
| -rw-r--r-- | eater_cpu/eater_computer.sv | 7 | ||||
| -rw-r--r-- | eater_cpu/eater_decoder.sv | 92 |
3 files changed, 101 insertions, 2 deletions
diff --git a/eater_cpu/Makefile b/eater_cpu/Makefile index 9145135..ab0e7b1 100644 --- a/eater_cpu/Makefile +++ b/eater_cpu/Makefile @@ -1,4 +1,4 @@ -cpu: eater_computer_tb.sv eater_computer.sv zbuffer.sv eater_register.v eater_alu.sv ../playground/my_mem.v ../nandgame/counter.sv +cpu: eater_computer_tb.sv eater_computer.sv zbuffer.sv eater_register.v eater_alu.sv eater_decoder.sv ../playground/my_mem.v ../nandgame/counter.sv iverilog -o $@ -g2012 -DIVERILOG $^ HARDWARE_SUFFIX := .sv @@ -10,7 +10,7 @@ include ../common.mk .PHONY: simpc simpc: simpc/Vcomputer -simpc/Vcomputer: eater_computer.sv zbuffer.sv eater_register.v eater_alu.sv ../playground/my_mem.v ../nandgame/counter.sv +simpc/Vcomputer: eater_computer.sv zbuffer.sv eater_register.v eater_alu.sv eater_decoder.sv ../playground/my_mem.v ../nandgame/counter.sv #computer.sv cpp/Vcomputer__main.cpp cpp/disas.cpp cpp/simpc_ui.cpp # -CFLAGS "-I${PWD}/cpp" verilator \ diff --git a/eater_cpu/eater_computer.sv b/eater_cpu/eater_computer.sv index f7f0952..f9104af 100644 --- a/eater_cpu/eater_computer.sv +++ b/eater_cpu/eater_computer.sv @@ -165,4 +165,11 @@ eater_register OUT ( .always_out(OUT_out) ); +eater_decoder decoder ( + .clk_i(clk_in), + .instruction_i(INS_out), + .enable_control_i(0), + .flags_o() +); + endmodule 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 |
