R2000.C
En este archivo implementamos el camino de datos con la unidad de control del procesador monociclo.También implementamos las distintas funciones para la inicialización de los elementos del procesador , y para la visualización del contenido de las memorias y de los registros.
#include<stdio.h>
#include<stdlib.h>
#include"defs.h"
#include"clock.h"
#include"gates.h"
#include"decods.h"
#include"muxs.h"
#include"latches.h"
#include"flip-flops.h"
#include"fr32x32.h"
#include"regs.h"
#include"srams.h"
#include"alucon.h"
#include"alu32.h"
#include"control.h"
#include"r2000.h"
void r2000::run(void)
{
CLOCK clock(13);
WIRE vcc=VCC, gnd=GND, clk=GND;
long iter=0;
inicializar_elementos();
do
{
clock.run(iter,clk);
pc.run(clk,pcin,pcout);
mi.run(vcc,gnd,pcout,mi_in,inst);
for(int i=0;i<6;i++)
control_in[i]=inst[i+26];
for(int i=0;i<5;i++)
{
reg1[i]=inst[i+21];
reg2[i]=inst[i+16];
reg3[i]=inst[i+11];
}
for(int i=0;i<16;i++)
dir[i]=inst[i];
control.run(control_in,RegDst,ALUSrc,MemToReg,RegWrite,MemRead,MemWrite,Branch,AluOp[1],AluOp[0],Salir,Jump);
for(int i=0;i<5;i++)
{
mux0in[0]=reg2[i];
mux0in[1]=reg3[i];
mux[i].run(mux0in,RegDst,mux0out[i]);
}
p_and2.run(RegWrite2,clk,RegWrite);
reg.run(regdata,reg1,reg2,mux0out,RegWrite2,dato1,dato2);
for(int i=0;i<6;i++)
alucin[i]=dir[i];
for(int i=0;i<16;i++)
extdir[i]=dir[i];
for(int i=16;i<32;i++)
extdir[i]=dir[15];
alucon.run(alucin,AluOp,alusel);
for(int i=0;i<32;i++)
{
mux1in[0]=dato2[i];
mux1in[1]=extdir[i];
mux[i+5].run(mux1in,ALUSrc,mux1out[i]);
}
bngate=alusel[2];
a_op[0]=alusel[0];
a_op[1]=alusel[1];
alu.run(dato1,mux1out,bngate,a_op,alures,overflow,carry_out,zero);
for(int i=0;i<5;i++)
d_addr[i]=alures[i];
p_and3.run(MemWrite2,clk,MemWrite);
md.run(vcc,MemWrite2,d_addr,dato2,md_out);
for(int i=0;i<32;i++)
{
mux3in[1]=md_out[i];
mux3in[0]=alures[i];
mux[i+37].run(mux3in,MemToReg,mux3out[i]);
regdata[i]=mux3out[i];
}
add[0].run(pcout,cuatro,gnd,add0out,carry_out2);
add[1].run(add0out,extdir,gnd,add1out,carry_out2);
p_and.run(andout,zero,Branch);
for(int i=0;i<32;i++)
{
mux2in[0]=add0out[i];
mux2in[1]=add1out[i];
mux[i+69].run(mux2in,andout,mux2out[i]);
}
for (int i=0;i<26;i++)
{
mux4in[1]=inst[i];
mux4in[0]=mux2out[i];
mux[i+101].run(mux4in,Jump,mux4out[i]);
}
for (int i=26;i<32;i++)
{
mux4in[1]=add0out[i];
mux4in[0]=mux2out[i];
mux[i+101].run(mux4in,Jump,mux4out[i]);
}
for(int i=0;i<32;i++)
pcin[i]=mux4out[i];
iter++;
}while (Salir!=VCC);
}
void r2000::cargar_instruccion(WIRE instruc[32], WIRE pc[6])
{
WIRE salida[32];
WIRE write=GND,vcc=VCC,gnd=GND;
for(int i=0;i<4;i++) mi.run(vcc,write,pc,instruc,salida);
write=VCC;
for(int i=0;i<4;i++) mi.run(vcc,write,pc,instruc,salida);
}
void r2000::cargar_datos(int dato, int direccion)
{
WIRE data[32],salida[32],dir[6];
WIRE write=GND,vcc=VCC,gnd=GND;
decimal_binario(dato,data,32);
decimal_binario(direccion,dir,6);
for(int i=0;i<4;i++) md.run(vcc,write,dir,data,salida);
write=VCC;
for(int i=0;i<4;i++) md.run(vcc,write,dir,data,salida);
}
void r2000::printb(char texto[],WIRE bus[],int tamano)
{
printf("\n%s",texto);
for (int i=tamano-1;i>=0;i--)
if (bus[i]==GND) printf("%d",bus[i]);
else printf ("1");
}
void r2000::printb(char texto[],WIRE bus)
{
if (bus==GND) printf("\n%s %d",texto,bus);
else printf ("1");
}
void r2000::imprimir_meminst(void)
{
WIRE gnd=GND,vcc=VCC,addr0[32],out0[32];
int i,j,k;
printf("\nMemoria de instruccion:\n");
printf("----------------------\n");
for(j=0;j<32;j++) {
printf("Dir %2d:",j);
addr0[0] = (j&1)*255;
addr0[1] = ((j>>1)&1)*255;
addr0[2] = ((j>>2)&1)*255;
addr0[3] = ((j>>3)&1)*255;
addr0[4] = ((j>>4)&1)*255;
for(i=0;i<4;i++)
{
mi.run(vcc,gnd,addr0,out0,out0);
}
for(k=31;k>=0;k--)
{
if (out0[k]==GND) printf("%d",out0[k]);
else printf ("1");
}
printf("\n");
}
}
void r2000::imprimir_memdatos(void)
{
WIRE gnd=GND,vcc=VCC,nada[32],addr0[32],out0[32],out1[32];
int i,j,k;
printf("\nMemoria de datos:\n");
printf("-----------------\n");
for(j=0;j<32;j++) {
printf("Direccion %2d:",j);
addr0[0] = (j&1)*255;
addr0[1] = ((j>>1)&1)*255;
addr0[2] = ((j>>2)&1)*255;
addr0[3] = ((j>>3)&1)*255;
addr0[4] = ((j>>4)&1)*255;
for(i=0;i<4;i++)
{
md.run(vcc,gnd,addr0,out0,out0);
}
for(k=31;k>=0;k--)
{
if (out0[k]==GND) printf("%d",out0[k]);
else printf ("1");
}
printf("\n");
}
}
void r2000::imprimir_registros(void)
{
WIRE nada[32],addr0[32],addr1[32],out0[32],out1[32],gnd=GND;
int i,j,k;
printf("\nContenido de los Registros:\n");
printf("---------------------------\n");
for(j=0;j<32;j++) {
printf("Reg %2d:",j);
addr0[0] = (j&1)*255;
addr0[1] = ((j>>1)&1)*255;
addr0[2] = ((j>>2)&1)*255;
addr0[3] = ((j>>3)&1)*255;
addr0[4] = ((j>>4)&1)*255;
for(i=0;i<3;i++)
{
reg.run(nada,addr0,addr1,nada,gnd,out0,out1);
}
for(k=31;k>=0;k--)
{
if (out0[k]==GND) printf("%d",out0[k]);
else printf ("1");
}
printf("\n");
}
}
void r2000::imprimir_buses(void)
{
printf("\n\nBuses \n");
printf("------\n");
printb("Pcin: ",pcin,32);
printb("Pcout: ",pcout,32);
printb("RegDst: ",RegDst);
printb("ALUSrc: ",ALUSrc);
printb("MemToReg: ",MemToReg);
printb("RegWrite: ",RegWrite);
printb("RegWrite2: ",RegWrite2);
printb("MemRead: ",MemRead);
printb("MemWrite: ",MemWrite);
printb("Branch: ",Branch);
printb("AluOp: ",AluOp,2);
printb("Regdata: ",regdata,32);
printb("Bngate: ",bngate);
printf("\n");
}
void r2000::cargar_registro(WIRE direccion[5], WIRE dato[32])
{
WIRE j[5], k[32],g[32];
WIRE write=VCC;
for(int i=0;i<4;i++) reg.run(dato,j,j,direccion,write,k,g);
write=GND;
for(int i=0;i<4;i++) reg.run(dato,j,j,direccion,write,k,g);
}
void r2000::inicializar_elementos(void)
{
WIRE ck = VCC;
WIRE vcc=VCC, gnd=GND;
WIRE in[32];
WIRE out[32];
WIRE direccion[6];
for (int i=0;i<32;i++) in[i]=GND;
for (int i=0;i<5;i++) {
pc.run(ck,in,out);
}
ck = GND;
for (int i=0;i<5;i++) {
pc.run(ck,in,out);
}
for(int i=0;i<32;i++)
{
cuatro[i]=GND;
inst[i]=GND;
}
cuatro[0]=VCC;
}
void r2000::cargar_meminst(char archivo[])
{
FILE *fp=NULL;
int aux,j=0;
WIRE inst[32],address[6]={GND,GND,GND,GND,GND,GND};
fp=fopen(archivo,"r");
if (fp==NULL)
{
printf("No se encuentra el archivo.");
exit(0);
}
do{
j++;
for (int i=31;i>=0;i--)
{
aux=getc(fp) - '0';
if (aux==0) inst[i]=GND;
if (aux==1) inst[i]=VCC;
}
getc(fp);
cargar_instruccion(inst,address);
address[0] = (j&1)*255;
address[1] = ((j>>1)&1)*255;
address[2] = ((j>>2)&1)*255;
address[3] = ((j>>3)&1)*255;
address[4] = ((j>>4)&1)*255;
}
while (!feof(fp));
}
void r2000::decimal_binario(int decimal, WIRE binario[],int tamano)
{
if (tamano>0)
{
binario[0] = (decimal&1)*255;
for(int i=1;i<tamano;i++)
binario[i] = ((decimal>>i)&1)*255;
}
else
printf("\nEl tamaño no es correcto\n");
}