📄 oc8051_decoder.v
字号:
////////////////////////////////////////////////////////////////////////// //////// 8051 core decoder //////// //////// This file is part of the 8051 cores project //////// http://www.opencores.org/cores/8051/ //////// //////// Description //////// Main 8051 core module. decodes instruction and creates //////// control sigals. //////// //////// To Do: //////// optimize state machine, especially IDS ASS and AS3 //////// //////// Author(s): //////// - Simon Teran, simont@opencores.org //////// ////////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2000 Authors and OPENCORES.ORG //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer. //////// //////// This source file is free software; you can redistribute it //////// and/or modify it under the terms of the GNU Lesser General //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any //////// later version. //////// //////// This source is distributed in the hope that it will be //////// useful, but WITHOUT ANY WARRANTY; without even the implied //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //////// PURPOSE. See the GNU Lesser General Public License for more //////// details. //////// //////// You should have received a copy of the GNU Lesser General //////// Public License along with this source; if not, download it //////// from http://www.opencores.org/lgpl.shtml //////// ////////////////////////////////////////////////////////////////////////////// CVS Revision History//// $Log: oc8051_decoder.v,v $// Revision 1.22 2003/07/01 20:47:38 simont// add /* synopsys xx_case */ to case statments.//// Revision 1.21 2003/06/03 17:09:57 simont// pipelined acces to axternal instruction interface added.//// Revision 1.20 2003/05/06 11:10:38 simont// optimize state machine.//// Revision 1.19 2003/05/06 09:41:35 simont// remove define OC8051_AS2_PCL, chane signal src_sel2 to 2 bit wide.//// Revision 1.18 2003/05/05 15:46:36 simont// add aditional alu destination to solve critical path.//// Revision 1.17 2003/04/25 17:15:51 simont// change branch instruction execution (reduse needed clock periods).//// Revision 1.16 2003/04/09 16:24:03 simont// change wr_sft to 2 bit wire.//// Revision 1.15 2003/04/09 15:49:42 simont// Register oc8051_sfr dato output, add signal wait_data.//// Revision 1.14 2003/01/13 14:14:40 simont// replace some modules//// Revision 1.13 2002/10/23 16:53:39 simont// fix bugs in instruction interface//// Revision 1.12 2002/10/17 18:50:00 simont// cahnge interface to instruction rom//// Revision 1.11 2002/09/30 17:33:59 simont// prepared header////// synopsys translate_off`include "oc8051_timescale.v"// synopsys translate_on`include "oc8051_defines.v"module oc8051_decoder (clk, rst, op_in, op1_c, ram_rd_sel_o, ram_wr_sel_o, bit_addr, wr_o, wr_sfr_o, src_sel1, src_sel2, src_sel3, alu_op_o, psw_set, eq, cy_sel, comp_sel, pc_wr, pc_sel, rd, rmw, istb, mem_act, mem_wait, wait_data);//// clk (in) clock// rst (in) reset// op_in (in) operation code [oc8051_op_select.op1]// eq (in) compare result [oc8051_comp.eq]// ram_rd_sel (out) select, whitch address will be send to ram for read [oc8051_ram_rd_sel.sel, oc8051_sp.ram_rd_sel]// ram_wr_sel (out) select, whitch address will be send to ram for write [oc8051_ram_wr_sel.sel -r, oc8051_sp.ram_wr_sel -r]// wr (out) write - if 1 then we will write to ram [oc8051_ram_top.wr -r, oc8051_acc.wr -r, oc8051_b_register.wr -r, oc8051_sp.wr-r, oc8051_dptr.wr -r, oc8051_psw.wr -r, oc8051_indi_addr.wr -r, oc8051_ports.wr -r]// src_sel1 (out) select alu source 1 [oc8051_alu_src1_sel.sel -r]// src_sel2 (out) select alu source 2 [oc8051_alu_src2_sel.sel -r]// src_sel3 (out) select alu source 3 [oc8051_alu_src3_sel.sel -r]// alu_op (out) alu operation [oc8051_alu.op_code -r]// psw_set (out) will we remember cy, ac, ov from alu [oc8051_psw.set -r]// cy_sel (out) carry in alu select [oc8051_cy_select.cy_sel -r]// comp_sel (out) compare source select [oc8051_comp.sel]// bit_addr (out) if instruction is bit addresable [oc8051_ram_top.bit_addr -r, oc8051_acc.wr_bit -r, oc8051_b_register.wr_bit-r, oc8051_sp.wr_bit -r, oc8051_dptr.wr_bit -r, oc8051_psw.wr_bit -r, oc8051_indi_addr.wr_bit -r, oc8051_ports.wr_bit -r]// pc_wr (out) pc write [oc8051_pc.wr]// pc_sel (out) pc select [oc8051_pc.pc_wr_sel]// rd (out) read from rom [oc8051_pc.rd, oc8051_op_select.rd]// reti (out) return from interrupt [pin]// rmw (out) read modify write feature [oc8051_ports.rmw]// pc_wait (out)//input clk, rst, eq, mem_wait, wait_data;input [7:0] op_in;output wr_o, bit_addr, pc_wr, rmw, istb, src_sel3;output [1:0] psw_set, cy_sel, wr_sfr_o, src_sel2, comp_sel;output [2:0] mem_act, src_sel1, ram_rd_sel_o, ram_wr_sel_o, pc_sel, op1_c;output [3:0] alu_op_o;output rd;reg rmw;reg src_sel3, wr, bit_addr, pc_wr;reg [3:0] alu_op;reg [1:0] src_sel2, comp_sel, psw_set, cy_sel, wr_sfr;reg [2:0] mem_act, src_sel1, ram_wr_sel, ram_rd_sel, pc_sel;//// state if 2'b00 then normal execution, sle instructin that need more than one clock// op instruction bufferreg [1:0] state;wire [1:0] state_dec;reg [7:0] op;wire [7:0] op_cur;reg [2:0] ram_rd_sel_r;reg stb_i;assign rd = !state[0] && !state[1] && !wait_data;// && !stb_o;assign istb = (!state[1]) && stb_i;assign state_dec = wait_data ? 2'b00 : state;assign op_cur = mem_wait ? 8'h00 : (state[0] || state[1] || mem_wait || wait_data) ? op : op_in;//assign op_cur = (state[0] || state[1] || mem_wait || wait_data) ? op : op_in;assign op1_c = op_cur[2:0];assign alu_op_o = wait_data ? `OC8051_ALU_NOP : alu_op;assign wr_sfr_o = wait_data ? `OC8051_WRS_N : wr_sfr;assign ram_rd_sel_o = wait_data ? ram_rd_sel_r : ram_rd_sel;assign ram_wr_sel_o = wait_data ? `OC8051_RWS_DC : ram_wr_sel;assign wr_o = wait_data ? 1'b0 : wr;//// main block// unregisterd outputsalways @(op_cur or eq or state_dec or mem_wait)begin case (state_dec) /* synopsys full_case parallel_case */ 2'b01: begin casex (op_cur) /* synopsys parallel_case */ `OC8051_DIV : begin ram_rd_sel = `OC8051_RRS_B; end `OC8051_MUL : begin ram_rd_sel = `OC8051_RRS_B; end default begin ram_rd_sel = `OC8051_RRS_DC; end endcase stb_i = 1'b1; bit_addr = 1'b0; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; comp_sel = `OC8051_CSS_DC; rmw = `OC8051_RMW_N; end 2'b10: begin casex (op_cur) /* synopsys parallel_case */ `OC8051_SJMP : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_Y; pc_sel = `OC8051_PIS_SO1; comp_sel = `OC8051_CSS_DC; bit_addr = 1'b0; end `OC8051_JC : begin ram_rd_sel = `OC8051_RRS_PSW; pc_wr = eq; pc_sel = `OC8051_PIS_SO1; comp_sel = `OC8051_CSS_CY; bit_addr = 1'b0; end `OC8051_JNC : begin ram_rd_sel = `OC8051_RRS_PSW; pc_wr = !eq; pc_sel = `OC8051_PIS_SO1; comp_sel = `OC8051_CSS_CY; bit_addr = 1'b0; end `OC8051_JNZ : begin ram_rd_sel = `OC8051_RRS_ACC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO1; comp_sel = `OC8051_CSS_AZ; bit_addr = 1'b0; end `OC8051_JZ : begin ram_rd_sel = `OC8051_RRS_ACC; pc_wr = eq; pc_sel = `OC8051_PIS_SO1; comp_sel = `OC8051_CSS_AZ; bit_addr = 1'b0; end `OC8051_RET : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_Y; pc_sel = `OC8051_PIS_AL; comp_sel = `OC8051_CSS_DC; bit_addr = 1'b0; end `OC8051_RETI : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_Y; pc_sel = `OC8051_PIS_AL; comp_sel = `OC8051_CSS_DC; bit_addr = 1'b0; end `OC8051_CJNE_R : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_DES; bit_addr = 1'b0; end `OC8051_CJNE_I : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_DES; bit_addr = 1'b0; end `OC8051_CJNE_D : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_DES; bit_addr = 1'b0; end `OC8051_CJNE_C : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_DES; bit_addr = 1'b0; end `OC8051_DJNZ_R : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO1; comp_sel = `OC8051_CSS_DES; bit_addr = 1'b0; end `OC8051_DJNZ_D : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_DES; bit_addr = 1'b0; end `OC8051_JB : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_BIT; bit_addr = 1'b0; end `OC8051_JBC : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_BIT; bit_addr = 1'b1; end `OC8051_JMP_D : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_Y; pc_sel = `OC8051_PIS_ALU; comp_sel = `OC8051_CSS_DC; bit_addr = 1'b0; end `OC8051_JNB : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = !eq; pc_sel = `OC8051_PIS_SO2; comp_sel = `OC8051_CSS_BIT; bit_addr = 1'b1; end `OC8051_DIV : begin ram_rd_sel = `OC8051_RRS_B; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; comp_sel = `OC8051_CSS_DC; bit_addr = 1'b0; end `OC8051_MUL : begin ram_rd_sel = `OC8051_RRS_B; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; comp_sel = `OC8051_CSS_DC; bit_addr = 1'b0; end default begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; comp_sel = `OC8051_CSS_DC; bit_addr = 1'b0; end endcase rmw = `OC8051_RMW_N; stb_i = 1'b1; end 2'b11: begin casex (op_cur) /* synopsys parallel_case */ `OC8051_CJNE_R : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; end `OC8051_CJNE_I : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; end `OC8051_CJNE_D : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; end `OC8051_CJNE_C : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; end `OC8051_DJNZ_R : begin ram_rd_sel = `OC8051_RRS_DC; pc_wr = `OC8051_PCW_N; pc_sel = `OC8051_PIS_DC; end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -