📄 ac51_exe_ctrl.v
字号:
//// ac51_exe_ctrl.v//// ac51 microcontroller core//// Version 0.6//// Copyright 2008, Hideyuki Abe. All rights reserved.// Distributed under the terms of the MIT License.//`include "ac51_defs.v"`define EXE_STATE_LEN 2`define EST_IDLE 2'b00`define EST_EXE1 2'b01`define EST_EXE2 2'b10`define EST_EXE3 2'b11`define INT_STATE_LEN 2`define INTST_NONE 2'b00`define INTST_LOW 2'b01`define INTST_HIGH 2'b10module ac51_exe_ctrl( clk, rst, inst1_r, inst_rdy, inst_ack, jmp_req, jmp_ack, pc_mux, cpc_mux, sp_mux, dptr_mux, acc_mux, acc_zero, breg_mux, op_sel, ina_mux, inb_mux, tmp_mux, tmp_zero, bit_data, cy_bit, flg_upd, ea_mux, ibus_mux, iwd_mux, pbus_mux, xbus_mux, pack, xack, int_req, int_pri, int_ack);input clk;input rst;input [7:0] inst1_r;input inst_rdy;output inst_ack;output jmp_req;input jmp_ack;output [`PCMUX_LEN - 1:0] pc_mux;output [`CPCMUX_LEN - 1:0] cpc_mux;output [`SPMUX_LEN - 1:0] sp_mux;output [`DPMUX_LEN - 1:0] dptr_mux;output [`ACCMUX_LEN - 1:0] acc_mux;input acc_zero;output [`BRGMUX_LEN - 1:0] breg_mux;output [`ALUOP_LEN - 1:0] op_sel;output [`AMUX_LEN - 1:0] ina_mux;output [`BMUX_LEN - 1:0] inb_mux;output [`TMUX_LEN - 1:0] tmp_mux;input tmp_zero;input bit_data;input cy_bit;output [2:0] flg_upd; // bit0 - ac, bit1 - cy, bit2 - ovoutput [`EAMUX_LEN - 1:0] ea_mux;output [`IMUX_LEN - 1:0] ibus_mux;output [`IWDMUX_LEN - 1:0] iwd_mux;output [`PMUX_LEN - 1:0] pbus_mux;output [`XMUX_LEN - 1:0] xbus_mux;input pack;input xack;input [5:0] int_req;input [5:0] int_pri;output [5:0] int_ack;reg [`EXE_STATE_LEN - 1:0] state;reg [`EXE_STATE_LEN - 1:0] state_nxt;reg [2:0] div_cnt;reg div_start;wire div_end;reg [`INT_STATE_LEN - 1:0] int_state;reg [`INT_STATE_LEN - 1:0] int_state_nxt;reg [`INT_STATE_LEN - 1:0] int_state_sav;reg int_state_push;reg int_state_pop;wire [5:0] int_req_h;wire [5:0] int_req_l;reg int_exe;reg int_exe_nxt;reg [5:0] cur_int;reg [`INT_STATE_LEN - 1:0] int_pshst;reg [`PCMUX_LEN - 1:0] int_pcmux;reg [5:0] int_ack;reg inst_req;reg jmp_req;reg jmp_fetch;reg jmp_fetch_nxt;reg [`PCMUX_LEN - 1:0] pc_mux;reg [`CPCMUX_LEN - 1:0] cpc_mux;reg [`SPMUX_LEN - 1:0] sp_mux;reg [`DPMUX_LEN - 1:0] dptr_mux;reg [`ACCMUX_LEN - 1:0] acc_mux;reg [`BRGMUX_LEN - 1:0] breg_mux;reg [`ALUOP_LEN - 1:0] op_sel;reg [`AMUX_LEN - 1:0] ina_mux;reg [`BMUX_LEN - 1:0] inb_mux;reg [`TMUX_LEN - 1:0] tmp_mux;reg [2:0] flg_upd; // bit0 - ac, bit1 - cy, bit2 - ovreg [`EAMUX_LEN - 1:0] ea_mux;reg [`IMUX_LEN - 1:0] ibus_mux;reg [`IWDMUX_LEN - 1:0] iwd_mux;reg [`PMUX_LEN - 1:0] pbus_mux;reg [`XMUX_LEN - 1:0] xbus_mux;always @(posedge clk or negedge rst) begin if(~rst) state <= `EST_IDLE; else state <= state_nxt;end // alwaysalways @(posedge clk or negedge rst) begin if(~rst) div_cnt <= 3'd0; else if(div_start) div_cnt <= 3'd5; else if(~div_end) div_cnt <= div_cnt - 3'd1;end // alwaysassign div_end = (div_cnt == 3'd0);always @(posedge clk or negedge rst) begin if(~rst) jmp_fetch <= 1'b0; else jmp_fetch <= jmp_fetch_nxt;endalways @(jmp_fetch or inst_ack or jmp_ack) begin if(inst_ack) jmp_fetch_nxt = 1'b0; else if(jmp_ack) jmp_fetch_nxt = 1'b1; else jmp_fetch_nxt = jmp_fetch;end // always combalways @(jmp_ack or inst_ack or jmp_fetch) begin if(jmp_ack) cpc_mux = `CPCMUX_PCN; else begin if(jmp_fetch) cpc_mux = `CPCMUX_NULL; else begin if(inst_ack) cpc_mux = `CPCMUX_PCR; else cpc_mux = `CPCMUX_NULL; end endend // always combalways @(posedge clk or negedge rst) begin if(~rst) begin int_state <= `INTST_NONE; int_state_sav <= `INTST_NONE; end else if(int_state_push) begin int_state <= int_state_nxt; int_state_sav <= int_state; end else if(int_state_pop) begin int_state <= int_state_sav; int_state_sav <= `INTST_NONE; endend // alwaysassign int_req_h = int_req & int_pri; // high priority int requestassign int_req_l = int_req & ~int_pri; // low priority int requestalways @(posedge clk or negedge rst) begin if(~rst) int_exe <= 1'b0; else int_exe <= int_exe_nxt;end // alwaysalways @( int_exe or int_ack or inst_req or int_state or int_req or int_req_h or int_req_l) begin int_exe_nxt = int_exe; if(| int_ack) begin int_exe_nxt = 1'b0; end else if(inst_req) begin if(int_state == `INTST_LOW) begin if(| int_req_h) int_exe_nxt = 1'b1; end else if(int_state == `INTST_NONE) begin if(| int_req) int_exe_nxt = 1'b1; end endend // always combalways @(int_req_h or int_req_l) begin cur_int = 6'b000000; if(int_req_h[0]) cur_int = 6'b000001; else if(int_req_h[1]) cur_int = 6'b000010; else if(int_req_h[2]) cur_int = 6'b000100; else if(int_req_h[3]) cur_int = 6'b001000; else if(int_req_h[4]) cur_int = 6'b010000; else if(int_req_h[5]) cur_int = 6'b100000; else if(int_req_l[0]) cur_int = 6'b000001; else if(int_req_l[1]) cur_int = 6'b000010; else if(int_req_l[2]) cur_int = 6'b000100; else if(int_req_l[3]) cur_int = 6'b001000; else if(int_req_l[4]) cur_int = 6'b010000; else if(int_req_l[5]) cur_int = 6'b100000;end // always combalways @(int_req_h or int_req_l) begin if(| int_req_h) int_pshst = `INTST_HIGH; else if(| int_req_l) int_pshst = `INTST_LOW; else int_pshst = `INTST_NONE;end // always combalways @(cur_int) begin int_pcmux = `PCMUX_ZERO; if(cur_int[0]) int_pcmux = `PCMUX_INT0; else if(cur_int[1]) int_pcmux = `PCMUX_INT1; else if(cur_int[2]) int_pcmux = `PCMUX_INT2; else if(cur_int[3]) int_pcmux = `PCMUX_INT3; else if(cur_int[4]) int_pcmux = `PCMUX_INT4; else if(cur_int[5]) int_pcmux = `PCMUX_INT5;end // always combassign inst_ack = inst_req & inst_rdy;always @( state or inst_rdy or inst1_r or acc_zero or tmp_zero or bit_data or div_end or cy_bit or jmp_ack or pack or xack or int_state or int_exe or cur_int or int_pshst or int_pcmux or int_req or int_pri) begin jmp_req = 1'b0; pc_mux = `PCMUX_ZERO; sp_mux = `SPMUX_NULL; dptr_mux = `DPMUX_NULL; ibus_mux = `IMUX_NULL; iwd_mux = `IWDMUX_ZERO; pbus_mux = `PMUX_NULL; xbus_mux = `XMUX_NULL; acc_mux = `ACCMUX_NULL; breg_mux = `BRGMUX_NULL; op_sel = `ALUOP_NULL; ina_mux = `AMUX_ZERO; inb_mux = `BMUX_ZERO; tmp_mux = `TMUX_NULL; flg_upd = 3'b000; ea_mux = `EAMUX_NULL; div_start = 1'b0; int_state_nxt = int_state; int_state_push = 1'b0; int_state_pop = 1'b0; int_ack = 5'b00000; inst_req = 1'b0; state_nxt = state; if(int_exe) begin if(state == `EST_EXE1 | state == `EST_IDLE) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_OUTA; iwd_mux = `IWDMUX_CPCL; sp_mux = `SPMUX_OUTA; state_nxt = `EST_EXE2; end else if(state == `EST_EXE2) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_OUTA; iwd_mux = `IWDMUX_CPCH; sp_mux = `SPMUX_OUTA; state_nxt = `EST_EXE3; end else begin jmp_req = 1'b1; pc_mux = int_pcmux; if(jmp_ack) begin int_ack = cur_int; int_state_nxt = int_pshst; int_state_push = 1'b1; state_nxt = `EST_IDLE; end end end else if(state == `EST_IDLE) begin inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; end else begin if(inst1_r == `OPC_NOP) begin inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end else if(inst1_r[4:0] == `OPC_AJMP) begin jmp_req = 1'b1; pc_mux = `PCMUX_ABS; if(jmp_ack) state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_LJMP) begin jmp_req = 1'b1; pc_mux = `PCMUX_LONG; if(jmp_ack) state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_RR_A) begin op_sel = `ALUOP_RR; ina_mux = `AMUX_ACC; acc_mux = `ACCMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_INC_A) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_ACC; inb_mux = `BMUX_ONE; acc_mux = `ACCMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_INC_DIR) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_DRD2RMW; state_nxt = `EST_EXE2; end else begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_IDATA; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_DWR2; iwd_mux = `IWDMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end else if(inst1_r[7:1] == `OPC_INC_RI) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_RIRD; state_nxt = `EST_EXE2; end else begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_IDATA; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_RIWR; iwd_mux = `IWDMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end else if(inst1_r[7:3] == `OPC_INC_RN) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_RNRD; state_nxt = `EST_EXE2; end else begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_IDATA; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_RNWR; iwd_mux = `IWDMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end else if(inst1_r == `OPC_JBC_BIT) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_BTRD2RMW; state_nxt = `EST_EXE2; end else if(state == `EST_EXE2) begin if(bit_data) begin op_sel = `ALUOP_BCLR; ina_mux = `AMUX_IDATA; inb_mux = `BMUX_INST2; ibus_mux = `IMUX_BTWR2; iwd_mux = `IWDMUX_OUTA; state_nxt = `EST_EXE3; end else begin inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end else begin jmp_req = 1'b1; ea_mux = `EAMUX_REL3; pc_mux = `PCMUX_EA; if(jmp_ack) state_nxt = `EST_IDLE; end end else if(inst1_r[4:0] == `OPC_ACALL) begin if(state == `EST_EXE1) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_OUTA; iwd_mux = `IWDMUX_PCL; sp_mux = `SPMUX_OUTA; state_nxt = `EST_EXE2; end else if(state == `EST_EXE2) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_OUTA; iwd_mux = `IWDMUX_PCH; sp_mux = `SPMUX_OUTA; state_nxt = `EST_EXE3; end else begin jmp_req = 1'b1; pc_mux = `PCMUX_ABS; if(jmp_ack) state_nxt = `EST_IDLE; end end else if(inst1_r == `OPC_LCALL) begin if(state == `EST_EXE1) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_OUTA; iwd_mux = `IWDMUX_PCL; sp_mux = `SPMUX_OUTA; state_nxt = `EST_EXE2; end else if(state == `EST_EXE2) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_OUTA; iwd_mux = `IWDMUX_PCH; sp_mux = `SPMUX_OUTA; state_nxt = `EST_EXE3; end else begin jmp_req = 1'b1; pc_mux = `PCMUX_LONG; if(jmp_ack) state_nxt = `EST_IDLE; end end else if(inst1_r == `OPC_RRC_A) begin op_sel = `ALUOP_RRC; ina_mux = `AMUX_ACC; flg_upd = 3'b010; // update cy flag acc_mux = `ACCMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_DEC_A) begin op_sel = `ALUOP_SUB; ina_mux = `AMUX_ACC; inb_mux = `BMUX_ONE; acc_mux = `ACCMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_DEC_DIR) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_DRD2RMW; state_nxt = `EST_EXE2; end else begin op_sel = `ALUOP_SUB; ina_mux = `AMUX_IDATA; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_DWR2; iwd_mux = `IWDMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end else if(inst1_r[7:1] == `OPC_DEC_RI) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_RIRD; state_nxt = `EST_EXE2; end else begin op_sel = `ALUOP_SUB; ina_mux = `AMUX_IDATA; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_RIWR; iwd_mux = `IWDMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end else if(inst1_r[7:3] == `OPC_DEC_RN) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_RNRD; state_nxt = `EST_EXE2; end else begin op_sel = `ALUOP_SUB; ina_mux = `AMUX_IDATA; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_RNWR; iwd_mux = `IWDMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end else if(inst1_r == `OPC_JB_BIT) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_BTRD2; state_nxt = `EST_EXE2; end else begin if(bit_data) begin jmp_req = 1'b1; ea_mux = `EAMUX_REL3; pc_mux = `PCMUX_EA; if(jmp_ack) state_nxt = `EST_IDLE; end else begin inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end end end else if(inst1_r == `OPC_RET) begin if(state == `EST_EXE1) begin op_sel = `ALUOP_SUB; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_SP; sp_mux = `SPMUX_OUTA; state_nxt = `EST_EXE2; end else if(state == `EST_EXE2) begin op_sel = `ALUOP_SUB; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_SP; tmp_mux = `TMUX_IDATA; state_nxt = `EST_EXE3; end else begin op_sel = `ALUOP_SUB; ina_mux = `AMUX_SP; inb_mux = `BMUX_ONE; ibus_mux = `IMUX_SP; jmp_req = 1'b1; pc_mux = `PCMUX_POP; if(jmp_ack) begin sp_mux = `SPMUX_OUTA; state_nxt = `EST_IDLE; end end end else if(inst1_r == `OPC_RLA) begin op_sel = `ALUOP_RL; ina_mux = `AMUX_ACC; acc_mux = `ACCMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_ADD_A_IMM) begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_ACC; inb_mux = `BMUX_INST2; flg_upd = 3'b111; // update ac, cy, & ov flag acc_mux = `ACCMUX_OUTA; inst_req = 1'b1; if(inst_rdy) state_nxt = `EST_EXE1; else state_nxt = `EST_IDLE; end else if(inst1_r == `OPC_ADD_A_DIR) begin if(state == `EST_EXE1) begin ibus_mux = `IMUX_DRD2; state_nxt = `EST_EXE2; end else begin op_sel = `ALUOP_ADD; ina_mux = `AMUX_ACC; inb_mux = `BMUX_IDATA; flg_upd = 3'b111; // update ac, cy, & ov flag acc_mux = `ACCMUX_OUTA;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -