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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [zipbones.v] - Rev 42

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

///////////////////////////////////////////////////////////////////////////
//
// Filename:	zipbones.v
//
// Project:	Zip CPU -- a small, lightweight, RISC CPU soft core
//
// Purpose:	In the spirit of keeping the Zip CPU small, this implements a
//		Zip System with no peripherals: Any peripherals you wish will
//		need to be implemented off-module.
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Tecnology, LLC
//
///////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
//
// 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
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// License:	GPL, v3, as defined and found on www.gnu.org,
//		http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
//
module	zipbones(i_clk, i_rst,
		// Wishbone master interface from the CPU
		o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data,
			i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
		// Incoming interrupts
		i_ext_int,
		// Our one outgoing interrupt
		o_ext_int,
		// Wishbone slave interface for debugging purposes
		i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data,
			o_dbg_ack, o_dbg_stall, o_dbg_data);
	parameter	RESET_ADDRESS=32'h0100000, START_HALTED=1,
			EXTERNAL_INTERRUPTS=1;
	input	i_clk, i_rst;
	// Wishbone master
	output	wire		o_wb_cyc, o_wb_stb, o_wb_we;
	output	wire	[31:0]	o_wb_addr;
	output	wire	[31:0]	o_wb_data;
	input			i_wb_ack, i_wb_stall;
	input		[31:0]	i_wb_data;
	input			i_wb_err;
	// Incoming interrupts
	input		[(EXTERNAL_INTERRUPTS-1):0]	i_ext_int;
	// Outgoing interrupt
	output	wire		o_ext_int;
	// Wishbone slave
	input			i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr;
	input		[31:0]	i_dbg_data;
	output	reg		o_dbg_ack;
	output	wire		o_dbg_stall;
	output	wire	[31:0]	o_dbg_data;
 
	// 
	//
	//
	wire	sys_cyc, sys_stb, sys_we;
	wire	[4:0]	sys_addr;
	wire	[31:0]	cpu_addr;
	wire	[31:0]	sys_data;
	wire		sys_ack, sys_stall;
 
	//
	// The external debug interface
	//
	// We offer only a limited interface here, requiring a pre-register
	// write to set the local address.  This interface allows access to
	// the Zip System on a debug basis only, and not to the rest of the
	// wishbone bus.  Further, to access these registers, the control
	// register must first be accessed to both stop the CPU and to 
	// set the following address in question.  Hence all accesses require
	// two accesses: write the address to the control register (and halt
	// the CPU if not halted), then read/write the data from the data
	// register.
	//
	wire		cpu_break, dbg_cmd_write;
	reg		cmd_reset, cmd_halt, cmd_step, cmd_clear_pf_cache;
	reg	[4:0]	cmd_addr;
	wire	[1:0]	cpu_dbg_cc;
	assign	dbg_cmd_write = (i_dbg_cyc)&&(i_dbg_stb)&&(i_dbg_we)&&(~i_dbg_addr);
	//
	initial	cmd_reset = 1'b1;
	always @(posedge i_clk)
		cmd_reset <= ((dbg_cmd_write)&&(i_dbg_data[6]));
	//
	initial	cmd_halt  = 1'b1;
	always @(posedge i_clk)
		if (i_rst)
			cmd_halt <= (START_HALTED == 1)? 1'b1 : 1'b0;
		else if (dbg_cmd_write)
			cmd_halt <= ((i_dbg_data[10])||(i_dbg_data[8]));
		else if ((cmd_step)||(cpu_break))
			cmd_halt  <= 1'b1;
 
	always @(posedge i_clk)
		if (i_rst)
			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;
	always @(posedge i_clk)
		cmd_step <= (dbg_cmd_write)&&(i_dbg_data[8]);
	//
	always @(posedge i_clk)
		if (dbg_cmd_write)
			cmd_addr <= i_dbg_data[4:0];
 
	wire	cpu_reset;
	assign	cpu_reset = (cmd_reset)||(i_rst);
 
	wire	cpu_halt, cpu_dbg_stall;
	assign	cpu_halt = (i_rst)||((cmd_halt)&&(~cmd_step));
	wire	[31:0]	pic_data;
	wire	[31:0]	cmd_data;
	// Values:
	//	0x0003f -> cmd_addr mask
	//	0x00040 -> reset
	//	0x00080 -> PIC interrrupts enabled
	//	0x00100 -> cmd_step
	//	0x00200 -> cmd_stall
	//	0x00400 -> cmd_halt
	//	0x00800 -> cmd_clear_pf_cache
	//	0x01000 -> cc.sleep
	//	0x02000 -> cc.gie
	//	0x10000 -> External interrupt line is high
	assign	cmd_data = { 7'h00, {(9-EXTERNAL_INTERRUPTS){1'b0}}, i_ext_int,
			2'b00, cpu_dbg_cc,
			1'b0, cmd_halt, (~cpu_dbg_stall), 1'b0,
			pic_data[15], cpu_reset, 1'b0, cmd_addr };
	wire	cpu_gie;
	assign	cpu_gie = cpu_dbg_cc[1];
 
	//
	// The CPU itself
	//
	wire		cpu_gbl_stb, cpu_lcl_cyc, cpu_lcl_stb, 
			cpu_we, cpu_dbg_we,
			cpu_op_stall, cpu_pf_stall, cpu_i_count;
	wire	[31:0]	cpu_data, wb_data;
	wire		cpu_ack, cpu_stall, cpu_err;
	wire	[31:0]	cpu_dbg_data;
	assign cpu_dbg_we = ((i_dbg_cyc)&&(i_dbg_stb)
					&&(i_dbg_we)&&(i_dbg_addr));
	zipcpu	#(RESET_ADDRESS) thecpu(i_clk, cpu_reset, i_ext_int,
			cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we,
				i_dbg_data, cpu_dbg_stall, cpu_dbg_data,
				cpu_dbg_cc, cpu_break,
			o_wb_cyc, o_wb_stb,
				cpu_lcl_cyc, cpu_lcl_stb,
				o_wb_we, o_wb_addr, o_wb_data,
				i_wb_ack, i_wb_stall, wb_data,
				i_wb_err,
			cpu_op_stall, cpu_pf_stall, cpu_i_count);
 
	// Return debug response values
	assign	o_dbg_data = (~i_dbg_addr)?cmd_data :cpu_dbg_data;
	initial o_dbg_ack = 1'b0;
	always @(posedge i_clk)
		o_dbg_ack <= (i_dbg_cyc)&&((~i_dbg_addr)||(~o_dbg_stall));
	assign	o_dbg_stall=(i_dbg_cyc)&&(cpu_dbg_stall)&&(i_dbg_addr);
 
	assign	o_ext_int = (cmd_halt) && (~cpu_stall);
 
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.