/
lizz_kuzz
/
cpu
Обзор
Документация
Войти
/
lizz_kuzz
/
cpu
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
control_unit/src/control_unit.sv
144 строки
5 KB
lizz_kuzz
work version
14 май 2026, 23:07
14 май 2026, 23:07
1fa5600
Код
Авторство
О чём код?
module control_unit import cpu_pkg::*; import control_unit_pkg::*; ( input logic start_i, input code_t opcode_i, input flags_t flags_i, input logic [DATA_ADDR_W-1:0] addr_1_i, input logic clk_i, input logic rstn_i, output logic [PROG_ADDR_W -1:0] pc_o, output logic cu_program_mem_o, output logic program_wr_o, output logic cu_program_wr_o, output logic [2:0] cu_curr_addr_o, output logic cu_curr_data_o, output logic arg_1_valid_o, output logic arg_2_valid_o, output logic cu_rdata_o, output code_t opcode_o, output logic done_o ); cu_state_type state_nxt; cu_state_type state_ff; logic [PROG_ADDR_W-1:0] pc_reg; code_t opcode_reg; always_ff @(posedge clk_i) begin if (~rstn_i) begin state_ff <= STATE_FILL_MEM; end else begin state_ff <= state_nxt; end end always_ff @(posedge clk_i or negedge rstn_i) begin if (~rstn_i) begin pc_reg <= '0; opcode_reg <= code_t'(0); end else begin if (state_ff == STATE_FETCH && ((opcode_i == JL & flags_i.fl1) | (opcode_i == JE & flags_i.fl2) | (opcode_i == JG & flags_i.fl3))) begin pc_reg <= addr_1_i; end else if (state_ff == STATE_FETCH && ((opcode_i == JL) | (opcode_i == JE) | (opcode_i == JG))) begin pc_reg <= pc_reg + 1; end if (state_ff == STATE_EXECUTE) begin pc_reg <= pc_reg + 1; end if (state_ff == STATE_WR_ARG_1 || state_ff == STATE_WR_ARG_2) begin opcode_reg <= opcode_i; end if (state_ff == STATE_WR_ARG_2 && (opcode_i == LW || opcode_i == SW)) begin opcode_reg <= MOV; end end end always_comb begin case (state_ff) STATE_FILL_MEM: state_nxt = (start_i) ? STATE_FETCH : STATE_FILL_MEM; STATE_FETCH: state_nxt = (opcode_i == END_OPCODE) ? STATE_DONE : (opcode_i == JE | opcode_i == JL | opcode_i == JG) ? STATE_FETCH : STATE_WR_ARG_1; STATE_WR_ARG_1: state_nxt = STATE_WR_ARG_2; STATE_WR_ARG_2: state_nxt = STATE_EXECUTE; STATE_EXECUTE: state_nxt = STATE_FETCH; STATE_DONE: state_nxt = STATE_FILL_MEM; default: state_nxt = STATE_FILL_MEM; endcase end always_comb begin pc_o = pc_reg; opcode_o = opcode_reg; cu_program_mem_o = 1'b0; program_wr_o = 1'b0; cu_program_wr_o = 1'b0; cu_curr_addr_o = 2'b0; cu_curr_data_o = 1'b0; cu_rdata_o = 1'b0; done_o = 1'b0; arg_1_valid_o = 1'b0; arg_2_valid_o = 1'b0; case (state_ff) STATE_FILL_MEM: begin // default 0 end STATE_FETCH: begin cu_program_mem_o = 1'b1; cu_curr_data_o = 1'b1; cu_curr_addr_o = 2'd1; cu_program_wr_o = 1'b1; end STATE_WR_ARG_1: begin if (opcode_i == SW) begin cu_curr_addr_o = 2'd3; end else begin cu_curr_addr_o = 2'd1; end cu_program_mem_o = 1'b1; cu_rdata_o = 1'b0; arg_1_valid_o = 1'b1; end STATE_WR_ARG_2: begin if (opcode_i == LW) begin cu_curr_addr_o = 2'd3; end else begin cu_curr_addr_o = 2'd2; end cu_program_mem_o = 1'b1; cu_rdata_o = 1'b1; arg_2_valid_o = 1'b1; end STATE_EXECUTE: begin if (opcode_i == SW) begin cu_curr_addr_o = 2'd3; end else begin cu_curr_addr_o = 2'd1; end cu_curr_data_o = 1'b1; cu_program_wr_o = 1'b1; cu_program_mem_o = 1'b1; program_wr_o = 1'b1; end STATE_DONE: begin done_o = 1'b1; cu_program_mem_o = cu_program_mem_o; program_wr_o = program_wr_o; cu_program_wr_o = cu_program_wr_o; cu_curr_addr_o = cu_curr_addr_o; cu_curr_data_o = cu_curr_data_o; cu_rdata_o = cu_rdata_o; end endcase end endmodule: control_unit