data/full_repos/permissive/417465579/firmware/rev0.1/ram_8mb.v
data/verilator_xmls/a1450838-8be7-4652-9439-98fc68a46a7a.xml
module ram_8mb( cpu_a, cpu_d, cpu_nas,cpu_nlds,cpu_nuds,cpu_clk, cpu_rw, cpu_nreset,
                dram_nras, dram_nlcas, dram_nucas, dram_ma, dram_wrn, dram_oen,
					 configured
  				  );

	input [23:1] cpu_a;

	inout [3:0] cpu_d;
	reg   [3:0] cpu_d;

	input cpu_nas,cpu_nlds,cpu_nuds;
	input cpu_clk;
   input cpu_rw;
	
	input cpu_nreset;

	output dram_nras;
	reg    dram_nras;

	output dram_nlcas,dram_nucas;
	reg    dram_nlcas,dram_nucas;

	output [11:0] dram_ma;
	reg    [11:0] dram_ma;

	output dram_wrn;


	output dram_oen;
		
	output configured;


	reg    mux_switch;

	reg  [3:0] datout;

	wire [7:0] high_addr;
	wire [5:0] low_addr;


	reg mem_selected;

	reg rfsh_ras,rfsh_cas;

	reg access_ras,access_cas;

	reg read_cycle;
	reg write_cycle;
	
	reg autoconf_on;
	reg cpu_nas_z;

	reg [1:0] rfsh_select;

	reg mode_8mb = 1, mode_4mb = 0, mode_slow = 0, mode_slow4mb = 0;


	assign high_addr = cpu_a[23:16];
	assign low_addr  = cpu_a[6:1];
	



	always @*
	begin


		mem_selected = 1'b0;
		
		
		casex( high_addr )

		8'b001xxxxx:
		begin
			if( mode_8mb==1'b1 || mode_4mb==1'b1 || mode_slow4mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end

		8'b010xxxxx:
		begin
			if( mode_8mb==1'b1 || mode_4mb==1'b1 || mode_slow4mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end
		
		8'b011xxxxx:
		begin
			if( mode_8mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end
		
		8'b100xxxxx:
		begin
			if( mode_8mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end

		8'b110xxxxx:
		begin
			if( (mode_slow==1'b1 || mode_slow4mb==1'b1) && ( high_addr[4:3]==2'b00 || high_addr[4:3]==2'b01 || high_addr[4:3]==2'b10 ) )
			begin

				mem_selected = 1'b1;
			end
		end
		
		default: begin end
		
		endcase
	end



	always @(posedge cpu_clk,posedge cpu_nas)
	begin
		if( cpu_nas==1 )
		begin
			access_ras <= 0;
			access_cas <= 0;
		end
		else
		begin
			access_ras <= 1;
			access_cas <= access_ras;
		end
	end





	always @(negedge cpu_clk)
	begin
		if( cpu_nas==1 )
		begin
			rfsh_cas <= ~rfsh_cas;
		end
		else
		begin
			rfsh_cas <= 0;
		end

		if( (rfsh_cas == 1'b0) && (cpu_nas==1) )
		begin
			rfsh_select <= rfsh_select + 2'b01;
		end
	end

	always @*
	begin
		rfsh_ras <= rfsh_cas & cpu_clk;
	end




	always @*
	begin
		dram_nras <= ~( ( access_ras ) | ((rfsh_select==2'b00)?rfsh_ras:1'b0) );





		dram_nlcas <= ~( ( ~cpu_nlds & access_cas & mem_selected ) | rfsh_cas );
		dram_nucas <= ~( ( ~cpu_nuds & access_cas & mem_selected ) | rfsh_cas );
	end







	always @(negedge cpu_clk,negedge access_ras)
	begin
		if( access_ras==0 )
		begin
			mux_switch <= 0;
		end
		else
		begin
			mux_switch <= 1;
		end
	end


	always @*
	begin
		if( mux_switch==0 )
			dram_ma[11:0] <= cpu_a[22:11];
		else
		 begin
			dram_ma[9:0] <= cpu_a[10:1];
			dram_ma[11:10] <= 2'b00;
		 end	
	end






	always @(posedge cpu_clk)
	begin
		cpu_nas_z <= cpu_nas;
	end


	always @(posedge cpu_clk, posedge cpu_nas)
	begin
		if( cpu_nas==1 )
		begin
			read_cycle  <= 0;
			write_cycle <= 0;
		end
		else
		begin
			if( cpu_nas==0 && cpu_nas_z==1 )
			begin
				if( (cpu_nlds&cpu_nuds)==0 )
					read_cycle <= 1;
				else
					write_cycle <= 1;
			end
		end
	end


	always @*
	begin
		case( low_addr )
		6'b000000:
			datout <= 4'b1110;
		6'b000001:
			begin
				if( mode_8mb==1'b1 )
					datout <= 4'b0000;
				else if( mode_4mb==1'b1 || mode_slow4mb==1'b1 )
					datout <= 4'b0111;
				else datout <= 4'bxxxx;

			end

		6'b000010:
			datout <= 4'hE;
		6'b000011:
			datout <= 4'hE;

		6'b000100:
			datout <= 4'h3;
		6'b000101:
			datout <= 4'hf;

		6'b001000:
			datout <= 4'hE;
		6'b001001:
			datout <= 4'hE;

		6'b001010:
			datout <= 4'he;
		6'b001011:
			datout <= 4'he;

		6'b100000:
			datout <= 4'b0000;
		6'b100001:
			datout <= 4'b0000;

		default:
			datout <= 4'b1111;
		endcase
	end


	always @*
	begin
		if( read_cycle==1 && high_addr==8'hE8 && autoconf_on==1 && (mode_8mb==1'b1 || mode_4mb==1'b1 || mode_slow4mb==1'b1) )
			cpu_d[3:0] <= datout;
		else
			cpu_d[3:0] <= 4'bZZZZ;
	end


	always @(posedge write_cycle,negedge cpu_nreset)
	begin
		if( cpu_nreset==0 )
			autoconf_on <= 1;
		else
		begin
			if( high_addr==8'hE8 && low_addr[5:2]==4'b1001 )
				autoconf_on <= 0;
		end
	end

	
	assign dram_wrn = cpu_rw | (~mem_selected);
	assign configured = ~autoconf_on;
	assign dram_oen = autoconf_on;


endmodule
module ram_8mb( cpu_a, cpu_d, cpu_nas,cpu_nlds,cpu_nuds,cpu_clk, cpu_rw, cpu_nreset,
                dram_nras, dram_nlcas, dram_nucas, dram_ma, dram_wrn, dram_oen,
					 configured
  				  );


	input [23:1] cpu_a;

	inout [3:0] cpu_d;
	reg   [3:0] cpu_d;

	input cpu_nas,cpu_nlds,cpu_nuds;
	input cpu_clk;
   input cpu_rw;
	
	input cpu_nreset;

	output dram_nras;
	reg    dram_nras;

	output dram_nlcas,dram_nucas;
	reg    dram_nlcas,dram_nucas;

	output [11:0] dram_ma;
	reg    [11:0] dram_ma;

	output dram_wrn;


	output dram_oen;
		
	output configured;


	reg    mux_switch;

	reg  [3:0] datout;

	wire [7:0] high_addr;
	wire [5:0] low_addr;


	reg mem_selected;

	reg rfsh_ras,rfsh_cas;

	reg access_ras,access_cas;

	reg read_cycle;
	reg write_cycle;
	
	reg autoconf_on;
	reg cpu_nas_z;

	reg [1:0] rfsh_select;

	reg mode_8mb = 1, mode_4mb = 0, mode_slow = 0, mode_slow4mb = 0;


	assign high_addr = cpu_a[23:16];
	assign low_addr  = cpu_a[6:1];
	



	always @*
	begin


		mem_selected = 1'b0;
		
		
		casex( high_addr )

		8'b001xxxxx:
		begin
			if( mode_8mb==1'b1 || mode_4mb==1'b1 || mode_slow4mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end

		8'b010xxxxx:
		begin
			if( mode_8mb==1'b1 || mode_4mb==1'b1 || mode_slow4mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end
		
		8'b011xxxxx:
		begin
			if( mode_8mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end
		
		8'b100xxxxx:
		begin
			if( mode_8mb==1'b1 )
			begin

				mem_selected = 1'b1;
			end
		end

		8'b110xxxxx:
		begin
			if( (mode_slow==1'b1 || mode_slow4mb==1'b1) && ( high_addr[4:3]==2'b00 || high_addr[4:3]==2'b01 || high_addr[4:3]==2'b10 ) )
			begin

				mem_selected = 1'b1;
			end
		end
		
		default: begin end
		
		endcase
	end



	always @(posedge cpu_clk,posedge cpu_nas)
	begin
		if( cpu_nas==1 )
		begin
			access_ras <= 0;
			access_cas <= 0;
		end
		else
		begin
			access_ras <= 1;
			access_cas <= access_ras;
		end
	end





	always @(negedge cpu_clk)
	begin
		if( cpu_nas==1 )
		begin
			rfsh_cas <= ~rfsh_cas;
		end
		else
		begin
			rfsh_cas <= 0;
		end

		if( (rfsh_cas == 1'b0) && (cpu_nas==1) )
		begin
			rfsh_select <= rfsh_select + 2'b01;
		end
	end

	always @*
	begin
		rfsh_ras <= rfsh_cas & cpu_clk;
	end




	always @*
	begin
		dram_nras <= ~( ( access_ras ) | ((rfsh_select==2'b00)?rfsh_ras:1'b0) );





		dram_nlcas <= ~( ( ~cpu_nlds & access_cas & mem_selected ) | rfsh_cas );
		dram_nucas <= ~( ( ~cpu_nuds & access_cas & mem_selected ) | rfsh_cas );
	end







	always @(negedge cpu_clk,negedge access_ras)
	begin
		if( access_ras==0 )
		begin
			mux_switch <= 0;
		end
		else
		begin
			mux_switch <= 1;
		end
	end


	always @*
	begin
		if( mux_switch==0 )
			dram_ma[11:0] <= cpu_a[22:11];
		else
		 begin
			dram_ma[9:0] <= cpu_a[10:1];
			dram_ma[11:10] <= 2'b00;
		 end	
	end






	always @(posedge cpu_clk)
	begin
		cpu_nas_z <= cpu_nas;
	end


	always @(posedge cpu_clk, posedge cpu_nas)
	begin
		if( cpu_nas==1 )
		begin
			read_cycle  <= 0;
			write_cycle <= 0;
		end
		else
		begin
			if( cpu_nas==0 && cpu_nas_z==1 )
			begin
				if( (cpu_nlds&cpu_nuds)==0 )
					read_cycle <= 1;
				else
					write_cycle <= 1;
			end
		end
	end


	always @*
	begin
		case( low_addr )
		6'b000000:
			datout <= 4'b1110;
		6'b000001:
			begin
				if( mode_8mb==1'b1 )
					datout <= 4'b0000;
				else if( mode_4mb==1'b1 || mode_slow4mb==1'b1 )
					datout <= 4'b0111;
				else datout <= 4'bxxxx;

			end

		6'b000010:
			datout <= 4'hE;
		6'b000011:
			datout <= 4'hE;

		6'b000100:
			datout <= 4'h3;
		6'b000101:
			datout <= 4'hf;

		6'b001000:
			datout <= 4'hE;
		6'b001001:
			datout <= 4'hE;

		6'b001010:
			datout <= 4'he;
		6'b001011:
			datout <= 4'he;

		6'b100000:
			datout <= 4'b0000;
		6'b100001:
			datout <= 4'b0000;

		default:
			datout <= 4'b1111;
		endcase
	end


	always @*
	begin
		if( read_cycle==1 && high_addr==8'hE8 && autoconf_on==1 && (mode_8mb==1'b1 || mode_4mb==1'b1 || mode_slow4mb==1'b1) )
			cpu_d[3:0] <= datout;
		else
			cpu_d[3:0] <= 4'bZZZZ;
	end


	always @(posedge write_cycle,negedge cpu_nreset)
	begin
		if( cpu_nreset==0 )
			autoconf_on <= 1;
		else
		begin
			if( high_addr==8'hE8 && low_addr[5:2]==4'b1001 )
				autoconf_on <= 0;
		end
	end

	
	assign dram_wrn = cpu_rw | (~mem_selected);
	assign configured = ~autoconf_on;
	assign dram_oen = autoconf_on;


endmodule