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

Subversion Repositories openfire2

[/] [openfire2/] [trunk/] [rtl/] [sram_wrapper.v] - Rev 6

Compare with Previous | Blame | View Log

/*	MODULE: openfire sram controller
	DESCRIPTION: Controls multiple access to SRAM
 
AUTHOR: 
Antonio J. Anton
Anro Ingenieros (www.anro-ingenieros.com)
aj@anro-ingenieros.com
 
REVISION HISTORY:
Revision 1.0, 26/03/2007
Initial release
 
COPYRIGHT:
Copyright (c) 2007 Antonio J. Anton
 
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in 
the Software without restriction, including without limitation the rights to 
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
of the Software, and to permit persons to whom the Software is furnished to do 
so, subject to the following conditions:
 
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.*/
 
`timescale 1ns / 1ps
`include "openfire_define.v"
 
module sram_controller(
   rst, clk,
 
	ram_addr, ram_oe_n,  ram_we_n,		// external 2x 256Kx16 sram modules in SP3 Starter Kit
	ram1_io,  ram1_ce_n, ram1_ub_n, ram1_lb_n,
	ram2_io,  ram2_ce_n, ram2_ub_n, ram2_lb_n,
 
	addr1, data2mem1, data2cpu1, re1, we1, done1, select1,
	addr2, data2cpu2, re2, done2,
	addr3, data2cpu3, re3, done3
);
 
input					rst;
input					clk;
 
output 	[17:0]	ram_addr;		// SRAM ADDR (256K @)
output				ram_oe_n;		// OE_N shared by 2 IC
output				ram_we_n;		//	WE_N shared by 2 IC
inout		[15:0]	ram1_io;			//	I/O data port SRAM1
output				ram1_ce_n;		// SRAM1 CE_N	chip enable
output				ram1_ub_n;		// UB_N	upper byte select
output				ram1_lb_n;		// LB_N  lower byte select
inout		[15:0]	ram2_io;			//	I/O data port SRAM2
output				ram2_ce_n;		// SRAM2 CE_N	chip enable
output				ram2_ub_n;		// UB_N	upper byte select
output				ram2_lb_n;		// LB_N  lower byte select
 
input		[17:0]	addr1;			// port #1 lines
input		[31:0]	data2mem1;
output	[31:0]	data2cpu1;
input					re1;
input					we1;
output				done1;
input		[3:0]		select1;
 
input		[17:0]	addr2;			// port #2 lines
output	[31:0]	data2cpu2;
input					re2;
output				done2;
 
input		[17:0]	addr3;			// port #3 lines
output	[31:0]	data2cpu3;
input					re3;
output				done3;
 
// ----- state machine for arbitrated access ----------
 
wire		p1 = re1 | we1;	// operation requested on each port
wire		p2 = re2;
wire		p3 = re3;
 
reg		op_done1;			// operation completed on each port
reg		op_done2;
reg		op_done3;
 
reg [31:0] data2cpu1;		// register data output to cpu
reg [31:0] data2cpu2;
reg [31:0] data2cpu3;
 
reg [17:0] addr2_cached;	// cache imem address
 
assign	done1 = op_done1;
assign 	done2 = (addr2 == addr2_cached) & op_done2;
assign	done3 = op_done3;
 
//synthesis translate_off
initial begin
	data2cpu1 <= 0;
	data2cpu2 <= 0;
	data2cpu3 <= 0;
end
//synthesis translate_on
 
parameter [3:0] Idle  = 4'b0001,		// different states
					 Port1 = 4'b0010,
					 Port2 = 4'b0100,
					 Port3 = 4'b1000;
 
reg	[3:0] state;			// store different states
wire	[3:0] bytesel;			// byte select for the current operation
 
assign bytesel = (state == Port1) ? select1 : 4'b1111;		// byteselect to the physical ram
 
always @(posedge clk)
begin
	if(rst)						// reinitialite FSM
	begin
		state <= Idle;
		op_done1 <= 0;
		op_done2 <= 0;
		op_done3 <= 0;
   end
	else
	begin
		case(state)				// process FSM
		 Idle : begin					// IDLE
		 		op_done1	<= 0;			// if any request -> fall associate done
				op_done2 <= 0;
				op_done3 <= 0;
				if(p2) 		state   <= Port2;		// PORT2 in progress
				else if(p1) state   <= Port1;		// PORT1 in progress
				else if(p3)	state   <= Port3;		// PORT3 in progress
			   end
 
		 Port1 : begin						// PORT1 completed
		 		data2cpu1 <= { ram1_io, ram2_io };
		 		op_done1 <= 1;
				op_done2 <= 0;
				op_done3 <= 0;
				if(p2)	   state <= Port2;
				else if(p3) state <= Port3;
				else 			state <= Idle;
			  end
 
		 Port2 : begin						// PORT2 completed
		 		data2cpu2 	 <= { ram1_io, ram2_io };
				addr2_cached <= addr2;
				op_done1 <= 0;
				op_done2 <= 1;
				op_done3 <= 0;
				if(p3)		state <= Port3;
				else if(p1) state <= Port1;
				else			state <= Idle;
			  end
 
		 Port3 : begin						// PORT3 completed
		 		data2cpu3 <= { ram1_io, ram2_io };
				op_done1 <= 0;
				op_done2 <= 0;
				op_done3 <= 1;
				if(p1)		state <= Port1;
				else if(p2)	state <= Port2;
				else 			state <= Idle;
			  end
		endcase
	end	// else
end		// always
 
// --------- physical sram interface -----------
 
assign 	ram_oe_n = ~1;					// oe always active (check: power consumption?)
assign 	ram_we_n = ~(state == Port1 & we1);
 
assign	ram1_ce_n = 0;					// chip select enabled
assign	ram1_ub_n = ~bytesel[3];	// upper/lower byte enabled
assign	ram1_lb_n = ~bytesel[2];
 
assign	ram2_ce_n = 0;					// chip select enabled
assign	ram2_ub_n = ~bytesel[1];	// upper/lower byte enabled
assign	ram2_lb_n = ~bytesel[0];
 
assign 	ram_addr	= (state == Port3) ? addr3 :		// address bus
						  (state == Port2) ? addr2 :
						  addr1;
 
wire	[31:0] data2mem = data2mem1;		// only port #1 can write to memory
 
assign ram1_io = ~ram_we_n ? data2mem[31:16] : 16'bZ;		// write port (tristate)
assign ram2_io	= ~ram_we_n ? data2mem[15:0]  : 16'bZ;
 
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.