//////////////////////////////////////////////////////////////////////
//// ////
//// 8051 cores top level module ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// 8051 definitions. ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// 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: not supported by cvs2svn $
// Revision 1.32 2003/06/20 13:36:37 simont
// ram modules added.
//
// Revision 1.31 2003/06/17 14:17:22 simont
// BIST signals added.
//
// Revision 1.30 2003/06/03 16:51:24 simont
// include "8051_defines" added.
//
// Revision 1.29 2003/05/07 12:36:03 simont
// chsnge comp.des to des1
//
// Revision 1.28 2003/05/06 09:41:35 simont
// remove define OC8051_AS2_PCL, chane signal src_sel2 to 2 bit wide.
//
// Revision 1.27 2003/05/05 15:46:37 simont
// add aditional alu destination to solve critical path.
//
// Revision 1.26 2003/04/29 11:24:31 simont
// fix bug in case execution of two data dependent instructions.
//
// Revision 1.25 2003/04/25 17:15:51 simont
// change branch instruction execution (reduse needed clock periods).
//
// Revision 1.24 2003/04/11 10:05:59 simont
// deifne OC8051_ROM added
//
// Revision 1.23 2003/04/10 12:43:19 simont
// defines for pherypherals added
//
// Revision 1.22 2003/04/09 16:24:04 simont
// change wr_sft to 2 bit wire.
//
// Revision 1.21 2003/04/09 15:49:42 simont
// Register oc8051_sfr dato output, add signal wait_data.
//
// Revision 1.20 2003/04/03 19:13:28 simont
// Include instruction cache.
//
// Revision 1.19 2003/04/02 15:08:30 simont
// raname signals.
//
// Revision 1.18 2003/01/13 14:14:41 simont
// replace some modules
//
// Revision 1.17 2002/11/05 17:23:54 simont
// add module oc8051_sfr, 256 bytes internal ram
//
// Revision 1.16 2002/10/28 14:55:00 simont
// fix bug in interface to external data ram
//
// Revision 1.15 2002/10/23 16:53:39 simont
// fix bugs in instruction interface
//
// Revision 1.14 2002/10/17 18:50:00 simont
// cahnge interface to instruction rom
//
// Revision 1.13 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(
input wb_rst_i,
input wb_clk_i,
//interface to instruction rom
output [15:0] wbi_adr_o, // Instruction address
input [31:0] wbi_dat_i, // ROM data input
output wbi_stb_o, // Instruction stobe
input wbi_ack_i, // INstruction acknoledge
output wbi_cyc_o, // Instruction cycle
input wbi_err_i, // INstruction error
//interface to data ram
input [7:0] wbd_dat_i, // RAM data input
output [7:0] wbd_dat_o, // RAM data output
output [15:0] wbd_adr_o, // Data address
output wbd_we_o, // Data write enable
input wbd_ack_i, // Data acknowledge
output wbd_stb_o, // Data strobe
output wbd_cyc_o, // Data cycle
input wbd_err_i, // Data error
// interface to internal data ram
output [7:0] rd_addr,
output [7:0] wr_addr,
output [7:0] wr_dat,
input [7:0] ram_data,
output desCy,
output bit_data,
output wr_ram,
output bit_addr_o
);
assign wr_ram = (wr_o && (!wr_addr[7] || wr_ind));
wire ea_in = 1'b0; // External ROM only
// Tie off interrupts
wire int0_i, int1_i;
assign int0_i = 1'b0;
assign int1_i = 1'b0;
wire [7:0] dptr_hi,
dptr_lo,
ri,
data_out,
op1,
op2,
op3,
acc,
p0_out,
p1_out,
p2_out,
p3_out,
sp,
sp_w;
wire [31:0] idat_onchip;
wire [15:0] pc;
assign wbd_cyc_o = wbd_stb_o;
wire src_sel3;
wire [1:0] wr_sfr,
src_sel2;
wire [2:0] ram_rd_sel, // ram read
ram_wr_sel, // ram write
src_sel1;
wire [7:0] ram_data,
ram_out, //data from ram
sfr_out,
wr_dat,
wr_addr, //ram write addres
rd_addr; //data ram read addres
wire sfr_bit;
wire [1:0] cy_sel, //carry select; from decoder to cy_selct1
bank_sel;
wire rom_addr_sel, //rom addres select; alu or pc
rmw,
ea_int;
wire reti,
intr,
istb;
wire [7:0] int_src;
wire mem_wait;
wire [2:0] mem_act;
wire [3:0] alu_op; //alu operation (from decoder)
wire [1:0] psw_set; //write to psw or not; from decoder to psw (through register)
wire [7:0] src1, //alu sources 1
src2, //alu sources 2
src3, //alu sources 3
des_acc,
des1, //alu destination 1
des2; //alu destinations 2
wire desCy, //carry out
desAc,
desOv, //overflow
alu_cy,
wr, //write to data ram
wr_o;
wire rd, //read program rom
pc_wr;
wire [2:0] pc_wr_sel; //program counter write select (from decoder to pc)
wire [7:0] op1_n, //from memory_interface to decoder
op2_n,
op3_n;
wire [1:0] comp_sel; //select source1 and source2 to compare
wire eq, //result (from comp1 to decoder)
srcAc,
cy,
rd_ind,
wr_ind,
comp_wait;
wire [2:0] op1_cur;
wire bit_addr, //bit addresable instruction
bit_data, //bit data from ram to ram_select
bit_out, //bit data from ram_select to alu and cy_select
bit_addr_o,
wait_data;
//
// cpu to cache/wb_interface
wire iack_i,
istb_o,
icyc_o;
wire [31:0] idat_i;
wire [15:0] iadr_o;
//
// decoder
oc8051_decoder oc8051_decoder1(.clk(wb_clk_i),
.rst(wb_rst_i),
.op_in(op1_n),
.op1_c(op1_cur),
.ram_rd_sel_o(ram_rd_sel),
.ram_wr_sel_o(ram_wr_sel),
.bit_addr(bit_addr),
.src_sel1(src_sel1),
.src_sel2(src_sel2),
.src_sel3(src_sel3),
.alu_op_o(alu_op),
.psw_set(psw_set),
.cy_sel(cy_sel),
.wr_o(wr),
.pc_wr(pc_wr),
.pc_sel(pc_wr_sel),
.comp_sel(comp_sel),
.eq(eq),
.wr_sfr_o(wr_sfr),
.rd(rd),
.rmw(rmw),
.istb(istb),
.mem_act(mem_act),
.mem_wait(mem_wait),
.wait_data(wait_data));
wire [7:0] sub_result;
//
//alu
oc8051_alu oc8051_alu1(.rst(wb_rst_i),
.clk(wb_clk_i),
.op_code(alu_op),
.src1(src1),
.src2(src2),
.src3(src3),
.srcCy(alu_cy),
.srcAc(srcAc),
.des_acc(des_acc),
.sub_result(sub_result),
.des1(des1),
.des2(des2),
.desCy(desCy),
.desAc(desAc),
.desOv(desOv),
.bit_in(bit_out));
oc8051_alu_src_sel oc8051_alu_src_sel1(.clk(wb_clk_i),
.rst(wb_rst_i),
.rd(rd),
.sel1(src_sel1),
.sel2(src_sel2),
.sel3(src_sel3),
.acc(acc),
.ram(ram_out),
.pc(pc),
.dptr({dptr_hi, dptr_lo}),
.op1(op1_n),
.op2(op2_n),
.op3(op3_n),
.src1(src1),
.src2(src2),
.src3(src3));
//
//
oc8051_comp oc8051_comp1(.sel(comp_sel),
.eq(eq),
.b_in(bit_out),
.cy(cy),
.acc(acc),
.des(sub_result)
);
//
//External ROM only
assign ea_int = 1'b0;
assign idat_onchip = 32'h0;
//
//
oc8051_cy_select oc8051_cy_select1(.cy_sel(cy_sel),
.cy_in(cy),
.data_in(bit_out),
.data_out(alu_cy));
//
//
oc8051_indi_addr oc8051_indi_addr1 (.clk(wb_clk_i),
.rst(wb_rst_i),
.wr_addr(wr_addr),
.data_in(wr_dat),
.wr(wr_o),
.wr_bit(bit_addr_o),
.ri_out(ri),
.sel(op1_cur[0]),
.bank(bank_sel));
assign icyc_o = istb_o;
//
//
oc8051_memory_interface oc8051_memory_interface1(.clk(wb_clk_i),
.rst(wb_rst_i),
// internal ram
.wr_i(wr),
.wr_o(wr_o),
.wr_bit_i(bit_addr),
.wr_bit_o(bit_addr_o),
.wr_dat(wr_dat),
.des_acc(des_acc),
.des1(des1),
.des2(des2),
.rd_addr(rd_addr),
.wr_addr(wr_addr),
.wr_ind(wr_ind),
.bit_in(bit_data),
.in_ram(ram_data),
.sfr(sfr_out),
.sfr_bit(sfr_bit),
.bit_out(bit_out),
.iram_out(ram_out),
// external instrauction rom
.iack_i(iack_i),
.iadr_o(iadr_o),
.idat_i(idat_i),
.istb_o(istb_o),
// internal instruction rom
.idat_onchip(idat_onchip),
// data memory
.dadr_o(wbd_adr_o),
.ddat_o(wbd_dat_o),
.dwe_o(wbd_we_o),
.dstb_o(wbd_stb_o),
.ddat_i(wbd_dat_i),
.dack_i(wbd_ack_i),
// from decoder
.rd_sel(ram_rd_sel),
.wr_sel(ram_wr_sel),
.rn({bank_sel, op1_cur}),
.rd_ind(rd_ind),
.rd(rd),
.mem_act(mem_act),
.mem_wait(mem_wait),
// external access
.ea(ea_in),
.ea_int(ea_int),
// instructions outputs to cpu
.op1_out(op1_n),
.op2_out(op2_n),
.op3_out(op3_n),
// interrupt interface
.intr(intr),
.int_v(int_src),
.istb(istb),
//pc
.pc_wr_sel(pc_wr_sel),
.pc_wr(pc_wr & comp_wait),
.pc(pc),
// sfr's
.sp_w(sp_w),
.dptr({dptr_hi, dptr_lo}),
.ri(ri),
.acc(acc),
.sp(sp)
);
//
//
oc8051_sfr oc8051_sfr1(.rst(wb_rst_i),
.clk(wb_clk_i),
.adr0(rd_addr[7:0]),
.adr1(wr_addr[7:0]),
.dat0(sfr_out),
.dat1(wr_dat),
.dat2(des2),
.des_acc(des_acc),
.we(wr_o && !wr_ind),
.bit_in(desCy),
.bit_out(sfr_bit),
.wr_bit(bit_addr_o),
.ram_rd_sel(ram_rd_sel),
.ram_wr_sel(ram_wr_sel),
.wr_sfr(wr_sfr),
.comp_sel(comp_sel),
.comp_wait(comp_wait),
// acc
.acc(acc),
// sp
.sp(sp),
.sp_w(sp_w),
// psw
.bank_sel(bank_sel),
.desAc(desAc),
.desOv(desOv),
.psw_set(psw_set),
.srcAc(srcAc),
.cy(cy),
// ports
.rmw(rmw),
// int
.int_ack(1'b0),
.intr(intr),
.int0(int0_i),
.int1(int1_i),
.reti(reti),
.int_src(int_src),
// dptr
.dptr_hi(dptr_hi),
.dptr_lo(dptr_lo),
.wait_data(wait_data)
);
assign wbi_adr_o = iadr_o ;
assign idat_i = wbi_dat_i ;
assign wbi_stb_o = 1'b1 ;
assign iack_i = wbi_ack_i ;
assign wbi_cyc_o = 1'b1 ;
endmodule