Пример #1
0
int dram_system_get_request(struct dram_system_t *system)
{
	unsigned int logical_channel_id;

	struct dram_controller_t *controller;

	struct dram_request_t *request;
	request = list_get(system->dram_request_list, 0);
	/* Do nothing if no request is passed */
	if (!request)
		return 0;


	/* Decode request address */
	dram_decode_address(system, request->addr, &logical_channel_id,
			NULL, NULL, NULL, NULL, NULL);

	/* Send request to the request queue*/
	/* return 0 if request queue cannot take any request at this moment */
	controller = list_get(system->dram_controller_list, logical_channel_id);
	if (!dram_controller_get_request(controller, request))
		return 0;

	/* Return */
	return 1;
}
Пример #2
0
int dram_controller_get_request(struct dram_controller_t *controller, struct dram_request_t *request)
{
	int i;
	unsigned int rank_id, bank_id, physical_channel_id;
	struct dram_bank_info_t *info;

	/* Do nothing if pointer is not passed*/
	if (!request || !controller)
		return 0;

	/* Decode address*/
	dram_decode_address(request->system, request->addr,
			NULL, &rank_id, NULL, &bank_id, NULL, &physical_channel_id);

	/* Locate bank info */
	i = (physical_channel_id) * (controller->dram_num_ranks) * (controller->dram_num_banks_per_device) + (rank_id) * (controller->dram_num_banks_per_device) + (bank_id);
	info = list_get(controller->dram_bank_info_list, i);
	list_add(info->request_queue, request);

	return 1;
}
Пример #3
0
void dram_controller_process_request(struct dram_controller_t *controller)
{
	int i;
	unsigned int num_bank_info;
	unsigned int row_id, column_id;
	struct dram_request_t *request;
	struct dram_bank_info_t *info;
	struct dram_command_t *command_precharge;
	struct dram_command_t *command_activate;
	struct dram_command_t *command_access;

	/* Go through bank info list */
	num_bank_info = list_count(controller->dram_bank_info_list);
	for (i = 0; i < num_bank_info; i++)
	{
		/* Locate bank info */
		info = list_get(controller->dram_bank_info_list, i);

		/* Fetch a request from request queue */
		request = list_dequeue(info->request_queue);

		if (request)
		{
			dram_decode_address(request->system, request->addr, NULL, NULL,
						&row_id, NULL, &column_id, NULL);

			/* Determine policy to be used */
			switch (controller->rb_policy)
			{

				/* Open page row buffer policy */
				case open_page_row_buffer_policy:

					/* Row hit */
					if (info->row_buffer_valid && info->active_row_id == row_id)
					{
						/* Create single read/write command */
						command_access = dram_command_create();

						command_access->dram = list_get(controller->dram_list, info->channel_id);
						if (request->type == request_type_read)
						{
							command_access->type = dram_command_read;
							command_access->u.read.rank_id = info->rank_id;
							command_access->u.read.bank_id = info->bank_id;
							command_access->u.read.column_id = column_id;
						}
						else if (request->type == request_type_write)
						{
							command_access->type = dram_command_write;
							command_access->u.write.rank_id = info->rank_id;
							command_access->u.write.bank_id = info->bank_id;
							command_access->u.write.column_id = column_id;
						}

						/* Append command to queue */
						list_add(info->command_queue, command_access);
					}
					/* Row miss - different row was activated */
					else if (info->row_buffer_valid)
					{
						/* Create pre, act, rd/wr three commands */
						command_precharge = dram_command_create();
						command_activate = dram_command_create();
						command_access = dram_command_create();

						/* Precharge */
						command_precharge->type = dram_command_precharge;
						command_precharge->dram = list_get(controller->dram_list, info->channel_id);
						command_precharge->u.precharge.rank_id = info->rank_id;
						command_precharge->u.precharge.bank_id = info->bank_id;

						/* Activate */
						command_activate->type = dram_command_activate;
						command_activate->dram = list_get(controller->dram_list, info->channel_id);
						command_activate->u.activate.rank_id = info->rank_id;
						command_activate->u.activate.bank_id = info->bank_id;
						command_activate->u.activate.row_id = row_id;

						/* Access */
						command_access->dram = list_get(controller->dram_list, info->channel_id);
						if (request->type == request_type_read)
						{
							command_access->type = dram_command_read;
							command_access->u.read.rank_id = info->rank_id;
							command_access->u.read.bank_id = info->bank_id;
							command_access->u.read.column_id = column_id;
						}
						else if (request->type == request_type_write)
						{
							command_access->type = dram_command_write;
							command_access->u.write.rank_id = info->rank_id;
							command_access->u.write.bank_id = info->bank_id;
							command_access->u.write.column_id = column_id;
						}

						list_add(info->command_queue, command_precharge);
						list_add(info->command_queue, command_activate);
						list_add(info->command_queue, command_access);

						/* Update the active row status */
						info->active_row_id = row_id;
					}
					/* Row miss - no row was activated */
					else
					{
						/* Create act, rd/wr two commands */
						command_activate = dram_command_create();
						command_access = dram_command_create();

						/* Activate */
						command_activate->type = dram_command_activate;
						command_activate->dram = list_get(controller->dram_list, info->channel_id);
						command_activate->u.activate.rank_id = info->rank_id;
						command_activate->u.activate.bank_id = info->bank_id;
						command_activate->u.activate.row_id = row_id;

						/* Access */
						command_access->dram = list_get(controller->dram_list, info->channel_id);
						if (request->type == request_type_read)
						{
							command_access->type = dram_command_read;
							command_access->u.read.rank_id = info->rank_id;
							command_access->u.read.bank_id = info->bank_id;
							command_access->u.read.column_id = column_id;
						}
						else if (request->type == request_type_write)
						{
							command_access->type = dram_command_write;
							command_access->u.write.rank_id = info->rank_id;
							command_access->u.write.bank_id = info->bank_id;
							command_access->u.write.column_id = column_id;
						}

						list_add(info->command_queue, command_activate);
						list_add(info->command_queue, command_access);

						/* Update the active row status */
						info->row_buffer_valid = 1;
						info->active_row_id = row_id;
					}

					break;

				/* Close page row buffer policy */
				case close_page_row_buffer_policy:

					/* Create act, rd/wr, pre three commands */
					command_activate = dram_command_create();
					command_access = dram_command_create();
					command_precharge = dram_command_create();

					/* Activate */
					command_activate->type = dram_command_activate;
					command_activate->dram = list_get(controller->dram_list, info->channel_id);
					command_activate->u.activate.rank_id = info->rank_id;
					command_activate->u.activate.bank_id = info->bank_id;
					command_activate->u.activate.row_id = row_id;

					/* Access */
					command_access->dram = list_get(controller->dram_list, info->channel_id);
					if (request->type == request_type_read)
					{
						command_access->type = dram_command_read;
						command_access->u.read.rank_id = info->rank_id;
						command_access->u.read.bank_id = info->bank_id;
						command_access->u.read.column_id = column_id;
					}
					else if (request->type == request_type_write)
					{
						command_access->type = dram_command_write;
						command_access->u.write.rank_id = info->rank_id;
						command_access->u.write.bank_id = info->bank_id;
						command_access->u.write.column_id = column_id;
					}

					/* Precharge */
					command_precharge->type = dram_command_precharge;
					command_precharge->dram = list_get(controller->dram_list, info->channel_id);
					command_precharge->u.precharge.rank_id = info->rank_id;
					command_precharge->u.precharge.bank_id = info->bank_id;

					list_add(info->command_queue, command_activate);
					list_add(info->command_queue, command_access);
					list_add(info->command_queue, command_precharge);

					/* Update the active row status */
					info->row_buffer_valid = 0;

					break;

				case hybird_page_row_buffer_policy:

			
					break;

				default:

					break;

			}

			dram_request_free(request);
		}
	}
}