Exemple #1
0
/*
 * Read a numeric value from a pointer, into the value union of a magic
 * pointer, according to the magic type.  Update the string pointer to point
 * just after the number read.  Return 0 for success, non-zero for failure.
 */
static int getvalue(struct magic *m, char **p)
{
    int slen;

    if (m->type == STRING) {
		*p = getstr(*p, m->value.s, sizeof(m->value.s), &slen);
		m->vallen = slen;
    }
    else if (m->reln != 'x')
		m->value.l = signextend(m, strtol(*p, p, 0));
    return 0;
}
Exemple #2
0
int main(int argc, char ** argv)
{
	char * binfilename = NULL;
	char * srcfilename = NULL;
	char * base = NULL;
	int i, cycle;
	bus32 tmp;

	bus8 inst_mem[4096];	/* instruction memory */
	bus8 main_mem[4096];	/* main memory */
	bus32 gnd;				/* ground bus signal */
	bus32 pc;				/* program counter */
	bus32 pc4;				/* PC + 4 bus */
	bus32 ir;				/* instruction register */
	bus32 jmp_addr;		/* jump bus */
	bus32 imm_sext;		/* immediate sign extended bus */
	bus32 imm_shext;		/* immediate sign extended shifted bus */
	bus32 branch_addr;	/* branch bus */
	bus32 mbranch_addr;	/* mbranch bus */

	/* control unit signals */
	wire reg_write, reg_dest;
	wire mem_read, mem_write, mem_toreg;
	wire jump, branch;
	wire alu_src;
	bus3 alu_op;

	/* register memory signals & controls */
	bus32 reg_in, reg_out1, reg_out2;
	bus32 reg_write_addr;

	/* main memory signal */
	bus32 mem_out;
	
	/* alu signals */
	wire zero;
	bus32 alu_src_val, alu_out;

	if (argc == 1) {
		fprintf(stderr, "usage: %s <filename>\n", argv[0]);
		return -1;
	}
	
	srcfilename = argv[1];
	base = _parse_filename(srcfilename);
	if (!base) return -1;
	binfilename = malloc(sizeof(char) * (strlen(base) + 5));
	sprintf(binfilename, "%s.bin", base);

	printf("assembling %s to %s...\n", srcfilename, binfilename);
	if (!Assemble(srcfilename, binfilename)) return -1;

	printf("loading %s into memory...\n", binfilename);
	LoadMemory(binfilename, inst_mem);	


	/* load PC with initial VM address of 0x00000000 */
	setbus32(gnd, "00000000000000000000000000000000");
	setbus32(pc, gnd);

	/* initialize memory */
	InitializeRegisterFileAccess();
	for (i=0; i < 4096; i++) setbus8(main_mem[i], "00000000");

   for(cycle=0; ; cycle++) 
	{
		/* load IR with PC value */
		MemoryAccess(ir, pc, gnd, '0', inst_mem); 

		/* report fetched register values */
		printf("cycle: %d, PC: %.32s (%d), IR: %.32s\n\t", cycle, pc, bus32toint(pc), ir);

		/* halt check */
		if (bus32toint(ir) == 0x0000003F) {
			printf("\nmachine halted\n");
			break;
		}
	
		/* PC + 4 data path */
		RCAdder_32(pc4, gnd, pc, "00000000000000000000000000000100", '0');

		/* jump data path */
		shiftleft2x(jmp_addr, ir);
		jmp_addr[0] = pc4[0];
		jmp_addr[1] = pc4[1];
		jmp_addr[2] = pc4[2];
		jmp_addr[3] = pc4[3];

		/* sign extended / shifted immediate data path */
		signextend(imm_sext, &ir[16]); 
		shiftleft2x(imm_shext, imm_sext); 

		/* control unit data path */
		ControlUnit(ir, &ir[26], &reg_write, &reg_dest,
						&mem_read, &mem_write, &mem_toreg, 
						&jump, &branch, &alu_src, alu_op);

		/* register memory data path - read */
		Mux2_5(reg_write_addr, &ir[11], &ir[16], reg_dest);
		RegisterFileAccess(&reg_out1, &reg_out2, &ir[6], &ir[11], reg_write_addr, reg_in, '0');

		/* alu data path */
		Mux2_32(alu_src_val, reg_out2, imm_sext, alu_src);
		zero = ALU(&alu_out, reg_out1, alu_src_val, alu_op);

		/* branch data path */
		RCAdder_32(branch_addr, gnd, pc4, imm_shext, '0');
		Mux2_32(mbranch_addr, pc4, branch_addr, AND2_1(zero, branch));
		Mux2_32(pc, mbranch_addr, jmp_addr, jump);

		/* main memory data path */
		MemoryAccess(mem_out, alu_out, reg_out2, mem_write, main_mem);
		Mux2_32(reg_in, alu_out, mem_out, mem_toreg);

		/* register memory data path - write */
		RegisterFileAccess(&reg_out1, &reg_out2, &ir[6], &ir[11], reg_write_addr, reg_in, reg_write);

		/* dump register memory and signal information */
		for (i=0; i < 14; i++) {
			inttobusn(i, 5, tmp);
			RegisterFileAccess(&reg_out1, &reg_out2, tmp, &ir[11], reg_write_addr, reg_in, '0');
			printf("R%d: %d, ", i, bus32toint(reg_out1));
		}
		printf("\b\b\n\tbranch_addr = %.32s (%d) jmp_addr = %.32s (%d)\n",
			branch_addr, bus32toint(branch_addr), jmp_addr, bus32toint(jmp_addr));
		printf("\topcode = %.6s, imm_sext = %.32s (%d), imm_shext = %.32s (%d), PC+4 = %.32s (%d)\n",
			ir, imm_sext, bus32toint(imm_sext), imm_shext, bus32toint(imm_shext), pc4, bus32toint(pc4));
		printf("\treg_write = %c, reg_dest = %c, mem_read = %c, mem_write = %c, mem_toreg = %c, jump = %c, branch = %c, alu_src = %c, alu_op = %.3s, zero = %c\n",
			reg_write, reg_dest, mem_read, mem_write, mem_toreg, jump, branch, alu_src, alu_op, zero);
		getchar();
	}

	printf("\ntotal no. cycles: %d\n", cycle);

    // report end of program information

	free(binfilename);
}
Exemple #3
0
/*
 * parse one line from magic file, put into magic[index++] if valid
 */
static int parse(char *l, int lineno)
{
    struct magic *m;
    char *t, *s;
    magic_server_config_rec *conf = &mime_global;
    TSRMLS_FETCH();

    /* allocate magic structure entry */
    m = (struct magic *) calloc(1, sizeof(struct magic));

    /* append to linked list */
    m->next = NULL;
    if (!conf->magic || !conf->last) {
		conf->magic = conf->last = m;
    }
    else {
		conf->last->next = m;
		conf->last = m;
    }

    /* set values in magic structure */
    m->flag = 0;
    m->cont_level = 0;
    m->lineno = lineno;

    while (*l == '>') {
		++l;			/* step over */
		m->cont_level++;
    }

    if (m->cont_level != 0 && *l == '(') {
		++l;			/* step over */
		m->flag |= INDIR;
    }

    /* get offset, then skip over it */
    m->offset = (int) strtol(l, &t, 0);
    if (l == t) {
		if(MIME_MAGIC_G(debug))
			php_error_docref("http://www.php.net/mime_magic" TSRMLS_CC, E_WARNING, ": (%s:%d) offset `%s' invalid", MIME_MAGIC_G(magicfile), lineno, l);
    }
    l = t;

    if (m->flag & INDIR) {
		m->in.type = LONG;
		m->in.offset = 0;
		/*
		 * read [.lbs][+-]nnnnn)
		 */
		if (*l == '.') {
			switch (*++l) {
			case 'l':
				m->in.type = LONG;
				break;
			case 's':
				m->in.type = SHORT;
				break;
			case 'b':
				m->in.type = BYTE;
				break;
			default:
				if(MIME_MAGIC_G(debug))
					php_error_docref("http://www.php.net/mime_magic" TSRMLS_CC, E_WARNING, ": (%s:%d) indirect offset type %c invalid", MIME_MAGIC_G(magicfile), lineno, *l);
				break;
			}
			l++;
		}
		s = l;
		if (*l == '+' || *l == '-')
			l++;
		if (isdigit((unsigned char) *l)) {
			m->in.offset = strtol(l, &t, 0);
			if (*s == '-')
				m->in.offset = -m->in.offset;
		}
		else
			t = l;
		if (*t++ != ')') {
			if(MIME_MAGIC_G(debug))
				php_error_docref("http://www.php.net/mime_magic" TSRMLS_CC, E_WARNING, ": (%s:%d) missing ')' in indirect offset", MIME_MAGIC_G(magicfile), lineno);
		}
		l = t;
    }


    while (isdigit((unsigned char) *l))
		++l;
    EATAB;

#define NBYTE           4
#define NSHORT          5
#define NLONG           4
#define NSTRING         6
#define NDATE           4
#define NBESHORT        7
#define NBELONG         6
#define NBEDATE         6
#define NLESHORT        7
#define NLELONG         6
#define NLEDATE         6

    if (*l == 'u') {
		++l;
		m->flag |= UNSIGNED;
    }

    /* get type, skip it */
    if (strncmp(l, "byte", NBYTE) == 0) {
		m->type = BYTE;
		l += NBYTE;
    }
    else if (strncmp(l, "short", NSHORT) == 0) {
		m->type = SHORT;
		l += NSHORT;
    }
    else if (strncmp(l, "long", NLONG) == 0) {
		m->type = LONG;
		l += NLONG;
    }
    else if (strncmp(l, "string", NSTRING) == 0) {
		m->type = STRING;
		l += NSTRING;
    }
    else if (strncmp(l, "date", NDATE) == 0) {
		m->type = DATE;
		l += NDATE;
    }
    else if (strncmp(l, "beshort", NBESHORT) == 0) {
		m->type = BESHORT;
		l += NBESHORT;
    }
    else if (strncmp(l, "belong", NBELONG) == 0) {
		m->type = BELONG;
		l += NBELONG;
    }
    else if (strncmp(l, "bedate", NBEDATE) == 0) {
		m->type = BEDATE;
		l += NBEDATE;
    }
    else if (strncmp(l, "leshort", NLESHORT) == 0) {
		m->type = LESHORT;
		l += NLESHORT;
    }
    else if (strncmp(l, "lelong", NLELONG) == 0) {
		m->type = LELONG;
		l += NLELONG;
    }
    else if (strncmp(l, "ledate", NLEDATE) == 0) {
		m->type = LEDATE;
		l += NLEDATE;
    }
    else {
		if(MIME_MAGIC_G(debug))
			php_error_docref("http://www.php.net/mime_magic" TSRMLS_CC, E_WARNING, ": (%s:%d) type %s invalid", MIME_MAGIC_G(magicfile), lineno, l);
		return -1;
    }
    /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
    if (*l == '&') {
		++l;
		m->mask = signextend(m, strtol(l, &l, 0));
    }
    else
		m->mask = ~0L;
    EATAB;

    switch (*l) {
    case '>':
    case '<':
		/* Old-style anding: "0 byte &0x80 dynamically linked" */
    case '&':
    case '^':
    case '=':
		m->reln = *l;
		++l;
		break;
    case '!':
		if (m->type != STRING) {
			m->reln = *l;
			++l;
			break;
		}
		/* FALL THROUGH */
    default:
		if (*l == 'x' && isspace((unsigned char) l[1])) {
			m->reln = *l;
			++l;
			goto GetDesc;	/* Bill The Cat */
		}
		m->reln = '=';
		break;
    }
    EATAB;

    if (getvalue(m, &l))
		return -1;
    /*
     * now get last part - the description
     */
 GetDesc:
    EATAB;
    if (l[0] == '\b') {
		++l;
		m->nospflag = 1;
    }
    else if ((l[0] == '\\') && (l[1] == 'b')) {
		++l;
		++l;
		m->nospflag = 1;
    }
    else
		m->nospflag = 0;

	if (!is_valid_mimetype(l, strlen(l))) {
		if(MIME_MAGIC_G(debug))
			php_error_docref("http://www.php.net/mime_magic" TSRMLS_CC, E_WARNING, ": (%s:%d) '%s' is not a valid mimetype, entry skipped", MIME_MAGIC_G(magicfile), lineno, l);
		return -1;
	}
	
	strlcpy(m->desc, l, sizeof(m->desc));
    return 0;
}
Exemple #4
0
static int
mcheck(union VALUETYPE* p, struct magic *m)
{
	register u_int32_t l = m->value.l;
	register u_int32_t v = 0;
	int matched;
	
	if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
		warnx("mcheck: BOINK");
		return (1);
	}
	switch (m->type) {
	case BYTE:
		v = p->b;
		break;
	case SHORT:
	case BESHORT:
	case LESHORT:
		v = p->h;
		break;
	case LONG:
	case BELONG:
	case LELONG:
	case DATE:
	case BEDATE:
	case LEDATE:
		v = p->l;
		break;
	case STRING:
		l = 0;
		/* What we want here is:
		 * v = strncmp(m->value.s, p->s, m->vallen);
		 * but ignoring any nulls.  bcmp doesn't give -/+/0
		 * and isn't universally available anyway.
		 */
		v = 0;
		{
			register u_char *a = (u_char *) m->value.s;
			register u_char *b = (u_char *) p->s;
			register int len = m->vallen;
			
			while (--len >= 0)
				if ((v = *b++ - *a++) != '\0')
					break;
		}
		break;
	default:
		errx(1, "mcheck: invalid type %d", m->type);
		/* NOTREACHED */
	}
	v = signextend(m, v) & m->mask;
	
	switch (m->reln) {
	case 'x':
		matched = 1;
		break;
	case '!':
		matched = v != l;
		break;
	case '=':
		matched = v == l;
		break;
	case '>':
		if (m->flag & UNSIGNED) {
			matched = v > l;
		}
		else matched = (int32_t) v > (int32_t) l;
		break;
	case '<':
		if (m->flag & UNSIGNED) {
			matched = v < l;
		}
		else matched = (int32_t) v < (int32_t) l;
		break;
	case '&':
		matched = (v & l) == l;
		break;
	case '^':
		matched = (v & l) != l;
		break;
	default:
		matched = 0;
		errx(1, "mcheck: can't happen: invalid relation %d", m->reln);
		/* NOTREACHED */
	}
	if (matched && Opt_debug)
		mdump(m);
	
	return (matched);
}
Exemple #5
0
static int
magic_parse(char *p)
{
	struct magic *m;
	char *t, *s;
	int i, j;
	
	if (Magiccnt + 1 > Magicmax)
		errx(1, "magic_parse: magic table full");
	
	m = &Magic[Magiccnt];
	m->flag = 0;
	m->cont_level = 0;

	while (*p == '>') {
		p++;		/* step over */
		m->cont_level++;
	}
	if (m->cont_level != 0 && *p == '(') {
		p++;		/* step over */
		m->flag |= INDIR;
	}
	if (m->cont_level != 0 && *p == '&') {
		p++;		/* step over */
		m->flag |= ADD;
	}
	/* Get offset, then skip over it. */
	m->offset = (int) strtoul(p, &t, 0);
	if (p == t)
		errx(1, "magic_parse: offset %s invalid", p);
	p = t;

	if (m->flag & INDIR) {
		m->in.type = LONG;
		m->in.offset = 0;

		/* read [.lbs][+-]nnnnn) */
		if (*p == '.') {
			p++;
			switch (LOWCASE(*p)) {
			case 'l':
				m->in.type = LONG;
				break;
			case 'h':
			case 's':
				m->in.type = SHORT;
				break;
			case 'c':
			case 'b':
				m->in.type = BYTE;
				break;
			default:
				errx(1, "magic_parse: indirect offset "
				     "type '%c' invalid", *p);
				break;
			}
			p++;
		}
		s = p;
		if (*p == '+' || *p == '-') p++;

		if (isdigit((u_char) *p)) {
			m->in.offset = strtoul(p, &t, 0);
			if (*s == '-') m->in.offset = - m->in.offset;
		}
		else t = p;
		
		if (*t++ != ')')
			errx(1, "magic_parse: missing ')' in indirect offset");
		p = t;
	}

	while (isascii((u_char) *p) && isdigit((u_char) *p)) p++;
	while (isascii((u_char) *p) && isspace((u_char) *p)) p++;

	if (*p == 'u') {
		p++;
		m->flag |= UNSIGNED;
	}
	/* Get type, skip it. */
	t = p;
	for (i = 0; i < 12; i++) {
		j = strlen(Magictypes[i]);
		if (strncmp(p, Magictypes[i], j) == 0) {
			m->type = i + 1;
			p += j;
			break;
		}
	}
	if (p == t)
		errx(1, "magic_parse: type %s invalid", p);
	
	/* New-style and'ing: "0 byte&0x80 =0x80 dynamically linked" */
	if (*p == '&') {
		p++;
		m->mask = signextend(m, strtoul(p, &p, 0));
		eatsize(&p);
	}
	else m->mask = ~0L;

	while (isascii((u_char) *p) && isspace((u_char) *p)) p++;

	switch(*p) {
	case '>':
	case '<':
		/* Old-style and'ing: "0 byte &0x80 dynamically linked" */
	case '&':
	case '^':
	case '=':
		m->reln = *p;
		p++;
		break;
	case '!':
		if (m->type != STRING) {
			m->reln = *p;
			p++;
			break;
		}
		/* FALLTHRU */
	default:
		if (*p == 'x' && isascii((u_char) p[1]) &&
		    isspace((u_char) p[1])) {
			m->reln = *p;
			p++;
			goto parse_get_desc;   /* Bill The Cat */
		}
		m->reln = '=';
		break;
	}
	while (isascii((u_char) *p) && isspace((u_char) *p)) p++;
	
	if (getvalue(m, &p))
		return (0);
	
 parse_get_desc:
	/* Now get last part - the description. */
	while (isascii((u_char) *p) && isspace((u_char) *p)) p++;
	
	strlcpy(m->desc, p, sizeof(m->desc));
	
	if (Opt_debug) {
		mdump(m);
	}
	Magiccnt++;
	return (1);
}
int
sc_main(int argc, char* argv[])
{
	sc_report_handler::
	set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING);

	char stbuf[256];

	// SIGNALS

	// Data signals
	sc_signal< sc_bv<DWORD> >		bus_mux1;
	sc_signal< sc_bv<DWORD> >		bus_mux2;
	sc_signal< sc_bv<DWORD> >		bus_mux3;
	sc_signal< sc_bv<AWORDREG> >		bus_mux4;

	sc_signal< sc_bv<6> >			bus_decoder_instr_31_26;
	sc_signal< sc_bv<AWORDREG> >		bus_decoder_instr_25_21;
	sc_signal< sc_bv<AWORDREG> >		bus_decoder_instr_20_16;
	sc_signal< sc_bv<AWORDREG> >		bus_decoder_instr_15_11;
	sc_signal< sc_bv<SIGNEXTENDBIT> >	bus_decoder_instr_15_0;
	sc_signal< sc_bv<6> >			bus_decoder_instr_5_0;

	sc_signal< sc_bv<DWORD> >		bus_pc;

	sc_signal< sc_bv<DWORD> >		bus_add1;
	sc_signal< sc_bv<DWORD> >		bus_add2;

	sc_signal< sc_bv<DWORD> >		bus_shiftleft;

	sc_signal< sc_bv<DWORD> >		bus_signextend;

	sc_signal< sc_bv<DWORD> >		bus_imem_1;

	sc_signal< sc_bv<DWORD> >		bus_dmem_1;

	sc_signal< sc_bv<DWORD> >		bus_alu_result;
	sc_signal< sc_bv<1> >			bus_alu_zero;

	sc_signal< sc_bv<DWORD> >		bus_registers_1;
	sc_signal< sc_bv<DWORD> >		bus_registers_2;

	// Control signals
	sc_signal< sc_bv<1> >		bus_ctrl_regdst;
	sc_signal< sc_bv<1> >		bus_ctrl_branch;
	sc_signal< sc_bv<1> >		bus_ctrl_memread;
	sc_signal< sc_bv<1> >		bus_ctrl_memtoreg;
	sc_signal< sc_bv<2> >		bus_ctrl_aluop;
	sc_signal< sc_bv<1> >		bus_ctrl_memwrite;
	sc_signal< sc_bv<1> >		bus_ctrl_alusrc;
	sc_signal< sc_bv<1> >		bus_ctrl_regwrite;
	sc_signal< sc_bv<DWORD> >	bus_ctrl_c4;

	sc_signal< sc_bv<3> >		bus_aluctrl;

	sc_signal< sc_bv<1> >		bus_and1;

	// MODULES

	REGISTER	pc("pc");
                            
	ADD		add1("add1");
	ADD		add2("add2");

	AND		and1("and1");

	ROM		imem("instruction_memory");	// Instruction memory
	RAM		dmem("data_memory");		// Data memory

	REGFILE		registers("registers");		// Registerfile

	ALU		alu("alu");
	ALUCTRL		aluctrl("aluctrl");

	SIGNEXTEND	signextend("signextend");

	SHIFTLEFT	shiftleft("shiftleft");

	CTRL		ctrl("ctrl");

	DECODER		decoder("decoder");

	MUX		mux1("mux1");
	MUX		mux2("mux2");
	MUX		mux3("mux3");
	MUX2_AWORDREG	mux4("mux4");

	sc_clock	clk("clock", 20);		// Clock

	// CONNECTIONS

	// Program counter
	pc.in(bus_mux1);
	pc.out(bus_pc);
	pc.w(clk);
	pc.clk(clk);

	// Add 1 (PC + 4)
	add1.a(bus_pc);
	add1.b(bus_ctrl_c4);
	add1.r(bus_add1);

	// Add 2 (add1 + shiftleft)
	add2.a(bus_add1);
	add2.b(bus_shiftleft);
	add2.r(bus_add2);

	// Mux 1 (add1 or add2)
	mux1.in0(bus_add1);
	mux1.in1(bus_add2);
	mux1.sel(bus_and1);
	mux1.out(bus_mux1);

	// Shift left 2
	shiftleft.in(bus_signextend);
	shiftleft.out(bus_shiftleft);

	// Sign extend
	signextend.in(bus_decoder_instr_15_0);
	signextend.out(bus_signextend);

	// Decoder (Select correct part of instruction for registerfile)
	decoder.instr(bus_imem_1);
	decoder.instr_31_26(bus_decoder_instr_31_26);
	decoder.instr_25_21(bus_decoder_instr_25_21);
	decoder.instr_20_16(bus_decoder_instr_20_16);
	decoder.instr_15_11(bus_decoder_instr_15_11);
	decoder.instr_15_0(bus_decoder_instr_15_0);
	decoder.instr_5_0(bus_decoder_instr_5_0);

	// Mux 4 (Select address for write to registerfile)
	mux4.in0(bus_decoder_instr_20_16);
	mux4.in1(bus_decoder_instr_15_11);
	mux4.sel(bus_ctrl_regdst);
	mux4.out(bus_mux4);

	// ALU
	alu.a(bus_registers_1);
	alu.b(bus_mux2);
	alu.r(bus_alu_result);
	alu.z(bus_alu_zero);
	alu.ctrl(bus_aluctrl);

	// Mux 2 (Registerfile or signextend)
	mux2.in0(bus_registers_2);
	mux2.in1(bus_signextend);
	mux2.sel(bus_ctrl_alusrc);
	mux2.out(bus_mux2);

	// ALU ctrl
	aluctrl.ALUop(bus_ctrl_aluop);
	aluctrl.functionCode(bus_decoder_instr_5_0);
	aluctrl.ALUctrl(bus_aluctrl);

	// Mux 3 (ALU result or memory result to register)
	mux3.in0(bus_alu_result);
	mux3.in1(bus_dmem_1);
	mux3.sel(bus_ctrl_memtoreg);
	mux3.out(bus_mux3);

	// AND
	and1.a(bus_alu_zero);
	and1.b(bus_ctrl_branch);
	and1.r(bus_and1);

	// Registerfile
	registers.r_addr_reg1(bus_decoder_instr_25_21);
	registers.r_addr_reg2(bus_decoder_instr_20_16);
	registers.w_addr_reg(bus_mux4);
	registers.r_data_reg1(bus_registers_1);
	registers.r_data_reg2(bus_registers_2);
	registers.w_data_reg(bus_mux3);
	registers.w(bus_ctrl_regwrite);
	registers.clk(clk);

	// Data memory
	dmem.a_read(bus_alu_result);
	dmem.d_read(bus_dmem_1);
	dmem.r(bus_ctrl_memread);
	dmem.a_write(bus_alu_result);
	dmem.d_write(bus_registers_2);
	dmem.w(bus_ctrl_memwrite);
	dmem.clk(clk);

	// Instruction Memory 
	imem.a_read(bus_pc);
	imem.d_read(bus_imem_1);
	imem.clk(clk);

	// Controller
	ctrl.Opcode(bus_decoder_instr_31_26);
	ctrl.RegDst(bus_ctrl_regdst);
	ctrl.Branch(bus_ctrl_branch);
	ctrl.MemRead(bus_ctrl_memread);
	ctrl.MemtoReg(bus_ctrl_memtoreg);
	ctrl.ALUop(bus_ctrl_aluop);
	ctrl.MemWrite(bus_ctrl_memwrite);
	ctrl.ALUSrc(bus_ctrl_alusrc);
	ctrl.RegWrite(bus_ctrl_regwrite);
	ctrl.c4(bus_ctrl_c4);

	// INITIALIZATION

	imem.rom_init("mips.rom"); 
	dmem.ram_init("mips.ram");

	// TRACING

	sc_trace_file* tf;
	tf = sc_create_vcd_trace_file("mips");

	// Signals
	sc_trace(tf, clk,		"clock");
	sc_trace(tf, bus_mux1,			"bus_mux1");
	sc_trace(tf, bus_mux2,			"bus_mux2");
	sc_trace(tf, bus_mux3,			"bus_mux3");
	sc_trace(tf, bus_mux4,			"bus_mux4");
	sc_trace(tf, bus_pc,			"bus_pc");
	sc_trace(tf, bus_add1,			"bus_add1");
	sc_trace(tf, bus_add2,			"bus_add2");
	sc_trace(tf, bus_shiftleft,		"bus_shiftleft");
	sc_trace(tf, bus_signextend,		"bus_signextend");
	sc_trace(tf, bus_imem_1,		"bus_imem_1");
	sc_trace(tf, bus_dmem_1,		"bus_dmem_1");
	sc_trace(tf, bus_alu_result,		"bus_alu_result");
	sc_trace(tf, bus_alu_zero,		"bus_alu_zero");
	sc_trace(tf, bus_registers_1,		"bus_registers_1");
	sc_trace(tf, bus_registers_2,		"bus_registers_2");
	sc_trace(tf, bus_ctrl_regdst,		"bus_ctrl_regdst");
	sc_trace(tf, bus_ctrl_branch,		"bus_ctrl_branch");
	sc_trace(tf, bus_ctrl_memread,		"bus_ctrl_memread");
	sc_trace(tf, bus_ctrl_memtoreg,		"bus_ctrl_memtoreg");
	sc_trace(tf, bus_ctrl_aluop,		"bus_ctrl_aluop");
	sc_trace(tf, bus_ctrl_memwrite,		"bus_ctrl_memwrite");
	sc_trace(tf, bus_ctrl_alusrc,		"bus_ctrl_alusrc");
	sc_trace(tf, bus_ctrl_regwrite,		"bus_ctrl_regwrite");
	sc_trace(tf, bus_ctrl_c4,		"bus_ctrl_c4");
	sc_trace(tf, bus_aluctrl,		"bus_aluctrl");
	sc_trace(tf, bus_and1,			"bus_and1");
	sc_trace(tf, bus_decoder_instr_31_26,	"bus_decoder_instr_31_26");
	sc_trace(tf, bus_decoder_instr_25_21,	"bus_decoder_instr_25_21");
	sc_trace(tf, bus_decoder_instr_20_16,	"bus_decoder_instr_20_16");
	sc_trace(tf, bus_decoder_instr_15_11,	"bus_decoder_instr_15_11");
	sc_trace(tf, bus_decoder_instr_15_0,	"bus_decoder_instr_15_0");
	sc_trace(tf, bus_decoder_instr_5_0,	"bus_decoder_instr_5_0");

	for (int i = 0; i < REGSIZE; i++) {
		sprintf(stbuf, "registers.reg(%d)", i);
		sc_trace(tf, registers.rfile[i], stbuf);
	}

	for (int i = 0; i < RAMSIZE; i++) {
		sprintf(stbuf, "memory.dmem(%d)", i);
		sc_trace(tf, dmem.ramfile[i], stbuf);
	}

	for (int i = 0; i < ROMSIZE; i++) {
		sprintf(stbuf, "memory.imem(%d)", i);
		sc_trace(tf, imem.romfile[i], stbuf);
	}

	// SIMULATION

	int sim_time = 500;
	if (argc == 2)
		sim_time = atoi(argv[1]);

	sc_start(sim_time, SC_NS);

	sc_close_vcd_trace_file(tf);
	dmem.ram_dump("mips_ram.dump");

	return 0;
}