//Greg Chabala //control unit `timescale 1ns/100ps module control_unit(load_ctl, inc_ctl, clr_ctl, cin, flag_en, ALU_sel, op_sel, read_mem, write_mem, bus_ctl, IR_out, flag_out, clk, R, reset, DR_zero, AC_lh); output [5:0] load_ctl; //0-AR, 1-PC, 2-DR, 3-AC, 4-IR, 5-TR output [5:0] inc_ctl; output [5:0] clr_ctl; output read_mem; output write_mem; output [2:0] bus_ctl; output cin; output flag_en; output ALU_sel; output [3:0] op_sel; //flags 0: overflow // 1: carry // 2: sign // 3: zero input [15:0] IR_out; input [3:0] flag_out; input clk; input R; input reset; input DR_zero; input [1:0] AC_lh; wire [3:0] SC_out; wire SC_clr; wire SC_inc; wire [7:0] D_input; wire [15:0] T_input; seq_counter SC(SC_out, SC_clr | reset, SC_inc, clk); a3to8_decoder D1(D_input, IR_out[14:12]); a4to16_decoder D2(T_input, SC_out); control_logic CTL(load_ctl, inc_ctl, clr_ctl, cin, flag_en, ALU_sel, op_sel, read_mem, write_mem, SC_clr, SC_inc, bus_ctl, IR_out[11:0], IR_out[15], D_input, T_input, flag_out, R, DR_zero, clk, AC_lh, reset); endmodule module control_logic(load_ctl, inc_ctl, clr_ctl, cin, flag_en, ALU_sel, op_sel, read_mem, write_mem, SC_clr, SC_inc, bus_ctl, addy, I, D, T, flag, R, DR_zero, clk, AC_lh, reset); output [5:0] load_ctl; //0-AR, 1-PC, 2-DR, 3-AC, 4-IR, 5-TR output [5:0] inc_ctl; output [5:0] clr_ctl; output read_mem; output write_mem; output [2:0] bus_ctl; output SC_clr, SC_inc; output cin; output flag_en; output ALU_sel; output [3:0] op_sel; input [11:0] addy; input I; input [7:0] D; input [15:0] T; input [3:0] flag; input R; input DR_zero; input clk; input [1:0] AC_lh; input reset; wire E_out; wire E_in; wire E_load; wire E_clr; wire E_comp; flipflop E(E_out, E_in, E_load, E_clr, clk, E_comp); //flags 0: overflow // 1: carry // 2: sign // 3: zero assign read_mem = ((~R) & T[1]) | ((~D[7]) & I & T[3]) | ((D[0] | D[1] | D[2] | D[6]) & T[4]) | (D[7] & (~I) & addy[9] & addy[10] & T[4]); assign write_mem = (R & T[1]) | (D[6] & T[6]) | (T[4] & (D[3] | D[5])); assign SC_clr = ((D[0] | D[1] | D[2] | D[5]) & T[5]) | (D[7] & T[5]) | (D[6] & T[6]) | (R & T[2]) | ((D[3] | D[4]) & T[4]); assign SC_inc = 1'b1; assign cin = 1'b0; assign flag_en = 1'b1; assign ALU_sel = D[7] & (~I) & T[3] & (addy[7] | addy[6] | addy[9]); assign load_ctl[0] = ((~R) & (T[0] | T[2])) | ((~D[7]) & I & T[3]) | (T[3] & D[7] & (~I) & addy[9] & addy[10]); assign inc_ctl[0] = D[5] & T[4]; assign clr_ctl[0] = R & T[0]; assign load_ctl[1] = (D[4] & T[4]) | (D[5] & T[5]); assign inc_ctl[1] = ((~R) & T[1]) | (R & T[2]) | (DR_zero & D[6] & T[6]) | ((D[7] & (~I) & T[3]) & (((~AC_lh[1]) & addy[4]) | (flag[2] & addy[3]) | (flag[3] & addy[2]) | ((~E_out) & addy[1]))) | (T[4] & D[7] & (~I) & addy[9] & addy[10]); assign clr_ctl[1] = R & T[1]; assign load_ctl[2] = (D[0] | D[1] | D[2] | D[6] | (D[7] & (~I) & addy[9] & addy[10])) & T[4]; assign inc_ctl[2] = D[6] & T[5]; assign clr_ctl[2] = 1'b0; assign load_ctl[3] = (D[7] & (~I) & T[3] & (addy[7] | addy[6] | addy[9])) | ((D[0] | D[1] | D[2]) & T[5]) | (D[7] & (~I) & addy[9] & addy[10] & T[5]); assign inc_ctl[3] = D[7] & (~I) & T[3] & addy[5]; assign clr_ctl[3] = D[7] & (~I) & T[3] & addy[11]; assign load_ctl[4] = (~R) & T[1]; assign inc_ctl[4] = 1'b0; assign clr_ctl[4] = 1'b0; assign load_ctl[5] = R & T[0]; assign inc_ctl[5] = 1'b0; assign clr_ctl[5] = 1'b0; assign op_sel[0] = D[7] & (~I) & T[3] & addy[9]; assign op_sel[1] = (D[2] & T[5]) | (D[7] & (~I) & T[3] & addy[9]) | (D[7] & (~I) & addy[9] & addy[10] & T[5]); assign op_sel[2] = (D[0] & T[5]) | (D[7] & (~I) & T[3] & (addy[6] | addy[9])); assign op_sel[3] = D[7] & (~I) & T[3] & (addy[7] | addy[6]); assign bus_ctl[0] = (D[5] & T[5]) | (D[6] & T[6]) | ((~R) & (T[2] | T[1])) | ((~D[7]) & I & T[3]) | ((D[0] | D[1] | D[2] | D[4] | D[6]) & T[4]) | (D[7] & (~I) & addy[9] & addy[10] & T[4]); assign bus_ctl[1] = T[0] | T[1] | (D[6] & T[6]) | ((D[0] | D[1] | D[2] | D[5] | D[6]) & T[4]) | ((~D[7]) & I & T[3]) | (T[3] & D[7] & (~I) & addy[9] & addy[10]) | (D[7] & (~I) & addy[9] & addy[10] & T[4]); assign bus_ctl[2] = ((D[0] | D[1] | D[2] | D[3] | D[6]) & T[4]) | T[1] | ((~R) & T[2]) | ((~D[7]) & I & T[3]) | (D[7] & (~I) & addy[9] & addy[10] & T[4]); assign E_clr = (D[7] & (~I) & T[3] & addy[10]) | reset; assign E_comp = D[7] & (~I) & T[3] & addy[8]; assign E_load = (D[1] & T[5]) | (D[7] & (~I) & T[3] & (addy[7] | addy[6])); assign E_in = (D[1] & T[5])? flag[1] : (D[7] & (~I) & T[3] & addy[7])? AC_lh[0] : (D[7] & (~I) & T[3] & addy[6])? AC_lh[1] : 1'bz; endmodule module seq_counter (out, clear, cnt, clk); //input [3:0] in; /* parallel load input */ //input load; /* load parallel input */ input clear; /* clear the counter to 4'h0 */ input cnt; /* count enable input */ input clk; /* clock input */ output [3:0] out; /* output of counter */ reg [3:0] Q; /* four bit register to hold count */ /* State changes only on positive clock transitions */ always @(negedge clk) begin if(clear == 1'b1) /* If clear is high, it has priority */ Q <= 4'b000; //else if(load == 1'b1) /* load has the next highest */ // Q <= in; else if(cnt == 1'b1) /* followed by count enable */ Q <= Q + 4'b0001; else Q <= Q; end /* Set the output to always be equal to the internal state */ assign out = Q; endmodule module flipflop(out, in, load, clear, clk, comp); input in; input load, clear, clk, comp; output out; reg out; always @(posedge clk) if (clear) out <= 1'b0; else if (load) out <= in; else if (comp) out <= ~out; else out <= out; endmodule