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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [peripherals/] [ziptrap.v] - Rev 101

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

///////////////////////////////////////////////////////////////////////////
//
// Filename:	ziptrap.v
//
// Project:	Zip CPU -- a small, lightweight, RISC CPU soft core
//
// Purpose:	On any write, generate an interrupt.  On any read, return
//		the value from the last write.
//
//	This peripheral was added to the Zip System to compensate for the lack
//	of any trap instruction within the Zip instruction set.  Such an 
//	instruction is used heavily by modern operating systems to switch
//	from a user process to a system process.  Since there was no way
//	to build such an interface without a trap instruction, this was added
//	to accomplish that purpose.
//
//	However, in early simulation testing it was discovered that this
//	approach would not be very suitable: the interrupt was not generated
//	the next clock as one would expect.  Hence, executing a trap became:
//
//		TRAP	$5		MOV $TrapAddr, R0
//					LDI $5,R1
//					STO R1,(R0)
//					NOOP
//					NOOP -- here the trap would take effect
//		ADD $5,R6		ADD $5,R6
//
//	This was too cumbersome, necessitating NOOPS and such.  Therefore,
//	the CC register was extended to hold a trap value.  This leads to
//
//		TRAP $5			LDI	$500h,CC
//				; Trap executes immediately, user sees no
//				; delay's, no extra wait instructions.
//		ADD $5,R6		ADD $5,R6
//
//	(BTW: The add is just the "next instruction", whatever that may be.)
//	Note the difference: there's no longer any need to load the trap
//	address into a register (something that usually could not be done with
//	a move, but rather a LDIHI/LDILO pair).  There's no longer any wait
//	for the Wishbone bus, which could've introduced a variable delay.
//	Neither are there any wait states while waiting for the system process
//	to take over and respond.  Oh, and another difference, the new approach
//	no longer requires the system to activate an interrupt line--the user
//	process can always initiate such an interrupt.  Hence, the new
//	solution is better rendering this peripheral obsolete.
//
//	It is maintained here to document this part of the learning process.
//
//
//
// Creator:	Dan Gisselquist, Ph.D.
//		Gisselquist Technology, 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	ziptrap(i_clk,
		i_wb_cyc, i_wb_stb, i_wb_we, i_wb_data,
			o_wb_ack, o_wb_stall, o_wb_data,
		o_int);
	parameter		BW = 32; // Bus width
	input				i_clk;
	// Wishbone inputs
	input				i_wb_cyc, i_wb_stb, i_wb_we;
	input		[(BW-1):0]	i_wb_data;
	// Wishbone outputs
	output	reg			o_wb_ack;
	output	wire			o_wb_stall;
	output	reg	[(BW-1):0]	o_wb_data;
	// Interrupt output
	output	reg			o_int;
 
	initial	o_wb_ack = 1'b0;
	always @(posedge i_clk)
		o_wb_ack <= ((i_wb_cyc)&&(i_wb_stb));
	assign	o_wb_stall = 1'b0;
 
	// Initially set to some of bounds value, such as all ones.
	initial	o_wb_data = {(BW){1'b1}};
	always @(posedge i_clk)
		if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
			o_wb_data <= i_wb_data;
 
	// Set the interrupt bit on any write.
	initial	o_int = 1'b0;
	always @(posedge i_clk)
		if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
			o_int <= 1'b1;
		else
			o_int <= 1'b0;
 
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.