module controller ( ir_out, clk, reset, halt_current, int_request, tmp_out, ccr_out, t0_done, t1_done, t2_done, lower, //Outputs c_state, acc_op, acc_sel, alu_sel, bdg_sel, ma_sel, md_sel, ccr_sel, loadccr, loadtmp, loadir, loadma, loadmd, loadcnct, loadpc, rd_sel, rs_sel, rn_sel, load_r0h, load_r0l, load_r1h, load_r1l, load_r2h, load_r2l, load_r3h, load_r3l, load_r4h, load_r4l, load_r5h, load_r5l, load_r6h, load_r6l, load_r7h, load_r7l, load_t0, load_t1, load_t2, // MEMORY Outputs rd_bar, wr_bar, ram_ce, dummy, ); //inputs input[15:0] ir_out, tmp_out; input[7:0] ccr_out; input t0_done, t1_done, t2_done, lower; input clk, reset, halt_current, int_request; // outputs output[7:0] c_state; output[3:0] acc_op, acc_sel; output[5:0] alu_sel; output[1:0] bdg_sel, ma_sel, ccr_sel, loadtmp,loadmd, loadcnct; output[4:0] rd_sel, rs_sel, rn_sel; output[1:0] load_r0h, load_r0l, load_r1h, load_r1l, load_r2h, load_r2l, load_r3h, load_r3l, load_r4h, load_r4l, load_r5h, load_r5l, load_r6h, load_r6l, load_r7h, load_r7l; output loadpc, md_sel, loadccr, loadir, loadma, load_t0, load_t1, load_t2, rd_bar, wr_bar, ram_ce; output dummy; //Input port data types wire[15:0] ir_out, tmp_out; wire[7:0] ccr_out; wire t0_done, t1_done, t2_done, lower; wire clk, reset, halt_current, int_request; // output port datatypes reg[7:0] c_state; reg[3:0] acc_op, acc_sel; reg[5:0] alu_sel; reg[1:0] bdg_sel, ma_sel, ccr_sel, loadtmp,loadmd, loadcnct; reg[4:0] rd_sel, rs_sel, rn_sel; reg[1:0] load_r0h, load_r0l, load_r1h, load_r1l, load_r2h, load_r2l, load_r3h, load_r3l, load_r4h, load_r4l, load_r5h, load_r5l, load_r6h, load_r6l, load_r7h, load_r7l; reg loadpc, md_sel, loadccr, loadir, loadma, load_t0, load_t1, load_t2, rd_bar, wr_bar, ram_ce; reg dummy; // Internal variables //typedef enum {idle, F1, F1_int, F2, D1, D2, D2_0} fsm_states; //typedef enum {idle, F1, F1_int, F2, D1, D2, D2_0} fsm_states; //fsm_states reg state; reg[size-1:0] current_state, next_state, state_after, state_now; //reg inc_current, inc_next; //reg loadccr_current, loadccr_next; //reg md_sel_current, md_sel_next; //reg[1:0] ccr_sel_current, ccr_sel_next; //reg[3:0] acc_op_current, acc_op_next; //reg[3:0] reg_current, reg_next; //reg[3:0] acc_sel_current, acc_sel_next; //reg[4:0] rd_sel_current, rd_sel_next; //reg[4:0] rs_sel_current, rs_sel_next; //reg[5:0] alu_sel_current, alu_sel_next; //internal constants parameter size = 6; parameter idle = 6'b000000, F1 = 6'b000001, F1_int = 6'b000010, F2 = 6'b000011, D1 = 6'b000100, D2 = 6'b000101, D2_0 = 6'b000110, D2_1 = 6'b000111, D3 = 6'b001000, E_rd_inc = 6'b001001, E_rd_B = 6'b001010, E_rd_W = 6'b001011, D2_4 = 6'b001100, D2_5 = 6'b001101, D2_6 = 6'b001110, D2_7a = 6'b001111, D2_7b = 6'b010000, D2_7c = 6'b010001; // combinational part initial c_state = 8'b00000000; initial dummy = 1'b0; always @ (posedge clk) begin : FSM_COMBO if (reset == 1'b1) begin current_state = idle; end else begin dummy = 1'b0; loadir = 1'b0; loadma = 1'b0; loadpc = 2'b00; loadmd = 2'b00; loadcnct=2'b00; load_t0 = 1'b0; load_t1 = 1'b0; load_t2 = 1'b0; ma_sel = 2'b00; md_sel = 1'b0; ccr_sel = 2'b00; loadccr = 1'b0; loadtmp = 2'b00; acc_op = 4'b0000; acc_sel = 4'b0000; alu_sel = 6'b000000; bdg_sel = 2'b00; rd_sel = 5'b00000; rs_sel = 5'b00000; rn_sel = 5'b00000; load_r0l = 2'b00; load_r0h = 2'b00; load_r1l = 2'b00; load_r1h = 2'b00; load_r2l = 2'b00; load_r2h = 2'b00; load_r3l = 2'b00; load_r3h = 2'b00; load_r4l = 2'b00; load_r4h = 2'b00; load_r5l = 2'b00; load_r5h = 2'b00; load_r6l = 2'b00; load_r6h = 2'b00; load_r7l = 2'b00; load_r7h = 2'b00; // Memory control signals wr_bar = 1'b1; rd_bar = 1'b1; ram_ce = 1'b0; case(current_state) idle : begin next_state = F1; c_state = 8'h00; //dummy <= 1'b0; end F1 : begin c_state = 8'h04; if (halt_current == 1'b1) begin // Halt enabled next_state = idle; end else if (int_request == 1'b1) begin // Interruption Handler next_state = F1_int; end else begin //-- Normal Run, reading from mem(pc) next_state = F2; loadma = 1'b1; //-- mux_ma in pc state_after = F2; end end F1_int : begin//Interruption handler next_state = F1; c_state = 8'h05; end F2 : begin // Load Instrctn & Incrmnt PC c_state = 8'h06; rd_bar = 1'b0; //--Rdng from MEM ram_ce = 1'b1; rn_sel = 5'b11000; //--md(24) loadir = 1'b1; //-- pc rd_sel = 5'b11001; //--pc(25) alu_sel = 6'b010101 ; //--inc_2 loadpc = 2'b01 ; //--alu next_state = D1; dummy = 1'b0; end D1 : begin//-- first byte decision c_state = 8'h07; if (ir_out[15]== 1'b0) begin // -- Direct next_state = D2; end else if (ir_out[15] == 1'b1) begin // -- IMM next_state = D3; end else begin next_state = idle; end end D2 : begin c_state = 8'h08; //-- first byte high dummy = 1'b1; case (ir_out[15:12]) 4'h0 : // -- ALU (0x) next_state = D2_0; 4'h1 : // -- Logicals (1x) next_state = D2_1; 4'h2 : begin //-- MOV_B from MEM (2x) ma_sel = 2'b11; //--abs address loadma = 1'b1; next_state = E_rd_inc; state_after = E_rd_B; end 4'h3 : begin //-- MOV_B to MEM (3x) ma_sel = 2'b11; //-- abs address loadma = 1'b1; next_state = E_rd_inc; state_after = E_rd_W; end 4'h4 : //-- Branch (4x) next_state = D2_4; 4'h5 : //-- MultJump back (5x) next_state = D2_5; 4'h6 : //-- BIT / MOV (6x) next_state = D2_6; 4'h7 : begin //-- BIT (7x) case (ir_out[11:10]) 2'b00 : next_state = D2_7a; 2'b01 : next_state = D2_7b; default : next_state = D2_7c; endcase end default : next_state = idle; endcase end D2_0 : begin c_state = 8'h09; next_state = idle; end default : begin next_state = idle; dummy = 1'b0; end D2_1 : next_state = idle; D3 : next_state = idle; E_rd_inc : next_state = idle; E_rd_B : next_state = idle; E_rd_W : next_state = idle; D2_4 : next_state = idle; D2_5 : next_state = idle; D2_6 : next_state = idle; D2_7a : next_state = idle; D2_7b : next_state = idle; D2_7c : next_state = idle; endcase end end endmodule