📄 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.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, eq, ram_rd_sel, ram_wr_sel, bit_addr,
wr, src_sel1, src_sel2, src_sel3, alu_op, psw_set, cy_sel, imm_sel, pc_wr,
pc_sel, comp_sel, rom_addr_sel, ext_addr_sel, wad2, rd, we_o, reti,
rmw, stb_o, ack_i, wr_xaddr, istb, ea, iack, pc_wait, nop);
//
// 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]
// wad2 (out) write acc from destination 2 [oc8051_acc.wad2 -r]
// imm_sel (out) immediate select [oc8051_immediate_sel.sel -r]
// pc_wr (out) pc write [oc8051_pc.wr]
// pc_sel (out) pc select [oc8051_pc.pc_wr_sel]
// rom_addr_sel (out) rom address select (alu destination or pc) [oc8051_rom_addr_sel.select]
// ext_addr_sel (out) external address select (dptr or Ri) [oc8051_ext_addr_sel.select]
// rd (out) read from rom [oc8051_pc.rd, oc8051_op_select.rd]
// we_o (out) write to external rom [pin]
// reti (out) return from interrupt [pin]
// rmw (out) read modify write feature [oc8051_ports.rmw]
// istb (out) strobe to instruction rom// ea (in) extrnal access// iack (in) scknowlage from external rom// pc_wait (out)// nop (out) insert nops//
input clk, rst, eq, ack_i, iack, ea;input [7:0] op_in;
output wr, reti, we_o, bit_addr, src_sel3, rom_addr_sel, ext_addr_sel,
pc_wr, wad2, rmw, stb_o, wr_xaddr, istb, pc_wait;
output [1:0] ram_rd_sel, src_sel1, src_sel2, psw_set, cy_sel, pc_sel, comp_sel;
output [2:0] ram_wr_sel, imm_sel;
output [3:0] alu_op;
output rd, nop;
reg reti, write_x, rmw, stb_buff, we_buff, istb_t;
reg wr, bit_addr, src_sel3, rom_addr_sel, ext_addr_sel, pc_wr, wad2, stb, stbw, wr_xaddr;
reg [1:0] comp_sel, psw_set, ram_rd_sel, src_sel1, src_sel2, pc_sel, cy_sel;
reg [3:0] alu_op;
reg [2:0] ram_wr_sel, imm_sel;
//
// state if 2'b00 then normal execution, sle instructin that need more than one clock
// op instruction buffer
reg [1:0] state;
reg [7:0] op;
reg stb_i;wire [7:0] op_cur;
//
// if state = 2'b00 then read nex instruction
assign rd = !state[0] && !state[1] && !stb_o;
assign istb = ((!state[1]) && stb_i) || istb_t;assign nop = (!state[1]) || istb_t;
assign stb_o = stb_buff || stbw;
assign we_o = we_buff;
//assign we_o = write_x || we_buff;
assign op_cur = (state[0] || state[1] || stb_o) ? op : op_in;assign pc_wait = !istb_t && rd;
//
// main block
// case of instruction set control signals
always @(op_cur or eq or state or op or stb_o or istb_t)
begin
if (stb_o) begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_DC;
src_sel1 = `OC8051_ASS_DC;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
imm_sel = `OC8051_IDS_DC;
wr = 1'b0;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = `OC8051_PCW_N;
pc_sel = `OC8051_PIS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DC;
rmw = `OC8051_RMW_N; stb_i = 1'b1; bit_addr = 1'b0;
wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end else begin
case (state)
2'b01: begin
casex (op_cur)
`OC8051_ACALL :begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_SP;
src_sel1 = `OC8051_ASS_IMM;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
imm_sel = `OC8051_IDS_PCH;
wr = 1'b1;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = `OC8051_PCW_N;
pc_sel = `OC8051_PIS_DC;
comp_sel = `OC8051_CSS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DC;
rmw = `OC8051_RMW_N;
stb_i = 1'b1; bit_addr = 1'b0;
wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end
`OC8051_AJMP : begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_DC;
src_sel1 = `OC8051_ASS_DC;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
imm_sel = `OC8051_IDS_DC;
wr = 1'b0;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = `OC8051_PCW_N;
pc_sel = `OC8051_PIS_DC;
comp_sel = `OC8051_CSS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DC;
rmw = `OC8051_RMW_N;
bit_addr = 1'b0;
stb_i = 1'b1; wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end
`OC8051_LCALL :begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_SP;
src_sel1 = `OC8051_ASS_IMM;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
imm_sel = `OC8051_IDS_PCH;
wr = 1'b1;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = `OC8051_PCW_N;
pc_sel = `OC8051_PIS_DC;
comp_sel = `OC8051_CSS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DC;
rmw = `OC8051_RMW_N;
bit_addr = 1'b0;
stb_i = 1'b1; wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end
`OC8051_DIV : begin
ram_rd_sel = `OC8051_RRS_D;
ram_wr_sel = `OC8051_RWS_B;
src_sel1 = `OC8051_ASS_ACC;
src_sel2 = `OC8051_ASS_RAM;
alu_op = `OC8051_ALU_DIV;
wr = 1'b1;
psw_set = `OC8051_PS_OV;
cy_sel = `OC8051_CY_0;
pc_wr = `OC8051_PCW_N;
pc_sel = `OC8051_PIS_DC;
imm_sel = `OC8051_IDS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DC;
stb_i = 1'b1; rmw = `OC8051_RMW_N; bit_addr = 1'b0;
wad2 = `OC8051_WAD_Y;
rom_addr_sel = `OC8051_RAS_PC;
end
`OC8051_MUL : begin
ram_rd_sel = `OC8051_RRS_D;
ram_wr_sel = `OC8051_RWS_B;
src_sel1 = `OC8051_ASS_ACC;
src_sel2 = `OC8051_ASS_RAM;
alu_op = `OC8051_ALU_MUL;
wr = 1'b1;
psw_set = `OC8051_PS_OV;
cy_sel = `OC8051_CY_0;
pc_wr = `OC8051_PCW_N;
pc_sel = `OC8051_PIS_DC;
imm_sel = `OC8051_IDS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DC;
rmw = `OC8051_RMW_N; bit_addr = 1'b0;
stb_i = 1'b1; wad2 = `OC8051_WAD_Y;
rom_addr_sel = `OC8051_RAS_PC;
end
default begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_DC;
src_sel1 = `OC8051_ASS_DC;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
wr = 1'b0;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = `OC8051_PCW_N;
pc_sel = `OC8051_PIS_DC;
imm_sel = `OC8051_IDS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DC;
rmw = `OC8051_RMW_N; bit_addr = 1'b0;
stb_i = 1'b1; wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end
endcase
end
2'b10:
casex (op_cur)
`OC8051_CJNE_R : begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_DC;
src_sel1 = `OC8051_ASS_DC;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
wr = 1'b0;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = !eq;
pc_sel = `OC8051_PIS_ALU;
imm_sel = `OC8051_IDS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DES;
rmw = `OC8051_RMW_N; bit_addr = 1'b0;
stb_i = 1'b1; wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end
`OC8051_CJNE_I : begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_DC;
src_sel1 = `OC8051_ASS_DC;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
wr = 1'b0;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = !eq;
pc_sel = `OC8051_PIS_ALU;
imm_sel = `OC8051_IDS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DES;
rmw = `OC8051_RMW_N; bit_addr = 1'b0;
stb_i = 1'b1; wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end
`OC8051_CJNE_D : begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_DC;
src_sel1 = `OC8051_ASS_DC;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
wr = 1'b0;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = !eq;
pc_sel = `OC8051_PIS_ALU;
imm_sel = `OC8051_IDS_DC;
src_sel3 = `OC8051_AS3_DC;
comp_sel = `OC8051_CSS_DES;
rmw = `OC8051_RMW_N; bit_addr = 1'b0;
stb_i = 1'b1; wad2 = `OC8051_WAD_N;
rom_addr_sel = `OC8051_RAS_PC;
end
`OC8051_CJNE_C : begin
ram_rd_sel = `OC8051_RRS_DC;
ram_wr_sel = `OC8051_RWS_DC;
src_sel1 = `OC8051_ASS_DC;
src_sel2 = `OC8051_ASS_DC;
alu_op = `OC8051_ALU_NOP;
wr = 1'b0;
psw_set = `OC8051_PS_NOT;
cy_sel = `OC8051_CY_0;
pc_wr = !eq;
pc_sel = `OC8051_PIS_ALU;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -