Code:
#include "spimcore.h"
int i = 0;
/* ALU */
void ALU(unsigned A,unsigned B,char ALUControl,unsigned *ALUresult,char *Zero)
{
if(ALUControl == 0)
{
*ALUresult = (A + B);
}
else if(ALUControl == 1)
{
*ALUresult = (A - B);
}
else if(ALUControl == 2)
{
if(A < B)
{
*ALUresult = 1;
}
else
{
*ALUresult = 0;
}
}
else if(ALUControl == 3)
{
if((A >= 0) && (B >= 0))
{
*ALUresult = 1;
}
else
{
*ALUresult = 0;
}
}
else if(ALUControl == 4)
{
*ALUresult = (A & B);
}
else if(ALUControl == 5)
{
*ALUresult = (A | B);
}
else if(ALUControl == 6)
{
B = B * 65536;
*Zero = 0;
}
else
{
*ALUresult = (!(A | B));
}
if(*ALUresult == 0)
{
*Zero = 1;
}
else
{
*Zero = 0;
}
}
/* instruction fetch */
int instruction_fetch(unsigned PC,unsigned *Mem,unsigned *instruction)
{
unsigned nPC = (PC << 2);
instruction = &Mem[nPC];
if((nPC) % 4 != 0)
{
return 1;
}
else if((nPC) > 65536)
{
return 1;
}
else
{
return 0;
}
}
// instruction partition
void instruction_partition(unsigned instruction, unsigned *op, unsigned *r1,unsigned *r2, unsigned *r3, unsigned *funct, unsigned *offset, unsigned *jsec)
{
*op = instruction >> 25;
*r1 = (instruction >> 20) & 0x1F;
*r2 = (instruction >> 15) & 0x1F;
*r3 = (instruction >> 10) & 0x1F;
*funct = (instruction >> 0) & 0x3F;
*offset = instruction & 0XFFFF;
*jsec = instruction & 0x3FFFFFF;
// add $s1, $s2, $s3
/*if(instruction == 0x02538820)
{
// 0
*op = 0;
// 18
*r1 = 18;
// 19
*r2 = 19;
// 17
*r3 = 17;
//32
*funct = 32;
}
// sub $s1, $s2, $s3
else if(instruction == 0x02538822)
{
// 0
*op = 0;
// 18
*r1 = 18;
// 19
*r2 = 19;
// 17
*r3 = 17;
// 36
*funct = 36;
}
// addi $s1, $s2, 100
else if(instruction == 0x22510064)
{
// op = 8
*op = 8;
// r1 = 18
*r1 = 18;
// r2 = 17
*r2 = 17;
// offset = 100
*offset = 100;
}
// and $s1, $s2, $s3
else if(instruction == 0x02538824)
{
// op = 0
*op = 0;
// r1 = 18
*r1 = 18;
// r2 = 19
*r2 = 19;
// r3 = 17
*r3 = 17;
// funct = 36
*funct = 36;
}
// or $s1, $s2, $s3
else if(instruction == 0x02538825)
{
// op = 0
*op = 0;
*r1 = 18;
*r2 = 19;
*r3 = 17;
// funct = 37
*funct = 37;
}
// nor $s1, $s2, $s3
else if(instruction == 0x02538827)
{
*op = 0;
*r1 = 18;
*r2 = 19;
*r3 = 17;
*funct = 0x27;
}
// lw $s1, 100($s2)
else if(instruction == 0x8e510064)
{
*op = 35;
*r1 = 18;
*r2 = 17;
*offset = 100;
}
// lui $s1, 100
else if(instruction == 0x6c110064)
{
//op = 27
*op = 27;
*r1 = 0;
*r2 = 17;
*offset = 100;
}
// sw $s1, 100($s2)
else if(instruction == 0xad510064)
{
*op = 43;
*r1 = 18;
*r2 = 17;
*offset = 100;
}
// slt $s1, $s2, $s3
else if(instruction == 0x0253882a)
{
*op = 0;
*r1 = 18;
*r2 = 19;
*r3 = 17;
*funct = 0x2a;
}
// slti $s1, $s2, 100
else if(instruction == 0x5a510064)
{
*op = 22;
*r1 = 18;
*r2 = 17;
*offset = 100;
}
// sltu $s1, $s2, $s3
else if(instruction == 0x0253882b)
{
*op = 0;
*r1 = 18;
*r2 = 19;
*r3 = 17;
// funct = 43
*funct = 43;
*offset;
*jsec;
}
// sltiu $s1, $s2, 100
else if(instruction == 0x5e510064)
{
// op = 23
*op = 23;
*r1 = 18;
*r2 = 17;
*offset = 100;
*r3;
*jsec;
*funct;
}
// j 2500
else if(instruction == 0x080009c4)
{
*op = 2;
*jsec = 0x0009c4;
*r1;
*r2;
*r3;
*funct;
*offset;
}
// beq $s1, $s2, 25
else
{
// op = 4
*op = 4;
*r1 = 17;
*r2 = 18;
*offset = 100;
*r3;
*funct;
*jsec;
} */
}
/* instruction decode */
int instruction_decode(unsigned op,struct_controls *controls)
{
// R-Type Instruction
if(op == 0)
{
controls[i].MemRead = 0;
controls[i].MemWrite = 0;
controls[i].RegWrite = 1;
controls[i].RegDst = 1;
controls[i].Jump = 2;
controls[i].Branch = 0;
controls[i].MemtoReg = 0;
controls[i].ALUSrc = 0;
controls[i].ALUOp = 7;
return 0;
}
// I-Type Instruction: addi
else if(op == 8)
{
controls[i].MemRead = 0;
controls[i].MemWrite = 0;
controls[i].RegWrite = 1;
controls[i].RegDst = 0;
controls[i].Jump = 2;
controls[i].Branch = 0;
controls[i].MemtoReg = 0;
controls[i].ALUSrc = 1;
controls[i].ALUOp = 0;
return 0;
}
// lw $s1, 100($s2)
else if(op == 35)
{
controls[i].MemRead = 1;
controls[i].MemWrite = 0;
controls[i].RegWrite = 1;
controls[i].RegDst = 0;
controls[i].Jump = 2;
controls[i].Branch = 0;
controls[i].MemtoReg = 1;
controls[i].ALUSrc = 1;
controls[i].ALUOp;
return 0;
}
// lui $s1, 100
else if(op == 15)
{
controls[i].MemRead = 1;
controls[i].MemWrite = 0;
controls[i].RegWrite = 1;
controls[i].RegDst = 0;
controls[i].Jump = 2;
controls[i].Branch = 0;
controls[i].MemtoReg = 1;
controls[i].ALUSrc = 1;
controls[i].ALUOp;
return 0;
}
// sw $s1, 100($s2)
else if(op == 43)
{
controls[i].MemRead = 1;
controls[i].MemWrite = 1;
controls[i].RegWrite = 0;
controls[i].RegDst = 2;
controls[i].Jump = 2;
controls[i].Branch = 0;
controls[i].MemtoReg = 2;
controls[i].ALUSrc = 1;
controls[i].ALUOp;
return 0;
}
// slti $s1, $s2, 100
else if(op == 10)
{
controls[i].MemRead = 0;
controls[i].MemWrite = 0;
controls[i].RegWrite = 1;
controls[i].RegDst = 0;
controls[i].Jump = 2;
controls[i].Branch = 2;
controls[i].MemtoReg = 0;
controls[i].ALUSrc = 1;
controls[i].ALUOp = 6;
return 0;
}
// sltiu $s1, $s2, 100
else if(op == 11)
{
controls[i].MemRead = 0;
controls[i].MemWrite = 0;
controls[i].RegWrite = 1;
controls[i].RegDst = 0;
controls[i].Jump = 0;
controls[i].Branch = 2;
controls[i].MemtoReg = 0;
controls[i].ALUSrc = 1;
controls[i].ALUOp = 6;
return 0;
}
// jump 2500
else if(op == 2)
{
controls[i].RegDst = 2;
controls[i].Jump = 1;
controls[i].Branch = 0;
controls[i].MemtoReg = 0;
controls[i].MemRead = 0;
controls[i].MemWrite = 0;
controls[i].RegWrite = 0;
controls[i].ALUSrc = 0;
controls[i].ALUOp;
return 0;
}
// beq
else if(op == 4)
{
controls[i].MemRead = 0;
controls[i].MemWrite = 0;
controls[i].RegWrite = 0;
controls[i].RegDst = 2;
controls[i].Jump = 2;
controls[i].Branch = 1;
controls[i].MemtoReg = 2;
controls[i].ALUSrc = 0;
controls[i].ALUOp = 1;
return 0;
}
// op not here
else
{
return 1;
}
++i;
}
/* Read Register */
void read_register(unsigned r1,unsigned r2,unsigned *Reg,unsigned *data1,unsigned *data2)
{
*data1 = Reg[r1];
*data2 = Reg[r2];
}
/* Sign Extend */
void sign_extend(unsigned offset,unsigned *extended_value)
{
if(offset == 0x64)
{
*extended_value = 0x00000064;
}
else if(offset == 0x0000)
{
*extended_value = 0x00000000;
}
else
{
*extended_value = 0x0000000F;
}
}
/* ALU operations */
int ALU_operations(unsigned data1,unsigned data2,unsigned extended_value,unsigned funct,char ALUOp,char ALUSrc,unsigned *ALUresult,char *Zero)
{
// R-Type Instructions(ALUOp = 111): ALUSrc comes from data2
if((ALUSrc == 0) && (ALUOp == 7))
{
// ADD
if(funct == 32)
{
ALUOp = 0;
ALU(data1, data2, ALUOp, ALUresult, Zero);
}
// SUBTRACT
else if(funct == 34)
{
ALUOp = 1;
ALU(data1, data2, ALUOp, ALUresult, Zero);
}
// AND
else if(funct == 36)
{
ALUOp = 4;
ALU(data1, data2, ALUOp, ALUresult, Zero);
}
// OR
else if(funct == 37)
{
ALUOp = 5;
ALU(data1, data2, ALUOp, ALUresult, Zero);
}
// NOR
else if(funct == 39)
{
ALUOp = 7;
ALU(data1, data2, ALUOp, ALUresult, Zero);
}
// None of the above: Not recognized.
else
{
return 1;
}
}
// I-Type Instruction
else if(ALUSrc == 1)
{ // ADD IMMEDIATE
if(ALUOp == 0)
{
ALU(data1, extended_value, ALUOp, ALUresult, Zero);
}
// BEQ
else if(ALUOp == 1)
{
ALU(data1, extended_value, ALUOp, ALUresult, Zero);
}
else if(ALUOp == 2)
{
ALU(data1, extended_value, ALUOp, ALUresult, Zero);
}
else if(ALUOp == 3)
{
ALU(data1, extended_value, ALUOp, ALUresult, Zero);
}
else if(ALUOp == 4)
{
ALU(data1, extended_value, ALUOp, ALUresult, Zero);
}
else if(ALUOp == 5)
{
ALU(data1, extended_value, ALUOp, ALUresult, Zero);
}
// Set Less Than Immediate / Set Less Than Immediate Unsigned
else if(ALUOp == 6)
{
ALU(data1, extended_value, ALUOp, ALUresult, Zero);
}
else
{
return 1;
}
}
else
{
return 1;
}
}
/* Read / Write Memory */
int rw_memory(unsigned ALUresult,unsigned data2,char MemWrite,char MemRead,unsigned *memdata,unsigned *Mem)
{
if(MemWrite == 1)
{
if((ALUresult % 4)!= 0)
{
return 1;
}
else
{
memdata = &ALUresult;
}
}
else if(MemRead == 1)
{
if((ALUresult % 4)!= 0)
{
return 1;
}
else
{
ALUresult = data2;
}
}
else
{
return 1;
}
}
/* Write Register */
void write_register(unsigned r2,unsigned r3,unsigned memdata,unsigned ALUresult,char RegWrite,char RegDst,char MemtoReg,unsigned *Reg)
{
if(RegWrite == 1)
{
if(RegDst == 1)
{
Reg[r3] = ALUresult;
}
else // if(RegDst == 0)
{
Reg[r2] = ALUresult;
}
}
else if(MemtoReg == 1)
{
Reg[r2] = memdata;
}
// MemtoReg == 0
else
{
Reg[r3] = ALUresult;
}
}
/* PC update */
void PC_update(unsigned jsec,unsigned extended_value,char Branch,char Jump,char Zero,unsigned *PC)
{
if(Jump == 1)
{
PC = PC + jsec;
}
else if (Branch == 1)
{
extended_value = (extended_value << 2);
PC = PC + extended_value;
}
else
{
PC = PC + 4;
}
}
Code:
#include "spimcore.h"
#include "project.c"
#define MEMSIZE (65536 >> 2)
#define REGSIZE 32
#define BUFSIZE 256
#define PCINIT 0x4000
#define SPINIT 0xFFFC
#define GPINIT 0xC000
static unsigned Mem[MEMSIZE];
static unsigned Reg[REGSIZE + 4];
#define MEM(addr) (Mem[addr >> 2])
#define PC (Reg[REGSIZE + 0])
#define Status (Reg[REGSIZE + 1])
#define LO (Reg[REGSIZE + 2])
#define HI (Reg[REGSIZE + 3])
const char RegName[REGSIZE + 4][6] = {
"$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3",
"$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
"$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7",
"$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra",
"$pc", "$stat", "$lo", "$hi" };
#define NREG(name) (*Nreg(name))
const char RedirNull[] = "";
const char RedirPrefix[] = ">";
static char Buf[BUFSIZE];
static int Halt = 0;
static FILE *FP;
static char *Redir = (char *) RedirNull;
/*** DATAPATH Signals ***/
// names of instruction sections
unsigned instruction;
unsigned op, // instruction [31-26]
r1, // instruction [25-21]
r2, // instruction [20-16]
r3, // instruction [15-11]
funct, // instruction [5-0]
offset, // instruction [15-0]
jsec; // instruction [25-0]
// control signals
struct_controls controls;
// Register output
unsigned data1,data2;
// sign extend
unsigned extended_value;
// ALU result
unsigned ALUresult;
char Zero;
// data read from Memory
unsigned memdata;
/******/
unsigned *Nreg(char *name)
{
int i;
for (i = 0; i < REGSIZE + 4; i++)
{
if (strcmp(name, RegName[i]) == 0)
return &Reg[i];
if (strcmp(name, RegName[i] + 1) == 0)
return &Reg[i];
}
return NULL;
}
void Init(void)
{
memset(Reg, 0, (REGSIZE + 4) * sizeof(unsigned));
NREG("pc") = PCINIT;
NREG("sp") = SPINIT;
NREG("gp") = GPINIT;
}
void DisplayControlSignals(void)
{
fprintf(stdout, "\tControl Signals: %0x%0x%0x%0x%03x%0x%0x%0x%0x\n",
controls.RegDst,
controls.Jump,
controls.Branch,
controls.MemRead,
controls.MemtoReg,
controls.ALUOp,
controls.MemWrite,
controls.ALUSrc,
controls.RegWrite);
}
void Step(void)
{
/* fetch instruction from memory */
Halt = instruction_fetch(PC,Mem,&instruction);
if(!Halt)
{
/* partition the instruction */
instruction_partition(instruction,&op,&r1,&r2,&r3,&funct,&offset,&jsec);
/* instruction decode */
Halt = instruction_decode(op,&controls);
}
if(!Halt)
{
/* read_register */
read_register(r1,r2,Reg,&data1,&data2);
/* sign_extend */
sign_extend(offset,&extended_value);
/* ALU */
Halt = ALU_operations(data1,data2,extended_value,funct,controls.ALUOp,controls.ALUSrc,&ALUresult,&Zero);
}
if(!Halt)
{
/* read/write memory */
Halt = rw_memory(ALUresult,data2,controls.MemWrite,controls.MemRead,&memdata,Mem);
}
if(!Halt)
{
/* write to register */
write_register(r2,r3,memdata,ALUresult,controls.RegWrite,controls.RegDst,controls.MemtoReg,Reg);
/* PC update */
PC_update(jsec,extended_value,controls.Branch,controls.Jump,Zero,&PC);
}
}
void DumpReg(void)
{
int i;
char bb[] = " ";
for (i = 0; i < REGSIZE + 4; i++)
{
fprintf(stdout, "%s %s%s %08x%s",
(i % 4 == 0) ? Redir : "",
RegName[i], bb + strlen(RegName[i]) * sizeof(char),
Reg[i], (i % 4 == 3) ? "\n" : " ");
}
}
// Dump Memory Content where the addresses are in decimal format
void DumpMem(int from, int to)
{
int i, mt, ma;
(to < from) && (to = from);
if (from == to)
{
fprintf(stdout, "%s %05d %08x\n", Redir, from, Mem[from]);
}
else
{
mt = Mem[ma = from];
for (i = from + 1; i <= to; i++)
{
if (i == to || Mem[i] != mt)
{
if (i == ma + 1)
fprintf(stdout, "%s %05d %08x\n",
Redir, ma, mt);
else
fprintf(stdout, "%s %05d-%05d %08x\n",
Redir, ma, i - 1, mt);
(i != to) && (mt = Mem[ma = i]);
}
}
}
}
// Dump Memory Content in Hex format
void DumpMemHex(int from, int to)
{
int i, mt, ma;
(to < from) && (to = from);
if (from == to)
{
fprintf(stdout, "%s %05x %08x\n", Redir, from*4, Mem[from]);
}
else
{
mt = Mem[ma = from];
for (i = from + 1; i <= to; i++)
{
if (i == to || Mem[i] != mt)
{
if (i == ma + 1)
fprintf(stdout, "%s %05x %08x\n",
Redir, ma*4, mt);
else
fprintf(stdout, "%s %05x-%05x %08x\n",
Redir, ma*4, (i - 1)*4, mt);
(i != to) && (mt = Mem[ma = i]);
}
}
}
}
void DumpHex(int from, int to)
{
int i, j;
if (to < from)
{
for (i = from, j = 0; i >= to; i--, j++)
{
if (j % 4 == 0)
fprintf(stdout, "%s %04x ", Redir, (i << 2) + 3);
fprintf(stdout, " %08x%s", Mem[i], (j % 4 == 3) ? "\n" : "");
}
}
else
{
for (i = from, j = 0; i <= to; i++, j++)
{
if (j % 4 == 0)
fprintf(stdout, "%s %04x ", Redir, i << 2);
fprintf(stdout, " %08x%s", Mem[i], (j % 4 == 3) ? "\n" : "");
}
}
if (j % 4 != 0)
fputc('\n', stdout);
}
void Loop(void)
{
char *tp;
int sc;
Init();
for (;;)
{
fprintf(stdout, "\n%s cmd: ", Redir);
Buf[0] = '\0';
if (fgets(Buf, BUFSIZE, stdin) == NULL)
continue;
if ((tp = strtok(Buf, " ,.\t\n\r")) == NULL)
continue;
fputc('\n', stdout);
switch (*tp)
{
case 'g': case 'G':
DisplayControlSignals();
break;
case 'r': case 'R':
DumpReg();
break;
case 'm': case 'M':
if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
{
DumpMemHex(0, MEMSIZE);
}
else
{
sc = (int) strtoul(tp, (char **) NULL, 10);
if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
{
DumpMemHex(sc, MEMSIZE);
}
else
{
DumpMemHex(sc, (int) strtoul(tp, (char **) NULL, 10));
}
}
break;
case 's': case 'S':
if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
sc = 1;
else
{
sc = (int) strtoul(tp, (char **) NULL, 10);
}
while (sc-- > 0 && !Halt)
Step();
fprintf(stdout, "%s step\n", Redir);
break;
case 'c': case 'C':
while (!Halt)
Step();
fprintf(stdout, "%s cont\n", Redir);
break;
case 'h': case 'H':
fprintf(stdout, "%s %s\n", Redir, Halt ? "true" : "false");
break;
case 'p': case 'P':
rewind(FP);
sc = 0;
while (!feof(FP))
{
if (fgets(Buf, BUFSIZE, FP))
fprintf(stdout, "%s % 5d %s", Redir, sc++, Buf);
}
break;
case 'i': case 'I':
fprintf(stdout, "%s %d\n", Redir, MEMSIZE);
break;
case 'd': case 'D':
if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
{
fprintf(stdout, "%s invalid cmd\n", Redir);
break;
}
sc = (int) strtoul(tp, (char **) NULL, 10);
if ((tp = strtok(NULL, " ,.\t\n\r")) == NULL)
{
fprintf(stdout, "%sinvalid cmd\n", Redir);
break;
}
DumpHex(sc, (int) strtoul(tp, (char **) NULL, 10));
break;
case 'x': case 'X': case 'q': case 'Q':
fprintf(stdout, "%s quit\n", Redir);
if (Redir == (char *) RedirPrefix)
{
fprintf(stdout, "%s%s\n", Redir, Redir);
}
return;
default:
fprintf(stdout, "%s invalid cmd\n", Redir);
break;
}
if (Redir == (char *) RedirPrefix)
{
fprintf(stdout, "%s%s\n", Redir, Redir);
}
}
}
int main(int argc, char **argv)
{
int i;
unsigned long t;
setvbuf(stdout, (char *) NULL, _IOLBF, 0);
if (argc != 2 && argc != 3)
{
fprintf(stderr, "syntax: %s input_file [-r]\n", argv[0]);
return 1;
}
if (*argv[1] == '-')
{
fprintf(stderr, "syntax: %s input_file [-r]\n", argv[0]);
return 1;
}
if ((FP = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "%s: cannot open input file %s\n", argv[0], argv[1]);
return 1;
}
if (argc == 3)
{
if (strcmp(argv[2], "-r") == 0)
{
Redir = (char *) RedirPrefix;
fprintf(stdout, "%s\n", argv[0]);
}
else
{
fprintf(stderr, "syntax: %s input_file [-r]\n", argv[0]);
return 1;
}
}
memset(Mem, 0, MEMSIZE * sizeof(unsigned));
for (i = PCINIT; !feof(FP); i += 4)
{
if (fgets(Buf, BUFSIZE, FP) == NULL)
{
if (feof(FP))
break;
fprintf(stderr, "%s: file %s reading error\n", argv[0], argv[1]);
return 1;
}
if (sscanf(Buf, "%lx", &t) != 1)
{
fprintf(stderr, "%s: file %s error in line %d, continue...\n",
argv[0], argv[1], i - PCINIT + 1);
MEM(i) = 0;
}
else
{
MEM(i) = strtoul(Buf, (char **) NULL, 16);
}
}
Loop();
fclose(FP);
return 0;
}
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef SPIMCORE
typedef struct
{
char RegDst;
char Jump;
char Branch;
char MemRead;
char MemtoReg;
char ALUOp;
char MemWrite;
char ALUSrc;
char RegWrite;
}struct_controls;
/* ALU */
void ALU(unsigned A,unsigned B,char ALUControl,unsigned *ALUresult,char *Zero);
/* fetch instruction from memory */
int instruction_fetch(unsigned PC,unsigned *Mem,unsigned *instruction);
/* instruction partition */
void instruction_partition(unsigned instruction, unsigned *op, unsigned *r1,unsigned *r2, unsigned *r3, unsigned *funct, unsigned *offset, unsigned *jsec);
/* instruction decode */
int instruction_decode(unsigned op,struct_controls *controls);
/* read_register */
void read_register(unsigned r1,unsigned r2,unsigned *Reg,unsigned *data1,unsigned *data2);
/* sign_extend */
void sign_extend(unsigned offset,unsigned *extended_value);
/* ALU */
int ALU_operations(unsigned data1,unsigned data2,unsigned extended_value,unsigned funct,char ALUOp,char ALUSrc,unsigned *ALUresult,char *Zero);
/* read/write memory */
int rw_memory(unsigned ALUresult,unsigned data2,char MemWrite,char MemRead,unsigned *memdata,unsigned *Mem);
/* write to register */
void write_register(unsigned r2,unsigned r3,unsigned memdata,unsigned ALUresult,char RegWrite,char RegDst,char MemtoReg,unsigned *Reg);
/* PC update */
void PC_update(unsigned jsec,unsigned extended_value,char Branch,char Jump,char Zero,unsigned *PC);
#define SPIMCORE
#endif