1
0
Fork 0
2023-fpga-computer/src/sap3/controller.v

929 lines
28 KiB
Verilog

module controller(
input clk,
input rst,
input[7:0] opcode,
input[7:0] flags,
output[32:0] out
);
localparam DISPLAY = 32;
localparam HLT = 31;
localparam ALU_CS = 30;
localparam ALU_FLAGS_WE = 29;
localparam ALU_A_WE = 28;
localparam ALU_A_STORE = 27;
localparam ALU_A_RESTORE = 26;
localparam ALU_TMP_WE = 25;
localparam ALU_OP4 = 24;
localparam ALU_OP0 = 20;
localparam ALU_OE = 19;
localparam ALU_FLAGS_OE = 18;
localparam REG_RD_SEL4 = 17;
localparam REG_RD_SEL0 = 13;
localparam REG_WR_SEL4 = 12;
localparam REG_WR_SEL0 = 8;
localparam REG_EXT1 = 7;
localparam REG_EXT0 = 6;
localparam REG_OE = 5;
localparam REG_WE = 4;
localparam MEM_WE = 3;
localparam MEM_MAR_WE = 2;
localparam MEM_OE = 1;
localparam IR_WE = 0;
localparam REG_INC = 2'b01;
localparam REG_DEC = 2'b10;
localparam REG_INC2 = 2'b11;
localparam REG_BC = 5'b10000;
localparam REG_BC_B = 5'b00000;
localparam REG_BC_C = 5'b00001;
localparam REG_DE = 5'b10010;
localparam REG_DE_D = 5'b00010;
localparam REG_DE_E = 5'b00011;
localparam REG_HL = 5'b10100;
localparam REG_HL_H = 5'b00100;
localparam REG_HL_L = 5'b00101;
localparam REG_WZ = 5'b10110;
localparam REG_WZ_W = 5'b00110;
localparam REG_WZ_Z = 5'b00111;
localparam REG_PC = 5'b11000;
localparam REG_PC_P = 5'b01000;
localparam REG_PC_C = 5'b01001;
localparam REG_SP = 5'b11010;
localparam REG_SP_S = 5'b01010;
localparam REG_SP_P = 5'b01011;
reg[32:0] ctrl_word;
reg[3:0] stage;
reg stage_rst;
assign out = ctrl_word;
always @(negedge clk, posedge rst) begin
if (rst) begin
stage <= 0;
end else begin
if (stage_rst) begin
stage <= 0;
end else begin
stage <= stage + 1;
end
end
end
always @(*) begin
ctrl_word = 0;
stage_rst = 0;
if (stage == 0) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 1) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[IR_WE] = 1'b1;
end else if (stage == 2) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else begin
casez (opcode)
// NOP
8'o000: begin
stage_rst = 1'b1;
end
// HLT
8'o166: begin
if (stage == 3) begin
ctrl_word[HLT] = 1'b1;
end
end
// MOV Rd, M
// opcode[5:3] - Rd
8'o1?6: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
if (opcode[5:3] == 3'b111) begin
ctrl_word[ALU_A_WE] = 1'b1;
end else begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
ctrl_word[REG_WE] = 1'b1;
end
ctrl_word[MEM_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// MOV M, Rs
// opcode[2:0] - Rs
8'o16?: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
if (opcode[2:0] == 3'b111) begin
ctrl_word[ALU_OE] = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
ctrl_word[REG_OE] = 1'b1;
end
ctrl_word[MEM_WE] = 1'b1;
stage_rst = 1'b1;
end
end
// MOV Rd, Rs
// opcode[5:3] - Rd
// opcode[2:0] - Rs
8'o1??: begin
if (stage == 3) begin
if (opcode[2:0] == 3'b111) begin
ctrl_word[ALU_OE] = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
ctrl_word[REG_OE] = 1'b1;
end
if (opcode[5:3] == 3'b111) begin
ctrl_word[ALU_A_WE] = 1'b1;
end else begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
ctrl_word[REG_WE] = 1'b1;
end
stage_rst = 1'b1;
end
end
// INX, DCX
// opcode[5:4] - 16-bit Register
// opcode[3] - Dec(1) / Inc (0)
8'o0?3: begin
if (stage == 3) begin
if (opcode[5:4] == 2'b11)
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
else
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b10, opcode[5:4], 1'b0};
ctrl_word[REG_EXT1:REG_EXT0] = {opcode[3], ~opcode[3]};
stage_rst = 1'b1;
end
end
// INR/DCR M
// opcode[5:3] - Rs
// opcode[0] - INR (0), DCR (1)
8'o064: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[ALU_A_STORE] = 1'b1;
ctrl_word[ALU_A_WE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = {4'b1000, opcode[0]};
end else if (stage == 6) begin
ctrl_word[ALU_OE] = 1'b1;
ctrl_word[ALU_A_RESTORE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
stage_rst = 1'b1;
end
end
// INR/DCR Rs
// opcode[5:3] - Rs
// opcode[0] - INR (0), DCR (1)
8'o0?4, 8'o0?5: begin
if (stage == 3) begin
if (opcode[5:3] == 3'b111) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = 5'b10000;
stage_rst = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:3]};
ctrl_word[REG_OE] = 1'b1;
ctrl_word[ALU_A_STORE] = 1'b1;
ctrl_word[ALU_A_WE] = 1'b1;
end
end else if (stage == 4) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = {4'b1000, opcode[0]};
end else if (stage == 5) begin
ctrl_word[ALU_OE] = 1'b1;
ctrl_word[ALU_A_RESTORE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
ctrl_word[REG_WE] = 1'b1;
stage_rst = 1'b1;
end
end
// Arithmetic/Logic Set 0 (M)
// opcode[5:3] - ALU Op
8'o2?6: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[ALU_TMP_WE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
stage_rst = 1'b1;
end
end
// Arithmetic/Logic Set 0
// opcode[2:0] - Rs
// opcode[5:3] - ALU Op
8'o2??: begin
if (stage == 3) begin
if (opcode[2:0] == 3'b111) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
stage_rst = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
ctrl_word[REG_OE] = 1'b1;
end
ctrl_word[ALU_TMP_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
stage_rst = 1'b1;
end
end
// Arithmetic/Logic Set 1
// opcode[5:3] - ALU Op
8'o0?7: begin
if (stage == 3) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = {2'b01, opcode[5:3]};
stage_rst = 1'b1;
end
end
// Arithmetic/Logic Immediate
// opcode[5:3] - ALU Op
8'o3?6: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[ALU_TMP_WE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
stage_rst = 1'b1;
end
end
// MVI M, d8
8'o066: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, REG_WZ_W};
ctrl_word[REG_WE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, REG_WZ_W};
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
stage_rst = 1'b1;
end
end
// MVI Rd, d8
// opcode[5:3] - Rd
8'o0?6: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
if (opcode[5:3] == 3'b111) begin
ctrl_word[ALU_A_WE] = 1'b1;
end else begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
ctrl_word[REG_WE] = 1'b1;
end
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
stage_rst = 1'b1;
end
end
// LXI
// opcode[5:4] - Extended Register
8'o001, 8'o021, 8'o041, 8'o061: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
end else if (stage == 8) begin
if (opcode[5:4] == 2'b11)
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
else
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b10, opcode[5:4], 1'b0};
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[REG_WE] = 1'b1;
end else if (stage == 9) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
stage_rst = 1'b1;
end
end
// LDA/STA a16
// opcode[3]: STA (0) / LDA (1)
8'o062, 8'o072: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 9) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 10) begin
if (opcode[3] == 0) begin
ctrl_word[ALU_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else begin
ctrl_word[ALU_A_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end
stage_rst = 1'b1;
end
end
// STAX/LDAX Rs
// opcode[5:4] - Rs
// opcode[3] - STAX (0) / LDAX (1)
8'o002, 8'o012, 8'o022, 8'o032: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
ctrl_word[REG_OE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
ctrl_word[REG_OE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
if (opcode[3] == 1'b0) begin
ctrl_word[ALU_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else begin
ctrl_word[ALU_A_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end
stage_rst = 1'b1;
end
end
// SHLD, LHLD
// opcode[3] - SHLD (0) / LHLD (1)
8'o042, 8'o052: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[MEM_OE] = 1'b1;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 9) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 10) begin
if (opcode[3] == 1'b0) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_H;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL_H;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end
end else if (stage == 11) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 12) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 13) begin
if (opcode[3] == 1'b0) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_L;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL_L;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end
stage_rst = 1'b1;
end
end
// DAD
// opcode[5:4] - Extended Register
8'o011, 8'o031, 8'o051, 8'o071: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_L;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[ALU_A_STORE] = 1'b1;
ctrl_word[ALU_A_WE] = 1'b1;
end else if (stage == 4) begin
if (opcode[5:4] == 2'b11) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP_P;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
end
ctrl_word[REG_OE] = 1'b1;
ctrl_word[ALU_TMP_WE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = 5'b00000; // Add
end else if (stage == 6) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[ALU_OE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_H;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[ALU_A_WE] = 1'b1;
end else if (stage == 8) begin
if (opcode[5:4] == 2'b11) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP_S;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
end
ctrl_word[REG_OE] = 1'b1;
ctrl_word[ALU_TMP_WE] = 1'b1;
end else if (stage == 9) begin
ctrl_word[ALU_CS] = 1'b1;
ctrl_word[ALU_OP4:ALU_OP0] = 5'b00001; // Add w/ Carry
end else if (stage == 10) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[ALU_OE] = 1'b1;
ctrl_word[ALU_A_RESTORE] = 1'b1;
end else if (stage == 11) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// JMP
8'o303: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// Jump Conditional
// opcode[5:4] - flag
// opcode[3] - set (1) / unset (0)
8'o3?2: begin
if (stage == 3) begin
if (flags[opcode[5:4]] != opcode[3]) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC2;
stage_rst = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end
end else if (stage == 4) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// Call Conditional
// opcode[5:4] - flag
// opcode[3] - set (1) / unset (0)
8'o3?4: begin
if (stage == 3) begin
if (flags[opcode[5:4]] != opcode[3]) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC2;
stage_rst = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end
end else if (stage == 4) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 9) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
end else if (stage == 10) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 11) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_C;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else if (stage == 12) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
end else if (stage == 13) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 14) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_P;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else if (stage == 15) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// CALL
8'o315: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 9) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
end else if (stage == 10) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 11) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_C;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else if (stage == 12) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
end else if (stage == 13) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 14) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_P;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_WE] = 1'b1;
end else if (stage == 15) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// Return Conditional
// opcode[5:4] - flag
// opcode[3] - set (1) / unset (0)
8'o3?0: begin
if (stage == 3) begin
if (flags[opcode[5:4]] != opcode[3]) begin
stage_rst = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end
end else if (stage == 4) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 9) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// RET
8'o311: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 9) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_WE] = 1'b1;
ctrl_word[REG_OE] = 1'b1;
stage_rst = 1'b1;
end
end
// PUSH Rs
// opcode[5:4] - Extended Register
8'o3?5: begin
if (stage == 3) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
end else if (stage == 4) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 5) begin
if (opcode[5:4] == 2'b11) begin // PSW
ctrl_word[ALU_OE] = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
ctrl_word[REG_OE] = 1'b1;
end
ctrl_word[MEM_WE] = 1'b1;
end else if (stage == 6) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
end else if (stage == 7) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 8) begin
if (opcode[5:4] == 2'b11) begin // PSW
ctrl_word[ALU_FLAGS_OE] = 1'b1;
end else begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
ctrl_word[REG_OE] = 1'b1;
end
ctrl_word[MEM_WE] = 1'b1;
stage_rst = 1'b1;
end
end
// POP Rs
// opcode[5:4] - Extended Register
8'o301, 8'o321, 8'o341, 8'o361: begin
if (stage == 3) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 4) begin
if (opcode[5:4] == 2'b11) begin // PSW
ctrl_word[ALU_FLAGS_WE] = 1'b1;
end else begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:4], 1'b1};
ctrl_word[REG_WE] = 1'b1;
end
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 5) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
end else if (stage == 6) begin
ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
ctrl_word[REG_OE] = 1'b1;
ctrl_word[MEM_MAR_WE] = 1'b1;
end else if (stage == 7) begin
if (opcode[5:4] == 2'b11) begin // PSW
ctrl_word[ALU_A_WE] = 1'b1;
end else begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:4], 1'b0};
ctrl_word[REG_WE] = 1'b1;
end
ctrl_word[MEM_OE] = 1'b1;
end else if (stage == 8) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
stage_rst = 1'b1;
end
end
// OUT
8'o323: begin
if (stage == 3) begin
ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
ctrl_word[DISPLAY] = 1'b1;
stage_rst = 1'b1;
end
end
endcase
end
end
endmodule