`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    04:21:13 07/06/2007 
// Design Name: 
// Module Name:    memadap 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////



// mem_adaptor_r zum Lesen vom Speicher


module mem_adaptor_be_r (doutbus, abus, enbus, ssrbus, read_ack,
							dinmem, amem, enmem, ssrmem, type, clk);

output[31:0] doutbus;
reg[31:0] doutbus;

input[31:0] abus;

input enbus;
input ssrbus;

output read_ack;

input[31:0] dinmem;

output[31:0] amem;

output[3:0] enmem;
reg[3:0] enmem;

output[3:0] ssrmem;
reg[3:0] ssrmem;


input[1:0] type;

input clk;

wire[1:0] arest_o;
reg[1:0] arest;
	

reg enbus_1;

assign arest_o = abus[1:0];

reg[1:0] type_o;

assign amem = {abus[31:2], 2'b0};


// arest_o is actual arest, arest is old arest

initial begin
	type_o = 2'b00;
end

always @(posedge clk)
	begin
		if (enbus)
			begin
				arest <= arest_o;
			end
		type_o <= type;
	end

// enbus_1 is one clock delayed enbus
	
always @(posedge clk)
	begin
		enbus_1 <= enbus; 
	end
	
assign read_ack = enbus_1;	

always @(enbus or ssrbus or type or arest_o)
	begin
		case (type)
			2'b00: begin
				enmem = {4{enbus}};
				ssrmem = {4{ssrbus}};
			end
			2'b01: begin
				case (arest_o)
					2'b00: begin
						enmem = {2'b0, enbus, enbus};
						ssrmem = {2'b0, ssrbus, ssrbus};
					end
					default: begin
						enmem = {enbus, enbus, 2'b0};
						ssrmem = {ssrbus, ssrbus, 2'b0};
					end
				endcase
			end
			2'b10: begin
				case (arest_o)
					2'b00: begin
						enmem = {2'b0, enbus, enbus};
						ssrmem = {2'b0, ssrbus, ssrbus};
					end
					default: begin
						enmem = {enbus, enbus, 2'b0};
						ssrmem = {ssrbus, ssrbus, 2'b0};
					end
				endcase
			end
			default: begin
//				$displayh ( arest );
				case (arest_o)
					2'b00: begin
						enmem = {3'b0, enbus};
						ssrmem = {3'b0, ssrbus};
					end
					2'b01: begin
						enmem = {2'b0, enbus, 1'b0};
						ssrmem = {2'b0, ssrbus, 1'b0};
					end
					2'b10: begin
						enmem = {1'b0, enbus, 2'b0};
						ssrmem = {1'b0, ssrbus, 2'b0};
					end
					default: begin
						enmem = {enbus, 3'b0};
						ssrmem = {ssrbus, 3'b0};
					end
				endcase
			end
		endcase
	end
	
always @(dinmem or arest or type_o)
	begin
		case (type_o)
			2'b00: begin
				doutbus = {dinmem[7:0],dinmem[15:8],dinmem[23:16],dinmem[31:24]};
//				$display ( "doutbus = %h, dinmem = %h", doutbus, dinmem );
			end
			2'b01, 2'b10: begin
				case (arest)
					2'b00: begin
						doutbus = {16'b0,dinmem[7:0],dinmem[15:8]};
					end
					default: begin
						doutbus = {16'b0,dinmem[23:16],dinmem[31:24]};
					end
				endcase
			end
			default: begin
//				$displayh ( arest );
				case (arest)
					2'b00: begin
						doutbus = {24'b0,dinmem[7:0]};
					end
					2'b01: begin
						doutbus = {24'b0,dinmem[15:8]};
					end
					2'b10: begin
						doutbus = {24'b0,dinmem[23:16]};
					end
					default: begin
						doutbus = {24'b0,dinmem[31:24]};
					end
				endcase
			end
		endcase
	end

endmodule

// mem_adaptor_w zum Schreiben in den Speicher


module mem_adaptor_be_w (dinbus, abus, enbus, webus, ssrbus,
							doutmem, amem, enmem, wemem, ssrmem, type);

input[31:0] dinbus;

input[31:0] abus;

input enbus;
input webus;
input ssrbus;

output[31:0] doutmem;
reg[31:0] doutmem;

output[31:0] amem;

output[3:0] enmem;
reg[3:0] enmem;

output[3:0] wemem;
reg[3:0] wemem;

output[3:0] ssrmem;
reg[3:0] ssrmem;

input[1:0] type;

wire[1:0] arest;
	
assign arest = abus[1:0];

assign amem = {abus[31:2], 2'b0};



always @(dinbus or enbus or webus or ssrbus or type or arest)
	begin
		case (type)
			2'b00: begin
				doutmem = {dinbus[7:0],dinbus[15:8],dinbus[23:16],dinbus[31:24]};
				enmem = {4{enbus}};
				wemem = {4{webus}};
				ssrmem = {4{ssrbus}};
			end
			2'b01, 2'b10: begin
				case (arest)
					2'b00: begin
						doutmem = {16'b0,dinbus[7:0],dinbus[15:8]};
						enmem = {2'b0, enbus, enbus};
						wemem = {2'b0, webus, webus};
						ssrmem = {2'b0, ssrbus, ssrbus};
					end
					default: begin
						doutmem = {dinbus[7:0],dinbus[15:8],16'b0};
						enmem = {enbus, enbus, 2'b0};
						wemem = {webus, webus, 2'b0};
						ssrmem = {ssrbus, ssrbus, 2'b0};
					end
				endcase
			end
			default: begin
				case (arest)
					2'b00: begin
						doutmem = {24'b0,dinbus[7:0]};
						enmem = {3'b0, enbus};
						wemem = {3'b0, webus};
						ssrmem = {3'b0, ssrbus};
					end
					2'b01: begin
						doutmem = {16'b0,dinbus[7:0],8'b0};
						enmem = {2'b0, enbus, 1'b0};
						wemem = {2'b0, webus, 1'b0};
						ssrmem = {2'b0, ssrbus, 1'b0};
					end
					2'b10: begin
						doutmem = {8'b0,dinbus[7:0],16'b0};
						enmem = {1'b0, enbus, 2'b0};
						wemem = {1'b0, webus, 2'b0};
						ssrmem = {1'b0, ssrbus, 2'b0};
					end
					default: begin
						doutmem = {dinbus[7:0],24'b0};
						enmem = {enbus, 3'b0};
						wemem = {webus, 3'b0};
						ssrmem = {ssrbus, 3'b0};
					end
				endcase
			end
		endcase
	end

endmodule


