--- /dev/null
+`define STATE_READ 3'b100
+`define STATE_RUN 3'b010
+`define STATE_WRITE 3'b001
+
+`ifdef SIM
+ `define START_STATE `STATE_RUN
+`else
+ `define START_STATE `STATE_READ
+`endif
+
+module CTRL (input clk, input step_eval, input reader_finished, input eval_finished, input writer_finished, output gc_clock_enable, output eval_clock_enable, output reader_clock_enable, output writer_clock_enable, output reset, input gc_ram_we, input reader_ram_we, input [12:0] gc_ram_addr, input [12:0] reader_ram_addr, input [12:0] writer_ram_addr, input [15:0] gc_ram_di, input [15:0] reader_ram_di, output ram_we, output [12:0] ram_addr, output [15:0] ram_di, input uart_is_receiving, input uart_is_transmitting, output [4:0] led);
+ reg [3:0] state = `START_STATE;
+
+ wire is_reading = state == `STATE_READ;
+ wire is_running = state == `STATE_RUN;
+ wire is_writing = state == `STATE_WRITE;
+
+ assign gc_clock_enable = is_running;
+ assign eval_clock_enable = step_eval & is_running;
+ assign reader_clock_enable = is_reading;
+ assign writer_clock_enable = is_writing;
+ assign reset = !is_running;
+
+ always @ (posedge clk) begin
+ if(is_writing & writer_finished)
+ state <= `STATE_READ;
+
+ if(is_reading & reader_finished)
+ state <= `STATE_RUN;
+
+ if(is_running & eval_finished)
+ state <= `STATE_WRITE;
+ end
+
+ assign ram_we = reader_clock_enable ? reader_ram_we : gc_ram_we;
+ assign ram_addr = reader_clock_enable ? reader_ram_addr : writer_clock_enable ? writer_ram_addr : gc_ram_addr;
+ assign ram_di = reader_clock_enable ? reader_ram_di : gc_ram_di;
+
+ assign led[0] = is_reading;
+ assign led[1] = uart_is_receiving;
+ assign led[2] = is_writing;
+ assign led[3] = uart_is_transmitting;
+ assign led[4] = is_running;
+endmodule