OpenCores
URL https://opencores.org/ocsvn/oms8051mini/oms8051mini/trunk

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [rtl/] [8051/] [oc8051_top.v] - Rev 30

Go to most recent revision | 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
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.