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

Subversion Repositories hive

[/] [hive/] [trunk/] [v01.09/] [pointer_ring.v] - Rev 2

Compare with Previous | Blame | View Log

/*
--------------------------------------------------------------------------------
 
Module : pointer_ring.v
 
--------------------------------------------------------------------------------
 
Function:
- Processor stack pointer storage ring.
 
Instantiates:
- (1x) vector_sr.v
 
Notes:
- 8 stage pointer storage ring for four BRAM based LIFOs:
  0 : clear applied (& all inputs)
  1 : pop applied
  2 : push applied; pop errors output
  3 : push errors output
  6 : pointers & writes output
- Logic assumes pop | push will not be issued simultaneously with clear.
- Externally concatenate thread 6 & pointers to form stack memory addresses.
- Level width is PTR_W+1 to accomodate 0 to 2^n levels (1 + 2n states).
- Empty push is to address 1, full push is to address 0.
- Combo pop/push is accomodated with no net fullness/pointer change.
- Pop when empty is a pop error.
- Push when full is a push error.
- Pop/push when full is NOT an error.
- Pop/push when empty is a pop error ONLY.
- Parameterized stack error handling.  If the associated protection is turned on 
  then pop/push errors are reported but otherwise not acted upon, i.e. errors 
  will not corrupt fullness/pointers.
 
--------------------------------------------------------------------------------
*/
 
module pointer_ring
	#(
	parameter	integer							THREADS			= 8,		// threads
	parameter	integer							STACKS			= 4,		// stacks
	parameter	integer							PNTR_W			= 5,		// stack pointer width
	parameter	integer							POP_PROT			= 1,		// 1=error protection, 0=none
	parameter	integer							PUSH_PROT		= 1		// 1=error protection, 0=none
	)
	(
	// clocks & resets
	input			wire								clk_i,						// clock
	input			wire								rst_i,						// async. reset, active high
	// control I/O
	input			wire								clr_i,						// stacks clear
	input			wire	[STACKS-1:0]			pop_i,						// stacks pop
	input			wire	[STACKS-1:0]			push_i,						// stacks push
	// pointers
	output		wire	[PNTR_W-1:0]			pntr0_o,						// stack pointer
	output		wire	[PNTR_W-1:0]			pntr1_o,						// stack pointer
	output		wire	[PNTR_W-1:0]			pntr2_o,						// stack pointer
	output		wire	[PNTR_W-1:0]			pntr3_o,						// stack pointer
	// write enables
	output		wire	[STACKS-1:0]			wr_o,							// write enables
	// errors
	output		wire	[STACKS-1:0]			pop_er_o,					// pop when empty, active high 
	output		wire	[STACKS-1:0]			push_er_o					// push when full, active high
	);
 
 
	/*
	----------------------
	-- internal signals --
	----------------------
	*/
	localparam	integer							LEVEL_W			= PNTR_W+1;  // +1 extra bit
	localparam	[LEVEL_W-1:0]					EMPTY_VAL		= 'b0;  // empty value
	localparam	[LEVEL_W-1:0]					FULL_VAL			= 1'b1 << PNTR_W;  // full value
	//
	integer											s, t;
	//
	reg					[LEVEL_W-1:0]			level[0:STACKS-1][0:THREADS-1];
	//
	reg					[STACKS-1:0]			pop_1, push_1, push_2;
	reg					[STACKS-1:0]			empty_1, full_2;
	wire					[STACKS-1:0]			dec_1, inc_2;
	reg					[STACKS-1:0]			pop_er_2, push_er_3;
 
 
	/*
	================
	== code start ==
	================
	*/
 
 
	// pipeline control signals
	always @ ( posedge clk_i or posedge rst_i ) begin
		if ( rst_i ) begin
			pop_1 <= 'b0;
			push_1 <= 'b0;
			push_2 <= 'b0;
		end else begin
			pop_1 <= pop_i;
			push_1 <= push_i;
			push_2 <= push_1;
		end
	end
 
	// decode watermarks
	always @ ( * ) begin
		for ( s=0; s<STACKS; s=s+1 ) begin
			empty_1[s] <= ( level[s][1] == EMPTY_VAL );
			full_2[s] <= ( level[s][2] == FULL_VAL );
		end
	end
 
	// prohibit pointer changes @ errors if configured to do so
	assign dec_1 = ( POP_PROT ) ? pop_1 & ~empty_1 : pop_1;
	assign inc_2 = ( PUSH_PROT ) ? push_2 & ~full_2 : push_2;
 
	// decode & register errors - pop when empty, push when full
	always @ ( posedge clk_i or posedge rst_i ) begin
		if ( rst_i ) begin
			pop_er_2 <= 'b0;
			push_er_3 <= 'b0;
		end else begin
			pop_er_2 <= pop_1 & empty_1;
			push_er_3 <= push_2 & full_2;
		end
	end
 
	// decode & pipeline levels
	always @ ( posedge clk_i or posedge rst_i ) begin
		if ( rst_i ) begin
			for ( s=0; s<STACKS; s=s+1 ) begin 
				for ( t=0; t<THREADS; t=t+1 ) begin 
					level[s][t] <= 'b0;
				end
			end
		end else begin
			for ( s=0; s<STACKS; s=s+1 ) begin 
				for ( t=0; t<THREADS; t=t+1 ) begin 
					if ( t == 0 ) level[s][t] <= level[s][THREADS-1];  // wrap around
					else if ( t == 1 ) level[s][t] <= ( clr_i ) ? 1'b0 : level[s][t-1];  // clear
					else if ( t == 2 ) level[s][t] <= ( dec_1[s] ) ? level[s][t-1] - 1'b1 : level[s][t-1];  // pop
					else if ( t == 3 ) level[s][t] <= ( inc_2[s] ) ? level[s][t-1] + 1'b1 : level[s][t-1];  // push
					else level[s][t] <= level[s][t-1];
				end
			end
		end
	end
 
 
	// decode & pipeline write enables
	vector_sr
	#(
	.REGS			( 4 ),
	.DATA_W		( STACKS ),
	.RESET_VAL	( 0 )
	)
	wr_pipe
	(
	.clk_i		( clk_i ),
	.rst_i		( rst_i ),
	.data_i		( inc_2 ),
	.data_o		( wr_o )
	);
 
 
	// output pointers
	assign pntr0_o = level[0][6][PNTR_W-1:0];
	assign pntr1_o = level[1][6][PNTR_W-1:0];
	assign pntr2_o = level[2][6][PNTR_W-1:0];
	assign pntr3_o = level[3][6][PNTR_W-1:0];
 
	// output errors
	assign pop_er_o = pop_er_2;
	assign push_er_o = push_er_3;
 
 
endmodule
 

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.