% ALU % CASE ir[7..5].q IS WHEN 0 => alu_c[] = acc_c[] + mem_c[]; % arithmetic add% alu[3..0].d=alu_c[3..0]; c.d = alu_c[4]; z.d = (alu_c[3..0] == 0); c.ena = select[5]; z.ena = select[5]; WHEN 1 => alu_c[] = acc_c[] - mem_c[]; % arithmetic sub% alu[3..0].d = alu_c[3..0]; c.d = alu_c[4]; z.d = (alu_c[3..0] == 0); c.ena = select[5]; z.ena = select[5]; WHEN 2 => alu_c[] = acc_c[] !& mem_c[]; % logic NAND % alu[3..0].d = alu_c[3..0]; c.d = alu_c[4]; z.d = (alu_c[3..0] == 0); c.ena = select[5]; z.ena = select[5]; WHEN 3 => IF ( ir[4..0].q == H"1F" ) THEN alu[2..0].d = acc[3..1].q; % Right shift% alu[3].d = GND; c.d = acc[0].q; z.d = (acc[3..1].q == 0); ELSE alu[3..1].d = acc[2..0].q; % left shift% alu[0].d = GND; c.d = acc[3].q; z.d = (acc[2..0].q == 0); END IF; c.ena = select[5]; z.ena = select[5]; WHEN OTHERS => alu[3..0].d = acc[3..0].q; % store also useing ALU % c.ena = GND; z.ena = GND; END CASE;
% Control % ss.clk = s_clk.q; ss.reset = reset; TABLE ss, ir[7..5].q, c, z => select[8..0], ss, fe; s0, B"XXX", X, X => B"000001001", s1, 1; % select8: IR(3..0) latch% s1, B"XXX", X, X => B"000010000", s2, 1; % select7: PC load% s2, B"XXX", X, X => B"100000001", s3, 1; % select6: ACC latch % s3, B"XXX", X, X => B"000010000", s4, 0; % select5: ALU latch % s4, B"0XX", X, X => B"000100000", s5, 0; % select4: PC count up or load enable % s5, B"0XX", X, X => B"001000010", s0, 1; % select3: IR(7..4) latch% s4, B"100", X, X => B"001000000", s0, 1; % select2: memory read/write % s4, B"101", X, X => B"000100000", s5, 0; % select1: ACC data select from ALU or memory % s5, B"101", X, X => B"000000110", s0, 1; % select0: address select PC(1) or IR(4..0)(0) % s4, B"110", 0, X => B"000000000", s0, 1; s4, B"110", 1, X => B"010010000", s0, 1; s4, B"111", X, 0 => B"010010000", s0, 1; s4, B"111", X, 1 => B"000000000", s0, 1; END TABLE;
IF select[0] THEN a_bus[] = pc[].q; % fetch cycle: read instruction % ELSE a_bus[] = ir[4..0].q; % exec cycle: read opeland % END IF; CASE select[2..1] IS WHEN 0 => acc[].d = mem_out[]; % ACC read from memory % WHEN 1 => acc[].d = alu[].q;% ACC read from ALU % WHEN 2 => mem_in[] = alu[].q; % ALU write to memory % WHEN 3 => mem_in[] = alu[].q; % ALU write to memory % END CASE; IF select[7] THEN pc[].d = ir[4..0].q; % Jump: JPC or JPNZ % ELSE pc[].d = pc[].q + 1; % count up PC % END IF;
% Memory % mem[].clk = t_clk.q; out_port[].clk = t_clk.q; ir[7..4].d=mem_out[]; ir[3..0].d=mem_out[]; CASE a_bus[] IS WHEN 0 => mem_out[] = H"8"; % ROM section % WHEN 1 => mem_out[] = H"8"; WHEN 2 => mem_out[] = H"0"; WHEN 3 => mem_out[] = H"9"; WHEN 4 => mem_out[] = H"B"; WHEN 5 => mem_out[] = H"F"; WHEN 6 => mem_out[] = H"F"; WHEN 7 => mem_out[] = H"F"; WHEN 8 => mem_out[] = H"1"; WHEN 9 => mem_out[] = H"2"; WHEN 10 => mem[3..0].d = mem_in[]; mem[3..0].ena = select[2]; mem_out[] = mem[3..0].q; % RAM section % WHEN 30 => mem_out[] = in_port[]; % Input prot % WHEN 31 => out_port[].d = mem_in[]; out_port[].ena = select[2]; % Output prot % WHEN OTHERS =>mem_out[] = H"F"; % data fix to F, when other address is accessed % END CASE;