URL
https://opencores.org/ocsvn/oms8051mini/oms8051mini/trunk
Subversion Repositories oms8051mini
[/] [oms8051mini/] [trunk/] [rtl/] [8051/] [oc8051_top.v] - Rev 26
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// 8051 cores top level module //// //// //// //// This file is part of the 8051 cores project //// //// http://www.opencores.org/cores/oms8051mini/ //// //// //// //// Description //// //// 8051 definitions. //// //// //// //// To Do: //// //// nothing //// //// //// //// Author(s): //// //// - Simon Teran, simont@opencores.org //// //// - Dinesh Annayya, dinesha@opencores.org //// ////////////////////////////////////////////////////////////////////// //// v0.0 - Dinesh A, 8th Dec 2016 //// 1. External ROM Interface Removed //// v0.1 - Dinesh A, 5th Jan 2017 //// 1. Active edge of reset changed from High to Low //// v0.2 - Dinesh A, 6th Jan 2017 //// 1. pc_next logic added //// //// ////////////////////////////////////////////////////////////////////// //// //// //// 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 // // `include "top_defines.v" module oc8051_top (resetn, wb_clk_i, //interface to data ram wbd_dat_i, wbd_dat_o, wbd_adr_o, wbd_we_o, wbd_ack_i, wbd_stb_o, wbd_cyc_o, wbd_err_i, // interrupt interface int0_i, int1_i, // port interface `ifdef OC8051_PORTS `ifdef OC8051_PORT0 p0_i, p0_o, `endif `ifdef OC8051_PORT1 p1_i, p1_o, `endif `ifdef OC8051_PORT2 p2_i, p2_o, `endif `ifdef OC8051_PORT3 p3_i, p3_o, `endif `endif // serial interface `ifdef OC8051_UART rxd_i, txd_o, `endif // counter interface `ifdef OC8051_TC01 t0_i, t1_i, `endif `ifdef OC8051_TC2 t2_i, t2ex_i, `endif // BIST `ifdef OC8051_BIST scanb_rst, scanb_clk, scanb_si, scanb_so, scanb_en, `endif // external access (active low) ea_in ); input resetn, // reset input wb_clk_i, // clock input int0_i, // interrupt 0 int1_i, // interrupt 1 ea_in, // external access wbd_ack_i, // data acknowalge wbd_err_i; // data error input [7:0] wbd_dat_i; // ram data input output wbd_we_o, // data write enable wbd_stb_o, // data strobe wbd_cyc_o; // data cycle output [7:0] wbd_dat_o; // data output output [15:0] wbd_adr_o; // data address `ifdef OC8051_PORTS `ifdef OC8051_PORT0 input [7:0] p0_i; // port 0 input output [7:0] p0_o; // port 0 output `endif `ifdef OC8051_PORT1 input [7:0] p1_i; // port 1 input output [7:0] p1_o; // port 1 output `endif `ifdef OC8051_PORT2 input [7:0] p2_i; // port 2 input output [7:0] p2_o; // port 2 output `endif `ifdef OC8051_PORT3 input [7:0] p3_i; // port 3 input output [7:0] p3_o; // port 3 output `endif `endif `ifdef OC8051_UART input rxd_i; // receive output txd_o; // transnmit `endif `ifdef OC8051_TC01 input t0_i, // counter 0 input t1_i; // counter 1 input `endif `ifdef OC8051_TC2 input t2_i, // counter 2 input t2ex_i; // `endif `ifdef OC8051_BIST input scanb_rst; input scanb_clk; input scanb_si; output scanb_so; input scanb_en; wire scanb_soi; `endif 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,pc_next; 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, int_ack, 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 [15:0] iadr_o; // // decoder oc8051_decoder u_decoder( .clk (wb_clk_i ), .resetn (resetn ), .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 u_alu( .resetn (resetn ), .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) ); // //data ram oc8051_ram_top u_ram_top( .clk (wb_clk_i ), .resetn (resetn ), .rd_addr (rd_addr ), .rd_data (ram_data ), .wr_addr (wr_addr ), .bit_addr (bit_addr_o ), .wr_data (wr_dat ), .wr (wr_o && (!wr_addr[7] || wr_ind)), .bit_data_in (desCy ), .bit_data_out (bit_data ) `ifdef OC8051_BIST , .scanb_rst (scanb_rst ), .scanb_clk (scanb_clk ), .scanb_si (scanb_soi ), .scanb_so (scanb_so ), .scanb_en (scanb_en ) `endif ); // oc8051_alu_src_sel u_alu_src_sel( .clk (wb_clk_i ), .resetn (resetn ), .rd (rd ), .sel1 (src_sel1 ), .sel2 (src_sel2 ), .sel3 (src_sel3 ), .acc (acc ), .ram (ram_out ), .pc (pc_next ), .dptr ({dptr_hi, dptr_lo} ), .op1 (op1_n ), .op2 (op2_n ), .op3 (op3_n ), .src1 (src1 ), .src2 (src2 ), .src3 (src3 ) ); // // oc8051_comp u_comp( .sel (comp_sel ), .eq (eq ), .b_in (bit_out ), .cy (cy ), .acc (acc ), .des (sub_result ) ); // //program rom `ifdef OC8051_ROM oc8051_rom u_rom( .resetn (resetn ), .clk (wb_clk_i ), .ea_int (ea_int ), .addr (iadr_o ), .data_o (idat_onchip ) ); `else assign ea_int = 1'b0; assign idat_onchip = 32'h0; `ifdef OC8051_SIMULATION initial begin $display("\t * "); $display("\t * Internal rom disabled!!!"); $display("\t * "); end `endif `endif // // oc8051_cy_select u_cy_select( .cy_sel (cy_sel ), .cy_in (cy ), .data_in (bit_out ), .data_out (alu_cy ) ); // // oc8051_indi_addr u_indi_addr ( .clk (wb_clk_i ), .resetn (resetn ), .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 ) ); // // oc8051_memory_interface u_memory_interface( .clk (wb_clk_i ), .resetn (resetn ), // 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 .iadr_o (iadr_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), .int_ack (int_ack ), .istb (istb ), .reti (reti ), //pc .pc_wr_sel (pc_wr_sel ), .pc_wr (pc_wr & comp_wait ), .pc (pc ), .pc_next (pc_next ), // sfr's .sp_w (sp_w ), .dptr ({dptr_hi, dptr_lo} ), .ri (ri ), .acc (acc ), .sp (sp ) ); // // oc8051_sfr u_sfr( .resetn (resetn ), .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 ), `ifdef OC8051_PORTS `ifdef OC8051_PORT0 .p0_out (p0_o ), .p0_in (p0_i ), `endif `ifdef OC8051_PORT1 .p1_out (p1_o ), .p1_in (p1_i ), `endif `ifdef OC8051_PORT2 .p2_out (p2_o ), .p2_in (p2_i ), `endif `ifdef OC8051_PORT3 .p3_out (p3_o ), .p3_in (p3_i ), `endif `endif // uart `ifdef OC8051_UART .rxd (rxd_i ), .txd (txd_o ), `endif // int .int_ack (int_ack ), .intr (intr ), .int0 (int0_i ), .int1 (int1_i ), .reti (reti ), .int_src (int_src ), // t/c 0,1 `ifdef OC8051_TC01 .t0 (t0_i ), .t1 (t1_i ), `endif // t/c 2 `ifdef OC8051_TC2 .t2 (t2_i ), .t2ex (t2ex_i ), `endif // dptr .dptr_hi (dptr_hi ), .dptr_lo (dptr_lo ), .wait_data (wait_data ) ); `ifdef OC8051_BIST assign scanb_soi=scanb_si; `endif `ifdef OC8051_SIMULATION initial begin #1 $display("\t * "); $display("\t * External rom interface: Pipelined interface"); $display("\t * "); end `endif // synopsys translate_off // Debug Purpose only // Stack Pointer Push & Pop analysis reg [7:0] StackMem[$]; reg [7:0] stack_pop; reg [7:0] pushpop_cnt; // Assumption, Both Write and Read access will not be // possbile in single clock cycle always @(posedge wb_clk_i or negedge resetn) begin if(resetn == 1'b0) begin pushpop_cnt = 0; end else begin if(ram_wr_sel==`OC8051_RWS_SP) begin StackMem.push_back(wr_dat); pushpop_cnt = pushpop_cnt + 1; end if(ram_rd_sel==`OC8051_RRS_SP) begin stack_pop = StackMem.pop_back(); pushpop_cnt = pushpop_cnt - 1; #2 // Add 1ns Delay to take care of Ram Dealy if(stack_pop != ram_data) begin $display("ERROR: Invalid Stack Pointer Pop Detected, Exp: %x,Rxd:%x",stack_pop,ram_data); $stop; end end end end // synopsys translate_on endmodule