// Copyright 2000 UCR all rights reserved // this program may be copy or altered so // long as this header stays intake // Original design Randy January rjanuary@cs.ucr.edu /* main.cc Randy January file description: Assembler for simple CPU */ #include #include #include void makeBinary(int, int); ofstream outfile; int main(int arg, char *argv[]) { char command[80]; int cnt = -1; int imm; char operand[18]; int i = 0; int reg; if (arg != 2) { cerr << "Usage: assemble "; exit(-1); } else { ifstream infile (argv[1], ios::in); if (!infile) { cerr << "Error opening " << argv[1] << endl; exit(-1); } outfile.open("scpu_rom.vhd", ios::out); while(infile) { infile >> command; if (strcmp(command, "loadi") == 0) { cnt += 1; } else if(strcmp(command, "add") == 0) { cnt += 1; } else if (strcmp(command, "sub") == 0) { cnt += 1; } else if(strcmp(command, "xor") == 0) { cnt += 1; } else if(strcmp(command, "and") == 0) { cnt += 1; } else if(strcmp(command, "or") == 0) { cnt += 1; } else if(strcmp(command, "shl") == 0) { cnt += 1; } else if(strcmp(command, "shr") == 0) { cnt += 1; } else if(strcmp(command, "jnz") == 0) { cnt += 1; } else if(strcmp(command, "jlz") == 0) { cnt += 1; } else if(strcmp(command, "store") == 0) { cnt += 1; } else if(strcmp(command, "loadm") == 0) { cnt += 1; } else if(strcmp(command, "mult") == 0) { cnt += 6; } else if(strcmp(command, "div") == 0) { cnt += 0; } else if(strcmp(command, "comp") == 0) { cnt += 0; } else if(strcmp(command, "equal") == 0) { cnt += 0; } else if (strcmp(command, "halt") == 0) { cnt += 1; } } outfile << "library IEEE;" << endl << "use IEEE.STD_LOGIC_1164.all;" << endl << "use IEEE.STD_LOGIC_ARITH.all;" << endl << "use WORK.SCPU_LIB.all;" << endl << endl << "entity scpu_rom is" << endl << "\tport (" << endl << "\t\trst : in std_logic;" << endl << "\t\tclk : in std_logic;" << endl << "\t\taddress : in integer;" << endl << "\t\tcommand : out unsigned (31 downto 0)" << endl << "\t\t);" << endl << "end scpu_rom;" << endl << "architecture beh of scpu_rom is" << endl << "--************************************************" << endl << "type ROM is array (0 to " << cnt << ") of unsigned (31 downto 0);" << endl << "constant program : ROM := (" << endl; infile.close(); infile.open(argv[1], ios::in); cnt = 0; while(infile) { infile >> command; if (strcmp(command, "loadi") == 0) { outfile << "\"00000"; infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); i = 17; infile >> imm; makeBinary(imm, i); outfile << "\"," << endl; cnt += 1; } else if(strcmp(command, "add") == 0) { outfile << "\"00001"; for (int j = 0; j < 3; j++) { infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); } outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "sub") == 0) { outfile << "\"00010"; for (int j = 0; j < 3; j++) { infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); } outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "xor") == 0) { outfile << "\"00011"; for (int j = 0; j < 3; j++) { infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); } outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "and") == 0) { outfile << "\"00100"; for (int j = 0; j < 3; j++) { infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); } outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "shr") == 0) { outfile << "\"00101"; infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); outfile << "000000000000000000\"," << endl; cnt += 1; } else if (strcmp(command, "shl") == 0) { outfile << "\"00110"; infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); outfile << "000000000000000000\"," << endl; cnt += 1; } else if (strcmp(command, "or") == 0) { outfile << "\"00111"; for (int j = 0; j < 3; j++) { infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); } outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "jlz") == 0) { outfile << "\"01000"; outfile << "000000000"; infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); i = 8; infile >> imm; makeBinary(imm, i); outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "jnz") == 0) { outfile << "\"01001"; outfile << "000000000"; infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); i = 8; infile >> imm; makeBinary(imm, i); outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "store") == 0) { outfile << "\"01010"; infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); outfile << "000000000"; i = 8; infile >> imm; makeBinary(imm, i); outfile << "\"," << endl; cnt += 1; } else if (strcmp(command, "loadm") == 0) { outfile << "\"01011"; infile.getline(operand, 80, 'R'); infile >> reg; i = 8; makeBinary(reg, i); i = 8; infile >> imm; makeBinary(imm, i); outfile << "000000000\"," << endl; cnt += 1; } else if (strcmp(command, "halt") == 0) { outfile << "\"11111000000000000000000000000000\"" << endl; } } outfile << ");" << endl; outfile << "--********************************************************" << endl << endl << "begin" << endl << "\tprocess(rst, clk, address)" << endl << "\t\tbegin" << endl << "\t\t\tif (rst = '1') then" << endl << "\t\t\t\tcommand <= CD_32;" << endl << "\t\telsif (clk'event and clk = '1') then" << endl << "\t\t\t\tcommand <= program(address);" << endl << "\t\t\tend if;" << endl << "\t\tend process;" << endl << "end beh;" << endl; infile.close(); outfile.close(); } } void makeBinary(int value, int size) { int binary[18]; int i; i = size; while (value != 0) { if ((value + 1)/2 > value/2) { binary[i] = 1; } else { binary[i] = 0; } i--; value = value/2; } while (i >= 0) { binary[i] = 0; i--; } i = 0; while (i < size + 1) { outfile << binary[i]; i++; } }