C:只在第一次迭代中工作的函数

C:只在第一次迭代中工作的函数,c,function,debugging,gdb,C,Function,Debugging,Gdb,我正在尝试设计一个流水线cpu模拟器。代码相当复杂,至少对我来说是这样。有多个头文件和源文件。代码可以编译 在运行时,它在第一次迭代(时钟周期)中运行良好。但从迭代来看并非如此。在花了数小时查找故障后,我发现了问题所在,但不知道原因。以下功能: MemoryAccess(ir, pc, ground, '0', instrMem); typedef char bit32[33]; bit8 instrMem[4096]; /* instruction memory */ bit32 p

我正在尝试设计一个流水线cpu模拟器。代码相当复杂,至少对我来说是这样。有多个头文件和源文件。代码可以编译

在运行时,它在第一次迭代(时钟周期)中运行良好。但从迭代来看并非如此。在花了数小时查找故障后,我发现了问题所在,但不知道原因。以下功能:

MemoryAccess(ir, pc, ground, '0', instrMem); 
typedef char bit32[33];
bit8 instrMem[4096];    /* instruction memory */
bit32 pc, ir, ground;
   for(cycle=0; ; cycle++) 
{
    /* load IR with PC value */
    printf("I am at the beginning of the cycle loop");
    MemoryAccess(ir, pc, ground, '0', instrMem); 

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

    /* halt check */
    if (bit32toint(ir) == 0x0000003F) {
        printf("\nmachine halted\n");
        break;
    }

    /* PC + 4 data path */
    RCAdder_32(pcPlus4, ground, pc, "00000000000000000000000000000100", '0');

    /* jump data path */
    shiftleftby2(jumpAddress, ir);
    jumpAddress[0] = pcPlus4[0];
    jumpAddress[1] = pcPlus4[1];
    jumpAddress[2] = pcPlus4[2];
    jumpAddress[3] = pcPlus4[3];

    /* sign extended / shifted immediate data path */
    signextend(immSignExt, &ir[16]); 
    shiftleftby2(immShifted, immSignExt); 

    /* control unit data path */
    ControlUnit(ir, &ir[26], &regWrite, &regDest,
                    &memRead, &memWrite, &memToReg, 
                    &jump, &branch, &aluSrc, aluOp);

    /* register memory data path - read */
    Mux2_5(regWriteAddr, &ir[11], &ir[16], regDest);
    registerAccess(&regOut1, &regOut2, &ir[6], &ir[11], regWriteAddr, regIn, '0');

    /* alu data path */
    Mux2_32(aluSrcVal, regOut2, immSignExt, aluSrc);
    zero = ALU(&aluOut, regOut1, aluSrcVal, aluOp);

    /* branch data path */
    RCAdder_32(branchAddress, ground, pcPlus4, immShifted, '0');
    Mux2_32(mbranchAddress, pcPlus4, branchAddress, AND2_1(zero, branch));
    Mux2_32(pc, mbranchAddress, jumpAddress, jump);

    /* main memory data path */
    MemoryAccess(memOut, aluOut, regOut2, memWrite, mainMem);
    Mux2_32(regIn, aluOut, memOut, memToReg);

    /* register memory data path - write */
    registerAccess(&regOut1, &regOut2, &ir[6], &ir[11], regWriteAddr, regIn, regWrite);

    /* dump register memory and signal information */
    for (i=0; i < 14; i++) {
        inttobitn(i, 5, tmp);
        registerAccess(&regOut1, &regOut2, tmp, &ir[11], regWriteAddr, regIn, '0');
        printf("R%d: %d, ", i, bit32toint(regOut1));
    }
    printf("\b\b\n\tbranchAddress = %.32s (%d) jumpAddress = %.32s (%d)\n",
        branchAddress, bit32toint(branchAddress), jumpAddress, bit32toint(jumpAddress));
    printf("\topcode = %.6s, immSignExt = %.32s (%d), immShifted = %.32s (%d), PC+4 = %.32s (%d)\n",
        ir, immSignExt, bit32toint(immSignExt), immShifted, bit32toint(immShifted), pcPlus4, bit32toint(pcPlus4));
    printf("\tregWrite = %c, regDest = %c, memRead = %c, memWrite = %c, memToReg = %c, jump = %c, branch = %c, aluSrc = %c, aluOp = %.3s, zero = %c\n",
        regWrite, regDest, memRead, memWrite, memToReg, jump, branch, aluSrc, aluOp, zero);
    getchar();
}
void MemoryAccess(bit32 read_out, bit32 addr, bit32 write_in, signal write_enable, bit8 memory[4096]){

int address= bitntoint(12, addr);
setbit8(read_out, memory[address]);
setbit8(&read_out[8], memory[address+1]);
setbit8(&read_out[16], memory[address+2]);
setbit8(&read_out[24], memory[address+3]);

if (write_enable){
    setbit8(memory[address], write_in);
    setbit8(memory[address+1], &write_in[8]);
    setbit8(memory[address+2], &write_in[16]);
    setbit8(memory[address+3], &write_in[24]);
}
在instrMem中的索引“pc”处获取指令并将其存储在“ir”中。以下是函数中变量的声明:

MemoryAccess(ir, pc, ground, '0', instrMem); 
typedef char bit32[33];
bit8 instrMem[4096];    /* instruction memory */
bit32 pc, ir, ground;
   for(cycle=0; ; cycle++) 
{
    /* load IR with PC value */
    printf("I am at the beginning of the cycle loop");
    MemoryAccess(ir, pc, ground, '0', instrMem); 

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

    /* halt check */
    if (bit32toint(ir) == 0x0000003F) {
        printf("\nmachine halted\n");
        break;
    }

    /* PC + 4 data path */
    RCAdder_32(pcPlus4, ground, pc, "00000000000000000000000000000100", '0');

    /* jump data path */
    shiftleftby2(jumpAddress, ir);
    jumpAddress[0] = pcPlus4[0];
    jumpAddress[1] = pcPlus4[1];
    jumpAddress[2] = pcPlus4[2];
    jumpAddress[3] = pcPlus4[3];

    /* sign extended / shifted immediate data path */
    signextend(immSignExt, &ir[16]); 
    shiftleftby2(immShifted, immSignExt); 

    /* control unit data path */
    ControlUnit(ir, &ir[26], &regWrite, &regDest,
                    &memRead, &memWrite, &memToReg, 
                    &jump, &branch, &aluSrc, aluOp);

    /* register memory data path - read */
    Mux2_5(regWriteAddr, &ir[11], &ir[16], regDest);
    registerAccess(&regOut1, &regOut2, &ir[6], &ir[11], regWriteAddr, regIn, '0');

    /* alu data path */
    Mux2_32(aluSrcVal, regOut2, immSignExt, aluSrc);
    zero = ALU(&aluOut, regOut1, aluSrcVal, aluOp);

    /* branch data path */
    RCAdder_32(branchAddress, ground, pcPlus4, immShifted, '0');
    Mux2_32(mbranchAddress, pcPlus4, branchAddress, AND2_1(zero, branch));
    Mux2_32(pc, mbranchAddress, jumpAddress, jump);

    /* main memory data path */
    MemoryAccess(memOut, aluOut, regOut2, memWrite, mainMem);
    Mux2_32(regIn, aluOut, memOut, memToReg);

    /* register memory data path - write */
    registerAccess(&regOut1, &regOut2, &ir[6], &ir[11], regWriteAddr, regIn, regWrite);

    /* dump register memory and signal information */
    for (i=0; i < 14; i++) {
        inttobitn(i, 5, tmp);
        registerAccess(&regOut1, &regOut2, tmp, &ir[11], regWriteAddr, regIn, '0');
        printf("R%d: %d, ", i, bit32toint(regOut1));
    }
    printf("\b\b\n\tbranchAddress = %.32s (%d) jumpAddress = %.32s (%d)\n",
        branchAddress, bit32toint(branchAddress), jumpAddress, bit32toint(jumpAddress));
    printf("\topcode = %.6s, immSignExt = %.32s (%d), immShifted = %.32s (%d), PC+4 = %.32s (%d)\n",
        ir, immSignExt, bit32toint(immSignExt), immShifted, bit32toint(immShifted), pcPlus4, bit32toint(pcPlus4));
    printf("\tregWrite = %c, regDest = %c, memRead = %c, memWrite = %c, memToReg = %c, jump = %c, branch = %c, aluSrc = %c, aluOp = %.3s, zero = %c\n",
        regWrite, regDest, memRead, memWrite, memToReg, jump, branch, aluSrc, aluOp, zero);
    getchar();
}
void MemoryAccess(bit32 read_out, bit32 addr, bit32 write_in, signal write_enable, bit8 memory[4096]){

int address= bitntoint(12, addr);
setbit8(read_out, memory[address]);
setbit8(&read_out[8], memory[address+1]);
setbit8(&read_out[16], memory[address+2]);
setbit8(&read_out[24], memory[address+3]);

if (write_enable){
    setbit8(memory[address], write_in);
    setbit8(memory[address+1], &write_in[8]);
    setbit8(memory[address+2], &write_in[16]);
    setbit8(memory[address+3], &write_in[24]);
}
问题是,从第二次迭代开始,“ir”的值仍然是“00000000”。我已经检查了instrMem,值并不都是0。我还使用驱动程序函数检查了MemoryAccess()的工作情况。它很好用

我无法理解为什么它在第一次迭代中运行良好,而不是从那时起

有人能帮忙吗。有没有办法找出问题所在

以下是main()函数的相关部分:

MemoryAccess(ir, pc, ground, '0', instrMem); 
typedef char bit32[33];
bit8 instrMem[4096];    /* instruction memory */
bit32 pc, ir, ground;
   for(cycle=0; ; cycle++) 
{
    /* load IR with PC value */
    printf("I am at the beginning of the cycle loop");
    MemoryAccess(ir, pc, ground, '0', instrMem); 

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

    /* halt check */
    if (bit32toint(ir) == 0x0000003F) {
        printf("\nmachine halted\n");
        break;
    }

    /* PC + 4 data path */
    RCAdder_32(pcPlus4, ground, pc, "00000000000000000000000000000100", '0');

    /* jump data path */
    shiftleftby2(jumpAddress, ir);
    jumpAddress[0] = pcPlus4[0];
    jumpAddress[1] = pcPlus4[1];
    jumpAddress[2] = pcPlus4[2];
    jumpAddress[3] = pcPlus4[3];

    /* sign extended / shifted immediate data path */
    signextend(immSignExt, &ir[16]); 
    shiftleftby2(immShifted, immSignExt); 

    /* control unit data path */
    ControlUnit(ir, &ir[26], &regWrite, &regDest,
                    &memRead, &memWrite, &memToReg, 
                    &jump, &branch, &aluSrc, aluOp);

    /* register memory data path - read */
    Mux2_5(regWriteAddr, &ir[11], &ir[16], regDest);
    registerAccess(&regOut1, &regOut2, &ir[6], &ir[11], regWriteAddr, regIn, '0');

    /* alu data path */
    Mux2_32(aluSrcVal, regOut2, immSignExt, aluSrc);
    zero = ALU(&aluOut, regOut1, aluSrcVal, aluOp);

    /* branch data path */
    RCAdder_32(branchAddress, ground, pcPlus4, immShifted, '0');
    Mux2_32(mbranchAddress, pcPlus4, branchAddress, AND2_1(zero, branch));
    Mux2_32(pc, mbranchAddress, jumpAddress, jump);

    /* main memory data path */
    MemoryAccess(memOut, aluOut, regOut2, memWrite, mainMem);
    Mux2_32(regIn, aluOut, memOut, memToReg);

    /* register memory data path - write */
    registerAccess(&regOut1, &regOut2, &ir[6], &ir[11], regWriteAddr, regIn, regWrite);

    /* dump register memory and signal information */
    for (i=0; i < 14; i++) {
        inttobitn(i, 5, tmp);
        registerAccess(&regOut1, &regOut2, tmp, &ir[11], regWriteAddr, regIn, '0');
        printf("R%d: %d, ", i, bit32toint(regOut1));
    }
    printf("\b\b\n\tbranchAddress = %.32s (%d) jumpAddress = %.32s (%d)\n",
        branchAddress, bit32toint(branchAddress), jumpAddress, bit32toint(jumpAddress));
    printf("\topcode = %.6s, immSignExt = %.32s (%d), immShifted = %.32s (%d), PC+4 = %.32s (%d)\n",
        ir, immSignExt, bit32toint(immSignExt), immShifted, bit32toint(immShifted), pcPlus4, bit32toint(pcPlus4));
    printf("\tregWrite = %c, regDest = %c, memRead = %c, memWrite = %c, memToReg = %c, jump = %c, branch = %c, aluSrc = %c, aluOp = %.3s, zero = %c\n",
        regWrite, regDest, memRead, memWrite, memToReg, jump, branch, aluSrc, aluOp, zero);
    getchar();
}
void MemoryAccess(bit32 read_out, bit32 addr, bit32 write_in, signal write_enable, bit8 memory[4096]){

int address= bitntoint(12, addr);
setbit8(read_out, memory[address]);
setbit8(&read_out[8], memory[address+1]);
setbit8(&read_out[16], memory[address+2]);
setbit8(&read_out[24], memory[address+3]);

if (write_enable){
    setbit8(memory[address], write_in);
    setbit8(memory[address+1], &write_in[8]);
    setbit8(memory[address+2], &write_in[16]);
    setbit8(memory[address+3], &write_in[24]);
}
}

Setbit8(a,b)将b复制到a中并附加“\0”

想要获得评论:

1显示的代码似乎没有增加
pc

2尽管您将
'0'
作为writeabel标志传递,但它并未按预期使用。你可能想换衣服

if (write_enable)
将来


由于以前版本的
内存
被作为第三个参数(
write\u in
)传入的指针引用的内容覆盖,这些参数可能是
0
s.

我们无法调试看不到的代码。当函数返回时,
ir
很可能超出范围。这只是一个猜测,因为您没有向我们显示代码。您不应该将
ir
的地址传递给
MemoryAccess
?我们需要查看相关的代码部分。@DavidSchwartz:是的,我理解。这里不可能给出完整的代码。但是你能告诉我调试这个问题的方法吗?可能是使用gdb或其他东西。在代码中添加大量的print语句,看看它首先偏离了您的预期。调试是一项从经验中获得的技能——也许你可以找到一位经验丰富的程序员来指导你。