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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [zipbones.v] - Diff between revs 201 and 209

Show entire file | Details | Blame | View Log

Rev 201 Rev 209
Line 11... Line 11...
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015, 2017, Gisselquist Technology, LLC
// Copyright (C) 2015-2019, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
Line 24... Line 24...
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// You should have received a copy of the GNU General Public License along
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
// target there if the PDF file isn't present.)  If not, see
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
// <http://www.gnu.org/licenses/> for a copy.
//
//
// License:     GPL, v3, as defined and found on www.gnu.org,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
 
`default_nettype        none
 
//
`include "cpudefs.v"
`include "cpudefs.v"
//
//
module  zipbones(i_clk, i_rst,
`define RESET_BIT       6
 
`define STEP_BIT        8
 
`define HALT_BIT        10
 
`define CLEAR_CACHE_BIT 11
 
//
 
module  zipbones(i_clk, i_reset,
                // Wishbone master interface from the CPU
                // Wishbone master interface from the CPU
                o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
                o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
                        i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
                        i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
                // Incoming interrupts
                // Incoming interrupts
                i_ext_int,
                i_ext_int,
Line 49... Line 56...
                o_ext_int,
                o_ext_int,
                // Wishbone slave interface for debugging purposes
                // Wishbone slave interface for debugging purposes
                i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data,
                i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data,
                        o_dbg_ack, o_dbg_stall, o_dbg_data
                        o_dbg_ack, o_dbg_stall, o_dbg_data
`ifdef  DEBUG_SCOPE
`ifdef  DEBUG_SCOPE
                , o_zip_debug
                , o_cpu_debug
`endif
`endif
                );
                );
        parameter       RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=30,
        parameter       RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=30,
                        LGICACHE=8, START_HALTED=0;
                        LGICACHE=8;
 
        parameter [0:0]   START_HALTED=0;
 
        parameter       EXTERNAL_INTERRUPTS=1,
 
`ifdef  OPT_MULTIPLY
 
                        IMPLEMENT_MPY = `OPT_MULTIPLY;
 
`else
 
                        IMPLEMENT_MPY = 0;
 
`endif
 
        parameter [0:0]
 
`ifdef  OPT_DIVIDE
 
                        IMPLEMENT_DIVIDE=1,
 
`else
 
                        IMPLEMENT_DIVIDE=0,
 
`endif
 
`ifdef  OPT_IMPLEMENT_FPU
 
                        IMPLEMENT_FPU=1,
 
`else
 
                        IMPLEMENT_FPU=0,
 
`endif
 
                        IMPLEMENT_LOCK=1;
 
        localparam      // Derived parameters
 
                        PHYSICAL_ADDRESS_WIDTH=ADDRESS_WIDTH,
 
                        PAW=ADDRESS_WIDTH,
 
`ifdef  OPT_MMU
 
                        VIRTUAL_ADDRESS_WIDTH=30,
 
`else
 
                        VIRTUAL_ADDRESS_WIDTH=PAW,
 
`endif
 
                        LGTLBSZ = 6,
 
                        VAW=VIRTUAL_ADDRESS_WIDTH;
 
 
        localparam      AW=ADDRESS_WIDTH;
        localparam      AW=ADDRESS_WIDTH;
        input   i_clk, i_rst;
        input   wire    i_clk, i_reset;
        // Wishbone master
        // Wishbone master
        output  wire            o_wb_cyc, o_wb_stb, o_wb_we;
        output  wire            o_wb_cyc, o_wb_stb, o_wb_we;
        output  wire    [(AW-1):0]       o_wb_addr;
        output  wire    [(PAW-1):0]      o_wb_addr;
        output  wire    [31:0]   o_wb_data;
        output  wire    [31:0]   o_wb_data;
        output  wire    [3:0]    o_wb_sel;
        output  wire    [3:0]    o_wb_sel;
        input                   i_wb_ack, i_wb_stall;
        input   wire            i_wb_ack, i_wb_stall;
        input           [31:0]   i_wb_data;
        input   wire    [31:0]   i_wb_data;
        input                   i_wb_err;
        input   wire            i_wb_err;
        // Incoming interrupts
        // Incoming interrupts
        input                   i_ext_int;
        input   wire            i_ext_int;
        // Outgoing interrupt
        // Outgoing interrupt
        output  wire            o_ext_int;
        output  wire            o_ext_int;
        // Wishbone slave
        // Wishbone slave
        input                   i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr;
        input   wire            i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr;
        input           [31:0]   i_dbg_data;
        input   wire    [31:0]   i_dbg_data;
        output  reg             o_dbg_ack;
        output  wire            o_dbg_ack;
        output  wire            o_dbg_stall;
        output  wire            o_dbg_stall;
        output  wire    [31:0]   o_dbg_data;
        output  wire    [31:0]   o_dbg_data;
        //
        //
`ifdef  DEBUG_SCOPE
`ifdef  DEBUG_SCOPE
        output  wire    [31:0]   o_zip_debug;
        output  wire    [31:0]   o_cpu_debug;
`endif
`endif
 
        wire            dbg_cyc, dbg_stb, dbg_we, dbg_addr, dbg_stall;
        // 
        wire    [31:0]   dbg_idata, dbg_odata;
        //
        reg             dbg_ack;
        //
 
        wire    sys_cyc, sys_stb, sys_we;
        assign  dbg_cyc     = i_dbg_cyc;
        wire    [4:0]    sys_addr;
        assign  dbg_stb     = i_dbg_stb;
        wire    [(AW-1):0]       cpu_addr;
        assign  dbg_we      = i_dbg_we;
        wire    [31:0]   sys_data;
        assign  dbg_addr    = i_dbg_addr;
        wire            sys_ack, sys_stall;
        assign  dbg_idata   = i_dbg_data;
 
        assign  o_dbg_ack   = dbg_ack;
 
        assign  o_dbg_stall = dbg_stall;
 
        assign  o_dbg_data  = dbg_odata;
        //
        //
        // The external debug interface
        // The external debug interface
        //
        //
        // We offer only a limited interface here, requiring a pre-register
        // We offer only a limited interface here, requiring a pre-register
        // write to set the local address.  This interface allows access to
        // write to set the local address.  This interface allows access to
Line 105... Line 144...
        //
        //
        wire            cpu_break, dbg_cmd_write;
        wire            cpu_break, dbg_cmd_write;
        reg             cmd_reset, cmd_halt, cmd_step, cmd_clear_pf_cache;
        reg             cmd_reset, cmd_halt, cmd_step, cmd_clear_pf_cache;
        reg     [4:0]    cmd_addr;
        reg     [4:0]    cmd_addr;
        wire    [3:0]    cpu_dbg_cc;
        wire    [3:0]    cpu_dbg_cc;
        assign  dbg_cmd_write = (i_dbg_cyc)&&(i_dbg_stb)&&(i_dbg_we)&&(~i_dbg_addr);
        assign  dbg_cmd_write = (dbg_stb)&&(dbg_we)&&(!dbg_addr);
        //
        //
        // Always start us off with an initial reset
        // Always start us off with an initial reset
        //
        //
        initial cmd_reset = 1'b1;
        initial cmd_reset = 1'b1;
        always @(posedge i_clk)
        always @(posedge i_clk)
                cmd_reset <= ((dbg_cmd_write)&&(i_dbg_data[6]));
                cmd_reset <= ((dbg_cmd_write)&&(dbg_idata[`RESET_BIT]));
        //
        //
        initial cmd_halt  = START_HALTED;
        initial cmd_halt  = START_HALTED;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
        if (i_reset)
                        cmd_halt <= (START_HALTED == 1)? 1'b1 : 1'b0;
                cmd_halt <= START_HALTED;
 
        else if (cmd_reset)
 
                cmd_halt <= START_HALTED;
                else if (dbg_cmd_write)
                else if (dbg_cmd_write)
                        cmd_halt <= ((i_dbg_data[10])||(i_dbg_data[8]));
                cmd_halt <= ((dbg_idata[`HALT_BIT])&&(!dbg_idata[`STEP_BIT]));
                else if ((cmd_step)||(cpu_break))
                else if ((cmd_step)||(cpu_break))
                        cmd_halt  <= 1'b1;
                        cmd_halt  <= 1'b1;
 
 
        initial cmd_clear_pf_cache = 1'b0;
        initial cmd_clear_pf_cache = 1'b1;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
                cmd_clear_pf_cache <= (dbg_cmd_write)&&(dbg_idata[`CLEAR_CACHE_BIT]);
                        cmd_clear_pf_cache <= 1'b0;
 
                else if (dbg_cmd_write)
 
                        cmd_clear_pf_cache <= i_dbg_data[11];
 
                else
 
                        cmd_clear_pf_cache <= 1'b0;
 
        //
        //
        initial cmd_step  = 1'b0;
        initial cmd_step  = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                cmd_step <= (dbg_cmd_write)&&(i_dbg_data[8]);
                cmd_step <= (dbg_cmd_write)&&(dbg_idata[`STEP_BIT]);
        //
        //
        initial cmd_addr = 5'h0;
        initial cmd_addr = 5'h0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (dbg_cmd_write)
                if (dbg_cmd_write)
                        cmd_addr <= i_dbg_data[4:0];
                        cmd_addr <= dbg_idata[4:0];
 
 
        wire    cpu_reset;
        wire    cpu_reset;
        assign  cpu_reset = (cmd_reset)||(i_rst);
        assign  cpu_reset = (cmd_reset);
 
 
        wire    cpu_halt, cpu_dbg_stall;
        wire    cpu_halt, cpu_dbg_stall;
        assign  cpu_halt = (i_rst)||((cmd_halt)&&(~cmd_step));
        assign  cpu_halt = (cmd_halt);
        wire    [31:0]   cmd_data;
        wire    [31:0]   cmd_data;
        // Values:
        // Values:
        //      0x0003f -> cmd_addr mask
        //      0x0003f -> cmd_addr mask
        //      0x00040 -> reset
        //      0x00040 -> reset
        //      0x00080 -> PIC interrrupts enabled
        //      0x00080 -> PIC interrrupt pending
        //      0x00100 -> cmd_step
        //      0x00100 -> cmd_step
        //      0x00200 -> cmd_stall
        //      0x00200 -> cmd_stall
        //      0x00400 -> cmd_halt
        //      0x00400 -> cmd_halt
        //      0x00800 -> cmd_clear_pf_cache
        //      0x00800 -> cmd_clear_pf_cache
        //      0x01000 -> cc.sleep
        //      0x01000 -> cc.sleep
        //      0x02000 -> cc.gie
        //      0x02000 -> cc.gie
        //      0x10000 -> External interrupt line is high
        //      0x10000 -> External interrupt line is high
        assign  cmd_data = { 7'h00, 8'h00, i_ext_int,
        assign  cmd_data = { 7'h00, 8'h00, i_ext_int,
                        cpu_dbg_cc,
                        cpu_dbg_cc,
                        1'b0, cmd_halt, (~cpu_dbg_stall), 1'b0,
                        1'b0, cmd_halt, (!cpu_dbg_stall), 1'b0,
                        1'b0, cpu_reset, 1'b0, cmd_addr };
                        i_ext_int, cpu_reset, 1'b0, cmd_addr };
 
 
        //
        //
        // The CPU itself
        // The CPU itself
        //
        //
        wire            cpu_gbl_stb, cpu_lcl_cyc, cpu_lcl_stb,
        wire            cpu_lcl_cyc, cpu_lcl_stb,
                        cpu_we, cpu_dbg_we,
                        cpu_dbg_we,
                        cpu_op_stall, cpu_pf_stall, cpu_i_count;
                        cpu_op_stall, cpu_pf_stall, cpu_i_count;
        wire    [31:0]   cpu_data;
 
        wire    [31:0]   cpu_dbg_data;
        wire    [31:0]   cpu_dbg_data;
        assign cpu_dbg_we = ((i_dbg_cyc)&&(i_dbg_stb)
        assign cpu_dbg_we = ((dbg_stb)&&(dbg_we)&&(dbg_addr));
                                        &&(i_dbg_we)&&(i_dbg_addr));
 
        zipcpu  #(.RESET_ADDRESS(RESET_ADDRESS),
        zipcpu  #(.RESET_ADDRESS(RESET_ADDRESS),
                        .ADDRESS_WIDTH(ADDRESS_WIDTH),
                        .ADDRESS_WIDTH(ADDRESS_WIDTH),
                        .LGICACHE(LGICACHE),
                        .LGICACHE(LGICACHE),
                        .WITH_LOCAL_BUS(0))
                        .WITH_LOCAL_BUS(0))
                thecpu(i_clk, cpu_reset, i_ext_int,
                thecpu(i_clk, cpu_reset, i_ext_int,
                        cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we,
                        cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we,
                                i_dbg_data, cpu_dbg_stall, cpu_dbg_data,
                                dbg_idata, cpu_dbg_stall, cpu_dbg_data,
                                cpu_dbg_cc, cpu_break,
                                cpu_dbg_cc, cpu_break,
                        o_wb_cyc, o_wb_stb,
                        o_wb_cyc, o_wb_stb,
                                cpu_lcl_cyc, cpu_lcl_stb,
                                cpu_lcl_cyc, cpu_lcl_stb,
                                o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
                                o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
                                i_wb_ack, i_wb_stall, i_wb_data,
                                i_wb_ack, i_wb_stall, i_wb_data,
                                (i_wb_err)||(cpu_lcl_cyc),
                                (i_wb_err)||(cpu_lcl_cyc),
                        cpu_op_stall, cpu_pf_stall, cpu_i_count
                        cpu_op_stall, cpu_pf_stall, cpu_i_count
`ifdef  DEBUG_SCOPE
`ifdef  DEBUG_SCOPE
                        , o_zip_debug
                        , o_cpu_debug
`endif
`endif
                        );
                        );
 
 
        // Return debug response values
        // Return debug response values
        assign  o_dbg_data = (~i_dbg_addr)?cmd_data :cpu_dbg_data;
        assign  dbg_odata = (!dbg_addr)?cmd_data :cpu_dbg_data;
        initial o_dbg_ack = 1'b0;
        initial dbg_ack = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_dbg_ack <= (i_dbg_cyc)&&((~i_dbg_addr)||(~o_dbg_stall));
                dbg_ack <= (dbg_stb)&&(!o_dbg_stall);
        assign  o_dbg_stall=(i_dbg_cyc)&&(cpu_dbg_stall)&&(i_dbg_addr);
        assign  dbg_stall= (cpu_dbg_stall)&&(dbg_addr);
 
 
 
        assign  o_ext_int = (cmd_halt) && (!i_wb_stall);
 
 
        assign  o_ext_int = (cmd_halt) && (~i_wb_stall);
        // Make Verilator happy
 
        // verilator lint_off UNUSED
 
        wire    [4:0] unused;
 
        assign  unused = { dbg_cyc, cpu_lcl_stb, cpu_op_stall, cpu_pf_stall, cpu_i_count };
 
        // verilator lint_on  UNUSED
 
 
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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