summaryrefslogtreecommitdiff
path: root/src/main.cc
blob: c69f6a3b5b933688465e196ee4ccd18e3c186c73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#include "logger.h"
#include <getopt.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <functional>

void err()
{
	std::cerr << "Usage:\n\trisc_vector [OPTIONS]\nOptions:\n\t--debug,\t-d: "
				 "turn on verbose output\n\t--no-python,\t-p: run without GUI\n"
			  << std::endl;
}

void parseArguments(int argc, char **argv, Logger &logger, bool &python)
{
	struct option long_options[] = {
		{"debug", no_argument, 0, 'd'},
		{"no-python", no_argument, 0, 'p'},
		{0, 0, 0, 0}};

	python = true;

	int opt;

	while ((opt = getopt_long(argc, argv, "d:p", long_options, NULL)) != -1) {
		switch (opt) {
		case 'd':
			logger.setLevel(DEBUG);
			logger.log(DEBUG, "DEBUG output enabled.");
			break;
		case 'p':
			logger.log(INFO, "Python will NOT be started!");
			python = false;
			break;
		default:
			err();
			exit(EXIT_FAILURE);
		}
	}
}

/**
 * Prints all available commands to the console.
 */
void help() {
    std::cout << "Available commands:\n"
              << "  load <memory-address> <pipeline-stage> - Load data from memory at specified address\n"
              << "  store <memory-address> <pipeline-stage> <data> - Stores data into memory at specified address\n"
              << "  load-memory-image <filename> - side door function that loads a memory image from a file and configures memory to the image\n"
              << "  reset - side door function that resets the memory configuration and cycles\n"
              << "  update-memory <memory-address> <data> - side door function that updates the memory at the specified address with data provided\n"
              << "  view-memory - side door function that views the current status of the entire memory subsystem\n"
              << "  view-memory-address <memory-address> - side door function that views data at specific memory address\n"
              << "  update-controls <configuration-file> - side door function that takes in a configuration file and updates the controls\n"
              << "  exit - Quits the program\n";
}


//TODO: These function stubs are to be improved after they have been implemented internally.

/**
 * Loads data from memory from the specified memory address.
 * @param memory_address address of the memory where data needs to be loaded from
 * @param pipeline_stage pipeline stage to be served by memory subsystem
 */
void load(int memory_address, int pipeline_stage) {
    std::cout << "Loading data from memory address " << memory_address
              << " at pipeline stage " << pipeline_stage << ".\n";
}

/**
 * Stores data into memory at the specified address.
 * @param memory_address address of the memory where data needs to be stored
 * @param pipeline_stage pipeline stage to be served by memory subsystem
 * @param data data value to be written to the memory
 */
void store(int memory_address, int pipeline_stage, int data) {
    std::cout << "Storing " << data << " into memory address " << memory_address
              << " at pipeline stage " << pipeline_stage << ".\n";
}

/**
 * Loads a memory image from a file and configures memory to the image.
 * This function provides a side door memory image loading interface to the memory system,
 * allowing the user to load a memory image from a file and configure the memory subsystem to the image.
 * @param filename name of file containing memory image
 */
void load_memory_image(const std::string& filename) {
    std::cout << "Loading memory image from file: " << filename << ".\n";
}

/**
 * Resets the memory configuration and cycles to their initial state.
 * This function provides a side door reset interface to the memory system,
 * allowing the user to reset the memory configuration directly.
 */
void reset() {
    std::cout << "Resetting memory configuration and cycles.\n";
}

/**
 * Updates the memory at the specified address with the given data.
 * This function provides a side door modification interface to the memory system,
 * allowing the user to modify the memory configuration directly.
 * @param memory_address address of the memory to be updated
 * @param data data value to be written to the memory
 */
void update_memory(int memory_address, int data) {
    std::cout << "Updating memory at address " << memory_address
              << " with data " << data << ".\n";
}

/**
 * Displays the current status of the entire memory subsystem.
 * This function provides a side door view into the memory system, 
 * showing its current state and configuration.
 */
void view_memory() {
    std::cout << "Viewing current status of memory subsystem.\n";
}

/**
 * Displays the data at the specified memory address.
 * This function provides a side door view into the memory system, 
 * showing the data at the specified memory address.
 * @param memory_address address of the memory to be viewed
 */
void view_memory_address(int memory_address) {
    std::cout << "Viewing data at memory address " << memory_address << ".\n";
}

/**
 * Updates the controls using a configuration file.
 * This function provides a side door modification interface to the control system,
 * allowing the user to update the controls directly.
 * @param config_file name of file containing control configuration
 */
void update_controls(const std::string& config_file) {
    std::cout << "Updating controls using configuration file: " << config_file << ".\n";
}


int main(int argc, char **argv)
{
	Logger logger("vector.log");
	logger.log(INFO, "Initializing...");

	bool python = true;
	parseArguments(argc, argv, logger, python);

	if (python) {
		// fork off python here
		;
		logger.log(INFO, "Python started.");
	}

    std::unordered_map<std::string, std::function<void(std::vector<std::string>)>> commands;
    
    commands["load"] = [](std::vector<std::string> args) {
        if (args.size() >= 2){
            try{
                load(std::stoi(args[0]), std::stoi(args[1]));
            } catch(const std::exception &e){
                std::cerr << "Invalid input: " << e.what() << std::endl;
            }
        }
        else {
            std::cout << "Usage: load <memory-address> <pipeline-stage>\n";
        }
        return;
    };

    commands["store"] = [](std::vector<std::string> args) {
        if (args.size() >= 3) {
            try{
                store(std::stoi(args[0]), std::stoi(args[1]), std::stoi(args[2]));
            }catch(const std::exception &e) {
                std::cerr << "Invalid input: " << e.what() << std::endl;
            }
        }
        else {
            std::cout << "Usage: store <memory-address> <pipeline-stage> <data>\n";
        }
        return;
    };

    commands["load-memory-image"] = [](std::vector<std::string> args) {
        if (!args.empty()) {
            load_memory_image(args[0]);
        }
        else {
            std::cout << "Usage: load-memory-image <filename>\n";
        }
        return;
    };

    commands["reset"] = [](std::vector<std::string> args) { 
        reset(); 
        return; 
    };

    commands["update-memory"] = [](std::vector<std::string> args) {
        if (args.size() >= 2) {
            try {
                update_memory(std::stoi(args[0]), std::stoi(args[1]));
            } catch(const std::exception &e){
                std::cerr << "Invalid input: all arguments are integers" << e.what() << std::endl;
            }
        }
        else{
            std::cout << "Usage: update-memory <memory-address> <data>\n";
        }
        return;
    };

    commands["view-memory"] = [](std::vector<std::string> args) { 
        view_memory();
        return;
    };

    commands["view-memory-address"] = [](std::vector<std::string> args) {
        if (!args.empty()) {
            try{
                view_memory_address(std::stoi(args[0]));
            }  catch(const std::exception &e){
                std::cerr << "Invalid input: " << e.what() << std::endl;
            }
        }
        else {
            std::cout << "Usage: view-memory-address <memory-address>\n";
        }
        return;
    };

    commands["update-controls"] = [](std::vector<std::string> args) {
        if (!args.empty()) {
            update_controls(args[0]);
        }
        else {
            std::cout << "Usage: update-controls <configuration-file>\n";
        }
        return;
    };

    commands["help"] = [](std::vector<std::string> args) { 
        help();
        return; 
    };

    std::cout << "Memory Command Processor Started. Type 'help' for a list of commands.\n";

    std::string input;
    while (true) {
        std::cout << "> ";
        std::getline(std::cin, input);
        std::istringstream iss(input);
        std::vector<std::string> tokens;
        std::string word;

        while (iss >> word) tokens.push_back(word);
        if (tokens.empty()) continue;

        std::string command = tokens[0];
        tokens.erase(tokens.begin());

        if (command == "exit") {
            std::cout << "Exiting...\n";
            break;
        }

        auto it = commands.find(command);
        if (it != commands.end()) {
            it->second(tokens);
        } else {
            std::cout << "Unknown command. Type 'help' for available commands.\n";
        }
    }

	return EXIT_SUCCESS;
}