111 lines
2.0 KiB
Verilog
111 lines
2.0 KiB
Verilog
module controller(
|
|
input clk,
|
|
input rst,
|
|
input[3:0] opcode,
|
|
output[11:0] out
|
|
);
|
|
|
|
localparam SIG_HLT = 11;
|
|
localparam SIG_PC_INC = 10;
|
|
localparam SIG_PC_EN = 9;
|
|
localparam SIG_MEM_LOAD = 8;
|
|
localparam SIG_MEM_EN = 7;
|
|
localparam SIG_IR_LOAD = 6;
|
|
localparam SIG_IR_EN = 5;
|
|
localparam SIG_A_LOAD = 4;
|
|
localparam SIG_A_EN = 3;
|
|
localparam SIG_B_LOAD = 2;
|
|
localparam SIG_ADDER_SUB = 1;
|
|
localparam SIG_ADDER_EN = 0;
|
|
|
|
localparam OP_LDA = 4'b0000;
|
|
localparam OP_ADD = 4'b0001;
|
|
localparam OP_SUB = 4'b0010;
|
|
localparam OP_HLT = 4'b1111;
|
|
|
|
reg[2:0] stage;
|
|
reg[11:0] ctrl_word;
|
|
|
|
always @(negedge clk, posedge rst) begin
|
|
if (rst) begin
|
|
stage <= 0;
|
|
end else begin
|
|
if (stage == 5) begin
|
|
stage <= 0;
|
|
end else begin
|
|
stage <= stage + 1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(*) begin
|
|
ctrl_word = 12'b0;
|
|
|
|
case (stage)
|
|
0: begin
|
|
ctrl_word[SIG_PC_EN] = 1;
|
|
ctrl_word[SIG_MEM_LOAD] = 1;
|
|
end
|
|
1: begin
|
|
ctrl_word[SIG_PC_INC] = 1;
|
|
end
|
|
2: begin
|
|
ctrl_word[SIG_MEM_EN] = 1;
|
|
ctrl_word[SIG_IR_LOAD] = 1;
|
|
end
|
|
3: begin
|
|
case (opcode)
|
|
OP_LDA: begin
|
|
ctrl_word[SIG_IR_EN] = 1;
|
|
ctrl_word[SIG_MEM_LOAD] = 1;
|
|
end
|
|
OP_ADD: begin
|
|
ctrl_word[SIG_IR_EN] = 1;
|
|
ctrl_word[SIG_MEM_LOAD] = 1;
|
|
end
|
|
OP_SUB: begin
|
|
ctrl_word[SIG_IR_EN] = 1;
|
|
ctrl_word[SIG_MEM_LOAD] = 1;
|
|
end
|
|
OP_HLT: begin
|
|
ctrl_word[SIG_HLT] = 1;
|
|
end
|
|
endcase
|
|
end
|
|
4: begin
|
|
case (opcode)
|
|
OP_LDA: begin
|
|
ctrl_word[SIG_MEM_EN] = 1;
|
|
ctrl_word[SIG_A_LOAD] = 1;
|
|
end
|
|
OP_ADD: begin
|
|
ctrl_word[SIG_MEM_EN] = 1;
|
|
ctrl_word[SIG_B_LOAD] = 1;
|
|
end
|
|
OP_SUB: begin
|
|
ctrl_word[SIG_MEM_EN] = 1;
|
|
ctrl_word[SIG_B_LOAD] = 1;
|
|
end
|
|
endcase
|
|
end
|
|
5: begin
|
|
case (opcode)
|
|
OP_ADD: begin
|
|
ctrl_word[SIG_ADDER_EN] = 1;
|
|
ctrl_word[SIG_A_LOAD] = 1;
|
|
end
|
|
OP_SUB: begin
|
|
ctrl_word[SIG_ADDER_SUB] = 1;
|
|
ctrl_word[SIG_ADDER_EN] = 1;
|
|
ctrl_word[SIG_A_LOAD] = 1;
|
|
end
|
|
endcase
|
|
end
|
|
endcase
|
|
end
|
|
|
|
assign out = ctrl_word;
|
|
|
|
endmodule
|
|
|